{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "a81d9ad2-9a47-4872-bf65-5a8dfb09c32f",
   "metadata": {
    "tags": []
   },
   "source": [
    "# Iteration\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8c915b00",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": [
     "hide-input"
    ]
   },
   "outputs": [],
   "source": [
    "import sys\n",
    "from pathlib import Path\n",
    "\n",
    "current = Path.cwd()\n",
    "for parent in [current, *current.parents]:\n",
    "    if (parent / '_config.yml').exists():\n",
    "        project_root = parent  # ← Add project root, not chapters\n",
    "        break\n",
    "else:\n",
    "    project_root = Path.cwd().parent.parent\n",
    "\n",
    "sys.path.insert(0, str(project_root))\n",
    "\n",
    "from shared import thinkpython, diagram, jupyturtle\n",
    "\n",
    "# Register as top-level modules so direct imports work in subsequent cells\n",
    "sys.modules['thinkpython'] = thinkpython\n",
    "sys.modules['diagram'] = diagram\n",
    "sys.modules['jupyturtle'] = jupyturtle"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "416537d4-ac02-45cd-b39a-ffebe7e61db4",
   "metadata": {},
   "source": [
    "The ability to repeat a block of code is one of the most powerful features in programming. We call this **iteration**. Python provides two primary loop constructs to handle this:\n",
    "\n",
    "*   **`for` loops**: Designed for **definite iteration**. Use these when you know in advance how many times code needs to run (e.g., iterating over a list of items).\n",
    "*   **`while` loops**: Designed for **indefinite iteration**. Use these when you want to repeat a task as long as a specific **condition** is true, even if you don't know exactly how many times that will be."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "354ca6eb-a8f1-4579-ae48-cd88fa8bc5b1",
   "metadata": {},
   "source": [
    "## Iterators and Iterables\n",
    "\n",
    "Iterators and iterables in Python are the inner workings of iterations. Iterators control loops, allowing you to traverse arbitrary data containers one item at a time. Iterables, on the other hand, provide the data that you want to iterate over. Python iterators are objects with .__iter__() and .__next__() methods, and iterables are objects that can return an iterator using the .__iter__() method {cite}`ramos_2025`. "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9ec543c3-e3e5-4570-9f42-1c2b89f21f47",
   "metadata": {},
   "source": [
    "Collections like lists, tuples, dictionaries, and sets are all `iterable` objects. They are `iterable` containers from which you can get an **iterator** using the `iter()` method:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2f820052-df4c-4961-815a-64672215eaa6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "apple\n",
      "banana\n",
      "cherry\n"
     ]
    }
   ],
   "source": [
    "tuple_fruit = (\"apple\", \"banana\", \"cherry\")\n",
    "itr = iter(tuple_fruit)       ### create iterator\n",
    "\n",
    "print(next(itr))       ### iterator itr has a `next()` method\n",
    "print(next(itr))\n",
    "print(next(itr))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "313ec035-1fae-4a96-b7f2-5b02ebb13b68",
   "metadata": {},
   "source": [
    "This is how the `for` loop iterates through an iterable object."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d3711dc9-13d5-4b14-a693-067f3b8ce256",
   "metadata": {},
   "source": [
    "When we need to iterate over the items in a **collection**, we typically use a for loop, which is specifically designed for this task. A `for` loop can loop through an object because the object is an **iterable**. An iterable is any Python object that can return its elements one at a time, allowing you to loop over it. Common Iterables in Python include: \n",
    "\n",
    "- Sequences: lists, tuples, strings, ranges\n",
    "- Collections: sets, dictionaries, frozensets\n",
    "- Files: file objects\n",
    "- Custom objects: anything implementing the iterator protocol"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "cbfa7cec-7815-4fa3-bd0f-0962bf3ac679",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello!\n",
      "Hello!\n",
      "Hello!\n"
     ]
    }
   ],
   "source": [
    "times = 0\n",
    "while times < 3:\n",
    "    print(\"Hello!\")\n",
    "    times += 1"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "94293ccb-6bc9-45b4-a101-9c51ce5d548c",
   "metadata": {},
   "source": [
    "## `For` Loops"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "637f80fa-4db3-4fdb-b140-11a9120e2170",
   "metadata": {},
   "source": [
    "The `for` loops are mostly used when you have a block of code that you want to **repeat** a **fixed number** of times and to execute code for each item. With a for loop, you want to either:\n",
    "- iterate over the **items** in a data collection (such as `list`, `tuple`, `string`, and `range`, or\n",
    "- iterate through a sequence of **numbers** using the `range()` constructor, or using the index for index-based iteration. \n",
    "\n",
    "In both situations, the number of iterations is known. There are times when we do not know the number of elements we are iterating through, e.g., when working with files: \n",
    "```python\n",
    "for line in open('data.txt'):\n",
    "    print(line)\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f770c720-c0e1-44c4-865f-2a185921d08d",
   "metadata": {},
   "source": [
    "Commonly used `for` loop patterns are:\n",
    "\n",
    "| For Loop Type              | Typical Syntax                | Iterates Over   | Best Use Case     | Key Idea             |\n",
    "| -------------------------- | ----------------------------- | --------------- | ----------------- | -------------------- |\n",
    "| Basic for-each             | `for x in collection:`        | **Elements**        | Processing items  | Loop through values  |\n",
    "| `range()` counting         | `for i in range(n):`          | **Numbers**         | Counting, repeats | Like a counting loop |\n",
    "| Index-based                | `for i in range(len(lst)):`   | Index numbers   | When index needed | Access by position   |\n",
    "| `enumerate()`              | `for i, x in enumerate(lst):` | Index + value   | Cleaner indexing  | Best practice        |\n",
    "| Nested for loop            | `for x in A: for y in B:`     | Combinations    | Grids, tables     | Loop inside loop     |\n",
    "\n",
    "Other for loop patters include looping through dictionaries, files, \n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b3c1e515-03ad-4aef-80e9-cd9b13041a18",
   "metadata": {},
   "source": [
    "### Looping through Iterables"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "384e6929-e5fb-48f7-b8b2-cc6e9695586e",
   "metadata": {},
   "source": [
    "Python’s basic for loop works much like the **foreach** loop in other programming languages. Here’s the basic syntax:"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a6dfc5fc-1ee3-44a2-ab7c-3e6116eba03e",
   "metadata": {},
   "source": [
    "```python\n",
    "for item in iterable:\n",
    "    <block>\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "19b68567-f85f-437e-a7cc-1b48a3ecaaba",
   "metadata": {},
   "source": [
    "In this syntax, we have:\n",
    "- the `for` keyword\n",
    "- the **loop variable**, item, which holds the current value in the target data collection\n",
    "- the **body** of a block of code that will run one iteration as the loop pulls one item from the iterable.\n",
    "\n",
    "Once the loop finishes iterating over the data, the execution flow jumps to the next statement after the loop."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1d534928-92fb-49f8-9326-4a5d504b7e15",
   "metadata": {},
   "source": [
    "Here are two quick examples of a for loop in Python. In the first example, we use a for loop to traverse a list of fruit names. The loop **body** contains a call to `print()`, which displays each fruit in each loop. "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "02fa6b3f-7133-47c4-acc9-476f3e634dd4",
   "metadata": {},
   "source": [
    "#### Loop through lists"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "f34f8206-ec6d-4e35-99e3-1ff797fb7deb",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "apple\n",
      "banana\n",
      "cherry\n"
     ]
    }
   ],
   "source": [
    "fruits = ['apple', 'banana', 'cherry']  ### iterable object\n",
    "\n",
    "for fruit in fruits:\n",
    "    print(fruit)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "7eabcede-f514-4993-a292-2db1b595dfe0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 4 9 16 25 "
     ]
    }
   ],
   "source": [
    "nums = [ 1, 2, 3, 4, 5 ]\n",
    "\n",
    "for num in nums:\n",
    "    print(num**2, end=\" \")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "389f5162-0a8c-4cc7-99f1-a261e0b39006",
   "metadata": {},
   "source": [
    "#### Loops through strings\n",
    "Note that this is character by character."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "6cb5b573-601c-42f5-a940-f1a4d244f990",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "h e l l o ,   w o r l d "
     ]
    }
   ],
   "source": [
    "for letter in 'hello, world':\n",
    "    print(letter, end=' ')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "099b78c6-9ff1-4af4-bdda-77a04d04dc38",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": [
     "thebe-interactive"
    ]
   },
   "outputs": [],
   "source": [
    "# === EXERCISE: Basic For Loop ===\n",
    "# Write a for loop that iterates through the list `prices` \n",
    "# and prints each price with a 10% tax added (price * 1.1).\n",
    "\n",
    "prices = [10.00, 20.00, 100.00]\n",
    "\n",
    "# TODO: Write your loop here\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "### your code ends here"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "id": "9086e0c5-ba35-4364-a7ce-7eb85fb2bc9a",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": [
     "hide-input"
    ]
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "11.0\n",
      "22.0\n",
      "110.00000000000001\n"
     ]
    }
   ],
   "source": [
    "prices = [10.00, 20.00, 100.00]\n",
    "\n",
    "for price in prices:\n",
    "    print(price * 1.1)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6537d512-6201-4d94-a075-e1276907dfa5",
   "metadata": {},
   "source": [
    "### Looping with `range`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "id": "dbc0ecdf-6d67-4b76-9d85-9425ddef4cbe",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1 2 3 4 "
     ]
    }
   ],
   "source": [
    "for i in range(5):\n",
    "    print(i, end = \" \")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6c01fd12-5e1c-466c-95dd-9b51fad46bd7",
   "metadata": {},
   "source": [
    "### Index-Based `for` Loop"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "id": "8f27746b-9805-48f1-b163-b49fad94a7a1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 10\n",
      "1 20\n",
      "2 30\n",
      "3 40\n"
     ]
    }
   ],
   "source": [
    "numbers = [10, 20, 30, 40]\n",
    "\n",
    "for i in range(len(numbers)):\n",
    "    print(i, numbers[i])       ### numbers[i] is the value at that position\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "170bdaf7-2b41-4ce6-a952-5465ce894403",
   "metadata": {},
   "source": [
    "### Nested Loops\n",
    "\n",
    "A **nested loop** is a loop inside the body of another loop. The \"inner\" loop finishes all of its iterations for every single iteration of the \"outer\" loop.\n",
    "\n",
    "**Syntax and Structure:**\n",
    "\n",
    "```python\n",
    "for outer_item in outer_sequence:\n",
    "    ### outer loop body\n",
    "    for inner_item in inner_sequence:\n",
    "        # inner loop body executes for each outer_item"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ee0873ea",
   "metadata": {},
   "source": [
    "A classic use case is generating a multiplication table. For every number `i` (rows), we iterate through numbers `j` (columns)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "a9794cce",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "4\t6\t8\t10\t12\t14\t16\t\n",
      "6\t9\t12\t15\t18\t21\t24\t\n",
      "8\t12\t16\t20\t24\t28\t32\t\n",
      "10\t15\t20\t25\t30\t35\t40\t\n",
      "12\t18\t24\t30\t36\t42\t48\t\n",
      "14\t21\t28\t35\t42\t49\t56\t\n",
      "16\t24\t32\t40\t48\t56\t64\t\n"
     ]
    }
   ],
   "source": [
    "for i in range(2, 9):          # Outer loop (rows)\n",
    "    for j in range(2, 9):      # Inner loop (columns)\n",
    "        print(f\"{i*j}\", end=\"\\t\")\n",
    "    print()                    # Newline after each row"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f74c6d4a",
   "metadata": {},
   "source": [
    "Nested loops are essential for working with multi-dimensional data, like matrices (lists of lists)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "id": "73346fe7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 2 3 \n",
      "4 5 6 \n",
      "7 8 9 \n"
     ]
    }
   ],
   "source": [
    "matrix = [\n",
    "    [1, 2, 3],\n",
    "    [4, 5, 6],\n",
    "    [7, 8, 9]\n",
    "]\n",
    "\n",
    "for row in matrix:\n",
    "    for item in row:\n",
    "        print(item, end=\" \")\n",
    "    print()  # Newline after printing a full row"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e93f5d75-654b-4ee7-b6f5-42477eb62bd6",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": [
     "thebe-interactive"
    ]
   },
   "outputs": [],
   "source": [
    "# === EXERCISE: Star Pattern ===\n",
    "# Use a nested loop to print the following pattern of stars:\n",
    "# *\n",
    "# * *\n",
    "# * * *\n",
    "# * * * *\n",
    "# * * * * *\n",
    "\n",
    "# Hint: The outer loop controls the rows (range 1 to 6).\n",
    "# The inner loop controls how many stars print on that row.\n",
    "for row in range(1, 6):\n",
    "    # TODO: write the inner loop\n",
    "    \n",
    "    print() # Newline after each row"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bd03d7c7-a9a9-4302-859c-3fd676200c9d",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": [
     "hide-input"
    ]
   },
   "outputs": [],
   "source": [
    "for row in range(1, 6):\n",
    "    for star in range(row):\n",
    "        print(\"*\", end=\" \")\n",
    "    print()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8f41698a",
   "metadata": {},
   "source": [
    "### Advanced for Loop\n",
    "\n",
    "Python provides several advanced techniques that make your code more elegant and readable: \n",
    "\n",
    "- enumerate() - getting index and value\n",
    "- zip() - parallel iteration\n",
    "- Unpacking in loops"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "23e10bac-3d1e-4c4b-ada1-f65e4b0ee53c",
   "metadata": {},
   "source": [
    "#### Enumerate\n",
    "\n",
    "Use enumerate() when you need both the position and the value in a loop."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "id": "2fd9dab6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0: apple\n",
      "1: banana\n",
      "2: cherry\n",
      "3: date\n"
     ]
    }
   ],
   "source": [
    "### enumerate example\n",
    "fruits = ['apple', 'banana', 'cherry', 'date']\n",
    "\n",
    "for index, fruit in enumerate(fruits):\n",
    "    print(f\"{index}: {fruit}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "id": "f3ec9bde-af9b-4f02-9f6c-156b7d7ce170",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 red\n",
      "1 blue\n",
      "2 green\n"
     ]
    }
   ],
   "source": [
    "colors = [\"red\", \"blue\", \"green\"]\n",
    "\n",
    "for index, color in enumerate(colors):\n",
    "    print(index, color)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "65635d3e-93de-470c-9d97-8664f45a7090",
   "metadata": {},
   "source": [
    "#### zip"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "id": "8e8f6388",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Alice \t 25 \t New York\n",
      "Bob \t 30 \t London\n",
      "Charlie \t 35 \t Tokyo\n"
     ]
    }
   ],
   "source": [
    "### zip example\n",
    "names = ['Alice', 'Bob', 'Charlie']\n",
    "ages = [25, 30, 35]\n",
    "cities = ['New York', 'London', 'Tokyo']\n",
    "\n",
    "for name, age, city in zip(names, ages, cities):\n",
    "    print(f\"{name} \\t {age} \\t {city}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f242e38c-c442-446b-b5e9-208b72efec29",
   "metadata": {},
   "source": [
    "#### Loop through Dictionaries"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "id": "383951ea",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "name: Alice\n",
      "age: 25\n",
      "city: New York\n",
      "job: Engineer\n",
      "\n",
      "Key: name\n",
      "Key: age\n",
      "Key: city\n",
      "Key: job\n",
      "\n",
      "Value: Alice\n",
      "Value: 25\n",
      "Value: New York\n",
      "Value: Engineer\n"
     ]
    }
   ],
   "source": [
    "person = {\n",
    "    'name': 'Alice',\n",
    "    'age': 25,\n",
    "    'city': 'New York',\n",
    "    'job': 'Engineer'\n",
    "}\n",
    "\n",
    "# Unpacking key-value pairs\n",
    "for key, value in person.items():\n",
    "    print(f\"{key}: {value}\")\n",
    "print()\n",
    "# Unpacking keys only\n",
    "for key in person.keys():\n",
    "    print(f\"Key: {key}\")\n",
    "print()\n",
    "# Unpacking values only\n",
    "for value in person.values():\n",
    "    print(f\"Value: {value}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "c7a012a8-180d-4bd5-8599-1f0a25243e6f",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": [
     "thebe-interactive"
    ]
   },
   "outputs": [],
   "source": [
    "# === EXERCISE: Zip Iteration ===\n",
    "# Use zip() to iterate through these two lists simultaneously.\n",
    "# Print the sentence: \"[Product] costs $[Price]\" for each item.\n",
    "# to align the prices, use \\t\n",
    "\n",
    "products = [\"Book\", \"Laptop\", \"Mouse\"]\n",
    "costs = [15, 900, 25]\n",
    "\n",
    "# TODO: Your code starts here\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "### your code stops here."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "049e0c8d-1c90-4104-b00c-01013312559a",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": [
     "hide-input"
    ]
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Book costs:\t $15\n",
      "Laptop costs:\t $900\n",
      "Mouse costs:\t $25\n"
     ]
    }
   ],
   "source": [
    "products = [\"Book\", \"Laptop\", \"Mouse\"]\n",
    "costs = [15, 900, 25]\n",
    "\n",
    "for item, price in zip(products, costs):\n",
    "    print(f\"{item} costs:\\t ${price}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "24ae2629-cdd3-462a-a6f5-8df90a8d9cf3",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": [
     "thebe-interactive"
    ]
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Total rainfall: 0\n"
     ]
    }
   ],
   "source": [
    "# === EXERCISE: Accumulator ===\n",
    "# Initialize a variable `total_rainfall` to 0.\n",
    "# Iterate through the list `weekly_rain`.\n",
    "# Add each value to `total_rainfall` using the += operator.\n",
    "# Print the total at the end.\n",
    "\n",
    "weekly_rain = [1.2, 0.5, 2.3, 0.0, 1.1]\n",
    "total_rainfall = 0\n",
    "\n",
    "### TODO: your code starts here\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "print(f\"Total rainfall: {total_rainfall}\")\n",
    "\n",
    "### TODO: your code stops here"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "4da8eed8-466a-4ac7-a033-555b8b381033",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": [
     "hide-input"
    ]
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Total rainfall: 5.1\n"
     ]
    }
   ],
   "source": [
    "weekly_rain = [1.2, 0.5, 2.3, 0.0, 1.1]\n",
    "total_rainfall = 0\n",
    "\n",
    "for rain in weekly_rain:\n",
    "    total_rainfall += rain\n",
    "\n",
    "print(f\"Total rainfall: {total_rainfall}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "923d5c99",
   "metadata": {},
   "source": [
    "## `while` Loops"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d0643f97",
   "metadata": {},
   "source": [
    "A Python `while` loop repeatedly executes a block of code as long as a specified **condition** remains `True`. Once the condition evaluates to `False`, the program continues with the statement immediately following the loop.\n",
    "\n",
    "Common patterns for using `while` loops include:\n",
    "|| Type                    | Controlled By    | Ends When               | Best For |\n",
    "|-| ----------------------- | ---------------- | ----------------------- |--|\n",
    "|1| **Counting** `while` | **Number condition** | Condition becomes False | Repetition with counters |\n",
    "|2| **Sentinel** `while`     | Special **value**    | Sentinel entered        | User input loops|\n",
    "|3| `while True`      | **`break`** | Break executes          | Menus, games, event loops |\n",
    "\n",
    "\n",
    "The syntax of the while loop is:\n",
    "```python\n",
    "while [condition]:\n",
    "    [statement(s)]     ### body; runs repeatedly when condition is True\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f715df73",
   "metadata": {},
   "source": [
    "The execution process of a `while` loop follows a specific cycle:\n",
    "\n",
    "1. Evaluate: Python checks if the condition is True.\n",
    "2. Execute: If True, the indented body runs.\n",
    "3. Repeat: After the body finishes, execution jumps back to step 1.\n",
    "4. Exit: If the condition evaluates to False, the loop stops, and the program proceeds to the code below it."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7ad1c35b",
   "metadata": {},
   "source": [
    "### Counting `while` (Condition-Controlled)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9c01c9ad-e08a-4d01-aa9c-533cb94fa29c",
   "metadata": {},
   "source": [
    "In a **counting** `while` loop:\n",
    "- Loop repeats while a numeric condition remains true.\n",
    "- A `while` loop requires a **counter** as a variable to **increment/decrement** to be ready. In this example, we need to define an indexing variable, **count**.\n",
    "- \"Off-by-one errors\": Python indexing is 0-based, so use `<` instead of `<=` for aligned boundary. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "9b3c2515",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1 2 3 4 5 6 7 8 9 "
     ]
    }
   ],
   "source": [
    "count = 0                        ### initialization of the variable\n",
    "while count < 10:                ### condition to check\n",
    "    print(count, end = \" \") \n",
    "    count = count+1              ### update counter"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d0043693-563c-4928-bb26-2cece7b671a5",
   "metadata": {},
   "source": [
    "### Sentinel `while` Loop (Data-Controlled)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bef9be28-b9f0-40ac-a6c7-3f89ddc225a5",
   "metadata": {},
   "source": [
    "In a sentinel `while` loop, the loop continues until a special value (sentinel) is entered."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "46d03a5f",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": [
     "thebe-interactive"
    ]
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Enter q to quit:  q\n"
     ]
    }
   ],
   "source": [
    "### PRACTICE:\n",
    "\n",
    "user_input = \"\"\n",
    "\n",
    "while user_input != \"q\":\n",
    "    # user_input = input(\"Enter q to quit: \")\n",
    "    user_input = \"q\"  ### for testing; replace with input() for actual use\n",
    "    print(f\"You entered: {user_input}\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ff83cb4b",
   "metadata": {},
   "source": [
    "### `while True` loop (Infinite Loop with break)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "d986009d-4eab-4823-a47c-89248245bbac",
   "metadata": {},
   "source": [
    "- An infinite while loop does not break:\n",
    "- A `while True` loop is an infinite loop, and we create a condition to exit manually."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ff362419",
   "metadata": {},
   "source": [
    "```python\n",
    "while True:\n",
    "    print(\"This runs forever\")\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4637f1bd",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Enter q to quit:  q\n"
     ]
    }
   ],
   "source": [
    "while True:\n",
    "    # user_input = input(\"Enter q to quit: \")\n",
    "    user_input = \"q\"  ### for testing; replace with input() for actual use\n",
    "    print(f\"You entered: {user_input}\")\n",
    "\n",
    "    if user_input == \"q\":        ### when condition met\n",
    "        break                    ### break!!"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9d0ad421-1c80-4c40-a6ea-ac8ef3d4c223",
   "metadata": {},
   "source": [
    "A `while True` loop in Python emulates the `do while` loop in languages like C, Java, or JavaScript, where the code block is run **at least once** before the condition is checked to decide whether to terminate. The syntax of the `do while` loop is:"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "92ab5c28-8c1e-4e8d-abf5-2cece1cfce84",
   "metadata": {},
   "source": [
    "\n",
    "```C\n",
    "do:\n",
    "    run code\n",
    "while condition is true\n",
    "```\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4ba044d5-da8f-4d31-82d5-625ff72005fa",
   "metadata": {},
   "source": [
    "In Java:\n",
    "```java\n",
    "do {\n",
    "    System.out.println(\"Hello\");\n",
    "} while (x < 5);\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "910edebd-41aa-4c21-983d-a9527a937fd0",
   "metadata": {},
   "source": [
    "## Loop Control Statements\n",
    "\n",
    "You can control the execution of a `for` or `while` loop using the following statements:\n",
    "\n",
    "1. **`break`** – Immediately exits the loop, even if the loop condition is still `True`.  \n",
    "2. **`continue`** – Skips the remainder of the current iteration and returns to the top of the loop to recheck the condition.  \n",
    "3. **`pass`** - Used as a **placeholder** to write empty loops (also used for empty control statements, functions, and classes).\n",
    "4. **`else` clause** – Executes only if the loop finishes normally (when the condition becomes `False`), and does **not** run if the loop is terminated by a `break` statement.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "a96b7ce0-d08c-42a0-9a59-7f22645dacb2",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1 2 3 4 "
     ]
    }
   ],
   "source": [
    "### 1/4. break statement for\n",
    "for i in range(10):\n",
    "    if i == 5:\n",
    "        break\n",
    "    print(i, end = \" \")       ### output: 0 1 2 3 4"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "2296d6c4",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1 2 3 4 5 "
     ]
    }
   ],
   "source": [
    "### 1/4. break statement while\n",
    "i = 0\n",
    "while i < 10:\n",
    "    print(i, end = \" \")\n",
    "    if i == 5:\n",
    "        break\n",
    "    i += 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "000519b6-8b16-49e6-a580-b7feccaf0be7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1 2 3 4 6 7 8 9 "
     ]
    }
   ],
   "source": [
    "### 2/4. continue statement for \n",
    "for i in range(10):\n",
    "    if i == 5:\n",
    "        continue\n",
    "    print(i, end = \" \")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "8c90249e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 2 3 4 6 7 8 9 10 "
     ]
    }
   ],
   "source": [
    "### 2/4. continue statement while \n",
    "i = 0\n",
    "while i < 10:\n",
    "  i += 1\n",
    "  if i == 5:\n",
    "    continue\n",
    "  print(i, end = \" \")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "f23b62d6-9b98-48f9-ad1a-e88096505443",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "9\n"
     ]
    }
   ],
   "source": [
    "### 3/4. pass statement for\n",
    "for i in range(10):\n",
    "    pass  # TODO: implement later\n",
    "print(i)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "b61a38eb",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Value of i : 10\n"
     ]
    }
   ],
   "source": [
    "### 3/4. pass statement for\n",
    "i = 0\n",
    "while i < 10:\n",
    "    i += 1\n",
    "    pass         ### TODO: do something later\n",
    "    # print(\"after pass\")     ### this will run, after pass!!!\n",
    "  \n",
    "print('Value of i :', i)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "1c6989ed-caec-492f-a7dc-b1d76e1c385f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1 2 3 4 5 6 7 8 9 Loop is over\n"
     ]
    }
   ],
   "source": [
    "### 4/4. else statement with loops\n",
    "for i in range(10):\n",
    "    print(i, end=' ')\n",
    "else:\n",
    "    print(\"Loop is over\") "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "3f3c0412",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1 2 3 4 5 6 7 8 9 Loop is over\n"
     ]
    }
   ],
   "source": [
    "### 4/4. else statement with loops\n",
    "i = 0\n",
    "while i < 10:\n",
    "    print(i, end=' ')\n",
    "    i += 1\n",
    "else:\n",
    "    print(\"Loop is over\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "07407730-a88c-4d4d-8989-5692321a0c21",
   "metadata": {},
   "source": [
    "`pass` works similarly to `continue` in a `while` loop, with distinctions:\n",
    "| Feature | `pass` | `continue` |\n",
    "| :--- | :--- | :--- |\n",
    "| **Definition** | A null operation; it literally does nothing. | Skips the remainder of the current loop iteration. |\n",
    "| **Context** | Can be used anywhere (**loops**, **functions**, **classes**, `if` statements). | Only allowed inside **loops** (`for` or `while`). |\n",
    "| **Impact on Flow** | Execution continues to the next statement in the block. | Execution jumps back to the start of the loop for the next cycle. |\n",
    "| **Primary Use** | Syntactic placeholder (prevents \"empty block\" errors). | Logic control (skips specific items based on a condition). |\n",
    "| **Example Scenario** | Creating an empty function for future implementation. | Printing only odd numbers by skipping even ones. |\\"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "88b2dcd7-2830-4a0f-92ad-40c09944c7bc",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": [
     "thebe-interactive"
    ]
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 "
     ]
    }
   ],
   "source": [
    "# === EXERCISE: Break and Continue ===\n",
    "# Loop through numbers from 1 to 20.\n",
    "# 1. If the number is divisible by 4, skip it (use continue).\n",
    "# 2. If the number is 18, stop the loop entirely (use break).\n",
    "# 3. Otherwise, print the number.\n",
    "\n",
    "for i in range(1, 21):\n",
    "    # TODO: check for 18 first (break)\n",
    "    \n",
    "    # TODO: check for divisible by 4 (continue)\n",
    "    \n",
    "    print(i, end=\" \")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "14d1d785-0938-48a8-af62-260974b79dc9",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": [
     "hide-input"
    ]
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 2 3 5 6 7 9 10 11 13 14 15 17 "
     ]
    }
   ],
   "source": [
    "for i in range(1, 21):\n",
    "    if i == 18:\n",
    "        break\n",
    "    \n",
    "    if i % 4 == 0:\n",
    "        continue\n",
    "    \n",
    "    print(i, end=\" \")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dcf65c8c-394c-4ad9-b1bb-e39e9f5b49a6",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "celltoolbar": "Tags",
  "kernelspec": {
   "display_name": ".venv",
   "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.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
