{ "cells": [ { "cell_type": "raw", "metadata": {}, "source": [ "---\n", "title: \"Notebook 4: Control Flow & Functions\"\n", "subtitle: \"COMP 1150 β€” Computer Science Concepts\"\n", "author: \"Brendan Shea, PhD\"\n", "date: last-modified\n", "---" ] }, { "cell_type": "markdown", "metadata": { "colab_header": true }, "source": [ "\n", "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/brendanpshea/computing_concepts_python/blob/main/v2/notebooks/COMP1150_NB04_ControlFlowFunctions.ipynb) \n", "[Download .ipynb](https://raw.githubusercontent.com/brendanpshea/computing_concepts_python/main/v2/notebooks/COMP1150_NB04_ControlFlowFunctions.ipynb) Β· [View on GitHub](https://github.com/brendanpshea/computing_concepts_python/blob/main/v2/notebooks/COMP1150_NB04_ControlFlowFunctions.ipynb)\n" ] }, { "cell_type": "markdown", "id": "nb4-02-video", "metadata": {}, "source": [ "πŸ“Ί **Lecture video:** *(link coming soon)*" ] }, { "cell_type": "markdown", "id": "nb4-03-outcomes", "metadata": {}, "source": [ "## Learning Outcomes\n", "\n", "By the end of this notebook, you will be able to:\n", "\n", "- **Write** conditional logic with `if` / `elif` / `else`, including nested decisions\n", "- **Combine** conditions with `and`, `or`, and `not`\n", "- **Repeat** work with `while` and `for` loops, and steer them with `break` and `continue`\n", "- **Recognise** and avoid infinite loops\n", "- **Decompose** a problem into functions with parameters, default values, and return values\n", "- **Document** a function with a docstring, and call it with keyword arguments\n", "- **Explain** variable scope β€” why a value inside a function stays inside\n", "- **Test** your logic against edge cases before trusting it\n", "\n", "*Maps to course LOs: 4 (algorithmic problem-solving), 6 (constructing Python), 8 (modular design & abstraction)*" ] }, { "cell_type": "markdown", "id": "nb4-04-hook", "metadata": {}, "source": [ "## The Big Contract\n", "\n", "Welcome to the **Lost Crew Rescue Company**. A shipful of children is stranded, and the Company has taken The Big Contract to bring every last one home.\n", "\n", "**Wendy Darling**, the operations lead β€” who assigns every task in \"thimbles\" of responsibility and refuses to explain the unit β€” has the same problem Scrooge had last notebook, only worse. A rescue isn't a straight line. Some children need a medic; some need an escort; some are ready to go. The plan has to *make decisions* and *repeat itself* for every child, and it's far too big to write as one block β€” it has to be broken into reusable pieces.\n", "\n", "That's this entire notebook: programs that choose, programs that repeat, and programs broken into named, reusable parts." ] }, { "cell_type": "markdown", "id": "nb4-05-roadmap", "metadata": {}, "source": [ "## The Roadmap\n", "\n", "| Part | What you'll learn |\n", "|---|---|\n", "| Making decisions | `if` / `elif` / `else`, nested decisions, `and` / `or` / `not` |\n", "| Repeating until done | `while` loops, and the infinite-loop trap |\n", "| Repeating a known number of times | `for` loops, `range`, looping over a list |\n", "| Steering loops | `break`, `continue`, loops inside loops |\n", "| Functions | `def`, parameters, defaults & keyword arguments, docstrings, `return`, scope, decomposition |\n", "| Testing | finding the inputs that break your code |\n", "\n", "Everything builds on Notebook 3: a loop's condition is just a **boolean expression**, and the workflow is still **problem β†’ pseudocode β†’ flowchart β†’ Python β†’ verify**." ] }, { "cell_type": "markdown", "id": "nb4-06-callback", "metadata": {}, "source": [ "Notebook 3 left one shape greyed-out in the flowchart legend: the **decision diamond**. Every program so far ran straight down, top to bottom. That ends now β€” the diamond comes alive in the very next section." ] }, { "cell_type": "markdown", "id": "nb4-07-howto", "metadata": {}, "source": [ "Same habit as last notebook: most code cells open with a `# ⬇️ CHANGE THESE` block. **Edit the values, press Shift + Enter, watch the behaviour change.** Loops and conditionals are best understood by poking them until they surprise you." ] }, { "cell_type": "markdown", "id": "nb4-08-if-intro", "metadata": {}, "source": [ "## Making Decisions: `if`\n", "\n", "**Tinker Bell** handles signals. She can hold exactly one feeling at a time β€” she is, functionally, a single `bool`. The gate either opens or it doesn't.\n", "\n", "An `if` statement runs a block of code **only when a condition is `True`**. The condition is exactly the kind of boolean expression you built in Notebook 3.\n", "\n", "```text\n", "if :\n", " \n", "```\n", "\n", "Two things Python is strict about: the **colon** after the condition, and the **indentation** of the block. The example below opens a gate only for the right password β€” change it and re-run." ] }, { "cell_type": "code", "execution_count": 1, "id": "nb4-09-if-code", "metadata": { "execution": { "iopub.execute_input": "2026-06-02T14:23:21.056666Z", "iopub.status.busy": "2026-06-02T14:23:21.055923Z", "iopub.status.idle": "2026-06-02T14:23:21.069089Z", "shell.execute_reply": "2026-06-02T14:23:21.066481Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Tinker Bell flares green.\n", "The gate opens.\n", "(the check is over)\n" ] } ], "source": [ "# ⬇️ CHANGE THIS, THEN RE-RUN\n", "password = \"pixie\"\n", "# ----------------------------------\n", "\n", "if password == \"pixie\":\n", " print(\"Tinker Bell flares green.\")\n", " print(\"The gate opens.\")\n", "\n", "print(\"(the check is over)\")" ] }, { "cell_type": "markdown", "id": "nb4-10-if-walkthrough", "metadata": {}, "source": [ "### Understanding the Code\n", "\n", "- `password == \"pixie\"` is a boolean expression β€” `True` or `False` (note `==` *tests*, `=` *assigns*; the NB 3 trap).\n", "- Both indented lines run **together**, only when the condition is `True`. They are the *block*.\n", "- `print(\"(the check is over)\")` is **not** indented, so it runs every time. Change `password` to anything else: the green-flare lines vanish, the last line stays." ] }, { "cell_type": "markdown", "id": "nb4-11-elif-intro", "metadata": {}, "source": [ "## `elif` and `else`: Choosing One of Many\n", "\n", "**Captain Hook** runs the rival outfit by rigid Articles: a table of rules where exactly one applies. That's `if` / `elif` / `else`:\n", "\n", "- `if` β€” checked first\n", "- `elif` (\"else if\") β€” checked only if the ones above were `False`; you can have many\n", "- `else` β€” the catch-all when nothing above matched\n", "\n", "Python checks them **top to bottom and stops at the first `True`**. The next cell sets a crew member's share by rank β€” try each rank." ] }, { "cell_type": "code", "execution_count": 2, "id": "nb4-12-elif-code", "metadata": { "execution": { "iopub.execute_input": "2026-06-02T14:23:21.074440Z", "iopub.status.busy": "2026-06-02T14:23:21.073990Z", "iopub.status.idle": "2026-06-02T14:23:21.082710Z", "shell.execute_reply": "2026-06-02T14:23:21.080551Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hook's Articles grant a 20% share.\n" ] } ], "source": [ "# ⬇️ CHANGE THIS, THEN RE-RUN\n", "rank = \"bosun\"\n", "# ----------------------------------\n", "\n", "if rank == \"captain\":\n", " share = 50\n", "elif rank == \"bosun\":\n", " share = 20\n", "elif rank == \"deckhand\":\n", " share = 10\n", "else:\n", " share = 0\n", "\n", "print(f\"Hook's Articles grant a {share}% share.\")" ] }, { "cell_type": "markdown", "id": "nb4-13-elif-walkthrough", "metadata": {}, "source": [ "### Understanding the Code\n", "\n", "- With `rank = \"bosun\"`: the `if` is `False`, the first `elif` is `True` β†’ `share = 20`, and Python **skips the rest entirely**. `deckhand` and `else` are never even looked at.\n", "- Order matters. If two conditions could both be true, the **first** one wins.\n", "- `else` has no condition β€” it's whatever's left. Try `rank = \"stowaway\"`: nothing matches, so `else` gives `share = 0`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### ✏️ Your Turn β€” Sort the Arrivals\n", "\n", "A child arrives at the rescue ship. Set `status` to `\"medical\"`, `\"escort\"`, or anything else, then use `if` / `elif` / `else` to print where they go: medical β†’ *To the sick bay*, escort β†’ *Assign an escort*, anything else β†’ *Cleared to board*." ] }, { "cell_type": "code", "metadata": {}, "execution_count": null, "outputs": [], "source": [ "#| eval: false\n", "# ⬇️ CHANGE THIS, THEN RE-RUN\n", "status = \"escort\"\n", "# ----------------------------------\n", "\n", "# TODO: print a different message for medical / escort / anything else." ] }, { "cell_type": "markdown", "id": "nb4-14-flowchart-intro", "metadata": {}, "source": [ "### The Same Logic, as a Flowchart\n", "\n", "Here is the `if`/`elif`/`else` above, drawn as a flowchart β€” the **decision diamond** Notebook 3 promised. Trace it like the code: enter at *Start*, follow a `True` or `False` arrow out of each diamond, and notice every path ends at the same `print`." ] }, { "cell_type": "code", "execution_count": 3, "id": "nb4-15-decision-flowchart", "metadata": { "cellView": "form", "execution": { "iopub.execute_input": "2026-06-02T14:23:21.087001Z", "iopub.status.busy": "2026-06-02T14:23:21.086625Z", "iopub.status.idle": "2026-06-02T14:23:22.244210Z", "shell.execute_reply": "2026-06-02T14:23:22.241948Z" }, "jupyter": { "source_hidden": true } }, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "S\n", "\n", "Start\n", "\n", "\n", "\n", "C\n", "\n", "rank == 'captain'?\n", "\n", "\n", "\n", "S->C\n", "\n", "\n", "\n", "\n", "\n", "B\n", "\n", "rank == 'bosun'?\n", "\n", "\n", "\n", "C->B\n", "\n", "\n", " False\n", "\n", "\n", "\n", "P1\n", "\n", "share = 50\n", "\n", "\n", "\n", "C->P1\n", "\n", "\n", " True\n", "\n", "\n", "\n", "P2\n", "\n", "share = 20\n", "\n", "\n", "\n", "B->P2\n", "\n", "\n", " True\n", "\n", "\n", "\n", "P3\n", "\n", "share = 0 (else)\n", "\n", "\n", "\n", "B->P3\n", "\n", "\n", " False\n", "\n", "\n", "\n", "E\n", "\n", "print share\n", "\n", "\n", "\n", "P1->E\n", "\n", "\n", "\n", "\n", "\n", "P2->E\n", "\n", "\n", "\n", "\n", "\n", "P3->E\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#| echo: false\n", "#@title πŸ“Š Decision-flowchart code (click to show)\n", "from graphviz import Digraph\n", "\n", "fc = Digraph(graph_attr={\"rankdir\": \"TB\"})\n", "fc.node(\"S\", \"Start\", shape=\"ellipse\", style=\"filled\", fillcolor=\"lightgreen\")\n", "fc.node(\"C\", \"rank == 'captain'?\", shape=\"diamond\", style=\"filled\", fillcolor=\"mistyrose\")\n", "fc.node(\"B\", \"rank == 'bosun'?\", shape=\"diamond\", style=\"filled\", fillcolor=\"mistyrose\")\n", "fc.node(\"P1\", \"share = 50\", shape=\"box\", style=\"filled\", fillcolor=\"lightyellow\")\n", "fc.node(\"P2\", \"share = 20\", shape=\"box\", style=\"filled\", fillcolor=\"lightyellow\")\n", "fc.node(\"P3\", \"share = 0 (else)\", shape=\"box\", style=\"filled\", fillcolor=\"lightyellow\")\n", "fc.node(\"E\", \"print share\", shape=\"parallelogram\", style=\"filled\", fillcolor=\"lightblue\")\n", "fc.edge(\"S\", \"C\")\n", "fc.edge(\"C\", \"P1\", label=\" True\")\n", "fc.edge(\"C\", \"B\", label=\" False\")\n", "fc.edge(\"B\", \"P2\", label=\" True\")\n", "fc.edge(\"B\", \"P3\", label=\" False\")\n", "fc.edge(\"P1\", \"E\"); fc.edge(\"P2\", \"E\"); fc.edge(\"P3\", \"E\")\n", "fc" ] }, { "cell_type": "markdown", "id": "nb4-16-flowchart-caption", "metadata": {}, "source": [ "**Reading it:** each diamond is one condition; the `True` arrow runs that branch, the `False` arrow falls through to the next test. Exactly one yellow box is ever reached. That single-path-through is the visual definition of `if`/`elif`/`else`." ] }, { "cell_type": "markdown", "id": "nb4-17-nested-intro", "metadata": {}, "source": [ "### Decisions Inside Decisions\n", "\n", "A decision can live *inside* another. The Sentry, **Doran Holt** β€” who won't let his own mother in without the password β€” needs two things true, in order: first a valid password, then a place on the list. The next cell nests one `if` inside another." ] }, { "cell_type": "code", "execution_count": 4, "id": "nb4-18-nested-code", "metadata": { "execution": { "iopub.execute_input": "2026-06-02T14:23:22.250665Z", "iopub.status.busy": "2026-06-02T14:23:22.250017Z", "iopub.status.idle": "2026-06-02T14:23:22.259249Z", "shell.execute_reply": "2026-06-02T14:23:22.257039Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Password ok β€” but you're not on the list.\n" ] } ], "source": [ "# ⬇️ CHANGE THESE, THEN RE-RUN\n", "has_password = True\n", "on_the_list = False\n", "# ----------------------------------\n", "\n", "if has_password:\n", " if on_the_list:\n", " print(\"Welcome aboard.\")\n", " else:\n", " print(\"Password ok β€” but you're not on the list.\")\n", "else:\n", " print(\"No password, no entry.\")" ] }, { "cell_type": "markdown", "id": "nb4-19-nested-walkthrough", "metadata": {}, "source": [ "### Understanding the Code\n", "\n", "- The **indentation level** shows the nesting: the inner `if`/`else` is two levels deep, so it only runs when the outer `if` is `True`.\n", "- This same logic could be written with `and` from Notebook 3: `if has_password and on_the_list:`. Nesting is clearer when the two checks need *different* messages; `and` is shorter when they don't. Both are valid β€” choose the readable one." ] }, { "cell_type": "markdown", "id": "a139ab23d05b", "metadata": {}, "source": [ "## Combining Conditions: `and`, `or`, `not`\n", "\n", "One test often isn't enough. Hook won't pay out unless a crew member is **both** signed to the Articles **and** present at muster. Python joins tests with three words:\n", "\n", "- `and` β€” `True` only when **both** sides are true\n", "- `or` β€” `True` when **at least one** side is true\n", "- `not` β€” flips a value: `not True` is `False`\n", "\n", "The next cell decides whether a crew member gets paid." ] }, { "cell_type": "code", "execution_count": 5, "id": "64c5b007bc79", "metadata": { "execution": { "iopub.execute_input": "2026-06-02T14:23:22.264192Z", "iopub.status.busy": "2026-06-02T14:23:22.263469Z", "iopub.status.idle": "2026-06-02T14:23:22.272810Z", "shell.execute_reply": "2026-06-02T14:23:22.270498Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Pay this crew member.\n" ] } ], "source": [ "# ⬇️ CHANGE THESE, THEN RE-RUN\n", "signed = True\n", "present = True\n", "deserted = False\n", "# ----------------------------------\n", "\n", "if signed and present and not deserted:\n", " print(\"Pay this crew member.\")\n", "elif signed or present:\n", " print(\"Hold for review.\")\n", "else:\n", " print(\"No claim.\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### ✏️ Your Turn β€” Clear for Takeoff\n", "\n", "The ship may launch only if it has fuel **and** the crew is aboard **and** it is **not** storming. Set the three boxes below, then print a single `True`/`False` for whether it can launch." ] }, { "cell_type": "code", "metadata": {}, "execution_count": null, "outputs": [], "source": [ "#| eval: false\n", "# ⬇️ CHANGE THESE, THEN RE-RUN\n", "has_fuel = True\n", "crew_aboard = True\n", "storming = False\n", "# ----------------------------------\n", "\n", "# TODO: print one True/False value: can the ship launch?" ] }, { "cell_type": "markdown", "id": "46be1bb057cc", "metadata": {}, "source": [ "### Understanding the Code\n", "\n", "- `signed and present and not deserted` is `True` only when **all three** parts hold: `signed` is `True`, `present` is `True`, and `deserted` is `False` (so `not deserted` is `True`).\n", "- Python reads `not` first, then `and`, then `or` β€” like `Γ—` before `+` in maths. When in doubt, add brackets: `(signed and present) or captain` makes the grouping plain.\n", "- **Short-circuit:** with `and`, if the first part is `False`, Python doesn't bother checking the rest β€” the answer can't change. `or` stops at the first `True`. Put the cheapest or most likely test first." ] }, { "cell_type": "markdown", "id": "nb4-20-while-intro", "metadata": {}, "source": [ "## Repeating Until Done: `while`\n", "\n", "**Peter Pan** is the field agent who never quits. A `while` loop is his whole personality: **repeat a block as long as a condition stays `True`.**\n", "\n", "```text\n", "while :\n", " \n", "```\n", "\n", "The condition is re-checked **before every pass**. Use `while` when you don't know in advance how many repetitions you'll need β€” only the condition that means \"stop.\" The next cell counts a clock down to zero." ] }, { "cell_type": "code", "execution_count": 6, "id": "nb4-21-while-code", "metadata": { "execution": { "iopub.execute_input": "2026-06-02T14:23:22.278302Z", "iopub.status.busy": "2026-06-02T14:23:22.277530Z", "iopub.status.idle": "2026-06-02T14:23:22.287020Z", "shell.execute_reply": "2026-06-02T14:23:22.285182Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The crocodile clock ticks: 5 left\n", "The crocodile clock ticks: 4 left\n", "The crocodile clock ticks: 3 left\n", "The crocodile clock ticks: 2 left\n", "The crocodile clock ticks: 1 left\n", "Time's up. Tick tock.\n" ] } ], "source": [ "# ⬇️ CHANGE THIS, THEN RE-RUN\n", "minutes = 5\n", "# ----------------------------------\n", "\n", "while minutes > 0:\n", " print(f\"The crocodile clock ticks: {minutes} left\")\n", " minutes = minutes - 1 # progress toward the exit\n", "\n", "print(\"Time's up. Tick tock.\")" ] }, { "cell_type": "markdown", "id": "nb4-22-while-walkthrough", "metadata": {}, "source": [ "### Understanding the Code β€” the Three-Part Loop\n", "\n", "Every safe `while` loop has three parts. Lose one and it breaks:\n", "\n", "1. **Initialise** β€” `minutes = 5` before the loop.\n", "2. **Test** β€” `while minutes > 0:` re-checked each pass.\n", "3. **Progress** β€” `minutes = minutes - 1` *moves the variable toward the stop condition*.\n", "\n", "The line that matters most is the progress line. Delete it and `minutes` is always 5, the condition is always `True`, and the loop runs **forever**." ] }, { "cell_type": "markdown", "id": "nb4-23-infinite", "metadata": {}, "source": [ "### ⚠️ The Infinite Loop\n", "\n", "Peter Pan refuses to grow up. As code, he is a loop with no progress toward its exit:\n", "\n", "```python\n", "age = 10\n", "while age < 18:\n", " print(\"Peter refuses to grow up.\")\n", " # age never changes -> the condition is always True -> forever\n", "```\n", "\n", "*(Deliberately not a runnable cell.)* If you ever start one by accident, **stop it** in Colab with the ⏹ button or **Runtime β†’ Interrupt execution**. The cure is always the same: make sure something inside the loop moves the test toward `False`." ] }, { "cell_type": "markdown", "id": "936350ac", "metadata": {}, "source": [ "### Will It Always Stop?\n", "\n", "Peter's loop never ends because nothing moves it toward the exit. That points at a quiet promise *every* loop makes: **something inside it must change so the condition will eventually become `False`.** Break that promise and the loop runs forever.\n", "\n", "Now a question that sounds easy and isn't: could you write one program that reads *any* loop and decides whether it will ever stop? For a small loop, sure β€” you trace it by hand. But in general, **no program can answer that question for every possible loop.** That isn't a gap in our cleverness; it was *proven* impossible. The result is called the **halting problem**, and we meet it properly in Notebook 7. For now, notice where you are: you bumped into one of the deepest limits in all of computer science just by writing a `while` loop." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### πŸ’­ Think About It β€” Will It Always Stop?\n", "\n", "You saw that a loop with the wrong condition can run forever. Sometimes it's obvious a loop will end; sometimes it really isn't.\n", "\n", "- For an everyday process (boiling pasta, waiting for a bus, searching your room for your keys), how do you *know* it will eventually finish? Is that guarantee built into the steps, or do you just trust it?\n", "- Can you describe a set of instructions that might run forever for some starting inputs but stop for others?\n", "- Why might it matter β€” for software running a plane or a hospital monitor β€” to be *certain* a program will always finish what it started?\n", "\n", "There are no single right answers here β€” share a sentence or two on each." ] }, { "cell_type": "markdown", "id": "nb4-24-while-flowchart-intro", "metadata": {}, "source": [ "### The `while` Loop, as a Flowchart\n", "\n", "A `while` loop is the first flowchart with an arrow that goes *backwards*. Watch the **\"loop back\"** edge: the diamond is tested, the body runs, and control returns to the diamond β€” over and over, until the test is finally `False`." ] }, { "cell_type": "code", "execution_count": 7, "id": "nb4-25-while-flowchart", "metadata": { "cellView": "form", "execution": { "iopub.execute_input": "2026-06-02T14:23:22.291786Z", "iopub.status.busy": "2026-06-02T14:23:22.291308Z", "iopub.status.idle": "2026-06-02T14:23:23.479061Z", "shell.execute_reply": "2026-06-02T14:23:23.476408Z" }, "jupyter": { "source_hidden": true } }, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "S\n", "\n", "minutes = 5\n", "\n", "\n", "\n", "C\n", "\n", "minutes > 0 ?\n", "\n", "\n", "\n", "S->C\n", "\n", "\n", "\n", "\n", "\n", "B\n", "\n", "print + minutes = minutes - 1\n", "\n", "\n", "\n", "C->B\n", "\n", "\n", " True\n", "\n", "\n", "\n", "E\n", "\n", "print 'Time's up'\n", "\n", "\n", "\n", "C->E\n", "\n", "\n", " False\n", "\n", "\n", "\n", "B->C\n", "\n", "\n", " loop back\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#| echo: false\n", "#@title πŸ“Š While-loop flowchart code (click to show)\n", "wf = Digraph(graph_attr={\"rankdir\": \"TB\"})\n", "wf.node(\"S\", \"minutes = 5\", shape=\"box\", style=\"filled\", fillcolor=\"lightyellow\")\n", "wf.node(\"C\", \"minutes > 0 ?\", shape=\"diamond\", style=\"filled\", fillcolor=\"mistyrose\")\n", "wf.node(\"B\", \"print + minutes = minutes - 1\", shape=\"box\", style=\"filled\", fillcolor=\"lightyellow\")\n", "wf.node(\"E\", \"print 'Time's up'\", shape=\"parallelogram\", style=\"filled\", fillcolor=\"lightblue\")\n", "wf.edge(\"S\", \"C\")\n", "wf.edge(\"C\", \"B\", label=\" True\")\n", "wf.edge(\"B\", \"C\", label=\" loop back\")\n", "wf.edge(\"C\", \"E\", label=\" False\")\n", "wf" ] }, { "cell_type": "markdown", "id": "nb4-26-while-flowchart-caption", "metadata": {}, "source": [ "**Reading it:** the `loop back` arrow *is* the repetition. The only way out is the `False` edge β€” which only happens because the body changes `minutes`. No backward arrow that can ever turn `False` = infinite loop." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### ✏️ Your Turn β€” Count the Pixie Dust\n", "\n", "The ship burns one measure of pixie dust each minute. Start with some `dust` and use a `while` loop to print how much is left each minute until it runs out, then print *Out of dust!*. Make sure something changes each pass β€” otherwise you'll loop forever." ] }, { "cell_type": "code", "metadata": {}, "execution_count": null, "outputs": [], "source": [ "#| eval: false\n", "# ⬇️ CHANGE THIS, THEN RE-RUN\n", "dust = 5\n", "# ----------------------------------\n", "\n", "# TODO: while dust > 0, print how much is left, then reduce dust by 1.\n", "# After the loop, print \"Out of dust!\"." ] }, { "cell_type": "markdown", "id": "nb4-27-for-intro", "metadata": {}, "source": [ "## Repeating a Known Number of Times: `for`\n", "\n", "**Nana**, head of safety, patrols the whole nursery every night, in order, and counts every child twice because once is not rigorous. When you know *exactly what to step through*, use a `for` loop.\n", "\n", "`range(1, n + 1)` produces `1, 2, ..., n` (the `+ 1` because `range` stops *before* its second number β€” the rule from Notebook 1's loops). The next cell patrols a fixed number of children." ] }, { "cell_type": "code", "execution_count": 8, "id": "nb4-28-for-range-code", "metadata": { "execution": { "iopub.execute_input": "2026-06-02T14:23:23.485785Z", "iopub.status.busy": "2026-06-02T14:23:23.484699Z", "iopub.status.idle": "2026-06-02T14:23:23.495314Z", "shell.execute_reply": "2026-06-02T14:23:23.492567Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Nana checks child #1\n", "Nana checks child #2\n", "Nana checks child #3\n", "Nana checks child #4\n", "Nursery secure.\n" ] } ], "source": [ "# ⬇️ CHANGE THIS, THEN RE-RUN\n", "children = 4\n", "# ----------------------------------\n", "\n", "for child in range(1, children + 1):\n", " print(f\"Nana checks child #{child}\")\n", "\n", "print(\"Nursery secure.\")" ] }, { "cell_type": "markdown", "id": "nb4-29-for-range-walkthrough", "metadata": {}, "source": [ "### Understanding the Code\n", "\n", "- `child` is the **loop variable**. Each pass it automatically takes the next value from `range` β€” you never update it yourself (the difference from `while`).\n", "- The loop runs a **known** number of times: exactly `children`. No infinite-loop risk β€” `range` is finite.\n", "- Use `for` when you can say *\"do this once for each ___\"*; use `while` when you can only say *\"keep going until ___\"*." ] }, { "cell_type": "markdown", "id": "nb4-30-for-list-intro", "metadata": {}, "source": [ "### Looping Directly Over a List\n", "\n", "A `for` loop doesn't need `range` at all β€” it can step straight through a **list**, handing you each item in turn. This is the cleanest loop in Python, and the next cell walks a roster of names." ] }, { "cell_type": "code", "execution_count": 9, "id": "nb4-31-for-list-code", "metadata": { "execution": { "iopub.execute_input": "2026-06-02T14:23:23.501145Z", "iopub.status.busy": "2026-06-02T14:23:23.499967Z", "iopub.status.idle": "2026-06-02T14:23:23.511528Z", "shell.execute_reply": "2026-06-02T14:23:23.509206Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Accounted for: Wendy\n", "Accounted for: John\n", "Accounted for: Michael\n", "3 children on the roster.\n" ] } ], "source": [ "# ⬇️ CHANGE THIS LIST, THEN RE-RUN\n", "roster = [\"Wendy\", \"John\", \"Michael\"]\n", "# ----------------------------------\n", "\n", "for name in roster:\n", " print(f\"Accounted for: {name}\")\n", "\n", "print(f\"{len(roster)} children on the roster.\")" ] }, { "cell_type": "markdown", "id": "nb4-32-for-list-walkthrough", "metadata": {}, "source": [ "### Understanding the Code\n", "\n", "- `for name in roster:` walks the list element by element; `name` is each child in turn. No `range`, no indexing.\n", "- `len(roster)` is the list's length (the same `len` from Notebook 3). Lists get a full notebook of their own next β€” here they're just something to loop over." ] }, { "cell_type": "markdown", "id": "nb4-33-accumulator-intro", "metadata": {}, "source": [ "### Totalling With an Accumulator\n", "\n", "Looping is most useful when each pass *adds to a running total*. You've seen this exact pattern before β€” Notebook 1's Lovelace factorial used `running_product`. The next cell uses the same idea to total supplies across a roster." ] }, { "cell_type": "code", "execution_count": 10, "id": "nb4-34-accumulator-code", "metadata": { "execution": { "iopub.execute_input": "2026-06-02T14:23:23.518043Z", "iopub.status.busy": "2026-06-02T14:23:23.516945Z", "iopub.status.idle": "2026-06-02T14:23:23.526725Z", "shell.execute_reply": "2026-06-02T14:23:23.524582Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Pack 12 supply units for 4 children.\n" ] } ], "source": [ "# ⬇️ CHANGE THESE, THEN RE-RUN\n", "supplies_per_child = 3\n", "roster = [\"Wendy\", \"John\", \"Michael\", \"Tootles\"]\n", "# ----------------------------------\n", "\n", "total = 0 # the accumulator β€” start empty\n", "for name in roster:\n", " total = total + supplies_per_child\n", "\n", "print(f\"Pack {total} supply units for {len(roster)} children.\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### ✏️ Your Turn β€” Total the Supplies\n", "\n", "Each child needs a different number of supplies. Use a `for` loop and an **accumulator** to add up the list below and print the total. (Try an empty list too β€” what should it print?)" ] }, { "cell_type": "code", "metadata": {}, "execution_count": null, "outputs": [], "source": [ "#| eval: false\n", "# ⬇️ CHANGE THIS LIST, THEN RE-RUN\n", "needs = [3, 1, 5, 1, 3]\n", "# ----------------------------------\n", "\n", "# TODO: start total = 0, add each value in needs with a for loop,\n", "# then print the total." ] }, { "cell_type": "markdown", "id": "nb4-35-accumulator-walkthrough", "metadata": {}, "source": [ "### Understanding the Code\n", "\n", "This is the **accumulator pattern**, now inside a real loop:\n", "\n", "- **Initialise before the loop:** `total = 0`.\n", "- **Update inside the loop:** `total = total + supplies_per_child`, once per child.\n", "- **Use after the loop:** print it.\n", "\n", "Initialise / update / use. Almost every \"add up / count / collect\" task is this pattern β€” the same shape as Lovelace's `running_product`." ] }, { "cell_type": "markdown", "id": "nb4-36-break-intro", "metadata": {}, "source": [ "## Steering Loops: `break` and `continue`\n", "\n", "Two keywords change a loop's flow, and both are almost always guarded by an `if`:\n", "\n", "- **`break`** β€” leave the loop *immediately*, skip whatever's left.\n", "- **`continue`** β€” skip the *rest of this pass* and jump to the next one.\n", "\n", "The next cell searches a roster: it skips one name and stops entirely at another." ] }, { "cell_type": "code", "execution_count": 11, "id": "nb4-37-break-code", "metadata": { "execution": { "iopub.execute_input": "2026-06-02T14:23:23.532392Z", "iopub.status.busy": "2026-06-02T14:23:23.531559Z", "iopub.status.idle": "2026-06-02T14:23:23.541290Z", "shell.execute_reply": "2026-06-02T14:23:23.539081Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Checked Wendy\n", "Found Slightly! Stop the search.\n", "Search ended.\n" ] } ], "source": [ "# ⬇️ CHANGE THESE, THEN RE-RUN\n", "roster = [\"Wendy\", \"John\", \"Slightly\", \"Michael\", \"Nibs\"]\n", "looking_for = \"Slightly\"\n", "# ----------------------------------\n", "\n", "for name in roster:\n", " if name == \"John\":\n", " continue # skip John, keep searching\n", " if name == looking_for:\n", " print(f\"Found {name}! Stop the search.\")\n", " break # leave the loop entirely\n", " print(f\"Checked {name}\")\n", "\n", "print(\"Search ended.\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### ✏️ Your Turn β€” Find the Stowaway\n", "\n", "Loop through `roster`, printing each name you check. The moment you reach `\"stowaway\"`, print *Caught!* and `break` out of the loop." ] }, { "cell_type": "code", "metadata": {}, "execution_count": null, "outputs": [], "source": [ "#| eval: false\n", "# ⬇️ CHANGE THESE, THEN RE-RUN\n", "roster = [\"Wendy\", \"John\", \"stowaway\", \"Michael\"]\n", "# ----------------------------------\n", "\n", "# TODO: loop the roster; print each name; when you hit \"stowaway\",\n", "# print \"Caught!\" and break." ] }, { "cell_type": "markdown", "id": "nb4-38-break-walkthrough", "metadata": {}, "source": [ "### Understanding the Code\n", "\n", "- `continue` at `John`: the `print(f\"Checked ...\")` line is skipped *for John only*; the loop moves straight to `Slightly`.\n", "- `break` at `Slightly`: the loop stops dead. `Michael` and `Nibs` are never checked.\n", "- This is **nested logic**: an `if` inside a `for`. Most real loops look like this β€” repetition wrapped around decisions." ] }, { "cell_type": "markdown", "id": "nb4-39-nested-loop-intro", "metadata": {}, "source": [ "### Loops Inside Loops\n", "\n", "A loop can contain another loop. Nana's rounds aren't one night β€” they're *every child, every night*. The next cell puts a child-loop inside a night-loop." ] }, { "cell_type": "code", "execution_count": 12, "id": "nb4-40-nested-loop-code", "metadata": { "execution": { "iopub.execute_input": "2026-06-02T14:23:23.545969Z", "iopub.status.busy": "2026-06-02T14:23:23.545284Z", "iopub.status.idle": "2026-06-02T14:23:23.553327Z", "shell.execute_reply": "2026-06-02T14:23:23.551987Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Night 1: Nana checks child #1\n", "Night 1: Nana checks child #2\n", "Night 1: Nana checks child #3\n", "Night 2: Nana checks child #1\n", "Night 2: Nana checks child #2\n", "Night 2: Nana checks child #3\n" ] } ], "source": [ "# ⬇️ CHANGE THESE, THEN RE-RUN\n", "nights = 2\n", "children = 3\n", "# ----------------------------------\n", "\n", "for night in range(1, nights + 1):\n", " for child in range(1, children + 1):\n", " print(f\"Night {night}: Nana checks child #{child}\")" ] }, { "cell_type": "markdown", "id": "nb4-41-nested-loop-walkthrough", "metadata": {}, "source": [ "### Understanding the Code\n", "\n", "- The **inner loop runs fully for each single pass of the outer loop**. Outer at `night 1` β†’ inner counts all 3 children β†’ *then* outer moves to `night 2`.\n", "- Total lines printed = `nights Γ— children` = 2 Γ— 3 = 6. Nested loops multiply; that matters a lot for speed later in the course.\n", "- Indentation depth shows the nesting β€” read it like an outline." ] }, { "cell_type": "markdown", "id": "fd36b357", "metadata": {}, "source": [ "## The Three Building Blocks: Why This Is All You Need\n", "\n", "Stop and notice something big. You have now seen every kind of control flow there is β€” not \"the ones we had time for,\" but *every* kind. Any algorithm, however huge, is built from just **three** structures:\n", "\n", "1. **Sequence** β€” do one step, then the next, in order. (Notebook 3's straight-line code.)\n", "2. **Selection** β€” choose between paths. (`if` / `elif` / `else`.)\n", "3. **Iteration** β€” repeat a block. (`while` and `for`.)\n", "\n", "That is the whole toolkit. A flight controller, a search engine, a video game β€” all of it is sequence, selection, and iteration, nested and combined. There is no secret fourth kind of control flow waiting in a later chapter." ] }, { "cell_type": "markdown", "id": "88e422fe", "metadata": {}, "source": [ "This isn't just a tidy observation β€” it's a proven theorem. In 1966, **Corrado BΓΆhm** and **Giuseppe Jacopini** showed that those three structures are *enough* to express any computation at all. It's called the **structured program theorem**, and it settled a real fight.\n", "\n", "Early programmers leaned on a command called `goto`, which could jump to *anywhere* else in the code. Programs became \"spaghetti\" β€” tangled jumps no human could follow. BΓΆhm and Jacopini proved `goto` was never necessary: sequence, selection, and iteration can do everything it could, in an orderly way. Modern languages quietly retired `goto`, and Wendy's rescue plans stay readable because of it. The diagram below shows the three shapes β€” the entire grammar of control flow." ] }, { "cell_type": "code", "execution_count": 13, "id": "98708e28", "metadata": { "cellView": "form", "execution": { "iopub.execute_input": "2026-06-02T14:23:23.558956Z", "iopub.status.busy": "2026-06-02T14:23:23.558457Z", "iopub.status.idle": "2026-06-02T14:23:24.582214Z", "shell.execute_reply": "2026-06-02T14:23:24.580496Z" }, "jupyter": { "source_hidden": true } }, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "cluster_seq\n", "\n", "Sequence\n", "\n", "\n", "cluster_sel\n", "\n", "Selection\n", "\n", "\n", "cluster_it\n", "\n", "Iteration\n", "\n", "\n", "\n", "s1\n", "\n", "Step 1\n", "\n", "\n", "\n", "s2\n", "\n", "Step 2\n", "\n", "\n", "\n", "s1->s2\n", "\n", "\n", "\n", "\n", "\n", "d\n", "\n", "test?\n", "\n", "\n", "\n", "y\n", "\n", "do A\n", "\n", "\n", "\n", "d->y\n", "\n", "\n", "True\n", "\n", "\n", "\n", "n\n", "\n", "do B\n", "\n", "\n", "\n", "d->n\n", "\n", "\n", "False\n", "\n", "\n", "\n", "t\n", "\n", "test?\n", "\n", "\n", "\n", "b\n", "\n", "body\n", "\n", "\n", "\n", "t->b\n", "\n", "\n", "True\n", "\n", "\n", "\n", "b->t\n", "\n", "\n", "loop back\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#| echo: false\n", "#@title 🧱 The three building blocks β€” diagram code (click to show)\n", "from graphviz import Digraph\n", "\n", "g = Digraph()\n", "g.attr(rankdir=\"TB\")\n", "g.attr(\"node\", fontname=\"Helvetica\")\n", "\n", "with g.subgraph(name=\"cluster_seq\") as s:\n", " s.attr(label=\"Sequence\", style=\"filled\", fillcolor=\"#e3f2fd\")\n", " s.node(\"s1\", \"Step 1\", shape=\"box\")\n", " s.node(\"s2\", \"Step 2\", shape=\"box\")\n", " s.edge(\"s1\", \"s2\")\n", "\n", "with g.subgraph(name=\"cluster_sel\") as s:\n", " s.attr(label=\"Selection\", style=\"filled\", fillcolor=\"#e8f5e9\")\n", " s.node(\"d\", \"test?\", shape=\"diamond\")\n", " s.node(\"y\", \"do A\", shape=\"box\")\n", " s.node(\"n\", \"do B\", shape=\"box\")\n", " s.edge(\"d\", \"y\", label=\"True\")\n", " s.edge(\"d\", \"n\", label=\"False\")\n", "\n", "with g.subgraph(name=\"cluster_it\") as s:\n", " s.attr(label=\"Iteration\", style=\"filled\", fillcolor=\"#fff3e0\")\n", " s.node(\"t\", \"test?\", shape=\"diamond\")\n", " s.node(\"b\", \"body\", shape=\"box\")\n", " s.edge(\"t\", \"b\", label=\"True\")\n", " s.edge(\"b\", \"t\", label=\"loop back\")\n", "g" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### πŸ’­ Think About It β€” Is That Really All There Is?\n", "\n", "You just learned that sequence, selection (`if`), and repetition (loops) are enough to express *any* algorithm at all.\n", "\n", "- Does it surprise you that everything a computer does reduces to just these three? Can you think of something a computer does that feels like it must need more β€” and guess how it might actually be built from the three?\n", "- Human instructions from a coach, teacher, or parent rarely sound like pure sequence/selection/repetition. What do humans add that these three building blocks leave out?\n", "- If these three are all you truly need, why do programming languages bother having so many other features? What might they be for?\n", "\n", "There are no single right answers here β€” share a sentence or two on each." ] }, { "cell_type": "markdown", "id": "d560115b", "metadata": {}, "source": [ "**Reading it:** Three shapes, left to right β€” a straight line (sequence), a fork (selection), and a loop-back arrow (iteration). Every program you ever write or read is some arrangement of just these three. That's a genuinely surprising fact, and it's the theoretical heart of this notebook." ] }, { "cell_type": "markdown", "id": "nb4-46-func-intro", "metadata": {}, "source": [ "## Decomposing Problems into Functions\n", "\n", "**Wendy Darling** never tackles The Big Contract as one job. She splits it into named sub-tasks, solves each once, and reuses them. That is **decomposition**, and the tool is the **function**.\n", "\n", "You met `def` informally in Notebook 1. Here it is, precisely:\n", "\n", "```text\n", "def name(parameters):\n", " \n", " return \n", "```\n", "\n", "- **Parameters** are named inputs the caller fills in.\n", "- **`return`** hands exactly one value back.\n", "- **Calling** it β€” `name(arguments)` β€” *is itself an expression* that becomes the returned value. The next cell defines and calls one." ] }, { "cell_type": "code", "execution_count": 15, "id": "nb4-47-def-code", "metadata": { "execution": { "iopub.execute_input": "2026-06-02T14:23:24.610394Z", "iopub.status.busy": "2026-06-02T14:23:24.609693Z", "iopub.status.idle": "2026-06-02T14:23:24.619189Z", "shell.execute_reply": "2026-06-02T14:23:24.617200Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Pack 12 units.\n", "20\n" ] } ], "source": [ "def supply_units(children, per_child):\n", " return children * per_child\n", "\n", "# ⬇️ CHANGE THESE CALLS, THEN RE-RUN\n", "needed = supply_units(4, 3)\n", "print(f\"Pack {needed} units.\")\n", "print(supply_units(10, 2))" ] }, { "cell_type": "markdown", "id": "nb4-48-def-walkthrough", "metadata": {}, "source": [ "### Understanding the Code\n", "\n", "- `def supply_units(children, per_child):` defines the function but **does not run it**. Nothing happens until it's *called*.\n", "- `supply_units(4, 3)` calls it: `children` becomes `4`, `per_child` becomes `3`, the body runs, `return` hands back `12`.\n", "- `needed = supply_units(4, 3)` stores that returned value; `print(supply_units(10, 2))` uses it directly. The call behaves exactly like the value it returns." ] }, { "cell_type": "markdown", "id": "f8ec119f", "metadata": {}, "source": [ "### A Function Is a Black Box\n", "\n", "Here's the deeper idea hiding inside `def`. Once Wendy has `supply_units`, she can *use* it without remembering how it works inside. The function's name and its inputs and output are its **interface** β€” the promise. The code in the body is the **implementation**. The caller is free to ignore the implementation entirely.\n", "\n", "That separation is **abstraction**, and it is arguably the single most important idea in computer science: hide the details behind a simple surface so you can think about one thing at a time. You already trust it constantly β€” `print()` and `int()` are black boxes you use every day without ever reading their source code. Every function you write becomes one more black box that future-you, or a teammate, can build on without reopening it." ] }, { "cell_type": "markdown", "id": "6581fd58", "metadata": {}, "source": [ "This is also *why* we decompose. A big problem split into well-named functions is a stack of black boxes, each small enough to understand and test on its own. Solving a problem by breaking it down until each piece is easy, then building back up, is called **top-down design** β€” the core problem-solving move in computer science.\n", "\n", "Decomposition has a second payoff: it kills repetition. Write a rule once, in one function, and call it everywhere instead of copying the logic. Programmers have a name for this principle β€” **DRY: Don't Repeat Yourself.** Repeated code is repeated bugs; a single function is a single place to fix." ] }, { "cell_type": "markdown", "id": "nb4-49-return-intro", "metadata": {}, "source": [ "### `return` vs `print`\n", "\n", "This is the single most common point of confusion with functions, so it gets its own example. `return` and `print` look similar but do completely different things. The next cell defines one function that **returns** and one that only **prints**, then inspects what the caller actually gets back." ] }, { "cell_type": "code", "execution_count": 16, "id": "nb4-50-return-code", "metadata": { "execution": { "iopub.execute_input": "2026-06-02T14:23:24.626447Z", "iopub.status.busy": "2026-06-02T14:23:24.625127Z", "iopub.status.idle": "2026-06-02T14:23:24.637325Z", "shell.execute_reply": "2026-06-02T14:23:24.634885Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "5\n", "r = 5 s = None\n" ] } ], "source": [ "def adds(a, b):\n", " return a + b # hands the value back\n", "\n", "def shows(a, b):\n", " print(a + b) # only displays it; returns nothing\n", "\n", "r = adds(2, 3) # r holds 5\n", "s = shows(2, 3) # prints 5, but s holds None\n", "print(\"r =\", r, \" s =\", s)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### ✏️ Your Turn β€” Write a Function\n", "\n", "Write a function `supplies_for(children, per_child)` that **returns** the total supplies needed (children Γ— per_child). Then call it and print the result. Return the value β€” don't `print` inside the function." ] }, { "cell_type": "code", "metadata": {}, "execution_count": null, "outputs": [], "source": [ "#| eval: false\n", "# TODO: define supplies_for(children, per_child) that RETURNS children * per_child,\n", "# then call it and print the result.\n", "\n", "# def supplies_for(children, per_child):\n", "# ..." ] }, { "cell_type": "markdown", "id": "nb4-51-return-walkthrough", "metadata": {}, "source": [ "### Understanding the Code\n", "\n", "- `return` gives a value **back to the program** β€” you can store it, do maths with it, pass it on.\n", "- `print` only puts text **on the screen** β€” the program gets nothing back.\n", "- A function with no `return` automatically returns `None`. That's why `s` is `None`: `shows` printed `5` but handed nothing back. If a function's result \"disappears,\" you almost certainly printed where you meant to return." ] }, { "cell_type": "markdown", "id": "nb4-52-scope-intro", "metadata": {}, "source": [ "### Scope: A Box That Stays Inside\n", "\n", "Remember the \"named box\" from Notebook 3? Inside a function, a variable lives in a box that **only exists while that function runs**. The next cell makes a local variable, returns it, and then tries to peek at it from outside." ] }, { "cell_type": "code", "execution_count": 17, "id": "nb4-53-scope-code", "metadata": { "execution": { "iopub.execute_input": "2026-06-02T14:23:24.644823Z", "iopub.status.busy": "2026-06-02T14:23:24.643892Z", "iopub.status.idle": "2026-06-02T14:23:24.654069Z", "shell.execute_reply": "2026-06-02T14:23:24.651148Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "pixie dust\n" ] } ], "source": [ "def brew():\n", " secret = \"pixie dust\" # a LOCAL box β€” exists only inside brew()\n", " return secret\n", "\n", "print(brew()) # works: 'pixie dust'\n", "\n", "# Uncomment the next line to see the error scope protects you from:\n", "# print(secret) # NameError: 'secret' is not defined out here" ] }, { "cell_type": "markdown", "id": "nb4-54-scope-walkthrough", "metadata": {}, "source": [ "### Understanding the Code\n", "\n", "- `secret` is **local** to `brew()`. When the function returns, the box is thrown away.\n", "- Using `secret` outside is a `NameError` β€” out there, the name was never defined.\n", "- Parameters are local too. This is *why* functions are safe building blocks: their internals can't collide with names elsewhere. Decomposition works because each piece is sealed." ] }, { "cell_type": "markdown", "id": "nb4-55-func-graphviz-intro", "metadata": {}, "source": [ "### Picture It: Arguments In, Value Out\n", "\n", "A function call is a small round trip. The diagram below shows it: the caller passes **arguments in**, the function works in its own **sealed local scope**, and a single **value comes back out**." ] }, { "cell_type": "code", "execution_count": 18, "id": "nb4-56-func-graphviz", "metadata": { "cellView": "form", "execution": { "iopub.execute_input": "2026-06-02T14:23:24.660251Z", "iopub.status.busy": "2026-06-02T14:23:24.659656Z", "iopub.status.idle": "2026-06-02T14:23:25.603187Z", "shell.execute_reply": "2026-06-02T14:23:25.600252Z" }, "jupyter": { "source_hidden": true } }, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "cluster_fn\n", "\n", "inside supply_units (local scope)\n", "\n", "\n", "\n", "C\n", "\n", "caller\n", "supply_units(4, 3)\n", "\n", "\n", "\n", "P\n", "\n", "children = 4\n", "per_child = 3\n", "\n", "\n", "\n", "C->P\n", "\n", "\n", " arguments in \n", "\n", "\n", "\n", "R\n", "\n", "return children * per_child\n", "\n", "\n", "\n", "P->R\n", "\n", "\n", "\n", "\n", "\n", "R->C\n", "\n", "\n", " 12 returned out \n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#| echo: false\n", "#@title πŸ“Š Function-call diagram code (click to show)\n", "g = Digraph(graph_attr={\"rankdir\": \"LR\"})\n", "g.node(\"C\", \"caller\\nsupply_units(4, 3)\", shape=\"box\", style=\"filled\", fillcolor=\"lightblue\")\n", "with g.subgraph(name=\"cluster_fn\") as f:\n", " f.attr(label=\"inside supply_units (local scope)\", style=\"filled\", fillcolor=\"oldlace\")\n", " f.node(\"P\", \"children = 4\\nper_child = 3\", shape=\"box\", style=\"filled\", fillcolor=\"lightyellow\")\n", " f.node(\"R\", \"return children * per_child\", shape=\"box\", style=\"filled\", fillcolor=\"lightyellow\")\n", " f.edge(\"P\", \"R\")\n", "g.edge(\"C\", \"P\", label=\" arguments in \")\n", "g.edge(\"R\", \"C\", label=\" 12 returned out \")\n", "g" ] }, { "cell_type": "markdown", "id": "nb4-57-func-graphviz-caption", "metadata": {}, "source": [ "**Reading it:** the shaded box is the local scope β€” `children` and `per_child` exist *only* in there. The caller never sees inside; it only sends arguments in and receives one value out. That sealed boundary is exactly what makes functions reusable." ] }, { "cell_type": "markdown", "id": "041e401759ec", "metadata": {}, "source": [ "### Default Values and Keyword Arguments\n", "\n", "A parameter can carry a **default value**, used only when the caller leaves it out. And when a function takes several parameters, you can **name** them at the call so you don't have to remember the order. The next cell gives `per_child` a default and shows both ways to call." ] }, { "cell_type": "code", "execution_count": 19, "id": "e876262751af", "metadata": { "execution": { "iopub.execute_input": "2026-06-02T14:23:25.608771Z", "iopub.status.busy": "2026-06-02T14:23:25.607937Z", "iopub.status.idle": "2026-06-02T14:23:25.618545Z", "shell.execute_reply": "2026-06-02T14:23:25.616303Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "12\n", "20\n", "20\n", "20\n" ] } ], "source": [ "def supply_units(children, per_child=3):\n", " return children * per_child\n", "\n", "print(supply_units(4)) # per_child defaults to 3 β†’ 12\n", "print(supply_units(4, 5)) # override by position β†’ 20\n", "print(supply_units(children=10, per_child=2)) # named arguments β†’ 20\n", "print(supply_units(per_child=2, children=10)) # named β†’ order doesn't matter β†’ 20" ] }, { "cell_type": "markdown", "id": "218ac266ef11", "metadata": {}, "source": [ "### Understanding the Code\n", "\n", "- `per_child=3` is a **default**. `supply_units(4)` leaves it out, so `per_child` is `3`. Defaults let one function handle both the common case and the special case.\n", "- Arguments **by position** (`supply_units(4, 5)`) match left to right. Arguments **by keyword** (`children=10, per_child=2`) name each one, so order stops mattering and the call reads like a sentence.\n", "- Rule of thumb: parameters **with** a default come **after** those without. `def f(a, b=1)` is fine; `def f(a=1, b)` is an error." ] }, { "cell_type": "markdown", "id": "a0cc20f544e1", "metadata": {}, "source": [ "### Docstrings: Saying What a Function Does\n", "\n", "A function that works but nobody understands is a liability. A **docstring** is a short string written as the first line *inside* the function. It's the standard place to say, in one sentence, what the function does β€” and Python reads it back through `help()`. The next cell adds one." ] }, { "cell_type": "code", "execution_count": 20, "id": "929fe4cf640b", "metadata": { "execution": { "iopub.execute_input": "2026-06-02T14:23:25.623744Z", "iopub.status.busy": "2026-06-02T14:23:25.622985Z", "iopub.status.idle": "2026-06-02T14:23:25.635281Z", "shell.execute_reply": "2026-06-02T14:23:25.632711Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Help on function supply_units in module __main__:\n", "\n", "supply_units(children, per_child=3)\n", " Return the total supply units needed for a group of children.\n", "\n", "Return the total supply units needed for a group of children.\n" ] } ], "source": [ "def supply_units(children, per_child=3):\n", " \"\"\"Return the total supply units needed for a group of children.\"\"\"\n", " return children * per_child\n", "\n", "help(supply_units) # Python prints the docstring\n", "print(supply_units.__doc__) # ...or read it directly" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### ✏️ Your Turn β€” Document It\n", "\n", "Take your `supplies_for` function from above. Give `per_child` a **default** of `3`, add a one-line **docstring** saying what it does, then call it once using a **keyword argument**." ] }, { "cell_type": "code", "metadata": {}, "execution_count": null, "outputs": [], "source": [ "#| eval: false\n", "# TODO: add a default (per_child=3) and a docstring, then call with a keyword arg.\n", "\n", "# def supplies_for(children, per_child=3):\n", "# \"\"\"...\"\"\"\n", "# ..." ] }, { "cell_type": "markdown", "id": "d88906e26ffc", "metadata": {}, "source": [ "### Understanding the Code\n", "\n", "- The triple-quoted line right under `def` is the docstring. It doesn't change what the function *does* β€” it documents it.\n", "- `help(supply_units)` and `supply_units.__doc__` both read it back, and Colab shows it as a tooltip when you call the function.\n", "- A good docstring says **what** the function returns and **what** the inputs mean β€” not how every line works. One clear sentence beats a paragraph." ] }, { "cell_type": "markdown", "id": "nb4-58-worked-intro", "metadata": {}, "source": [ "## The Workflow, With Functions: the Lost Crew Supply Run\n", "\n", "Now decomposition pays off on a real problem, through the full workflow. Wendy's problem, stated plainly:\n", "\n", "> *Given a roster where each child has a status (`\"medical\"`, `\"escort\"`, or anything else meaning `\"ready\"`), compute the total supply units the rescue needs. Medical children need 5, escort children need 3, ready children need 1.*\n", "\n", "- **Inputs:** `roster` (a list of status strings)\n", "- **Output:** total supply units (an integer)\n", "- **Decomposition:** one function decides *one child* (`assess`); another loops the whole roster and accumulates (`mission_total`)." ] }, { "cell_type": "markdown", "id": "nb4-59-worked-pseudocode", "metadata": {}, "source": [ "### Step 2 β€” Pseudocode\n", "\n", "```text\n", "FUNCTION assess(status):\n", " 1. IF status = \"medical\": RETURN 5\n", " 2. IF status = \"escort\": RETURN 3\n", " 3. OTHERWISE: RETURN 1\n", "\n", "FUNCTION mission_total(roster):\n", " 1. SET total = 0\n", " 2. FOR each status in roster:\n", " 2a. SET total = total + assess(status)\n", " 3. RETURN total\n", "```\n", "\n", "Two small algorithms. `mission_total` *calls* `assess` β€” a function using a function. That's decomposition in one picture." ] }, { "cell_type": "markdown", "id": "nb4-60-worked-flowchart-intro", "metadata": {}, "source": [ "### Step 3 β€” The Flowchart\n", "\n", "Here is `mission_total` as a flowchart. Notice it's a `for` loop over the roster with the **accumulator** inside β€” and each pass calls `assess` to decide that one child." ] }, { "cell_type": "code", "execution_count": 21, "id": "nb4-61-worked-flowchart", "metadata": { "cellView": "form", "execution": { "iopub.execute_input": "2026-06-02T14:23:25.641947Z", "iopub.status.busy": "2026-06-02T14:23:25.641210Z", "iopub.status.idle": "2026-06-02T14:23:26.031198Z", "shell.execute_reply": "2026-06-02T14:23:26.029235Z" }, "jupyter": { "source_hidden": true } }, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "S\n", "\n", "total = 0\n", "\n", "\n", "\n", "C\n", "\n", "more children\n", "in roster?\n", "\n", "\n", "\n", "S->C\n", "\n", "\n", "\n", "\n", "\n", "A\n", "\n", "total = total + assess(status)\n", "\n", "\n", "\n", "C->A\n", "\n", "\n", " yes\n", "\n", "\n", "\n", "R\n", "\n", "return total\n", "\n", "\n", "\n", "C->R\n", "\n", "\n", " no\n", "\n", "\n", "\n", "A->C\n", "\n", "\n", " next\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#| echo: false\n", "#@title πŸ“Š Workflow flowchart code (click to show)\n", "mf = Digraph(graph_attr={\"rankdir\": \"TB\"})\n", "mf.node(\"S\", \"total = 0\", shape=\"box\", style=\"filled\", fillcolor=\"lightyellow\")\n", "mf.node(\"C\", \"more children\\nin roster?\", shape=\"diamond\", style=\"filled\", fillcolor=\"mistyrose\")\n", "mf.node(\"A\", \"total = total + assess(status)\", shape=\"box\", style=\"filled\", fillcolor=\"lightyellow\")\n", "mf.node(\"R\", \"return total\", shape=\"parallelogram\", style=\"filled\", fillcolor=\"lightblue\")\n", "mf.edge(\"S\", \"C\")\n", "mf.edge(\"C\", \"A\", label=\" yes\")\n", "mf.edge(\"A\", \"C\", label=\" next\")\n", "mf.edge(\"C\", \"R\", label=\" no\")\n", "mf" ] }, { "cell_type": "markdown", "id": "nb4-62-worked-flowchart-caption", "metadata": {}, "source": [ "**Reading it:** the diamond is the `for` loop's \"any more items?\" test; the `yes` arrow loops back through the accumulator; the `no` arrow leaves with the finished `total`. The `assess(status)` call hides a whole second flowchart inside one box β€” that's the power of decomposition." ] }, { "cell_type": "markdown", "id": "nb4-63-worked-python-intro", "metadata": {}, "source": [ "### Step 4 β€” The Python\n", "\n", "Now translate both pseudocode functions line for line. Editable roster at the top so you can test it; the verification comes right after." ] }, { "cell_type": "code", "execution_count": 22, "id": "nb4-64-worked-python", "metadata": { "execution": { "iopub.execute_input": "2026-06-02T14:23:26.036463Z", "iopub.status.busy": "2026-06-02T14:23:26.035845Z", "iopub.status.idle": "2026-06-02T14:23:26.045573Z", "shell.execute_reply": "2026-06-02T14:23:26.043451Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Supplies needed: 15 units\n" ] } ], "source": [ "# ⬇️ CHANGE THIS ROSTER, THEN RE-RUN\n", "roster = [\"medical\", \"ready\", \"escort\", \"ready\", \"medical\"]\n", "# ----------------------------------\n", "\n", "def assess(status):\n", " if status == \"medical\":\n", " return 5\n", " elif status == \"escort\":\n", " return 3\n", " else:\n", " return 1\n", "\n", "def mission_total(children):\n", " total = 0\n", " for status in children:\n", " total = total + assess(status)\n", " return total\n", "\n", "print(f\"Supplies needed: {mission_total(roster)} units\")" ] }, { "cell_type": "markdown", "id": "nb4-65-worked-walkthrough", "metadata": {}, "source": [ "### Understanding the Code\n", "\n", "- `assess` is pure decision logic β€” one `if`/`elif`/`else`, one `return` per branch. It handles **one** child and nothing else.\n", "- `mission_total` is the accumulator pattern (initialise / update / use) **looping the roster** and *calling* `assess` each pass.\n", "- The last line is the whole program: call one function, print the result. Each piece is small enough to check on its own β€” the entire point of decomposition." ] }, { "cell_type": "markdown", "id": "nb4-66-worked-verify", "metadata": {}, "source": [ "### Step 5 β€” Verify by Hand\n", "\n", "`roster = [\"medical\", \"ready\", \"escort\", \"ready\", \"medical\"]`\n", "\n", "| status | assess |\n", "|---|---|\n", "| medical | 5 |\n", "| ready | 1 |\n", "| escort | 3 |\n", "| ready | 1 |\n", "| medical | 5 |\n", "\n", "Total = 5 + 1 + 3 + 1 + 5 = **15**. Run the cell β€” it should print `15`. Predicting the answer *before* running is the habit; the next section makes it a discipline." ] }, { "cell_type": "markdown", "id": "nb4-69-edge-intro", "metadata": {}, "source": [ "## Testing With Edge Cases\n", "\n", "**Mr. Smee** reads the fine print nobody else will. His idea of a threat is *\"but what if there are zero children?\"* β€” and he is always right to ask.\n", "\n", "Code that works on the *normal* input often shatters on the *extreme* one. Before trusting any function, run Smee's checklist:\n", "\n", "- **Zero / empty** β€” an empty list, the number 0\n", "- **Negative** β€” can a count go below zero?\n", "- **The boundary** β€” exactly the value where behaviour changes\n", "- **The unexpected** β€” a status nobody planned for\n", "- **Off-by-one** β€” first and last items of a loop\n", "\n", "The next cell looks correct β€” until Smee asks his question." ] }, { "cell_type": "code", "execution_count": 23, "id": "nb4-70-edge-code", "metadata": { "execution": { "iopub.execute_input": "2026-06-02T14:23:26.052047Z", "iopub.status.busy": "2026-06-02T14:23:26.051461Z", "iopub.status.idle": "2026-06-02T14:23:26.060100Z", "shell.execute_reply": "2026-06-02T14:23:26.057959Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3.0\n" ] } ], "source": [ "def average_supplies(roster):\n", " return mission_total(roster) / len(roster)\n", "\n", "print(average_supplies([\"medical\", \"ready\"])) # fine: 6 / 2 = 3.0\n", "\n", "# Smee asks: what about an empty roster?\n", "# Uncomment to see it shatter:\n", "# print(average_supplies([])) # ZeroDivisionError" ] }, { "cell_type": "markdown", "id": "nb4-71-edge-walkthrough", "metadata": {}, "source": [ "### Understanding the Code\n", "\n", "- On a normal roster, `average_supplies` is correct. On an **empty** roster, `len(roster)` is `0`, and dividing by zero crashes β€” the *exact* input Smee warned about.\n", "- Nothing in the function is \"wrong\" on the happy path. The bug only exists at the edge. **That's why you test edges deliberately** β€” the normal case hides them.\n", "- The habit: before running, write down what *should* happen for the weird inputs. Then run and compare. Surprises are bugs." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### ✏️ Your Turn β€” Break It (Smee's Checklist)\n", "\n", "The scaffold below re-creates `assess`, `mission_total`, and `average_supplies`. Your job is to **break them on purpose**.\n", "\n", "1. Find **two** inputs that break or mislead them β€” at least an **empty** roster and an **unexpected status** (does `\"VIP\"` silently count as `ready`? Is that intended?).\n", "2. For each, jot down the input, what you *expected*, and what *actually* happened.\n", "3. **Fix one** β€” for example, make `average_supplies` return `0` for an empty roster instead of crashing.\n", "\n", "Finding the breaking input *is* the skill. Smee is delighted when something breaks β€” that's a bug caught before the contract failed." ] }, { "cell_type": "code", "execution_count": 24, "id": "nb4-73-ex4-scaffold", "metadata": { "execution": { "iopub.execute_input": "2026-06-02T14:23:26.064964Z", "iopub.status.busy": "2026-06-02T14:23:26.064437Z", "iopub.status.idle": "2026-06-02T14:23:26.074049Z", "shell.execute_reply": "2026-06-02T14:23:26.071966Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "6\n" ] } ], "source": [ "# ✏️ Exercise 3 workspace.\n", "\n", "def assess(status):\n", " if status == \"medical\":\n", " return 5\n", " elif status == \"escort\":\n", " return 3\n", " else:\n", " return 1\n", "\n", "def mission_total(children):\n", " total = 0\n", " for status in children:\n", " total = total + assess(status)\n", " return total\n", "\n", "def average_supplies(roster):\n", " return mission_total(roster) / len(roster)\n", "\n", "# ⬇️ TRY BREAKING INPUTS HERE\n", "print(mission_total([\"medical\", \"ready\"]))\n", "# print(average_supplies([])) # <- start here\n" ] }, { "cell_type": "markdown", "id": "ba00c0fa", "metadata": {}, "source": [ "## Practice: PyQuiz\n", "\n", "More practice β€” same drill as Notebook 3. PyQuiz hands you a problem,\n", "you fill in the function body, click **Run Tests**. The bank below is\n", "heavier on `if`/`elif`/`else` and loops, since that's what this\n", "notebook taught you.\n", "\n", "A reminder on the two accumulator patterns you'll use a lot:\n", "\n", "```python\n", "# sum: start at 0, then +=\n", "total = 0\n", "for i in range(1, n + 1):\n", " total += i\n", "\n", "# product: start at 1, then *=\n", "product = 1\n", "for i in range(1, n + 1):\n", " product *= i\n", "```\n", "\n", "Run the cell below to load the practice tool.\n" ] }, { "cell_type": "code", "execution_count": null, "id": "b78a3d80", "metadata": { "execution": { "iopub.execute_input": "2026-06-02T14:23:26.078842Z", "iopub.status.busy": "2026-06-02T14:23:26.078396Z", "iopub.status.idle": "2026-06-02T14:23:32.304475Z", "shell.execute_reply": "2026-06-02T14:23:32.302425Z" } }, "outputs": [], "source": [ "# PyQuiz bootstrap β€” works in Colab or any local Jupyter.\n", "import os, urllib.request\n", "REPO = \"https://raw.githubusercontent.com/brendanpshea/computing_concepts_python/main\"\n", "if not os.path.exists(\"pyquiz.py\"):\n", " urllib.request.urlretrieve(f\"{REPO}/tools/python_code_quiz/pyquiz.py\", \"pyquiz.py\")\n", "\n", "from pyquiz import PracticeTool\n", "practice_tool = PracticeTool(\n", " json_url=f\"{REPO}/tools/python_code_quiz/banks/nb04_control_flow.json\"\n", ")\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## ✏️ Capstone β€” Build a Turn-Based Survival Game (AI-Assisted)\n", "\n", "This is where the whole notebook comes together. You'll build a small **turn-based game**: the player takes one action per turn, the game **loops** through the turns, each turn **decides** what happens, and the rules live in **functions** you write. Decisions, loops, functions β€” the three things this notebook is about, in one program.\n", "\n", "The default theme is the Lost Crew flying home β€” but **pick your own**: a dungeon crawl, a spaceship limping to port, a zombie night, a bakery rush before closing. Whatever it is, your game must:\n", "\n", "- **repeat** over several turns (a loop),\n", "- **branch** on what the player chooses or what randomly happens (`if` / `elif` / `else`),\n", "- be **broken into at least one function** you wrote (for example, one that resolves a single turn), and\n", "- track a **resource** that rises and falls β€” pixie dust, health, fuel, money β€” with a win or lose ending.\n", "\n", "**Step 1 β€” Design it first (before the AI).** In a markdown cell, jot down: your theme, the resource you track and its starting amount, the 2–3 actions a player can take each turn, what makes each one good or risky, and how the game is won or lost.\n", "\n", "**Step 2 β€” Turn your design into a prompt.** Fill the blanks and send it to Gemini (or Claude / ChatGPT):\n", "\n", "> *Write a small turn-based text game as a Python program for Google Colab. Theme: **[your theme]**. The player starts with **[N] [resource]** and plays up to **[number]** turns. Each turn they choose one of: **[your actions]**. Use `if`/`elif`/`else` to resolve the choice and change the resource. Put the per-turn logic in its own function. The game ends when **[win condition]** or **[lose condition]**. Show the resource each turn. Keep it short and beginner-readable.*\n", "\n", "**Step 3 β€” Get the bones working, then test.** Paste it into the cell below and **run it now**. Get the simplest version working first β€” one action, the resource changes, the loop ends β€” and check it by hand before adding more.\n", "\n", "**Step 4 β€” Add the bells and whistles.** Once the core runs, add **one or two** extras, testing after each: a random event each turn, a second resource, a high score, or a risky action with a big payoff.\n", "\n", "**Step 5 β€” Test it like Smee.** Try to break it: a turn count of 0, an action that isn't on the menu, a resource that goes negative. Fix one thing it gets wrong.\n", "\n", "**Step 6 β€” Reflect.** In a markdown cell, write 2–3 sentences: what did the AI get wrong or what did you improve, and how did you fix it?\n", "\n", "Remember the course rule: *AI is a fast first draft. You verify.*" ] }, { "cell_type": "code", "metadata": {}, "execution_count": null, "outputs": [], "source": [ "#| eval: false\n", "# ✏️ Paste your AI-built turn-based game here, then run it and fix what's broken." ] }, { "cell_type": "markdown", "id": "nb4-74-keyterms", "metadata": {}, "source": [ "## Key Terms\n", "\n", "- **Conditional** β€” Code that runs only when a condition is `True`.\n", "- **`if` / `elif` / `else`** β€” Choose exactly one branch; checked top-down, first `True` wins.\n", "- **Nested decision** β€” An `if` inside another `if`.\n", "- **`and` / `or` / `not`** β€” Combine or flip conditions; evaluated `not`, then `and`, then `or`.\n", "- **Short-circuit** β€” `and` / `or` stop checking once the result is already settled.\n", "- **`while` loop** β€” Repeats a block while a condition stays `True`.\n", "- **`for` loop** β€” Repeats once for each item in a range or list.\n", "- **Loop variable** β€” The variable a `for` loop assigns each pass.\n", "- **`range(a, b)`** β€” The integers from `a` up to but not including `b`.\n", "- **Iteration** β€” Repeating a block of code; one of the three control structures. (Also: one pass through a loop body.)\n", "- **Infinite loop** β€” A loop whose condition never becomes `False`; nothing makes progress toward the exit.\n", "- **`break` / `continue`** β€” Leave the loop entirely / skip to the next iteration.\n", "- **Accumulator** β€” A variable that builds a result across loop passes (initialise / update / use).\n", "- **Function** β€” A named, reusable block: `def name(parameters): ... return value`.\n", "- **Parameter / argument** β€” The named input in the definition / the actual value passed in a call.\n", "- **Default value** β€” A fallback for a parameter, used when the caller omits that argument.\n", "- **Keyword argument** β€” An argument passed by name (`per_child=2`), so the call order stops mattering." ] }, { "cell_type": "markdown", "id": "f7198adb", "metadata": {}, "source": [ "- **Docstring** β€” A one-line string just inside a function that says what it does; read back by `help()`.\n", "- **`return`** β€” Hands one value back to the caller; absent `return` yields `None`.\n", "- **`None`** β€” Python's \"no value\" value.\n", "- **Scope** β€” Where a name is visible; variables made inside a function are **local** to it.\n", "- **Decomposition** β€” Breaking a problem into small, separately-testable functions.\n", "- **Edge case** β€” An extreme or unusual input (empty, zero, negative, boundary) that often exposes bugs.\n", "- **Nested loop** β€” A loop inside a loop; total passes multiply.\n", "- **Sequence** β€” The simplest control structure: run steps one after another, in order.\n", "- **Selection** β€” Choosing between paths (`if` / `elif` / `else`); one of the three control structures.\n", "- **Structured program theorem** β€” The proven result (BΓΆhm & Jacopini, 1966) that any algorithm can be built from just sequence, selection, and iteration.\n", "- **`goto`** β€” An old command that could jump anywhere in the code; shown to be unnecessary and now avoided.\n", "- **Halting problem** β€” The proven impossibility of writing one program that decides whether *any* given program will stop; introduced fully in Notebook 7.\n", "- **Abstraction** β€” Hiding details behind a simple surface (a name, inputs, an output) so you can use something without knowing how it works inside.\n", "- **Black box** β€” Something you use through its interface without seeing its implementation; a function is one.\n", "- **Top-down design** β€” Solving a problem by breaking it into smaller sub-problems until each is easy, then building back up.\n", "- **DRY (Don't Repeat Yourself)** β€” Write a rule once in a function and reuse it, rather than copying code." ] }, { "cell_type": "markdown", "id": "nb4-75-summary", "metadata": {}, "source": [ "## Summary\n", "\n", "- **`if` / `elif` / `else`** make a program choose; the condition is a boolean expression; exactly one branch runs.\n", "- **`and` / `or` / `not`** combine conditions into one test, and short-circuit once the answer is settled.\n", "- **`while`** repeats until a condition turns `False` β€” and needs initialise / test / **progress**, or it loops forever.\n", "- **`for`** repeats a known number of times β€” over a `range` or a list; pair it with an **accumulator** to total things up.\n", "- **`break` / `continue`** steer loops; loops + ifs nest, and nested loops multiply.\n", "- **The three building blocks are everything.** Sequence, selection, and iteration are a *complete* set β€” the **structured program theorem** proves no fourth kind of control flow is needed.\n", "- **Functions are abstraction.** Each is a **black box** with an interface and a hidden implementation; decomposing a problem into black boxes is **top-down design**, and reusing one function instead of copying code is the **DRY** principle.\n", "- **\"Does it stop?\"** is a deeper question than it looks β€” the **halting problem** is waiting in Notebook 7.\n", "- **Edge cases** are how you find bugs the normal input hides. Predict, then run, then compare.\n", "\n", "Choose, repeat, decompose, test. That's most of programming." ] }, { "cell_type": "markdown", "id": "nb4-76-next", "metadata": {}, "source": [ "## What's Next\n", "\n", "We've been looping over lists and pretending they're simple. They aren't β€” and they're not the only way to organise data. **Notebook 5** is **Collections & Abstract Data Types**: lists, dictionaries, sets, and tuples, and how choosing the right container makes a problem easy or impossible. Wendy's roster is about to get a serious upgrade.\n", "\n", "*COMP 1150 β€” Computer Science Concepts Β· Brendan Shea, PhD* \n", "*Content licensed under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/).*" ] } ], "metadata": { "colab": { "provenance": [] }, "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.13.9" }, "widgets": { "application/vnd.jupyter.widget-state+json": { "state": { "0620a470a0f74fbc80d4d8a573979c15": { "model_module": "@jupyter-widgets/output", "model_module_version": "1.0.0", "model_name": "OutputModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/output", "_model_module_version": "1.0.0", "_model_name": "OutputModel", "_view_count": null, "_view_module": "@jupyter-widgets/output", "_view_module_version": "1.0.0", "_view_name": "OutputView", "layout": "IPY_MODEL_3ec23988b22f4006a34289b9874b7043", "msg_id": "", "outputs": [], "tabbable": null, "tooltip": null } }, "085f95c0362745d0a81ab26c02290fda": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "0bbc035003a540a1ae7b0a83846a9177": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "0cd9c2af09114f6d88d04c24e7e8a619": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "ButtonModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "ButtonModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "ButtonView", "button_style": "warning", "description": "Retry", "disabled": false, "icon": "refresh", "layout": "IPY_MODEL_eb2cb37da8564a538cb66d902a3fb7e4", "style": "IPY_MODEL_45a375466fbd444596471e0bf21c0977", "tabbable": null, "tooltip": null } }, "0cdc8501322a4aa4945cf4c2118c6e70": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "ButtonModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "ButtonModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "ButtonView", "button_style": "warning", "description": "Retry", "disabled": false, "icon": "refresh", "layout": "IPY_MODEL_a37a3d077fd64291bd844735bec2d1aa", "style": "IPY_MODEL_5b5b79a3c6cd4e809dbe2642baee5b68", "tabbable": null, "tooltip": null } }, "0f19bc876a9245cab5213c8dbd5d78ee": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "VBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "VBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "VBoxView", "box_style": "", "children": [ "IPY_MODEL_93437aa1398a4722bbaee5f38436d2a0", "IPY_MODEL_b50a6e727cc34d5786e2ef15a98857fd", "IPY_MODEL_2e3c88f305374f51822c5a3c28590c67", "IPY_MODEL_a786afc1c1c14edd91affbd6112a62fa", "IPY_MODEL_0620a470a0f74fbc80d4d8a573979c15" ], "layout": "IPY_MODEL_7be5346528c043c3999288110dd6e5b0", "tabbable": null, "tooltip": null } }, "11abd6232888449daaedb844c3a14676": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "1ca12ab867f84072914a0794e5283515": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": "200px" } }, "204eccff444e411e9ecc95f1ab9a46fc": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "StyleView", "bar_color": null, "description_width": "" } }, "2e3c88f305374f51822c5a3c28590c67": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "TextareaModel", "state": { "_dom_classes": [ "code-input" ], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "TextareaModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "TextareaView", "continuous_update": true, "description": "", "description_allow_html": false, "disabled": false, "layout": "IPY_MODEL_bf6d7316ad614fbfbe5142b7671398bf", "placeholder": "​", "rows": null, "style": "IPY_MODEL_3897d8ea715c4deb82cbaf281bebe803", "tabbable": null, "tooltip": null, "value": "def number_sign(number):\n pass" } }, "323ce34b507c429596de5a9981e69fcb": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "VBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "VBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "VBoxView", "box_style": "", "children": [ "IPY_MODEL_6f9b7c134c694094bfbaba9c5ebf1c13", "IPY_MODEL_bed2c52724344a1f8145b56c7e223005", "IPY_MODEL_e6e940c6072941de8b0ac7ad4abb2efe", "IPY_MODEL_b76c5a121b9347e7882619ac748cd0ea", "IPY_MODEL_463a2038989c40ceb4ca3b47eb3fe9ce", "IPY_MODEL_bb46461c92ce4a70827c891c06d70387" ], "layout": "IPY_MODEL_faed936fd05641b987b05053a733da93", "tabbable": null, "tooltip": null } }, "33150769402440d98afa03841611e905": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HTMLStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "StyleView", "background": null, "description_width": "", "font_size": null, "text_color": null } }, "3897d8ea715c4deb82cbaf281bebe803": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "TextStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "TextStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "StyleView", "background": null, "description_width": "", "font_size": null, "text_color": null } }, "39826bfe710848048c728bd882240563": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_0f19bc876a9245cab5213c8dbd5d78ee", "IPY_MODEL_323ce34b507c429596de5a9981e69fcb" ], "layout": "IPY_MODEL_b14cd6e7adf14a3eab20923f69e4425d", "tabbable": null, "tooltip": null } }, "3ec23988b22f4006a34289b9874b7043": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "41ec523143134de6968cc8f515942cdb": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "45a375466fbd444596471e0bf21c0977": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "ButtonStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "ButtonStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "StyleView", "button_color": null, "font_family": null, "font_size": null, "font_style": null, "font_variant": null, "font_weight": null, "text_color": null, "text_decoration": null } }, "463a2038989c40ceb4ca3b47eb3fe9ce": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "HTMLView", "description": "", "description_allow_html": false, "layout": "IPY_MODEL_dffa5975a0514a17849f61deb0188c3a", "placeholder": "​", "style": "IPY_MODEL_a3ccbe8bae0c45948b162e6c9bb68351", "tabbable": null, "tooltip": null, "value": "

Output

" } }, "4a7ddcbb4ad94827a9871daef5236f9b": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "5b5b79a3c6cd4e809dbe2642baee5b68": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "ButtonStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "ButtonStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "StyleView", "button_color": null, "font_family": null, "font_size": null, "font_style": null, "font_variant": null, "font_weight": null, "text_color": null, "text_decoration": null } }, "5beb35f6a3b340d2877c3a9ac5ca34b2": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "ButtonStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "ButtonStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "StyleView", "button_color": null, "font_family": null, "font_size": null, "font_style": null, "font_variant": null, "font_weight": null, "text_color": null, "text_decoration": null } }, "5dbb085889f54fcf8c1848d69c856109": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "DropdownModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "DropdownModel", "_options_labels": [ "Problem 1", "Problem 2", "Problem 3", "Problem 4", "Problem 5", "Problem 6", "Problem 7", "Problem 8", "Problem 9", "Problem 10", "Problem 11", "Problem 12", "Problem 13", "Problem 14", "Problem 15", "Problem 16", "Problem 17" ], "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "DropdownView", "description": "Skip to:", "description_allow_html": false, "disabled": false, "index": 0, "layout": "IPY_MODEL_1ca12ab867f84072914a0794e5283515", "style": "IPY_MODEL_ab16cf8b42604a98aaaf285306c09748", "tabbable": null, "tooltip": null } }, "6f9b7c134c694094bfbaba9c5ebf1c13": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "HTMLView", "description": "", "description_allow_html": false, "layout": "IPY_MODEL_4a7ddcbb4ad94827a9871daef5236f9b", "placeholder": "​", "style": "IPY_MODEL_f2216f574c5d4af9b63478bd4411b95f", "tabbable": null, "tooltip": null, "value": "

Sample Inputs and Outputs

" } }, "727fe025122746a99715880fbaaf7e1e": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "ButtonStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "ButtonStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "StyleView", "button_color": null, "font_family": null, "font_size": null, "font_style": null, "font_variant": null, "font_weight": null, "text_color": null, "text_decoration": null } }, "7aae2eccac2643579504e98873bb61ff": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "ButtonModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "ButtonModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "ButtonView", "button_style": "info", "description": "Next", "disabled": true, "icon": "arrow-right", "layout": "IPY_MODEL_11abd6232888449daaedb844c3a14676", "style": "IPY_MODEL_a6b6f9f512364482b03b1442b612902c", "tabbable": null, "tooltip": null } }, "7be5346528c043c3999288110dd6e5b0": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": "50%" } }, "7db901c54fae4860acd6dc906264a02f": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "831ad5e108ee421f85daa72d6ff45e2b": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "892a4d46495240bf87940283bf092c05": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "8e41e68d57fd4ba09d58cc223e90bbd2": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "ButtonModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "ButtonModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "ButtonView", "button_style": "primary", "description": "Show Hint", "disabled": false, "icon": "lightbulb-o", "layout": "IPY_MODEL_7db901c54fae4860acd6dc906264a02f", "style": "IPY_MODEL_727fe025122746a99715880fbaaf7e1e", "tabbable": null, "tooltip": null } }, "93437aa1398a4722bbaee5f38436d2a0": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "IntProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "IntProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "ProgressView", "bar_style": "", "description": "Progress:", "description_allow_html": false, "layout": "IPY_MODEL_99119e0d602948e5a23161bc380aa257", "max": 17, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_204eccff444e411e9ecc95f1ab9a46fc", "tabbable": null, "tooltip": null, "value": 0 } }, "99119e0d602948e5a23161bc380aa257": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": "100%" } }, "a37a3d077fd64291bd844735bec2d1aa": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "a3ccbe8bae0c45948b162e6c9bb68351": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HTMLStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "StyleView", "background": null, "description_width": "", "font_size": null, "text_color": null } }, "a6b6f9f512364482b03b1442b612902c": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "ButtonStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "ButtonStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "StyleView", "button_color": null, "font_family": null, "font_size": null, "font_style": null, "font_variant": null, "font_weight": null, "text_color": null, "text_decoration": null } }, "a786afc1c1c14edd91affbd6112a62fa": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_f5de35904eed411aae555f1131100182", "IPY_MODEL_0cd9c2af09114f6d88d04c24e7e8a619", "IPY_MODEL_7aae2eccac2643579504e98873bb61ff", "IPY_MODEL_8e41e68d57fd4ba09d58cc223e90bbd2", "IPY_MODEL_5dbb085889f54fcf8c1848d69c856109" ], "layout": "IPY_MODEL_f44ff158f08f4cfd9c036a7ba28be16b", "tabbable": null, "tooltip": null } }, "ab16cf8b42604a98aaaf285306c09748": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "StyleView", "description_width": "" } }, "b0b6abcfaafb483880660923be4e92d4": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "ButtonStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "ButtonStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "StyleView", "button_color": null, "font_family": null, "font_size": null, "font_style": null, "font_variant": null, "font_weight": null, "text_color": null, "text_decoration": null } }, "b14cd6e7adf14a3eab20923f69e4425d": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": "100%" } }, "b50a6e727cc34d5786e2ef15a98857fd": { "model_module": "@jupyter-widgets/output", "model_module_version": "1.0.0", "model_name": "OutputModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/output", "_model_module_version": "1.0.0", "_model_name": "OutputModel", "_view_count": null, "_view_module": "@jupyter-widgets/output", "_view_module_version": "1.0.0", "_view_name": "OutputView", "layout": "IPY_MODEL_41ec523143134de6968cc8f515942cdb", "msg_id": "", "outputs": [ { "data": { "text/html": "

Question 1/17

Return 'Negative' if the number is less than zero, otherwise 'Non-negative'. number_sign(-3) β†’ 'Negative'; number_sign(0) β†’ 'Non-negative'.

", "text/plain": "" }, "metadata": {}, "output_type": "display_data" } ], "tabbable": null, "tooltip": null } }, "b76c5a121b9347e7882619ac748cd0ea": { "model_module": "@jupyter-widgets/output", "model_module_version": "1.0.0", "model_name": "OutputModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/output", "_model_module_version": "1.0.0", "_model_name": "OutputModel", "_view_count": null, "_view_module": "@jupyter-widgets/output", "_view_module_version": "1.0.0", "_view_name": "OutputView", "layout": "IPY_MODEL_831ad5e108ee421f85daa72d6ff45e2b", "msg_id": "", "outputs": [], "tabbable": null, "tooltip": null } }, "bb46461c92ce4a70827c891c06d70387": { "model_module": "@jupyter-widgets/output", "model_module_version": "1.0.0", "model_name": "OutputModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/output", "_model_module_version": "1.0.0", "_model_name": "OutputModel", "_view_count": null, "_view_module": "@jupyter-widgets/output", "_view_module_version": "1.0.0", "_view_name": "OutputView", "layout": "IPY_MODEL_085f95c0362745d0a81ab26c02290fda", "msg_id": "", "outputs": [], "tabbable": null, "tooltip": null } }, "bed2c52724344a1f8145b56c7e223005": { "model_module": "@jupyter-widgets/output", "model_module_version": "1.0.0", "model_name": "OutputModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/output", "_model_module_version": "1.0.0", "_model_name": "OutputModel", "_view_count": null, "_view_module": "@jupyter-widgets/output", "_view_module_version": "1.0.0", "_view_name": "OutputView", "layout": "IPY_MODEL_892a4d46495240bf87940283bf092c05", "msg_id": "", "outputs": [ { "data": { "text/html": "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
InputOutput
[-5]'Negative'
[-100]'Negative'
[10]'Non-negative'
", "text/plain": "" }, "metadata": {}, "output_type": "display_data" } ], "tabbable": null, "tooltip": null } }, "bf6d7316ad614fbfbe5142b7671398bf": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": "200px", "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": "100%" } }, "c7f0ca5ea9d34719ba022925e62402a5": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "dffa5975a0514a17849f61deb0188c3a": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "e6e940c6072941de8b0ac7ad4abb2efe": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "HTMLView", "description": "", "description_allow_html": false, "layout": "IPY_MODEL_f23c8a7be7924e37ab71d43ab9fb890c", "placeholder": "​", "style": "IPY_MODEL_33150769402440d98afa03841611e905", "tabbable": null, "tooltip": null, "value": "

Results

" } }, "eb2cb37da8564a538cb66d902a3fb7e4": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "f2216f574c5d4af9b63478bd4411b95f": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HTMLStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "StyleView", "background": null, "description_width": "", "font_size": null, "text_color": null } }, "f23c8a7be7924e37ab71d43ab9fb890c": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "f44ff158f08f4cfd9c036a7ba28be16b": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "f5de35904eed411aae555f1131100182": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "ButtonModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "ButtonModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "ButtonView", "button_style": "success", "description": "Run", "disabled": false, "icon": "check", "layout": "IPY_MODEL_c7f0ca5ea9d34719ba022925e62402a5", "style": "IPY_MODEL_b0b6abcfaafb483880660923be4e92d4", "tabbable": null, "tooltip": null } }, "f8bc3ecb452e47f385d5c4cadc67aa45": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "ButtonModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "ButtonModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "ButtonView", "button_style": "info", "description": "Next", "disabled": true, "icon": "arrow-right", "layout": "IPY_MODEL_0bbc035003a540a1ae7b0a83846a9177", "style": "IPY_MODEL_5beb35f6a3b340d2877c3a9ac5ca34b2", "tabbable": null, "tooltip": null } }, "faed936fd05641b987b05053a733da93": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": "50%" } } }, "version_major": 2, "version_minor": 0 } } }, "nbformat": 4, "nbformat_minor": 5 }