{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "6b4fce18-128e-441d-9040-7d738b1ac1c8",
   "metadata": {},
   "source": [
    "## PDSP 2026, Lecture 07, 1 September 2026"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a88a4d36-24d2-469c-80b0-4eab41b2ce57",
   "metadata": {},
   "source": [
    "### Data types in Python"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e6440416-eede-4556-be8d-21bb543fa383",
   "metadata": {},
   "source": [
    "- Extracting unique elements from a list using a dictionary"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "6638ea8a-8203-4353-93c5-305021093606",
   "metadata": {},
   "outputs": [],
   "source": [
    "def uniqd(l):\n",
    "    for x in l:\n",
    "        uniqdict[x] = 1\n",
    "    return(list(uniqdict))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "1757d249-7da6-4b65-be0a-11707301f8ca",
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'uniqdict' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[31m---------------------------------------------------------------------------\u001b[39m",
      "\u001b[31mNameError\u001b[39m                                 Traceback (most recent call last)",
      "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[2]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m uniqd([\u001b[32m1\u001b[39m,\u001b[32m2\u001b[39m,\u001b[32m4\u001b[39m,\u001b[32m3\u001b[39m,\u001b[32m2\u001b[39m,\u001b[32m4\u001b[39m,\u001b[32m1\u001b[39m])\n",
      "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[1]\u001b[39m\u001b[32m, line 3\u001b[39m, in \u001b[36muniqd\u001b[39m\u001b[34m(l)\u001b[39m\n\u001b[32m      1\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m uniqd(l):\n\u001b[32m      2\u001b[39m     \u001b[38;5;28;01mfor\u001b[39;00m x \u001b[38;5;28;01min\u001b[39;00m l:\n\u001b[32m----> \u001b[39m\u001b[32m3\u001b[39m         uniqdict[x] = \u001b[32m1\u001b[39m\n\u001b[32m      4\u001b[39m     \u001b[38;5;28;01mreturn\u001b[39;00m(list(uniqdict))\n",
      "\u001b[31mNameError\u001b[39m: name 'uniqdict' is not defined"
     ]
    }
   ],
   "source": [
    "uniqd([1,2,4,3,2,4,1])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d93b17fa-cfc8-4dfc-a307-1c764bbf441c",
   "metadata": {},
   "source": [
    "- For `uniqdict[x] = 1` to make sense, Python needs to know that `uniqdict` is a dictionary\n",
    "- It is important to initialize `uniqdict` to `{}`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "cd76a57c-390e-45d5-933e-884051047462",
   "metadata": {},
   "outputs": [],
   "source": [
    "def uniqd(l):\n",
    "    uniqdict = {}\n",
    "    for x in l:\n",
    "        uniqdict[x] = 1\n",
    "    return(list(uniqdict))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "6c166ff9-c597-460e-87a7-e7d40abedba4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 2, 4, 3]"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "uniqd([1,2,4,3,2,4,1])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "451e5f98-d839-48ca-a388-265ea4a3b65f",
   "metadata": {},
   "source": [
    "- Likewise for a function that builds up a list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "aefb6a68-8ea2-44bc-8239-13aa7eb63557",
   "metadata": {},
   "outputs": [],
   "source": [
    "def factors(n):\n",
    "    for i in range(1,n+1):\n",
    "        if (n%i == 0):\n",
    "            factorlist.append(i)\n",
    "    return(factorlist)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "209fa358-0e39-4727-8e3d-adf47f775cd9",
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'factorlist' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[31m---------------------------------------------------------------------------\u001b[39m",
      "\u001b[31mNameError\u001b[39m                                 Traceback (most recent call last)",
      "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[6]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m factors(\u001b[32m24\u001b[39m)\n",
      "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[5]\u001b[39m\u001b[32m, line 4\u001b[39m, in \u001b[36mfactors\u001b[39m\u001b[34m(n)\u001b[39m\n\u001b[32m      1\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m factors(n):\n\u001b[32m      2\u001b[39m     \u001b[38;5;28;01mfor\u001b[39;00m i \u001b[38;5;28;01min\u001b[39;00m range(\u001b[32m1\u001b[39m,n+\u001b[32m1\u001b[39m):\n\u001b[32m      3\u001b[39m         \u001b[38;5;28;01mif\u001b[39;00m (n%i == \u001b[32m0\u001b[39m):\n\u001b[32m----> \u001b[39m\u001b[32m4\u001b[39m             factorlist.append(i)\n\u001b[32m      5\u001b[39m     \u001b[38;5;28;01mreturn\u001b[39;00m(factorlist)\n",
      "\u001b[31mNameError\u001b[39m: name 'factorlist' is not defined"
     ]
    }
   ],
   "source": [
    "factors(24)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "478e0345-67a9-49ed-b622-9163d5e2d1e1",
   "metadata": {},
   "outputs": [],
   "source": [
    "def factors(n):\n",
    "    factorlist = []\n",
    "    for i in range(1,n+1):\n",
    "        if (n%i == 0):\n",
    "            factorlist.append(i)\n",
    "    return(factorlist)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "35e55a6b-f830-4f97-9935-f91ee5c33645",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 2, 3, 4, 6, 8, 12, 24]"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "factors(24)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "312612ad-cbb3-4871-91b2-9e9a8165831b",
   "metadata": {},
   "source": [
    "### Nested collections\n",
    "- List of lists, list of tuples, dictionary whose values are lists ...\n",
    "- `matchlist` is a list of tuples\n",
    "- Use two indices to extract a value\n",
    "    - `matchlist[2]` is `(\"Toronto\",\"CAN\",\"BIH\",1,1,0,0,1.35,0.98)`\n",
    "    - `matchlist[2][1]` is `\"CAN\"`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "90dd963d-bf0a-4fa5-963d-1f79a418243d",
   "metadata": {},
   "outputs": [],
   "source": [
    "matchlist = [\n",
    "  (\"Mexico City\",\"MEX\",\"RSA\",2,0,0,0,1.84,0.52),\n",
    "  (\"Zapopan\",\"KOR\",\"CZE\",2,1,0,0,1.45,1.12),\n",
    "  (\"Toronto\",\"CAN\",\"BIH\",1,1,0,0,1.35,0.98),\n",
    "  (\"Inglewood\",\"USA\",\"PAR\",4,1,0,0,2.76,0.88),\n",
    "  (\"Foxborough\",\"QAT\",\"SUI\",1,1,0,0,0.78,1.54),\n",
    "  (\"East Rutherford\",\"BRA\",\"MAR\",1,1,0,0,1.62,1.1),\n",
    "  (\"Philadelphia\",\"HAI\",\"SCO\",0,1,0,0,1.25,0.65),\n",
    "  (\"Seattle\",\"AUS\",\"TUR\",2,0,0,0,1.48,0.72),\n",
    "  (\"Atlanta\",\"GER\",\"CUW\",7,1,0,0,4.82,0.44),\n",
    "  (\"Santa Clara\",\"NED\",\"JPN\",2,2,0,0,1.95,1.82),\n",
    "  (\"Houston\",\"CIV\",\"ECU\",1,0,0,0,1.1,0.95),\n",
    "  (\"Kansas City\",\"SWE\",\"TUN\",5,1,0,0,3.12,0.78),\n",
    "  (\"Miami Gardens\",\"ESP\",\"CPV\",0,0,0,0,2.15,0.35),\n",
    "  (\"Arlington\",\"BEL\",\"EGY\",1,1,0,0,1.58,1.12),\n",
    "  (\"Guadalupe\",\"KSA\",\"URU\",1,1,0,0,0.85,1.76),\n",
    "  (\"Vancouver\",\"IRN\",\"NZL\",2,2,0,0,1.88,1.2),\n",
    "  (\"East Rutherford\",\"FRA\",\"SEN\",3,1,0,0,2.44,1.05),\n",
    "  (\"Foxborough\",\"IRQ\",\"NOR\",1,4,0,0,0.68,2.85),\n",
    "  (\"Inglewood\",\"ARG\",\"ALG\",3,0,0,0,2.65,0.42),\n",
    "  (\"Santa Clara\",\"AUT\",\"JOR\",3,1,0,0,1.98,0.88),\n",
    "  (\"Atlanta\",\"POR\",\"COD\",1,1,0,0,1.78,1.15),\n",
    "  (\"Miami Gardens\",\"ENG\",\"CRO\",4,2,0,0,2.92,1.64),\n",
    "  (\"Houston\",\"GHA\",\"PAN\",1,0,0,0,1.3,0.75),\n",
    "  (\"Seattle\",\"UZB\",\"COL\",1,3,0,0,0.95,2.1),\n",
    "  (\"Atlanta\",\"MEX\",\"KOR\",1,0,0,0,1.62,0.58),\n",
    "  (\"Inglewood\",\"CZE\",\"RSA\",1,1,0,0,1.35,1.15),\n",
    "  (\"Vancouver\",\"CAN\",\"QAT\",6,0,0,0,3.82,0.22),\n",
    "  (\"Mexico City\",\"SUI\",\"BIH\",4,1,0,0,2.45,0.88),\n",
    "  (\"East Rutherford\",\"BRA\",\"HAI\",3,0,0,0,1.16,0.9),\n",
    "  (\"Arlington\",\"SCO\",\"MAR\",0,1,0,0,0.97,0.54),\n",
    "  (\"Toronto\",\"USA\",\"AUS\",2,0,0,0,1.21,0.32),\n",
    "  (\"Guadalupe\",\"TUR\",\"PAR\",0,1,0,0,0.4,0.3),\n",
    "  (\"Foxborough\",\"GER\",\"CIV\",2,1,0,0,1.85,0.72),\n",
    "  (\"Kansas City\",\"ECU\",\"CUW\",0,0,0,0,1.92,0.08),\n",
    "  (\"Philadelphia\",\"NED\",\"SWE\",5,1,0,0,3.45,0.88),\n",
    "  (\"Seattle\",\"TUN\",\"JPN\",0,4,0,0,0.35,3.12),\n",
    "  (\"Houston\",\"BEL\",\"IRN\",0,0,0,0,1.45,0.62),\n",
    "  (\"Miami Gardens\",\"NZL\",\"EGY\",1,3,0,0,0.55,2.15),\n",
    "  (\"Santa Clara\",\"ESP\",\"KSA\",4,0,0,0,3.28,0.25),\n",
    "  (\"East Rutherford\",\"URU\",\"CPV\",2,2,0,0,1.65,1.1),\n",
    "  (\"Arlington\",\"FRA\",\"IRQ\",3,0,0,0,2.21,0.45),\n",
    "  (\"Toronto\",\"NOR\",\"SEN\",3,2,0,0,1.95,1.48),\n",
    "  (\"Guadalupe\",\"ARG\",\"AUT\",2,0,0,0,1.78,0.55),\n",
    "  (\"Foxborough\",\"JOR\",\"ALG\",1,2,0,0,0.88,1.92),\n",
    "  (\"Kansas City\",\"POR\",\"UZB\",5,0,0,0,3.54,0.42),\n",
    "  (\"Philadelphia\",\"COL\",\"COD\",1,0,0,0,1.62,0.58),\n",
    "  (\"Seattle\",\"ENG\",\"GHA\",0,0,0,0,1.12,0.89),\n",
    "  (\"Mexico City\",\"PAN\",\"CRO\",0,1,0,0,0.42,1.48),\n",
    "  (\"Mexico City\",\"CZE\",\"MEX\",0,3,0,0,1.1,1.27),\n",
    "  (\"Zapopan\",\"RSA\",\"KOR\",1,0,0,0,1.26,1.39),\n",
    "  (\"Vancouver\",\"SUI\",\"CAN\",2,1,0,0,0.71,1.35),\n",
    "  (\"Toronto\",\"BIH\",\"QAT\",3,1,0,0,1.48,0.95),\n",
    "  (\"East Rutherford\",\"SCO\",\"BRA\",0,3,0,0,0.45,2.18),\n",
    "  (\"Foxborough\",\"MAR\",\"HAI\",4,2,0,0,2.35,1.12),\n",
    "  (\"Inglewood\",\"TUR\",\"USA\",3,2,0,0,1.62,1.45),\n",
    "  (\"Santa Clara\",\"PAR\",\"AUS\",0,0,0,0,0.55,0.48),\n",
    "  (\"Atlanta\",\"ECU\",\"GER\",2,1,0,0,1.28,1.55),\n",
    "  (\"Houston\",\"CUW\",\"CIV\",0,2,0,0,0.32,1.68),\n",
    "  (\"Kansas City\",\"TUN\",\"NED\",1,3,0,0,0.62,2.15),\n",
    "  (\"Seattle\",\"JPN\",\"SWE\",1,1,0,0,1.12,0.95),\n",
    "  (\"Arlington\",\"NZL\",\"BEL\",1,5,0,0,0.48,3.25),\n",
    "  (\"Guadalupe\",\"EGY\",\"IRN\",1,1,0,0,0.85,0.92),\n",
    "  (\"Miami Gardens\",\"URU\",\"ESP\",0,1,0,0,0.78,1.35),\n",
    "  (\"Philadelphia\",\"CPV\",\"KSA\",0,0,0,0,0.42,0.38),\n",
    "  (\"Foxborough\",\"NOR\",\"FRA\",1,4,0,0,1.3,0.96),\n",
    "  (\"East Rutherford\",\"SEN\",\"IRQ\",5,0,0,0,3.01,0.14),\n",
    "  (\"Santa Clara\",\"JOR\",\"ARG\",1,3,0,0,0.76,2.13),\n",
    "  (\"Inglewood\",\"ALG\",\"AUT\",3,3,0,0,1.62,1.44),\n",
    "  (\"Miami Gardens\",\"COL\",\"POR\",0,0,0,0,1.62,0.73),\n",
    "  (\"Atlanta\",\"COD\",\"UZB\",3,1,0,0,2.35,0.2),\n",
    "  (\"East Rutherford\",\"PAN\",\"ENG\",0,2,0,0,0.69,1.39),\n",
    "  (\"Philadelphia\",\"CRO\",\"GHA\",2,1,0,0,0.42,0.74),\n",
    "  (\"Inglewood\",\"RSA\",\"CAN\",0,1,0,0,0.13,1.32),\n",
    "  (\"Houston\",\"BRA\",\"JPN\",2,1,0,0,1.69,0.23),\n",
    "  (\"Foxborough\",\"GER\",\"PAR\",1,1,3,4,0.72,0.42),\n",
    "  (\"Guadalupe\",\"NED\",\"MAR\",1,1,2,3,0.23,1.4),\n",
    "  (\"Arlington\",\"CIV\",\"NOR\",1,2,0,0,1.15,2.02),\n",
    "  (\"East Rutherford\",\"FRA\",\"SWE\",3,0,0,0,3.17,0.67),\n",
    "  (\"Mexico City\",\"MEX\",\"ECU\",2,0,0,0,1.02,0.73),\n",
    "  (\"Atlanta\",\"ENG\",\"COD\",2,1,0,0,2.04,0.76),\n",
    "  (\"Seattle\",\"BEL\",\"SEN\",3,2,0,0,1.74,3.58),\n",
    "  (\"Santa Clara\",\"USA\",\"BIH\",2,0,0,0,0.92,0.25),\n",
    "  (\"Inglewood\",\"ESP\",\"AUT\",3,0,0,0,2.84,0.32),\n",
    "  (\"Toronto\",\"POR\",\"CRO\",2,1,0,0,2.18,1.34),\n",
    "  (\"Vancouver\",\"SUI\",\"ALG\",2,0,0,0,2.52,0.73),\n",
    "  (\"Arlington\",\"AUS\",\"EGY\",1,1,2,4,0.87,1.36),\n",
    "  (\"Miami Gardens\",\"ARG\",\"CPV\",3,2,0,0,2.16,0.46),\n",
    "  (\"Kansas City\",\"COL\",\"GHA\",1,0,0,0,2.19,0.26),\n",
    "  (\"Philadelphia\",\"PAR\",\"FRA\",0,1,0,0,0.3,1.8),\n",
    "  (\"Houston\",\"CAN\",\"MAR\",0,3,0,0,0.8,1.2),\n",
    "  (\"Arlington\",\"BRA\",\"NOR\",1,2,0,0,2.61,1.05),\n",
    "  (\"Mexico City\",\"MEX\",\"ENG\",2,3,0,0,1.88,1.61),\n",
    "  (\"Miami Gardens\",\"POR\",\"ESP\",0,1,0,0,0.63,1.69),\n",
    "  (\"Santa Clara\",\"USA\",\"BEL\",1,4,0,0,0.67,2.15),\n",
    "  (\"Kansas City\",\"ARG\",\"EGY\",3,2,0,0,2.12,1.54),\n",
    "  (\"Seattle\",\"SUI\",\"COL\",0,0,4,3,1.15,1.46),\n",
    "  (\"Foxborough\",\"FRA\",\"MAR\",2,0,0,0,3.1,0.13),\n",
    "  (\"Inglewood\",\"ESP\",\"BEL\",2,1,0,0,2.08,0.37),\n",
    "  (\"Miami Gardens\",\"NOR\",\"ENG\",1,2,0,0,0.77,0.96),\n",
    "  (\"Kansas City\",\"ARG\",\"SUI\",3,1,0,0,2.0,0.53),\n",
    "  (\"Arlington\",\"FRA\",\"ESP\",0,2,0,0,0.3,1.63),\n",
    "  (\"Atlanta\",\"ENG\",\"ARG\",1,2,0,0,0.54,1.80),\n",
    "  (\"Miami Gardens\",\"FRA\",\"ENG\",4,6,0,0,2.88,2.88),\n",
    "  (\"East Rutherford\",\"ESP\",\"ARG\",1,0,0,0,0.52,0.09)\n",
    "]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "15aec21a-795c-4e6a-8d82-bcf549fc5925",
   "metadata": {},
   "source": [
    "#### List of venues where each team played in FIFA 2026\n",
    "- Initially, build a dictionary of dictionaries\n",
    "    - Outer keys are team names\n",
    "    - Inner dictionary keys are venues where team played\n",
    "- Finally, convert dictionary of dictionaries into dictionary of lists"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "57606d60-c73b-471f-ae52-8c9d778b3629",
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_venues(l):\n",
    "    venues = {}\n",
    "    for m in l:\n",
    "        venue,team1,team2 = m[0],m[1],m[2]\n",
    "        for t in team1,team2:\n",
    "            if t in venues:\n",
    "                venues[t][venue] = 1   # Create/update entry for current venue\n",
    "            else:\n",
    "                venues[t] = {venue:1}  # Create a dictionary for venues[t]\n",
    "                                       # Equivalent to \n",
    "                                       #   venues[t] = {}\n",
    "                                       #   venues[t[[venue] = 1\n",
    "    venuelists = {}\n",
    "    for t in sorted(venues):           # Scan teams in alphabetical order\n",
    "        venuelists[t] = list(venues[t]) # Venues will be listed in the order they were added\n",
    "    return(venuelists)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "8bcaab1b-060b-4e00-8913-bd60b75824bb",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'ALG': ['Inglewood', 'Foxborough', 'Vancouver'],\n",
       " 'ARG': ['Inglewood',\n",
       "  'Guadalupe',\n",
       "  'Santa Clara',\n",
       "  'Miami Gardens',\n",
       "  'Kansas City',\n",
       "  'Atlanta',\n",
       "  'East Rutherford'],\n",
       " 'AUS': ['Seattle', 'Toronto', 'Santa Clara', 'Arlington'],\n",
       " 'AUT': ['Santa Clara', 'Guadalupe', 'Inglewood'],\n",
       " 'BEL': ['Arlington', 'Houston', 'Seattle', 'Santa Clara', 'Inglewood'],\n",
       " 'BIH': ['Toronto', 'Mexico City', 'Santa Clara'],\n",
       " 'BRA': ['East Rutherford', 'Houston', 'Arlington'],\n",
       " 'CAN': ['Toronto', 'Vancouver', 'Inglewood', 'Houston'],\n",
       " 'CIV': ['Houston', 'Foxborough', 'Arlington'],\n",
       " 'COD': ['Atlanta', 'Philadelphia'],\n",
       " 'COL': ['Seattle', 'Philadelphia', 'Miami Gardens', 'Kansas City'],\n",
       " 'CPV': ['Miami Gardens', 'East Rutherford', 'Philadelphia'],\n",
       " 'CRO': ['Miami Gardens', 'Mexico City', 'Philadelphia', 'Toronto'],\n",
       " 'CUW': ['Atlanta', 'Kansas City', 'Houston'],\n",
       " 'CZE': ['Zapopan', 'Inglewood', 'Mexico City'],\n",
       " 'ECU': ['Houston', 'Kansas City', 'Atlanta', 'Mexico City'],\n",
       " 'EGY': ['Arlington', 'Miami Gardens', 'Guadalupe', 'Kansas City'],\n",
       " 'ENG': ['Miami Gardens',\n",
       "  'Seattle',\n",
       "  'East Rutherford',\n",
       "  'Atlanta',\n",
       "  'Mexico City'],\n",
       " 'ESP': ['Miami Gardens',\n",
       "  'Santa Clara',\n",
       "  'Inglewood',\n",
       "  'Arlington',\n",
       "  'East Rutherford'],\n",
       " 'FRA': ['East Rutherford',\n",
       "  'Arlington',\n",
       "  'Foxborough',\n",
       "  'Philadelphia',\n",
       "  'Miami Gardens'],\n",
       " 'GER': ['Atlanta', 'Foxborough'],\n",
       " 'GHA': ['Houston', 'Seattle', 'Philadelphia', 'Kansas City'],\n",
       " 'HAI': ['Philadelphia', 'East Rutherford', 'Foxborough'],\n",
       " 'IRN': ['Vancouver', 'Houston', 'Guadalupe'],\n",
       " 'IRQ': ['Foxborough', 'Arlington', 'East Rutherford'],\n",
       " 'JOR': ['Santa Clara', 'Foxborough'],\n",
       " 'JPN': ['Santa Clara', 'Seattle', 'Houston'],\n",
       " 'KOR': ['Zapopan', 'Atlanta'],\n",
       " 'KSA': ['Guadalupe', 'Santa Clara', 'Philadelphia'],\n",
       " 'MAR': ['East Rutherford', 'Arlington', 'Foxborough', 'Guadalupe', 'Houston'],\n",
       " 'MEX': ['Mexico City', 'Atlanta'],\n",
       " 'NED': ['Santa Clara', 'Philadelphia', 'Kansas City', 'Guadalupe'],\n",
       " 'NOR': ['Foxborough', 'Toronto', 'Arlington', 'Miami Gardens'],\n",
       " 'NZL': ['Vancouver', 'Miami Gardens', 'Arlington'],\n",
       " 'PAN': ['Houston', 'Mexico City', 'East Rutherford'],\n",
       " 'PAR': ['Inglewood',\n",
       "  'Guadalupe',\n",
       "  'Santa Clara',\n",
       "  'Foxborough',\n",
       "  'Philadelphia'],\n",
       " 'POR': ['Atlanta', 'Kansas City', 'Miami Gardens', 'Toronto'],\n",
       " 'QAT': ['Foxborough', 'Vancouver', 'Toronto'],\n",
       " 'RSA': ['Mexico City', 'Inglewood', 'Zapopan'],\n",
       " 'SCO': ['Philadelphia', 'Arlington', 'East Rutherford'],\n",
       " 'SEN': ['East Rutherford', 'Toronto', 'Seattle'],\n",
       " 'SUI': ['Foxborough', 'Mexico City', 'Vancouver', 'Seattle', 'Kansas City'],\n",
       " 'SWE': ['Kansas City', 'Philadelphia', 'Seattle', 'East Rutherford'],\n",
       " 'TUN': ['Kansas City', 'Seattle'],\n",
       " 'TUR': ['Seattle', 'Guadalupe', 'Inglewood'],\n",
       " 'URU': ['Guadalupe', 'East Rutherford', 'Miami Gardens'],\n",
       " 'USA': ['Inglewood', 'Toronto', 'Santa Clara'],\n",
       " 'UZB': ['Seattle', 'Kansas City', 'Atlanta']}"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "get_venues(matchlist)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "b18f3eaf-a920-434f-bce3-adc99edf3463",
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_venues(l):\n",
    "    venues = {}\n",
    "    for m in l:\n",
    "        venue,team1,team2 = m[0],m[1],m[2]\n",
    "        for t in team1,team2:\n",
    "            if t in venues:\n",
    "                venues[t][venue] = 1   # Create/update entry for current venue\n",
    "            else:\n",
    "                venues[t] = {venue:1}  # Create a dictionary for venues[t]\n",
    "                                       # Equivalent to \n",
    "                                       #   venues[t] = {}\n",
    "                                       #   venues[t[[venue] = 1\n",
    "    venuelists = {}\n",
    "    for t in sorted(venues):           # Scan teams in alphabetical order\n",
    "        venuelists[t] = sorted(list(venues[t]))  # Sort venues in alphabetical order\n",
    "    return(venuelists)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "be9883ee-baa7-46a1-a8ee-a0d136f11fe4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'ALG': ['Foxborough', 'Inglewood', 'Vancouver'],\n",
       " 'ARG': ['Atlanta',\n",
       "  'East Rutherford',\n",
       "  'Guadalupe',\n",
       "  'Inglewood',\n",
       "  'Kansas City',\n",
       "  'Miami Gardens',\n",
       "  'Santa Clara'],\n",
       " 'AUS': ['Arlington', 'Santa Clara', 'Seattle', 'Toronto'],\n",
       " 'AUT': ['Guadalupe', 'Inglewood', 'Santa Clara'],\n",
       " 'BEL': ['Arlington', 'Houston', 'Inglewood', 'Santa Clara', 'Seattle'],\n",
       " 'BIH': ['Mexico City', 'Santa Clara', 'Toronto'],\n",
       " 'BRA': ['Arlington', 'East Rutherford', 'Houston'],\n",
       " 'CAN': ['Houston', 'Inglewood', 'Toronto', 'Vancouver'],\n",
       " 'CIV': ['Arlington', 'Foxborough', 'Houston'],\n",
       " 'COD': ['Atlanta', 'Philadelphia'],\n",
       " 'COL': ['Kansas City', 'Miami Gardens', 'Philadelphia', 'Seattle'],\n",
       " 'CPV': ['East Rutherford', 'Miami Gardens', 'Philadelphia'],\n",
       " 'CRO': ['Mexico City', 'Miami Gardens', 'Philadelphia', 'Toronto'],\n",
       " 'CUW': ['Atlanta', 'Houston', 'Kansas City'],\n",
       " 'CZE': ['Inglewood', 'Mexico City', 'Zapopan'],\n",
       " 'ECU': ['Atlanta', 'Houston', 'Kansas City', 'Mexico City'],\n",
       " 'EGY': ['Arlington', 'Guadalupe', 'Kansas City', 'Miami Gardens'],\n",
       " 'ENG': ['Atlanta',\n",
       "  'East Rutherford',\n",
       "  'Mexico City',\n",
       "  'Miami Gardens',\n",
       "  'Seattle'],\n",
       " 'ESP': ['Arlington',\n",
       "  'East Rutherford',\n",
       "  'Inglewood',\n",
       "  'Miami Gardens',\n",
       "  'Santa Clara'],\n",
       " 'FRA': ['Arlington',\n",
       "  'East Rutherford',\n",
       "  'Foxborough',\n",
       "  'Miami Gardens',\n",
       "  'Philadelphia'],\n",
       " 'GER': ['Atlanta', 'Foxborough'],\n",
       " 'GHA': ['Houston', 'Kansas City', 'Philadelphia', 'Seattle'],\n",
       " 'HAI': ['East Rutherford', 'Foxborough', 'Philadelphia'],\n",
       " 'IRN': ['Guadalupe', 'Houston', 'Vancouver'],\n",
       " 'IRQ': ['Arlington', 'East Rutherford', 'Foxborough'],\n",
       " 'JOR': ['Foxborough', 'Santa Clara'],\n",
       " 'JPN': ['Houston', 'Santa Clara', 'Seattle'],\n",
       " 'KOR': ['Atlanta', 'Zapopan'],\n",
       " 'KSA': ['Guadalupe', 'Philadelphia', 'Santa Clara'],\n",
       " 'MAR': ['Arlington', 'East Rutherford', 'Foxborough', 'Guadalupe', 'Houston'],\n",
       " 'MEX': ['Atlanta', 'Mexico City'],\n",
       " 'NED': ['Guadalupe', 'Kansas City', 'Philadelphia', 'Santa Clara'],\n",
       " 'NOR': ['Arlington', 'Foxborough', 'Miami Gardens', 'Toronto'],\n",
       " 'NZL': ['Arlington', 'Miami Gardens', 'Vancouver'],\n",
       " 'PAN': ['East Rutherford', 'Houston', 'Mexico City'],\n",
       " 'PAR': ['Foxborough',\n",
       "  'Guadalupe',\n",
       "  'Inglewood',\n",
       "  'Philadelphia',\n",
       "  'Santa Clara'],\n",
       " 'POR': ['Atlanta', 'Kansas City', 'Miami Gardens', 'Toronto'],\n",
       " 'QAT': ['Foxborough', 'Toronto', 'Vancouver'],\n",
       " 'RSA': ['Inglewood', 'Mexico City', 'Zapopan'],\n",
       " 'SCO': ['Arlington', 'East Rutherford', 'Philadelphia'],\n",
       " 'SEN': ['East Rutherford', 'Seattle', 'Toronto'],\n",
       " 'SUI': ['Foxborough', 'Kansas City', 'Mexico City', 'Seattle', 'Vancouver'],\n",
       " 'SWE': ['East Rutherford', 'Kansas City', 'Philadelphia', 'Seattle'],\n",
       " 'TUN': ['Kansas City', 'Seattle'],\n",
       " 'TUR': ['Guadalupe', 'Inglewood', 'Seattle'],\n",
       " 'URU': ['East Rutherford', 'Guadalupe', 'Miami Gardens'],\n",
       " 'USA': ['Inglewood', 'Santa Clara', 'Toronto'],\n",
       " 'UZB': ['Atlanta', 'Kansas City', 'Seattle']}"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "get_venues(matchlist)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6388018f-f399-4829-8110-410f5944711a",
   "metadata": {},
   "source": [
    "## Matrices\n",
    "- Matrix is a list of lists\n",
    "- Each row is a list of values `[v1,v2,...vm]`\n",
    "- Matrix is a list of rows `[ row1, row2, ..., rown ]`"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "58f33181-0d6f-444a-8b8b-0ef6a4b20882",
   "metadata": {},
   "source": [
    "### Transpose a matrix\n",
    "- Columns of original matrix are rows of transpose\n",
    "- If input is square, can swap `M[i][j]` and `M[j][i]`\n",
    "- If not square, need to construct transpose of correct dimension"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "ad6fba01-5e02-429a-a9e1-1cb5e01e3871",
   "metadata": {},
   "outputs": [],
   "source": [
    "def transpose(mat):\n",
    "    # Extract dimensions of input -- assume well-formed, non-empty\n",
    "    nrows = len(mat)\n",
    "    ncols = len(mat[0])\n",
    "    # Create an empty matrix for the transpose\n",
    "    trmat = []\n",
    "    for i in range(ncols):\n",
    "        trmat.append([])\n",
    "        \n",
    "    # Populate the transpose -- append each M[i][j] to row j of transpose\n",
    "    for i in range(nrows):\n",
    "        for j in range(ncols):\n",
    "            trmat[j].append(mat[i][j])\n",
    "    return(trmat)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "314e1ff4-8480-4592-9a45-0f80ee299b4e",
   "metadata": {},
   "outputs": [],
   "source": [
    "m = [[0,3],[1,4],[2,5]]\n",
    "mt = transpose(m)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "44d29c19-82e0-4114-92cb-dfcdfb4bdfc9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "([[0, 3], [1, 4], [2, 5]], [[0, 1, 2], [3, 4, 5]])"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m, mt"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "808ccf61-2af6-40d6-85d0-b30955522dc5",
   "metadata": {},
   "source": [
    "- Multiplication is repeated addition\n",
    "- `[0] * 5` is `[0]+[0]+[0]+[0]+[0]`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "f954c9c9-b766-4b9b-9fca-41bc5a05bae7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0, 0, 0, 0, 0]"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "[0]*5"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "18120f40-0753-407b-842f-01eb27e3be70",
   "metadata": {},
   "source": [
    "- Create an $n \\times n$ matrix of zeros\n",
    "  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "e414d27a-0ecf-44e9-b830-5c2a32f832c4",
   "metadata": {},
   "outputs": [],
   "source": [
    "def make_zero(n):\n",
    "    zero_row = [0] * n  # Create one row of zeros\n",
    "    zero_matrix = []      # Empty identity matrix\n",
    "    for i in range(n):\n",
    "        zero_matrix.append(zero_row)\n",
    "    return(zero_matrix)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "f30cdd80-954a-4391-8e12-c252e759a599",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[[0, 0, 0, 0, 0],\n",
       " [0, 0, 0, 0, 0],\n",
       " [0, 0, 0, 0, 0],\n",
       " [0, 0, 0, 0, 0],\n",
       " [0, 0, 0, 0, 0]]"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "make_zero(5)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c1037e1f-9d69-46fe-a6a3-9a2c1151fad8",
   "metadata": {},
   "source": [
    "- Create an $n \\times n$ identity matrix"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "327430b8-2c34-4ce0-8c36-bdccad20b72d",
   "metadata": {},
   "outputs": [],
   "source": [
    "def make_identity(n):\n",
    "    identity_matrix = make_zero(n)\n",
    "    for i in range(n):\n",
    "        identity_matrix[i][i] = 1\n",
    "    return(identity_matrix)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "fae09b9c-6827-4374-a233-0e0c654ff340",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[[1, 1, 1, 1, 1],\n",
       " [1, 1, 1, 1, 1],\n",
       " [1, 1, 1, 1, 1],\n",
       " [1, 1, 1, 1, 1],\n",
       " [1, 1, 1, 1, 1]]"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "make_identity(5)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f5851567-395a-4406-8c95-5e126ba4c2fa",
   "metadata": {},
   "source": [
    "- What happened?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "436cb7dc-3da8-4945-ac6e-5cb0381d04e6",
   "metadata": {},
   "outputs": [],
   "source": [
    "l1 = [4,3,1,2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "383292f5-6283-43a7-843e-0d6e47a28002",
   "metadata": {},
   "outputs": [],
   "source": [
    "l2 = l1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "3e4ddcbe-3299-466f-a3ee-8cd0a549272a",
   "metadata": {},
   "outputs": [],
   "source": [
    "l2.sort()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "c8cbe254-e150-48b4-ad37-76d38b379f4d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "([1, 2, 3, 4], [1, 2, 3, 4])"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l1, l2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0c8fbf94-4257-4d3b-9fda-693a3294c3fd",
   "metadata": {},
   "source": [
    "### Mutable and immutable values\n",
    "- Lists and dictionaries can be updated in place\n",
    "    - Can reassign `l[i]` or `d[k]`\n",
    "    - These are *mutable* values\n",
    "- Numbers (`int`, `float`), booleans, strings, tuples cannot be updated in place\n",
    "    - Immutable values"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d4373279-e990-4f41-a905-8f7855d12a78",
   "metadata": {},
   "source": [
    "### Mutability and assignment\n",
    "- Assigning a mutable value creates an *alias*\n",
    "- Updating through either the old or the new name indirectly affects the other"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "2f0eb59c-9579-423b-9fdf-c7461f517144",
   "metadata": {},
   "outputs": [],
   "source": [
    "l = [1,2,3]\n",
    "newl = l\n",
    "newl[0] = 4"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "85da70ff-bc70-4fe3-bbfd-3d00db2e1b2e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "([4, 2, 3], [4, 2, 3])"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l, newl"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "91c2e176-ef26-4557-9c41-7116bb92968d",
   "metadata": {},
   "outputs": [],
   "source": [
    "l[1] = 5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "2cb83a9a-166a-4b37-b87c-d1dd9138ea49",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "([4, 5, 3], [4, 5, 3])"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l, newl"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7bf2f8f1-fd7b-4248-b517-dd339d800c97",
   "metadata": {},
   "source": [
    "- For immutable values, assignment behaves as we would expect\n",
    "- The two names can be updated without affecting each other\n",
    "    - It is as though assignment copies the value"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "b5ad027b-e553-4404-aab1-e811aa140e41",
   "metadata": {},
   "outputs": [],
   "source": [
    "x = 17\n",
    "y = x\n",
    "y = 19"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "8a51d8a0-b730-4a68-a178-70f3a12594a4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(17, 19)"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x, y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "7307a69e-70e3-40e0-af7a-3bc7f0ca7089",
   "metadata": {},
   "outputs": [],
   "source": [
    "x = 18"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "1b3c3491-0b4a-4248-80f0-e12b68324686",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(18, 19)"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x, y"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fc20172e-7d1c-4129-bf82-fbfc290eedfc",
   "metadata": {},
   "source": [
    "### Mutable and immutable values\n",
    "- Lists and dictionaries are mutable\n",
    "- `int`, `float`, `bool`, strings, tuples are immutable"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fe986201-b1e1-4ecc-ac72-86413cf37d76",
   "metadata": {},
   "source": [
    "### Slices and copying lists\n",
    "- A slice creates a new list\n",
    "- `l[0:len(l)]` is a faithful copy of `l`\n",
    "    - Abbreviate as `l[:]`, *full slice*\n",
    "- Assigning a full slice makes a disjoint copy of a list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "a8cf63bb-6232-46e7-b43f-23b206a29047",
   "metadata": {},
   "outputs": [],
   "source": [
    "l1 = [1,2,3]\n",
    "l2 = l1[:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "24d776a8-9c5c-481a-b227-96dee10df3af",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "([1, 2, 3], [1, 2, 3])"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l1,l2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "5f68ceac-dd43-4a80-9166-41101f1cdc3d",
   "metadata": {},
   "outputs": [],
   "source": [
    "l1[2] = 6\n",
    "l2[0] = 4"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "9fce6893-abc2-4ba1-bfba-1f9253796e2f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "([1, 2, 6], [4, 2, 3])"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l1, l2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f25b5466-485e-4c8b-88f1-5b54bbcf8c47",
   "metadata": {},
   "source": [
    "### Calling functions\n",
    "- Suppose we have a function definition `def f(a,b):` and a function call `f(x,y)`\n",
    "- When `f(x,y)` is executed, it is as though we start `f` with the assignments\n",
    "```\n",
    "    a = x\n",
    "    b = y\n",
    "```\n",
    "- This explains how/when values can be updated within a function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "015b86a8-0fae-4296-a40d-467f27e12222",
   "metadata": {},
   "outputs": [],
   "source": [
    "def factorial(n):\n",
    "    ans = 1\n",
    "    while n >= 1:\n",
    "        ans = ans * n\n",
    "        n = n-1\n",
    "    return(ans)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "52622e0c-9c7f-4cf7-bbe5-df5c324de19c",
   "metadata": {},
   "outputs": [],
   "source": [
    "x = 6\n",
    "y = factorial(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "dde6d0d4-76d5-4b02-a7af-40a4b01592ec",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(6, 720)"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x,y"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "49ebd9c5-0854-4229-a0a9-166bd49ba8cb",
   "metadata": {},
   "source": [
    "- Inside the function, the parameter `n` is decremented to `0`\n",
    "- `n` is derived from the variable `x` passed when the function is called\n",
    "- Since `x` is immutable, the implicit assignment `n = x` *copies* the value of `x` into `n`\n",
    "- Updating `n` has no effect on `x`"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "52acb8b0-9dbb-4bba-a5c9-dfe17a03f3a1",
   "metadata": {},
   "source": [
    "- This also means we cannot write a function `swap` along the following lines"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "f74e379f-2a13-4c06-af40-a52efccd5965",
   "metadata": {},
   "outputs": [],
   "source": [
    "def swap(x,y):\n",
    "    (x,y) = (y,x)\n",
    "    return"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "3402481f-e7aa-4714-8e98-73129987de99",
   "metadata": {},
   "outputs": [],
   "source": [
    "m = 5\n",
    "n = 7\n",
    "swap(m,n)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "72f85b60-5532-4f24-a56a-73ffc8ce4bad",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(5, 7)"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m,n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f8123fa8-907e-41e5-81f8-754f34cdd771",
   "metadata": {},
   "source": [
    "- This will not work with mutable values either\n",
    "- The problem is the reassignment inside the function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "7d37d9a0-223e-4b1f-b00e-9491b2d9cb75",
   "metadata": {},
   "outputs": [],
   "source": [
    "list1 = [1,2,3]\n",
    "list2 = [4,5,6]\n",
    "swap(list1,list2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "dfa40284-283c-44cb-9ca1-b0d8fe183c00",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "([1, 2, 3], [4, 5, 6])"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list1, list2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "41a06c77-3b16-4394-883f-4725d59cfb64",
   "metadata": {},
   "source": [
    "### Passing mutable values to a function\n",
    "- Passing an argument is like executing an assignment statement before starting the function\n",
    "- For mutable values, this aliases the function parameter to the called value\n",
    "- In place changes in the function affect the value outside the function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "id": "d7ad990e-84b4-4aee-8933-85945f4b377c",
   "metadata": {},
   "outputs": [],
   "source": [
    "def concat(l1,l2):\n",
    "    l1.extend(l2)\n",
    "    return"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "id": "f60acfaf-e519-4591-8df9-ba1104f108df",
   "metadata": {},
   "outputs": [],
   "source": [
    "l3 = [1,2,3]\n",
    "l4 = [4,5,6]\n",
    "concat(l3,l4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "id": "1c88145f-8e48-4835-b301-8bfabdf8a972",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "([1, 2, 3, 4, 5, 6], [4, 5, 6])"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l3,l4"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bcea13c6-673b-4df9-b9e5-004678c5f2f3",
   "metadata": {},
   "source": [
    "- If we pass a slice, the value in the function is a disjoint copy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "id": "279ef5a3-2264-4883-b25c-9164e98c1e53",
   "metadata": {},
   "outputs": [],
   "source": [
    "l3 = [1,2,3]\n",
    "l4 = [4,5,6]\n",
    "concat(l3[:],l4[:])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "id": "4405d018-3f96-4ade-9680-560c14cd9e60",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "([1, 2, 3], [4, 5, 6])"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l3,l4"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6da228e5-f7d3-4e48-a661-06f8570af45a",
   "metadata": {},
   "source": [
    "- However, reassigning the variable inside the function creates a new value not connected to the outer value"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "id": "40e4be65-f6ed-427f-8999-abcc98239f08",
   "metadata": {},
   "outputs": [],
   "source": [
    "def concat2(l1,l2):\n",
    "    l1 = l1 + l2\n",
    "    return"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "id": "df61282e-b6e7-4f17-89b9-e4f948c1f742",
   "metadata": {},
   "outputs": [],
   "source": [
    "l3 = [1,2,3]\n",
    "l4 = [4,5,6]\n",
    "concat2(l3,l4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "id": "6730426d-4d9c-43f1-b3f7-6bc773197b34",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "([1, 2, 3], [4, 5, 6])"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l3,l4  # No effect - reassignment in function creates a local copy"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e553ebd8-fecd-4146-8137-a3612999229a",
   "metadata": {},
   "source": [
    "- In fact, our problem with `swap()` applies to mutable values as well\n",
    "- The statement `(m,n) = (n,m)` is a reassignment and creates new values inside the function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "id": "a96d6988-b967-4ed3-82a2-86897a02591a",
   "metadata": {},
   "outputs": [],
   "source": [
    "swap(l3,l4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "id": "7dae841d-45cb-4009-b0b8-8e3a8b23b879",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "([1, 2, 3], [4, 5, 6])"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l3,l4"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4275450f-89d1-4bd5-a0ad-be6e5b9e37a0",
   "metadata": {},
   "source": [
    "- Be careful not to mix reassignment with in-place modification\n",
    "- What is the outcome of the following?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "id": "c3939588-8afa-4c93-859d-6a64f8f076ca",
   "metadata": {},
   "outputs": [],
   "source": [
    "def myappend(l,x):\n",
    "    l = l.append(x)\n",
    "    return(l)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "id": "b4028812-d705-4139-961a-295236fe6f7a",
   "metadata": {},
   "outputs": [],
   "source": [
    "l1 = [1,2]\n",
    "l1 = myappend(l1,3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "id": "ddc81865-8cde-4ea3-a4b7-90814c3bd0d2",
   "metadata": {},
   "outputs": [],
   "source": [
    "l1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "id": "1e020be6-e3bb-40f1-b4c4-ac4c4f47defc",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "None\n"
     ]
    }
   ],
   "source": [
    "print(l1)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fe3caab7-9b51-4c70-87d7-95cc1c3be3cd",
   "metadata": {},
   "source": [
    "- `None` is a special value in Python that explicitly represents that no value is assigned\n",
    "- A function that does not return a value returns `None`\n",
    "- In the notebook, the value is \"empty\", but `print()` displays it as `None`\n",
    "    - In other words, `str(None)` converts the value `None` to the string `\"None\"`\n",
    "- `None` has its own type which is not compatible with any other type, so no operations are legal"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "id": "a16285fc-fd6b-4a64-9616-594deff8bf87",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'None'"
      ]
     },
     "execution_count": 60,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "str(None)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "id": "7803b20a-1153-4d43-8fab-f60ea141b3c0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "None\n"
     ]
    }
   ],
   "source": [
    "print(None)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "id": "b18e0629-d3ca-4d72-b571-9d9db075ba7e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "NoneType"
      ]
     },
     "execution_count": 62,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(None)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5049e36d-c33e-43e1-8d79-4eb4d90101e7",
   "metadata": {},
   "source": [
    "- Setting a variable to `None` is different from leaving it undefined"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "id": "ca5b3a9c-57fc-4edf-9eb3-65803ba452fc",
   "metadata": {},
   "outputs": [],
   "source": [
    "x = 7"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "id": "2e57380f-26d3-497d-b9b7-46f12cd20313",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "int"
      ]
     },
     "execution_count": 64,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "id": "32ea46c7-b466-498a-8a45-1a95e74e88d0",
   "metadata": {},
   "outputs": [],
   "source": [
    "del(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "id": "c2c9a7d8-cf18-4154-bf48-c972a2221cb4",
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'x' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[31m---------------------------------------------------------------------------\u001b[39m",
      "\u001b[31mNameError\u001b[39m                                 Traceback (most recent call last)",
      "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[66]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m x\n",
      "\u001b[31mNameError\u001b[39m: name 'x' is not defined"
     ]
    }
   ],
   "source": [
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "id": "357e46d6-f797-435a-a669-8f40a5e11ba8",
   "metadata": {},
   "outputs": [],
   "source": [
    "x = None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "id": "c43e9e8d-ba29-4c2e-a127-cfee03f5453a",
   "metadata": {},
   "outputs": [],
   "source": [
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dbe47d9c-8b7a-4d12-94c0-76c914910999",
   "metadata": {},
   "source": [
    "- We can test if a variable is set to `None`\n",
    "- We will use this later"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "id": "393c90d1-47c6-4928-b63e-702048ece34a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 69,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x == None"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
