{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "ce98b3d5",
   "metadata": {},
   "source": [
    "# Advanced List Concepts\n",
    "\n",
    "Understanding how Python manages list objects in memory is crucial for avoiding subtle bugs. This section explores object identity, aliasing, and how lists behave when passed to functions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6174e838",
   "metadata": {},
   "outputs": [],
   "source": [
    "import sys\n",
    "from pathlib import Path\n",
    "\n",
    "# Find project root by looking for _config.yml\n",
    "current = Path.cwd()\n",
    "for parent in [current, *current.parents]:\n",
    "    if (parent / '_config.yml').exists():\n",
    "        project_root = parent\n",
    "        break\n",
    "else:\n",
    "    project_root = Path.cwd().parent.parent\n",
    "\n",
    "# Add project root to path\n",
    "sys.path.insert(0, str(project_root))\n",
    "\n",
    "# Import shared teaching helpers and cell magics\n",
    "from shared import thinkpython, diagram, jupyturtle, structshape\n",
    "from shared.download import download\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d9d27df5",
   "metadata": {},
   "source": [
    "## Objects and Values\n",
    "\n",
    "If we run these assignment statements:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "id": "aa547282",
   "metadata": {},
   "outputs": [],
   "source": [
    "a = 'banana'\n",
    "b = 'banana'"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "33d020aa",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": []
   },
   "source": [
    "We know that `a` and `b` both refer to a string, but we don't know whether they refer to the *same* string. \n",
    "There are two possible states, shown in the following figure."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "id": "95a2aded",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": [
     "hide-input"
    ]
   },
   "outputs": [],
   "source": [
    "from shared.diagram import Bbox, Binding, Frame, Stack, Value, adjust, diagram\n",
    "\n",
    "s = 'banana'\n",
    "bindings = [Binding(Value(name), Value(repr(s))) for name in 'ab']\n",
    "frame1 = Frame(bindings, dy=-0.25)\n",
    "\n",
    "binding1 = Binding(Value('a'), Value(repr(s)), dy=-0.11)\n",
    "binding2 = Binding(Value('b'), draw_value=False, dy=0.11)\n",
    "frame2 = Frame([binding1, binding2], dy=-0.25)\n",
    "\n",
    "stack = Stack([frame1, frame2], dx=1.7, dy=0)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "id": "3d75a28c",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": [
     "hide-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 285x76 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "width, height, x, y = [2.85, 0.76, 0.17, 0.51]\n",
    "ax = diagram(width, height)\n",
    "bbox = stack.draw(ax, x, y)\n",
    "# adjust(x, y, bbox)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2f0b0431",
   "metadata": {},
   "source": [
    "In the diagram on the left, `a` and `b` refer to two different objects that have the\n",
    "same value. In the diagram on the right, they refer to the same object.\n",
    "To check whether two variables refer to the same object, you can use the `is` operator."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "id": "a37e37bf",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 85,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = 'banana'\n",
    "b = 'banana'\n",
    "a is b"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d1eb0e36",
   "metadata": {},
   "source": [
    "In this example, Python only created one string object, and both `a`\n",
    "and `b` refer to it.\n",
    "But when you create two lists, you get two objects."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "id": "d6af7316",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 86,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = [1, 2, 3]\n",
    "b = [1, 2, 3]\n",
    "a is b"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a8d4c3d4",
   "metadata": {},
   "source": [
    "So the state diagram looks like this."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "id": "dea08b82",
   "metadata": {
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [],
   "source": [
    "t = [1, 2, 3]\n",
    "binding1 = Binding(Value('a'), Value(repr(t)))\n",
    "binding2 = Binding(Value('b'), Value(repr(t)))\n",
    "frame = Frame([binding1, binding2], dy=-0.25)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 88,
   "id": "7e66ee69",
   "metadata": {
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAIgAAABgCAYAAADGrTq9AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjcsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvTLEjVAAAAAlwSFlzAAAPYQAAD2EBqD+naQAABQdJREFUeJzt3EkobXEcB/CfKTJcHuHVXaCQpJeQedgoNkToEWUhC6VkTAorGVaEWL0oJbKShSELr2fMs7AQXTLkGrIwZZ5e/39ZvFy/e6/cAd9PnQznnM6953zP//yOe34snp6engjgFZavzQBAQEArjCDAQkCAhYAACwEBFgICLAQEWAgIsBAQYCEgwEJAgIWAAAsBARYCAiwEBFgICLAQEGAhIMCypjc6Pz9/66pgYk5OTjovixEEWAgIsBAQYCEgwEJAgIWAAAsBARYCAiwEBFgICLAQEC0UCgVFRkbS2NiY/Pnv37+UmJhInp6elJOTQ7oaGhqimJgYioiIkFN7e7tO683Pz8v1xBQeHk4lJSV0c3Mj583MzMjfi9d4cnJChmDx1v8Pou9nMQUFBbS+vk63t7ekVCqps7NT7mRT2Nrakjs3ODiYAgICyNLy9fNEoVDQzs4Oubi4yJ/VajXt7+/T8vIyTUxMUH9/v07bnJubIx8fH/meT09PKT4+njo6OiguLo5d7/LykmxsbOT0+PhIeXl5FB0dTcXFxa++xg/5WUxzczNNTU3R7OysfIONjY1kKu7u7uTg4ECjo6PU29tLKysrcufrQqlUUlhYGNna2uq1TTEKPZ8Qzs7O5O/vLw+qNvb29jIcgji5rq6uyMLCgsz+01x9DQ4O0sDAAF1fX8vJzc3txTILCwu0t7dnrJckD/bx8bEMyuTkJGVlZdH3798Nvt3V1VX5XltbW3Vafnt7W17ONjc3KSkpiQoLC8lYjDKCiFGju7tbXofFNVWMHs/X0a9GrVZTdna2DIcIqC68vLzkJVGlUsn9Njw8TJ9qBBEFlLjuubq6ymHy169fGpcTRZgxXFxcyPpBHKxv377JekBbLfIeRO2SmppKlZWVlJ6ervf6jo6OlJGRIUfjzMxM+jQjiKj6/fz8KCQkRA6RP378IFM6OjqSxV9ycjLl5+dTYGDgu4RjcXGRUlJSNM47ODiQ80pLSyk3N/e/eeKyGhoaqnG9jY0Nuru7k9+Lk2tkZISCgoLoU40gosjq6en573d1dXVkKt7e3nJ6C5VKJQ+0CJiopcTIU15eLusCUXTa2dlpXK+hoYF2d3epq6tLTkJRUZG8KxEBsbbWfCh+//4tL89WVlZ0f39PCQkJVFVVRcZitNvcj0qhxy1kWVmZLHSjoqL02kZbW5u8wxG1iaFfo763uQiIFr6+vuTh4UH19fXy8mhOROEq6pnDw0NaWlqSQdEFAgIf7w9l8DEhIMBCQICFgAALAQEWAgIsBARYCAiwEBBgISDAQkCAhYAACwEB0wfEkH0bYFgYQbRQoHHK8E+UiZ1cUVFB4+Pj8oHh6upq+vnzJ5kKGqeczK8vRjT7/PnzR/Z2iOcqRSOReJzf1I1Tog1DtELq+lS7UqmU09raml7bFO/3mb6NU88+deOUeHpcEO2Hop90enr6RUDQOPVFG6c0MeZZYE7UaJzSrK+vj2pqauTZIB62bWpqerEMGqe+aOOU8PDwQLGxsZSWlkYtLS0mqz8ENE6ZWQ1ydnYmv9bW1pI5QOOU7tAXo4UCjVPorOP4onEKAflqnNA4Be8Fn8UACwEBFgICLAQEWAgIsBAQYCEgYJg/tcPXgBEEWAgIsBAQYCEgwEJAgIWAAAsBARYCAiwEBFgICLAQEGAhIMBCQICFgAALAQEWAgIsBARYCAiwEBBgISBAnH9XF5b1n3vZ8wAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 116x76 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "width, height, x, y = [1.16, 0.76, 0.21, 0.51]\n",
    "ax = diagram(width, height)\n",
    "bbox = frame.draw(ax, x, y)\n",
    "# adjust(x, y, bbox)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cc115a9f",
   "metadata": {},
   "source": [
    "In this case we would say that the two lists are **equivalent**, because they have the same elements, but not **identical**, because they are not the same object. \n",
    "If two objects are identical, they are also equivalent, but if they are equivalent, they are not necessarily identical."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 89,
   "id": "d0f49fa5",
   "metadata": {
    "tags": [
     "thebe-interactive"
    ]
   },
   "outputs": [],
   "source": [
    "### EXERCISE: Objects and Values\n",
    "x = [10, 20, 30]\n",
    "y = x\n",
    "z = [10, 20, 30]\n",
    "# 1. Check if x and y refer to the same object using \"is\"\n",
    "# 2. Check if x and z have the same value using \"==\"\n",
    "# 3. Check if x and z refer to the same object using \"is\"\n",
    "### Your code starts here:\n",
    "\n",
    "\n",
    "\n",
    "### Your code ends here."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "id": "ed132eb8",
   "metadata": {
    "tags": [
     "hide-input"
    ]
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x is y: True\n",
      "x == z: True\n",
      "x is z: False\n"
     ]
    }
   ],
   "source": [
    "# Solution\n",
    "x = [10, 20, 30]\n",
    "y = x\n",
    "z = [10, 20, 30]\n",
    "\n",
    "same_object_xy = x is y\n",
    "same_value_xz = x == z\n",
    "same_object_xz = x is z\n",
    "\n",
    "print(f\"x is y: {same_object_xy}\")  # True - same object (alias)\n",
    "print(f\"x == z: {same_value_xz}\")   # True - same value (equivalent)\n",
    "print(f\"x is z: {same_object_xz}\")  # False - different objects"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a58db021",
   "metadata": {},
   "source": [
    "## Aliasing\n",
    "\n",
    "If `a` refers to an object and you assign `b = a`, then both variables refer to the same object."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 91,
   "id": "d6a7eb5b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 91,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = [1, 2, 3]\n",
    "b = a\n",
    "b is a"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f6ab3262",
   "metadata": {},
   "source": [
    "So the state diagram looks like this."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "id": "dd406791",
   "metadata": {
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [],
   "source": [
    "t = [1, 2, 3]\n",
    "binding1 = Binding(Value('a'), Value(repr(t)), dy=-0.11)\n",
    "binding2 = Binding(Value('b'), draw_value=False, dy=0.11)\n",
    "frame = Frame([binding1, binding2], dy=-0.25)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 93,
   "id": "552e1e1e",
   "metadata": {
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 111x81 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "width, height, x, y = [1.11, 0.81, 0.17, 0.56]\n",
    "ax = diagram(width, height)\n",
    "bbox = frame.draw(ax, x, y)\n",
    "# adjust(x, y, bbox)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c676fde9",
   "metadata": {},
   "source": [
    "The association of a variable with an object is called a **reference**.\n",
    "In this example, there are two references to the same object.\n",
    "\n",
    "An object with more than one reference has more than one name, so we say the object is **aliased**.\n",
    "If the aliased object is mutable, changes made with one name affect the other.\n",
    "In this example, if we change the object `b` refers to, we are also changing the object `a` refers to."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 94,
   "id": "6e3c1b24",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[5, 2, 3]"
      ]
     },
     "execution_count": 94,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b[0] = 5\n",
    "a"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e3ef0537",
   "metadata": {},
   "source": [
    "So we would say that `a` \"sees\" this change.\n",
    "Although this behavior can be useful, it is error-prone.\n",
    "In general, it is safer to avoid aliasing when you are working with mutable objects.\n",
    "\n",
    "For immutable objects like strings, aliasing is not as much of a problem.\n",
    "In this example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 95,
   "id": "dad8a246",
   "metadata": {},
   "outputs": [],
   "source": [
    "c = 'banana'\n",
    "d = 'banana'"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "952bbf60",
   "metadata": {},
   "source": [
    "It almost never makes a difference whether `a` and `b` refer to the same\n",
    "string or not."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "id": "45f181b7",
   "metadata": {
    "tags": [
     "thebe-interactive"
    ]
   },
   "outputs": [],
   "source": [
    "### EXERCISE: Aliasing\n",
    "a = [1, 2, 3]\n",
    "# 1. Create an alias b that points to the same list as a\n",
    "# 2. Modify the list through b by changing the first element to 99\n",
    "# 3. Create a true copy c using slicing\n",
    "# 4. Modify c and observe that a remains unchanged\n",
    "### Your code starts here:\n",
    "\n",
    "\n",
    "\n",
    "### Your code ends here."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 97,
   "id": "1085deea",
   "metadata": {
    "tags": [
     "hide-input"
    ]
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a after aliasing: [99, 2, 3]\n",
      "b: [99, 2, 3]\n",
      "Same object? True\n",
      "\n",
      "a after copying: [99, 2, 3]\n",
      "c: [99, 777, 3]\n",
      "Same object? False\n"
     ]
    }
   ],
   "source": [
    "# Solution\n",
    "a = [1, 2, 3]\n",
    "b = a  # alias\n",
    "b[0] = 99\n",
    "\n",
    "print(f\"a after aliasing: {a}\")\n",
    "print(f\"b: {b}\")\n",
    "print(f\"Same object? {a is b}\")\n",
    "\n",
    "c = a[:]  # true copy\n",
    "c[1] = 777\n",
    "\n",
    "print(f\"\\na after copying: {a}\")\n",
    "print(f\"c: {c}\")\n",
    "print(f\"Same object? {a is c}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "35045bef",
   "metadata": {},
   "source": [
    "## List Arguments in Functions\n",
    "\n",
    "When you pass a list to a function, the function gets a reference to the\n",
    "list. If the function modifies the list, the caller sees the change. For\n",
    "example, `pop_first` uses the list method `pop` to remove the first element from a list."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "id": "613b1845",
   "metadata": {},
   "outputs": [],
   "source": [
    "def pop_first(lst):\n",
    "    return lst.pop(0)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4953b0f9",
   "metadata": {},
   "source": [
    "We can use it like this."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 99,
   "id": "3aff3598",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'a'"
      ]
     },
     "execution_count": 99,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "letters = ['a', 'b', 'c']\n",
    "pop_first(letters)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ef5d3c1e",
   "metadata": {},
   "source": [
    "The return value is the first element, which has been removed from the list -- as we can see by displaying the modified list."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 100,
   "id": "c10e4dcc",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['b', 'c']"
      ]
     },
     "execution_count": 100,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "letters"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e5288e08",
   "metadata": {},
   "source": [
    "In this example, the parameter `lst` and the variable `letters` are aliases for the same object, so the state diagram looks like this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 101,
   "id": "a13e72c7",
   "metadata": {
    "tags": [
     "hide-input"
    ]
   },
   "outputs": [],
   "source": [
    "from shared.diagram import make_list, Binding, Value\n",
    "\n",
    "lst = make_list('abc', dy=-0.3, offsetx=0.1)\n",
    "binding1 = Binding(Value('letters'), draw_value=False)\n",
    "frame1 = Frame([binding1], name='__main__', loc='left')\n",
    "\n",
    "binding2 = Binding(Value('lst'), draw_value=False, dx=0.61, dy=0.35)\n",
    "frame2 = Frame([binding2], name='pop_first', loc='left', offsetx=0.08)\n",
    "\n",
    "stack = Stack([frame1, frame2], dx=-0.3, dy=-0.5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 102,
   "id": "ac62b394",
   "metadata": {
    "tags": [
     "hide-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[np.float64(2.05), np.float64(1.22), np.float64(1.06), np.float64(0.85)]"
      ]
     },
     "execution_count": 102,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAOAAAACQCAYAAAARD2cgAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjcsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvTLEjVAAAAAlwSFlzAAAPYQAAD2EBqD+naQAADtVJREFUeJztnQuwVeMbxt9ujlCuuauIEqVIQ+4kIpcoROSayWVIZaZxq2lMY5gxhHGbiImEIUYuSUIlYVxSklsRuauOS4X6z++d/zpzOu1zzj5nr3W+tfZ+fjN79j7n7LP32muv5/ve7/ve9/karV+/fr0JIYLQOMzbCiEkQCECox5QiIBIgEIERAIUIiASoBABkQCFCIgEKERAJEAhAiIBChEQCVCIgEiAQgREAhQiIBKgEAGRAIUIiAQoREAkQCECIgEKERAJUIiASIBCBEQCFCIgEqBIBY0aNbIVK1b44xNPPNE+++yzGp8/evRoW716tWWdRrIlFGkR4O+//25bbbVVIs9PK+oBRepo27atffjhh/745ptvto4dO1rXrl39tnTpUhsyZIj/7fDDD/ff/fTTT5ZV1AOKVNCoUo+GAKdMmWJt2rSx3Xff3ZYvX27Nmze3v/76yxo3bmybbrqpekAhkqZly5a211572bnnnmv333+//fbbby6+YkIhqEgtTZo0sblz59rQoUM9zDz44IPtrbfesmKiaegDEKI6ysvL/cZYj9uCBQvsgw8+8MctWrSwlStXZn4SRgIUqWXlypXWv39/+/PPP33MRzh6/vnn+9+GDx9uvXr1ss0228ymTZtm22+/vWURTcIIERCNAYUIiAQoREAkQCECokmYGmAGrphhJjENlBfpec7n/KoHFCIgEqAQAZEAhQiIBChEQCRAIQIiAQoREAlQiIBIgEIERAIUIiCpFyCeH2nPlKByO3L0qomxY8du4OT1wgsv2Lx58xI+OlEbnTp1iuU5RSlAzHnSkjJVKLfccstGAnz33Xfr9Vr//feflSpvvvmmTZ482V566aXMn4fEBHjUUUd50eQRRxxhrVu3thtvvNFefPFFO+yww9x05/bbb6947ogRI6x79+7e2/H8yp6Qlf0i+b+bbrrJevTo4WY9OGaljS+++MKLSI888kg/TrxMAFsF6N27tx166KH2+OOP+/kYN26c//zII4/43ydNmmRHH320V33z3Pnz5/vvH3vsMevTp4/7o2DN8N5779mtt95qBx54oP8/t2+++SbgJzd74okn7Pnnn3dzpaT4+eef7Y8//rCzzjrLttlmG/v8888Lfs1tt93W76+//nr/3jiXnPvKrx09JzMFuQhwu+2285Zq1apVLp7zzjvP7rrrLvv++++tQ4cOtmzZMrcU4KS2atWq4kucMGGCvfzyyzndsk455RS/aH/55Rdr166dLVy40HbZZZckPkLeoS8hKBc/PfUxxxxjDz74oLVv395dvHr27Gl33323devWreJ5kY0C9nqdO3e2K664wn/G/+S2225zcZaVldmcOXNcuISpCHDYsGE2a9YsrwznnOy33362ePHijRzD8iXuyIJoZfr06fb3339bly5dvBHZeuuta/2/8joMMT766CNr1qyZ7bPPPvbjjz/aJ5984uc4DrimuGbh6aef9nP+7LPP1vv18jm/iVZD0BNgrMOXsMcee9hJJ53kgkIwCG7JkiXe67366qsuTL6IdevWuftVdZxzzjl+z4niNb/++uvEBFhXaDE//fRTu/DCCyt+R2u9aNEiF2BtTJ061S8oRByB0Lig4aCDDnLxAWLm8w8ePNiff/zxx+c8D/w/Rkac16o0bRr/17/TTju5lcTHH3/s/i0cb/SdxcHq1att880398ebbLJJrO7YM2bM8IiF74zzlWRP3iACrNwaI8SqP//777/eI1x55ZU+FqJH44sjDM33NXmNtEAwQWMze/bsev8/F+uoUaNy/j268KLPzgXzzjvvuMDoBR566CE75JBDrJgpKyuztWvX+mPu47Ip/Pbbb30oNHPmTG/YaAhPOOEEK/p6QFpLQgpaTi5AwrWsQmtP2DFx4kQfq8GXX37pomS8wt8Ix6MQNPo5gj0RLrnkErvoootst91281aYsO6AAw7Y6L2IFmipERw3el7Cs6oC5L0J2xsiBKXHe+211+ocgtaFnXfe2d5//30PQYmg4op++B64DnfccUe/Dh944AFrCIILkDHQgAEDbN999/WBbt++fS2rENI9+eSTNnLkSLvnnnt8ho7PNH78eP87Pf2pp57qTl44P/O5L7vsMg89CSVx/BozZowNHDjQe3ZaeELLXALkgmFMzdiPsJ7oIc5Qrz4wecbYNwnhReB+xvljboEGhEmoOOD669evn4f5NJZMeDUEckWrgbSvPxZKWpZ3yov0PKsiXoiUk3cIijX4cccdt9GaF2O3ypMDwIwmYUhDwRin6hoYIVCuWSzCvGuuuabBjk2ImlAIWoKhUYRC0GRRCCpEykl9LqgQxYwEKERAJEAhAiIBChEQCVCIgEiAQgREAhQiIMGTsdNMWhaqRfEiAYpYoHKDQmpKkbixrzs1dtg77LDDDjrL1SABiljASgR3gqpQ2iMBVo8EKGLhtNNOs+XLl7uzAUn61EZSC4nJkageCVAUDMXDVO5jjYFPC84AX331lXsCUSwsqkcCFAUbUeFgR+kX1eR77723WyxGrniiZiRAUS8Q3CuvvOI2FHi04tOJXQRWivi2MPkiakf1gKJO/PPPP+5NivMbhdh41nTs2LEi1MTQiBsepaVed9kitC+oKB4QFf6m9HqRGxsu54z5KoMQNe7LHwlQ5OUYzT4MTKwwwTJo0CBfXhCFo1Q0US1r1qxx1/J7773Xx3xnn322Wx8Wm/g6/X/nI+4xhs4Fnq1Lly6N/b3VA4qc4SbO0NOmTXPrd9byCDmTsLKvT6PAvg1k3dAgZH2mNfwZFamCDU/YtQmXOSZXcMKLnLzTQNOmTX3Rny3K4qLyzkcYK2OgjGM7DuVXX311hcse2wHEjQQoHPI3X3/9dd/2jAsS1232SEgbTZo0cWfsOHnjjTc2sN/kZ3pYrDXZCo71TXZKSgIJsMQh3Iz2dCCj5dhjj/ULLonWPgsMGjTIZ3FphE4++WRvlDgfSSEBljDfffedh5vs18heg4hPJVgbkvSSigRYglAqRI9Hz0elwgUXXGBt2rQJfVipgFCT9U1CULYQZ8u3JJEASwi2O2OMR1gF7H/H7kJ1yVpJA88884zvqhztEszORnHBrCr7UzIJc+mllyYafoJS0UoE1rBYTGeWk+3O2FW36p4eoShXKpooVri4WUyfP3++b2bJBqBp2dJbKATNRMtcn4kRNgdl+2qm1Fk7Yweprl27Kk8zZWgMWISwLTY1er/++qt1797da/OaN28e+rBEDiTAImLFihWePsZ+8cxqUpEuP5Z0IwEWASygU59HnR493emnn+6JxSoLSj8SYMazWBYvXuw1ekybkzbFFHpZWVnoQxN5IgFmFMZ3CA9Plnbt2nmZUNYrA0oRCTCDBri4j7399tu2xRZbuBdLhw4dFG5mFAkwQ+HmwoULfZKFVDLSpTA+atasWehDEwUgAWYASmTIYlmyZIn3dhghUZ8mso8EmGKo/ibUJGkawQ0cOND23HPP0IclSkmAZKVTl0XYdcYZZ/hFSS/AxViX9bH77rvPRo4cmdhxtmzZ0qvIq6se5xjIrB82bFhe4SZreVR9YwNI3iYznGmwhBAllow9efJkv3CZ8ast0x9yZfYTupGGhQiSSkWrTYAkQzNuY8eg2sLNGTNmeI0eDQ3LChjdFjPlKUn5C5FCWO86FBZ5b7jhBtt///2tffv2G5TsIxYy7ikVwdCHyQOYOXOmLxBTdcx9t27dfE+B6pg+fbpde+21NnfuXBcQP1O7dscdd/jfR48ebf369fMxEa/H5iD4eeBl0qVLF399TIWGDBniXzKvQflNktAQDB8+3N8HIyMExDEMHTrUj4GJk1wblmAJQY3exIkTvZent+/Tp48KZIucgmIaRMj4BL9ILjguLvw6WJNCbJ07d3ZhkhK1YMEC/x/u77zzTnv00UfdAGfAgAEebuXK2qBCe8yYMTZlyhS/ARdoZaIxEilXkbUC70FPyOI0xrGEn4ivJrHHBVUHJEDPmzdvg2Og0aAHJGMlFxw3PTV5mxxr1mr0RP0o6FumtAUw76GlZ8xCBj7C4waM1QinsD+Atm3bWs+ePf3xmWeeaT/88EOtYVlN4NcY5TtyHKRl4WbFBiGMnxr6QubzcQyXX365Nz48zucYEN7FF1/skYPEVzrEenXWJ/ewUCtzFqMjttxyS/ezpAfGRp0QmL3qGhKOgUaIEJIslR49enh1Qj6fQxULpUdBAnz44Yf9ntCJ7IzIxo0wDCFEO6dSABoVgfLcyBIBg1V6r1133bXwT2LmNgXMluJlOXbsWO+NGH8yQcIYiyyShrBx5xjo5UeNGmWtW7f2HYQYkDfUMYgSGQNS9MkkDBfcuHHj/IIHQi8mWgi/WL966qmnKno5/DsmTJhgV111lY+NJk2aFFsaFaHs4MGDPfTk2BiT4ntCtgjHQ49IT4MvSlIsW7bMP1t0DDRIvXr18mPAyZkekWOo7EUpSpd6L0MgGkxx6uKazMQMs4ENMRlSTNPjxW4VWJ6S85ypZQghROHUW4B0nHXdM4CZvly9H+awTL1XvbEIL0RD7Y5UHawjM8eRBKnIbWIpgZsQtUGyBUMZlmoYS/fu3TvTNvoKQUXmxlX9+/f3Okhmt/NZ4sl3dyRmq/v27esTZdzGjx/vv+d9qu4EXDK5oCFJy+SAJmFyM2fOHGvVqpXv2lsozNjjIHfdddf5Gm7kOlB567K6okkYUbSsWrXKE9zj2kKNpIkoBzeiEPHli0JQkTnWrFnjBcok4Wd5/AcSoMgU69ats6lTp/oYLc696gljSQUkaSSCEDRpJECRKRYtWuQJ/JSoUU3DxEkcUOxM2iTVNmQvUUr23HPPWdJoEqYGNAlTWuc5bjQJI0TKScVCfFop9ul/ER6NAYUIiAQoREAkQCECIgEKERAJUIiASIBCBEQCFCIgEqAQAZEAhQiIckGFCIh6QCECIgEKERAJUIiASIBCBEQCFCIgEqAQAZEAhQiIBChEQCRAIQIiAQoREAlQiIBIgEIERAIUIiASoBABkQCFCIgEKERAJEAhAiIBChEQCVAIC8f/AK12OWchyZ7WAAAAAElFTkSuQmCC",
      "text/plain": [
       "<Figure size 204x124 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "width, height, x, y = [2.04, 1.24, 1.06, 0.85]\n",
    "ax = diagram(width, height)\n",
    "bbox1 = stack.draw(ax, x, y)\n",
    "bbox2 = lst.draw(ax, x+0.5, y)\n",
    "bbox = Bbox.union([bbox1, bbox2])\n",
    "adjust(x, y, bbox)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9b3b07c9",
   "metadata": {},
   "source": [
    "Passing a reference to an object as an argument to a function creates a form of aliasing.\n",
    "If the function modifies the object, those changes persist after the function is done."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0c5b37ad",
   "metadata": {
    "tags": [
     "thebe-interactive"
    ]
   },
   "outputs": [],
   "source": [
    "### EXERCISE: List Arguments in Functions\n",
    "def add_item(lst, item):\n",
    "    \"\"\"Add item to list and return the list\"\"\"\n",
    "    lst.append(item)\n",
    "    return lst\n",
    "\n",
    "# 1. Create a list with [1, 2, 3], call it original\n",
    "# 2. Call add_item with your list and the value 4, \n",
    "#    save the result in a variable called updated\n",
    "# 3. Print the original list to see if it changed after calling the function\n",
    "# 4. check if original and updated refer to the same object using \"is\"\n",
    "### Your code starts here:\n",
    "\n",
    "\n",
    "\n",
    "### Your code ends here."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 111,
   "id": "f2c291b0",
   "metadata": {
    "tags": [
     "hide-input"
    ]
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Original list: [1, 2, 3]\n",
      "Returned list: [1, 2, 3, 4]\n",
      "Original list after function call: [1, 2, 3, 4]\n",
      "Same object? True\n"
     ]
    }
   ],
   "source": [
    "# Solution\n",
    "def add_item(lst, item):\n",
    "    \"\"\"Add item to list and return the list\"\"\"\n",
    "    lst.append(item)\n",
    "    return lst\n",
    "\n",
    "original = [1, 2, 3]\n",
    "print(f\"Original list: {original}\")\n",
    "\n",
    "updated = add_item(original, 4)\n",
    "print(f\"Returned list: {updated}\")\n",
    "print(f\"Original list after function call: {original}\")\n",
    "print(f\"Same object? {updated is original}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4c607d32",
   "metadata": {},
   "source": [
    "## The `all()` and `any()` Functions\n",
    "\n",
    "Python provides two built-in functions for checking Boolean conditions across list elements:\n",
    "\n",
    "- **`all(iterable)`**: Returns `True` if all elements are **truthy** (or if the list is empty)\n",
    "- **`any(iterable)`**: Returns `True` if at least one element is **truthy**\n",
    "\n",
    "These are particularly useful when combined with list comprehensions or generator expressions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 105,
   "id": "de205e19",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "All numbers even? True\n",
      "All numbers positive? True\n",
      "All mixed numbers positive? False\n"
     ]
    }
   ],
   "source": [
    "# all() - check if all elements satisfy a condition\n",
    "numbers = [2, 4, 6, 8, 10]\n",
    "\n",
    "# Check if all numbers are even\n",
    "all_even = all(num % 2 == 0 for num in numbers)\n",
    "print(f\"All numbers even? {all_even}\")\n",
    "\n",
    "# Check if all numbers are positive\n",
    "all_positive = all(num > 0 for num in numbers)\n",
    "print(f\"All numbers positive? {all_positive}\")\n",
    "\n",
    "# With a list containing a negative number\n",
    "mixed = [2, 4, -6, 8]\n",
    "all_positive_mixed = all(num > 0 for num in mixed)\n",
    "print(f\"All mixed numbers positive? {all_positive_mixed}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 106,
   "id": "c6c6c58c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Has any even number? False\n",
      "Has number > 5? True\n",
      "Has word longer than 10 chars? True\n"
     ]
    }
   ],
   "source": [
    "# any() - check if at least one element satisfies a condition\n",
    "numbers = [1, 3, 5, 7, 9]\n",
    "\n",
    "# Check if any number is even\n",
    "has_even = any(num % 2 == 0 for num in numbers)\n",
    "print(f\"Has any even number? {has_even}\")\n",
    "\n",
    "# Check if any number is greater than 5\n",
    "has_large = any(num > 5 for num in numbers)\n",
    "print(f\"Has number > 5? {has_large}\")\n",
    "\n",
    "# Practical example: check if any word is longer than 10 characters\n",
    "words = ['hello', 'world', 'programming', 'python']\n",
    "has_long_word = any(len(word) > 10 for word in words)\n",
    "print(f\"Has word longer than 10 chars? {has_long_word}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5d0a05d2",
   "metadata": {},
   "source": [
    "**Common use cases:**\n",
    "- Validation: `all(score >= 60 for score in scores)` - check if all students passed\n",
    "- Search: `any(word.startswith('py') for word in words)` - check if any word starts with 'py'\n",
    "- Data quality: `all(value is not None for value in data)` - check for missing data\n",
    "\n",
    "**Note:** Both `all()` and `any()` use **short-circuit evaluation**—they stop as soon as the result is determined, making them efficient for large lists."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "71d57ca9",
   "metadata": {
    "tags": [
     "thebe-interactive"
    ]
   },
   "outputs": [],
   "source": [
    "### EXERCISE: all() and any() Functions\n",
    "numbers = [2, 4, 6, 8, 9]\n",
    "words = ['python', 'java', 'javascript', 'go']\n",
    "# 1. Check if all numbers are even using list comprehension (print) \n",
    "# 2. Check if any word starts with 'j' using the \n",
    "#    method \".startswith()\" and list comprehension (print)\n",
    "# 3. Check if any number is greater than 10 (print)\n",
    "### Your code starts here:\n",
    "\n",
    "\n",
    "\n",
    "### Your code ends here."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 108,
   "id": "e9f6b2c0",
   "metadata": {
    "tags": [
     "hide-input"
    ]
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "All numbers even: False\n",
      "Any word starts with 'j': True\n",
      "Any number > 10: False\n"
     ]
    }
   ],
   "source": [
    "# Solution\n",
    "numbers = [2, 4, 6, 8, 9]\n",
    "words = ['python', 'java', 'javascript', 'go']\n",
    "\n",
    "all_even = all(num % 2 == 0 for num in numbers)\n",
    "any_starts_j = any(word.startswith('j') for word in words)\n",
    "any_gt_10 = any(num > 10 for num in numbers)\n",
    "\n",
    "print(f\"All numbers even: {all_even}\")\n",
    "print(f\"Any word starts with 'j': {any_starts_j}\")\n",
    "print(f\"Any number > 10: {any_gt_10}\")"
   ]
  }
 ],
 "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
}
