{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "6c5ad16d-1a64-474e-97da-2b203fdd81df",
   "metadata": {},
   "source": [
    "# Introduction to Python"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "d192e858-76f9-4d7d-81b4-c480de8e4047",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello world\n"
     ]
    }
   ],
   "source": [
    "print(\"hello world\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "eb6174d4-5b47-4303-9b12-e6e1761b60d2",
   "metadata": {},
   "outputs": [],
   "source": [
    "# this is a comment"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "205e46f4-87d4-494d-9c21-6cf10f13631e",
   "metadata": {},
   "source": [
    "## Basic Types and Operations"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2feffab6-ca1c-48f3-b1c3-20fb11f968e1",
   "metadata": {},
   "source": [
    "### Integers"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "dd0664ca-fe9e-4924-b5b0-50f311037e1b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "42"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "42"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "6a0ad5eb-3f10-4f6f-a625-7c6557562dde",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "11"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(3 +3)*7 - 31"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "e04aed84-eef7-4cc7-af24-a7b934f17968",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "13"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "2*3 + 7"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "c59f628c-6256-4fe6-94f7-b76004b0ae2f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "int"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(42)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "e7e70c05-c57a-44bb-8139-bd5bb5cd7b22",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "16"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "2 ** 4 # exponentiation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "a98fa6a7-f624-495d-84a4-70cc1ccb1cce",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "228910131428177603701755406038597370992866256605996714416239305740707356279544553417171483432814473032565478203542224449422544427767103399934794267554112492152570643747783615393289357881580751887291609577050486119385936116125581404470429097773717389138692933902315347725871293766854763709974986644983264429564711070350563522040399138184502765579565271776437524767219607364330343620246397252375590392067099313695524738912790075431862503208410123955197790844902368915156543066869228757701257705464810732957386428986999720416931970101723139791242081350688640076611213184787464723604890702270021713895829613969276994985014364487678263308362490038590335423610626980191000005473125921597417923940324803866846904812245997039463026449953790335867383604239048081272376364499889154174619381286132139726802541904422153396907189539634801218849822748376475140814390481137971610636651543538899732162561295745248744175743178153962997058705210024539453107059157058925528424545393257507597364998430284303652618537241371092574259540395037079680377978341031936"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "2 ** 3456 # int is arbitrarily large "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "0015beca-ec92-49c8-b880-3aca30df0dc8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "int"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(2 ** 3456)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3d342488-7040-4014-b9d6-80e2f67c6732",
   "metadata": {},
   "source": [
    "We can perform integer division using `//` (floor division)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "f2c26bd8-4031-422a-8d22-61e86fa9c788",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "6//7 # floor division"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "4e579403-8ecc-4da9-b58b-a50b72a8f8a1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "6"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "6%7 # mod"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8f85689a-4de5-4f22-93d9-3d4bd9c6cc46",
   "metadata": {},
   "source": [
    "### Booleans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "78f802a0-5fe8-47eb-ad6b-ad0623d5a7c9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "d429240d-33a1-463b-8d18-5f88cb56c7a2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "9ff32483-c4d9-498c-bf83-e412842fa1e2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "True and False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "86ed6b55-8ee0-4efc-83a4-9c76f4f488ac",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "True or False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "72e56850-ec5d-4587-8588-3073c66aee24",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "not True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "4a0d00c1-5ad2-4574-8cd9-328c72419f9e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(42 == 41) or (3 < 4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "9484f7a3-2dcc-4bff-a0f4-084bb0bf0ed0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "17 <= 41"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ee9a9357-7396-4e51-832f-45cf1ed58ca5",
   "metadata": {},
   "source": [
    "Booleans are a subtype of integers:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "9678f5a1-849e-4bc7-a7ec-d5ec17caaaed",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "True + 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "79161c05-edc0-42a9-8162-8bc4cb9a0d8c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "False + 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "08526a00-7021-48b5-92a9-160f1667c08b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "True == 1"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d590c86f-5c11-42f7-b859-8d0f06d064b7",
   "metadata": {},
   "source": [
    "`True` and `False` can be treated as the integers 1 and 0, respectively. Internally, they have the same representation."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "8eac06c7-bb5f-4907-9daf-44dc8e2fb713",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "bool"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "1279ccc5-33b1-4d06-9c06-69e6dd8c7b9b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(True) == type(1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "be5a803f-97dc-448e-aa30-2e6f2825fbb7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "isinstance(True, int)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fdc138e4-d456-40c2-ab12-84ce26e88abf",
   "metadata": {},
   "source": [
    "### Floating Point Numbers"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "39cc7b24-1d25-43f6-bad8-286716da755a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "float"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(3.14)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "05984e39-42a8-43d0-8875-7ad6cd55b96f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.8571428571428571"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "6/7 # real division"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "2e20bc99-cd42-4755-8863-eb26a769c303",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.1"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "1/10"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "a66436e0-d68e-494a-a2c5-26484fe338ef",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3.9354838709677415"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "12.2/3.1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "e75472a1-b4e8-4f1d-9005-178ade4ac59a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3.0"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "12.2//3.1 # floor division"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f7ee2618-52d2-4bfc-a592-8df2f47615b6",
   "metadata": {},
   "source": [
    "Be careful with floating-point number precision. Precision errors are common."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "80164425-fe81-45e7-a2e2-7c7ee92f3c99",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2.8999999999999986"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "12.2 - (3.1 * 3.0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "5dcae863-d320-4b39-9ee0-9830f60c235d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2.899999999999999"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "12.2 % 3.1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "eb4a89fc-fff3-474b-b000-66264c77d965",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "12.2 - (3.1 * 3) == 12.2%3.1"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9a4e2cdf-20ad-4c19-87af-d15e6c55e2fb",
   "metadata": {},
   "source": [
    "Some more examples:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "fbf84367-2548-4c19-9c1b-786ed8f5c493",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "1/10 == 0.1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "b90541e0-c25c-4e79-aebb-adcee9cdd9ce",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "1/10 == 0.100000000000000005551115"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "888656a2-c725-479b-98b6-7c7c2b50ed8b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "0.1 + 0.2 == 0.3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "7a8bd07f-924c-4e5f-9704-50380e21533f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.30000000000000004"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "0.1 + 0.2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "f6829b9f-0816-44bb-8d67-98487f053fc1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "0.3 == 0.299999999999999988897769753748434595763683319091796875"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d515f0c7-4f2e-4972-a43b-856575f10cde",
   "metadata": {},
   "source": [
    "<details>\n",
    "<summary>Why???</summary>\n",
    "Floating point numbers are represented in hardware as binary (base-2) fractions .\n",
    "\n",
    "Not every floating point number can be represented exactly in binary.\n",
    "\n",
    "The actual stored value is the nearest representable binary fraction. In the case of 1/10, the hardware representation is close to but not exactly equal to the true value of 1/10.\n",
    "</details>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5ff5b7e7-4305-469a-b7c8-d2a4ded35cef",
   "metadata": {},
   "source": [
    "It is **not** a good idea to compare real numbers for equality."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "59a5ee69-50e0-4eaa-a785-423c565b3ff2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import math\n",
    "\n",
    "math.isclose(0.1 + 0.2, 0.3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "2020ed5b-4b13-4926-bf92-12df87796955",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "math.isclose(12.2 - (3.1 * 3), 12.2%3.1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "e5511427-349c-452c-a678-52b6f5d1e1b6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on built-in function isclose in module math:\n",
      "\n",
      "isclose(a, b, *, rel_tol=1e-09, abs_tol=0.0)\n",
      "    Determine whether two floating-point numbers are close in value.\n",
      "\n",
      "      rel_tol\n",
      "        maximum difference for being considered \"close\", relative to the\n",
      "        magnitude of the input values\n",
      "      abs_tol\n",
      "        maximum difference for being considered \"close\", regardless of the\n",
      "        magnitude of the input values\n",
      "\n",
      "    Return True if a is close in value to b, and False otherwise.\n",
      "\n",
      "    For the values to be considered close, the difference between them\n",
      "    must be smaller than at least one of the tolerances.\n",
      "\n",
      "    -inf, inf and NaN behave similarly to the IEEE 754 Standard.  That\n",
      "    is, NaN is not close to anything, even itself.  inf and -inf are\n",
      "    only close to themselves.\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(math.isclose)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5ddf6898-2cc3-4794-855f-819d71cfbad3",
   "metadata": {},
   "source": [
    "### Type Conversions (Type Casting)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "63f58a39-c8cd-42d6-ad4a-230215eb7b61",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "int(2.99999)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "6a5570d1-d4eb-4700-98e1-80449fba312b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "round(2.55)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "4abba3b4-3363-4ba1-812a-cf1eda0f223d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "42.0"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "float(42)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "6f529373-2654-4f50-9ed8-8488fa0e29f7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'42.222'"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "str(42.222)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "f83e3711-6709-4fdd-af58-21d47b1335f5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2.0"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "1 + 1.0"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "845a5ae7-abe7-4b71-b243-2e766b5f42d1",
   "metadata": {},
   "source": [
    "### Strings"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "id": "bb243851-835c-4f86-ab3c-696034b2a55d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'This is a string!%67 '"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"This is a string!%67 \""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "id": "5cd44842-d2ca-4a1a-bd4d-87435107b09d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "str"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(\"This is a string\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "id": "371dc10a-7181-4c0e-859d-9023ed3c7d59",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'This is also a string'"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "'This is also a string'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "id": "afe0b75e-3501-43c1-b5c2-89673365f58c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'This is a\\nmultiline\\nstring but also a comment'"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"\"\"This is a\n",
    "multiline\n",
    "string but also a comment\"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "id": "0356b316-9f8a-472f-aebc-9138b9dcbb72",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'hello world'"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"hello \" + \"world\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "id": "c0d06135-439e-47b6-9902-d405d6075df4",
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "can only concatenate str (not \"int\") to str",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "Cell \u001b[0;32mIn[51], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mhello\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;241;43m+\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;241;43m3\u001b[39;49m\n",
      "\u001b[0;31mTypeError\u001b[0m: can only concatenate str (not \"int\") to str"
     ]
    }
   ],
   "source": [
    "\"hello\" + 3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ffc714b1-a65e-4fd2-8e60-71c071db6b3b",
   "metadata": {},
   "outputs": [],
   "source": [
    "3 * \"hello \""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "76456e1f-4fd0-4d3d-b73f-070a242f3b7a",
   "metadata": {},
   "outputs": [],
   "source": [
    "\"hello \" - \"world\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7c585ec1-504b-45ec-832e-0422d9d8eddb",
   "metadata": {},
   "outputs": [],
   "source": [
    "\"hello \" * \"world\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f0995e3c-609d-45f1-94a6-94b45f6cc4f6",
   "metadata": {},
   "outputs": [],
   "source": [
    "\"abcrt\" < \"acb\" # lexicographic comparison"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "599a7b40-6f9b-42d4-8f2f-37256d02d151",
   "metadata": {},
   "outputs": [],
   "source": [
    "\"dabcrt\" < \"acb\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "38c0a616-9437-4a31-8aa5-2d816a088ff3",
   "metadata": {},
   "outputs": [],
   "source": [
    "len(\"123456789\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "521ef9b3-7da2-471a-b854-344c65f3a6bc",
   "metadata": {},
   "source": [
    "#### More Type Conversions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "10ac3d8e-3d1c-4e61-8a24-22c8be64fa7c",
   "metadata": {},
   "outputs": [],
   "source": [
    "int(\"42\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9101cbdc-6dfc-4cf2-90c3-f82415a73b86",
   "metadata": {},
   "outputs": [],
   "source": [
    "int(\"42A\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0f8a7381-91d9-4c71-bd10-9f7432f66bfc",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(\"The answer is \" + str(6*7))\n",
    "\n",
    "print(\"The answer is\", 6*7)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3bde2918-6a83-40a1-b5c6-d56ccea2e233",
   "metadata": {},
   "outputs": [],
   "source": [
    "int(\"42.17\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "439db118-1070-4b1a-afd8-b311495101a2",
   "metadata": {},
   "outputs": [],
   "source": [
    "float(\"42.17\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5895fbe4-a02c-422e-b583-faaba81260b1",
   "metadata": {},
   "outputs": [],
   "source": [
    "int(float(\"42.17\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fda959e4-69a2-4090-9351-29d1ae02452a",
   "metadata": {},
   "outputs": [],
   "source": [
    "str(42/11)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b5a5d3e0-af05-4c63-a4e5-fa8a6cec6044",
   "metadata": {},
   "outputs": [],
   "source": [
    "str(False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5ee82271-e12c-4be4-8559-1a25ecaa462c",
   "metadata": {},
   "outputs": [],
   "source": [
    "False == 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "561a4cda-f40f-4509-b51e-babee4fc0efa",
   "metadata": {},
   "outputs": [],
   "source": [
    "str(False) == str(0)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3837dec1-24da-45e4-84d1-cfe02689060c",
   "metadata": {},
   "source": [
    "How many digits in `4**1212`?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a8259d5c-cf24-499a-af5a-9b987f3d2fc5",
   "metadata": {},
   "outputs": [],
   "source": [
    "4**1212"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b2d64b85-89a2-4277-b055-2cf6f05bad28",
   "metadata": {},
   "outputs": [],
   "source": [
    "len(str(4**1212))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b38ba844-6d4a-44d2-a905-df510806703d",
   "metadata": {},
   "source": [
    "## Variables and Assignment"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "738c9dae-be7e-4346-aa9b-7268c7d694a1",
   "metadata": {},
   "outputs": [],
   "source": [
    "a = 42 # assignment"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e924433e-460e-4560-bf4b-bf1171f3913d",
   "metadata": {},
   "source": [
    "Variables in Python are not explicitly declared!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "784a14f4-a706-4980-915b-54bc82a6402b",
   "metadata": {},
   "outputs": [],
   "source": [
    "a - 25"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c433ad46-ca18-4c68-9e46-05031fa4f2d4",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ab0534b8-af4d-40b5-8099-fd915cc5aef9",
   "metadata": {},
   "outputs": [],
   "source": [
    "a = a - 25\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "29094497-73ae-45d9-a930-ebbb25177aa7",
   "metadata": {},
   "outputs": [],
   "source": [
    "x - 11"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "93004830-fa09-4942-ad9f-0b300a593a88",
   "metadata": {},
   "outputs": [],
   "source": [
    "b = 11\n",
    "print(b)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b4d8af87-6251-442f-a135-83adedeb69f5",
   "metadata": {},
   "source": [
    "Variables are untyped and values of different values can be assigned to them:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cfa53c83-6d86-49dc-9f22-f122378e2ff9",
   "metadata": {},
   "outputs": [],
   "source": [
    "a = 2\n",
    "print(a)\n",
    "a = \"hi\"\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "af3ac547-6da6-4a83-a391-042578a1611f",
   "metadata": {},
   "outputs": [],
   "source": [
    "a+a*3"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9a6605d1-caca-4c70-acbf-002d85fe6b38",
   "metadata": {},
   "source": [
    "Chained assignment:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f2db5c59-72e7-4e78-b8fc-2da9b1e93ea8",
   "metadata": {},
   "outputs": [],
   "source": [
    "a = b = 42"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4ac4f69a-944e-438c-9399-981c2220a7b1",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(a,b)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2603b6ac-817f-4f4b-bb5b-c19428af4901",
   "metadata": {},
   "source": [
    "Multiple (parallel) assignment:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d2b12356-5099-442e-88e4-836e9affad67",
   "metadata": {},
   "outputs": [],
   "source": [
    "a, b = 17, 42 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "637d779c-a69c-4a19-845a-52cd13d3bcc2",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(a,b)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8ca6410d-5337-45f7-9838-4b97c1ff9e8c",
   "metadata": {},
   "source": [
    "We can use parallel assignment to swap the values of variables."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "240a53dc-a823-4186-9e64-edbc4336de9a",
   "metadata": {},
   "outputs": [],
   "source": [
    "tmp = a\n",
    "a = b \n",
    "b = tmp\n",
    "print(a,b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fcca0b8c-c160-4f6e-b978-22a9a2d369b4",
   "metadata": {},
   "outputs": [],
   "source": [
    "a, b = b, a\n",
    "print(a, b)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2ab303aa-a01a-44af-951f-e1d7a254d6b0",
   "metadata": {},
   "source": [
    "The right hand side of the assignment creates a temporary tuple that gets unpacked into the left hand-side (tuple unpacking)."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a772b4d9-b739-41b1-b592-d036ea9d077a",
   "metadata": {},
   "source": [
    "## Control Flow"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "90fb95f1-6b6e-41de-84ee-eb827ee4d8b2",
   "metadata": {},
   "outputs": [],
   "source": [
    "a = 17"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f7dd33c2-e325-4977-83b5-3a9c430da456",
   "metadata": {},
   "outputs": [],
   "source": [
    "if a == 42:\n",
    "    print(\"The answer is found\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "056e408d-7949-48bd-b568-2ceb2e86a14e",
   "metadata": {},
   "outputs": [],
   "source": [
    "a = 11\n",
    "\n",
    "if a == 42:\n",
    "    print(\"The answer is found\")\n",
    "elif a == 11:\n",
    "    print(\"11 was found\")\n",
    "else:\n",
    "    print(\"Not found\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5a08fae9-f6f7-483d-b576-5aa0a5dcf34b",
   "metadata": {},
   "source": [
    "Indentation is important!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f88e0077-9cfd-4dba-b1cf-aa9fc1b18d97",
   "metadata": {},
   "outputs": [],
   "source": [
    "a = 42\n",
    "if a == 42:\n",
    "    print(\"The answer is\")\n",
    "else:\n",
    "    print(\"The answer is not\")\n",
    "print(\"found\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "adda069e-e7b4-4945-a5b4-b8f73d389ccb",
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in [0,1,2,3,4,5,6,7,9]:\n",
    "    print(i*2)\n",
    "print(i)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d296e205-21f4-4edd-92c1-163b125e573a",
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in [42, \"dogs\", \"and\", \"cats\"]:\n",
    "    print(i)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "71fc5a64-12d2-4e80-b39f-c99b1256d16e",
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in [0,1,2,3,4,5,6,7,9]:\n",
    "    print(i*2)\n",
    "    if i == 4: break\n",
    "print(\"Loop has been terminated\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "445fa604-a03d-4c3f-8308-b6075a45b8b0",
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in [0,1,2,3,4,5,6,7,9]:\n",
    "    print(\"i =\", i)\n",
    "    if i == 4: continue\n",
    "    print(\"2 * i =\", i*2)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "41982d85-dfd5-4f2b-897c-3bc42f22a9ca",
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in range(10): # i is in [0,10)\n",
    "    print(i*2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1c73d1a8-99ae-4278-9aa8-e8b878d9922c",
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in range(10):\n",
    "    print(i)\n",
    "    print(i+1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b70d59a6-5840-43fd-bce0-b753730d872f",
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "for i in range(10):\n",
    "    print(i)\n",
    "print(i+1)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2f3adcea-a92d-45f8-bac0-f560766d38dc",
   "metadata": {},
   "source": [
    "White spaces **DO** matter!\n",
    "- Python uses indentation to indicate a block of code\n",
    "- Use 4 spaces per indentation level (style guide)\n",
    "- Avoid the use of tabs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0612861f-90c1-49d0-b8c0-932739f5874b",
   "metadata": {},
   "outputs": [],
   "source": [
    "a = 2\n",
    "for i in range(a+1,10):\n",
    "    print(i)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "66968aec-2dd4-40e3-9c9a-533431276c10",
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in range(3,10,4):\n",
    "    print(i)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "58a23fb2-b164-4b48-ab80-2886cdc9f0b4",
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in range(10,0,-1):\n",
    "    print(i)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "09ad315c-b101-428e-ae6a-d557b6113ff8",
   "metadata": {},
   "outputs": [],
   "source": [
    "for x in \"hello world\": \n",
    "    print(\"character:\", x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "59f50c7a-77ce-4706-a264-070ca9350f0b",
   "metadata": {},
   "outputs": [],
   "source": [
    "# what is the last value of x that will be printed?\n",
    "x = 1\n",
    "while x < 1000000:\n",
    "    print(x)\n",
    "    x = x * 2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "18d7e5c4-4c8b-4f38-a635-eccbdde00d42",
   "metadata": {},
   "source": [
    "`break` and `continue` also work inside while loops."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6c6889f5-779c-4f58-9ffb-8c0154e07073",
   "metadata": {},
   "source": [
    "## Functions"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6071e463-f097-42d9-b144-cedbfa788ddd",
   "metadata": {},
   "source": [
    "### Keyword Arguments "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "53c26560-6b48-4839-9c02-f34904e2ca0e",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(42)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1a8dec5d-028b-4178-a987-a41cca9832f8",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(\"the\", \"answer\", \"is\", 42)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "14974299-51a8-47f4-aed0-c258fc74cbb9",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(\"the\", \"answer\", \"is\", 42, sep=\"\\n\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ee89145e-6d02-48af-861b-1a953a355527",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(\"the\", \"answer\", \"is\", 42, sep=\",\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "07d35094-32ea-4c72-8b68-fbc0f6a0aeac",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(\"the\", \"answer\", \"is\", end=\": \")\n",
    "print(42)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c46a1e51-2230-40ff-9da1-2405505cfd6a",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(\"the\", \"answer\", \"is\", end=\": \")\n",
    "print(42)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ecd224fe-7479-48cf-aec7-0693c1ee7fb8",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(1,2,3, sep=\",\", end=\"\")\n",
    "print(4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bcd56ea7-9f21-413f-83af-e56977c9a6f0",
   "metadata": {},
   "outputs": [],
   "source": [
    "help(print)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "255ac0d0-b462-4f6e-a5a5-573e4153d987",
   "metadata": {},
   "source": [
    "### Function Definitions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a459ecf7-eb00-4237-916a-6604735be42a",
   "metadata": {},
   "outputs": [],
   "source": [
    "def f(x):\n",
    "    return x*(x+1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0c07395e-7372-4db0-9721-d625fcf00822",
   "metadata": {},
   "outputs": [],
   "source": [
    "f(6)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5b29c482-0875-4a49-9620-50a9659d5cd4",
   "metadata": {},
   "outputs": [],
   "source": [
    "help(f)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "16e872b8-58ee-4bba-9caa-806b1feed388",
   "metadata": {},
   "outputs": [],
   "source": [
    "def double(x):\n",
    "    \"\"\"Multiplies its argument by 2\"\"\"\n",
    "    return x * 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "986aea24-4d8f-496c-85cd-a75bd4f00ee5",
   "metadata": {},
   "outputs": [],
   "source": [
    "help(double)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d95c0ee0-9ad1-4d06-9857-e75141ac6efb",
   "metadata": {},
   "outputs": [],
   "source": [
    "double(21)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "38aa1415-00b6-49d7-b115-037f833447f7",
   "metadata": {},
   "outputs": [],
   "source": [
    "double(\"hello\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7825abc3-5a07-4e3c-9dc9-6c154e8733a7",
   "metadata": {},
   "source": [
    "Some functions may not return a result, but do something (e.g., print). This is called a side effect."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9e66c489-0918-4ee4-9c5c-c004dd40ecfa",
   "metadata": {},
   "outputs": [],
   "source": [
    "def f(x):\n",
    "    for i in range(x):\n",
    "        print(i)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0a33e3a4-ef52-47f7-8f5a-935fbca42ece",
   "metadata": {},
   "outputs": [],
   "source": [
    "f(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "04705b2d-a3ad-4326-9778-60cc262b3b8f",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(f(10))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "017e7a57-a884-4401-b813-28f3885dab43",
   "metadata": {},
   "source": [
    "`None` is a special value and denotes the absence of a value. Is useful for functions that do not return values, for partially defined data, etc."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "84d98c1d-b96f-4b01-a373-5b975b0dc64b",
   "metadata": {},
   "source": [
    "Some functions may return a value and have some side effects."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ca1eb8b7-f05f-42be-8c62-3e5046336152",
   "metadata": {},
   "outputs": [],
   "source": [
    "def g(x):\n",
    "    for i in range(x):\n",
    "        print(i)\n",
    "    return x+100"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f161874b-75da-4bb7-b7f5-578b79d8a45f",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(g(10))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c85cd838-ef0e-48c3-af85-9b57f2ce9e23",
   "metadata": {},
   "source": [
    "#### The Fibonacci Function"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "abcd70eb-72e5-4fe3-85ce-c167867de707",
   "metadata": {},
   "source": [
    "Fibonacci Sequence:\n",
    "- F(0) = 0\n",
    "- F(1) = 1\n",
    "- F(n+2) = F(n+1)+F(n)\n",
    "\n",
    "\n",
    "0 1 1 2 3 5 8 13 21 ..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1cb37c7e-8abe-4bb7-8196-74790b7abaf6",
   "metadata": {},
   "outputs": [],
   "source": [
    "def fib(n):\n",
    "    if n < 2: return n\n",
    "    return fib(n-1) + fib(n-2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "43e65fed-f304-4fa1-8195-8a1b48777e72",
   "metadata": {},
   "outputs": [],
   "source": [
    "fib(8)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "009b5696-5d94-4129-bc25-f5b8bc3b21ea",
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in range(10): print(fib(i))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5b5864f8-a639-48a4-a87e-0ad32ab4f7b5",
   "metadata": {},
   "outputs": [],
   "source": [
    "fib(35) # getting slower"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "febbe0a8-d1a7-46f4-a65b-97fa09e91892",
   "metadata": {},
   "outputs": [],
   "source": [
    "fib(40)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "20d2c664-7fef-4dd8-9ef9-aff7365e38a4",
   "metadata": {},
   "source": [
    "Why is it getting slower? Can we do better?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "296a6bb8-ea96-4d27-ae56-9a28841775b5",
   "metadata": {},
   "outputs": [],
   "source": [
    "# fast iterative solution\n",
    "\n",
    "def fib(n):\n",
    "    if n == 0: return 0\n",
    "    a,b = 0,1\n",
    "    for i in range(n-1):\n",
    "        a, b = b, a + b\n",
    "    return b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3076ba0d-a82a-478b-9c3a-a6d30e46400c",
   "metadata": {},
   "outputs": [],
   "source": [
    "fib(8)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5f0620c8-c1a2-45a5-847d-fcf3a58816cc",
   "metadata": {},
   "outputs": [],
   "source": [
    "fib(50)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a8a67df0-935a-4b42-b7f3-e478ab576dbb",
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in range(10): print(fib(i))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1944275e-4436-4d09-8d8c-af25f9065112",
   "metadata": {},
   "outputs": [],
   "source": [
    "fib(10000)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "afcf25e4-7d4c-4902-b696-adf32c8aeda4",
   "metadata": {},
   "outputs": [],
   "source": [
    "len(str(fib(10000))) # number of digits"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d0f64fef-8578-4b14-aacf-36a5fee2cc7f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# fast recursive solution\n",
    "\n",
    "def fib_helper(n, prev1, prev2):\n",
    "    if n == 0: return prev2\n",
    "    else:\n",
    "        return fib_helper(n-1, prev1 + prev2, prev1)\n",
    "\n",
    "def fib_rec(n):\n",
    "    return fib_helper(n, 1, 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "16f0c665-81d1-4606-952d-edc6ce1e319f",
   "metadata": {},
   "outputs": [],
   "source": [
    "fib_rec(8)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e383dc3f-674e-4949-a21e-9c713effd924",
   "metadata": {},
   "outputs": [],
   "source": [
    "fib_rec(50)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "af7c59e8-921d-400f-8a47-c7bc80503877",
   "metadata": {},
   "source": [
    "#### Variable Number of Arguments"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "77d178fa-aa97-427e-8de1-9ba202c8b947",
   "metadata": {},
   "outputs": [],
   "source": [
    "def f(x):\n",
    "    return (x*(x+1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "204ad035-2697-46f4-8c92-33493ec3a906",
   "metadata": {},
   "outputs": [],
   "source": [
    "f(6)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "35f41172-ce6a-4dda-ac12-c7cc86167e19",
   "metadata": {},
   "outputs": [],
   "source": [
    "f(6,7)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "92c7b13f-694c-4bfa-93da-fd618492ccc8",
   "metadata": {},
   "source": [
    "The funtion `print` takes a variable number of arguments and prints them with a space in between. How is this possible?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7ee735df-e352-475c-b52d-5e5a11f099df",
   "metadata": {},
   "outputs": [],
   "source": [
    "help(print)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "67828d4f-aa44-4373-b647-78bfeb88efa8",
   "metadata": {},
   "outputs": [],
   "source": [
    "def sum(*args):\n",
    "    s = 0\n",
    "    for i in args: s += i\n",
    "    return s"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4e8b7b13-1fa8-43f5-9864-2d01d383c9df",
   "metadata": {},
   "source": [
    "Above, `args` is essentially a tuple. The `*` before a parameter tells Python to collect all arguments and pack them into a tuple."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e465e53b-80af-47b8-a6c2-f33813e968d9",
   "metadata": {},
   "outputs": [],
   "source": [
    "sum(1,2,3,4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7cd28d2b-0c31-44fd-9541-4f8596f78944",
   "metadata": {},
   "outputs": [],
   "source": [
    "sum(1,2,3,4,5,\"42\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0165e92f-b67e-461e-b3d7-9071cfb8f5d0",
   "metadata": {},
   "outputs": [],
   "source": [
    "def sum(*args):\n",
    "    s = 0\n",
    "    for i in args: s += int(i)\n",
    "    return s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d0619db6-80c0-4973-b11d-6369fd2b45ef",
   "metadata": {},
   "outputs": [],
   "source": [
    "sum(1,2,3,4,5,\"42\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "747bc3a0-091e-4d69-8b48-9fd9b834fb03",
   "metadata": {},
   "source": [
    "#### Functions That Work for Multiple Types"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "80a8faa7-5697-4d88-9373-22aa5f182bd2",
   "metadata": {},
   "outputs": [],
   "source": [
    "fib(42)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cf0ab129-ff8c-4068-917a-888eb84f5c5b",
   "metadata": {},
   "outputs": [],
   "source": [
    "fib(\"42\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ae8102c0-7ddd-4561-9d09-4c8af9737ae6",
   "metadata": {},
   "outputs": [],
   "source": [
    "fib(int(\"42\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "00a0a736-8586-4fbe-8739-52af2a026893",
   "metadata": {},
   "outputs": [],
   "source": [
    "fib(\"a\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "96bdd649-d0f1-46be-af16-4a4ef281964a",
   "metadata": {},
   "outputs": [],
   "source": [
    "def fib(n):\n",
    "    n = int(n)\n",
    "    if n == 0: return 0\n",
    "    a, b = 0, 1\n",
    "    for i in range(n-1):\n",
    "        c = a + b\n",
    "        a,b = b,c\n",
    "    return b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f7bb39c3-cf68-41e3-85f5-4c8d265c08e6",
   "metadata": {},
   "outputs": [],
   "source": [
    "fib(\"42\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d9855b63-dfd8-468f-a01c-362f061214fc",
   "metadata": {},
   "outputs": [],
   "source": [
    "fib(\"haha\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dc1e483c-93bc-48ba-92b6-4bc4dfcb4909",
   "metadata": {},
   "outputs": [],
   "source": [
    "fib(3.14)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f54ba69f-6103-408c-ba8d-88e4497710ef",
   "metadata": {},
   "outputs": [],
   "source": [
    "def fib(n):\n",
    "    convert = False\n",
    "    if type(n) == str: \n",
    "        convert = True\n",
    "        n = int(n)\n",
    "    if n == 0: return 0\n",
    "    a, b = 0, 1\n",
    "    for i in range(n-1):\n",
    "        a,b = b,a + b\n",
    "        \n",
    "    return str(b) if convert else b\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8957a53d-168e-4238-a017-e827667dfeb7",
   "metadata": {},
   "outputs": [],
   "source": [
    "(42 if 3 < 4 else 11) + 12 # if-then-else at the expression level"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6570ecdc-4669-4f63-964f-880857403dec",
   "metadata": {},
   "outputs": [],
   "source": [
    "fib(42)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e06eba9e-ca01-4592-9db1-d3cb1ade0488",
   "metadata": {},
   "outputs": [],
   "source": [
    "fib('42')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0d77eca7-e05c-47bd-ad3a-613d1644b5fb",
   "metadata": {},
   "outputs": [],
   "source": [
    "fib(\"3\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6991c7ba-5a64-4e72-86aa-411bc58f80c0",
   "metadata": {},
   "outputs": [],
   "source": [
    "def foo(x):\n",
    "    if type(x) == int: return \"yes\"\n",
    "    else: return \"no\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "253231dc-5d1c-4ce5-afd8-453c3c4705cf",
   "metadata": {},
   "outputs": [],
   "source": [
    "foo(11)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "81e9560c-0ca2-4fb2-9a98-741a3f65233e",
   "metadata": {},
   "outputs": [],
   "source": [
    "foo(\"hi\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "27d4b570-918c-4840-9fc0-5a598f1349a4",
   "metadata": {},
   "outputs": [],
   "source": [
    "def foo(x):\n",
    "    return (\"yes\" if type(x) == int else \"no\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5781a324-cb1a-4538-a710-a283a1f9091a",
   "metadata": {},
   "outputs": [],
   "source": [
    "foo(42)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4c716a14-a507-4a8b-b9e1-52f46b93c17a",
   "metadata": {},
   "outputs": [],
   "source": [
    "foo(True)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bd6c125a-634b-47ee-82e9-9d14b06812b3",
   "metadata": {},
   "source": [
    "### More Keyword Arguments"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5591075d-05f3-4c75-91fb-2e85e96d9553",
   "metadata": {},
   "source": [
    "Task: Generalize the fibonacci function to optionally take the values of the first two terms."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f5e496c2-787d-42bd-bd1a-747f0d370b6b",
   "metadata": {},
   "outputs": [],
   "source": [
    "def fib(n, start_a=0, start_b=1):\n",
    "    if n == 0: return start_a\n",
    "    a,b = start_a, start_b\n",
    "    for i in range(n-1):\n",
    "        a, b = b, a + b\n",
    "    return b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9a6241bb-bd6c-4b9e-93a2-95c678a395a9",
   "metadata": {},
   "outputs": [],
   "source": [
    "fib(8)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "74243c6e-6cb7-4a06-a3f0-e2913ceb45f9",
   "metadata": {},
   "outputs": [],
   "source": [
    "fib(8, start_a=0, start_b=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "55a3aeb6-3362-4b02-9ed7-fa2102a14b22",
   "metadata": {},
   "outputs": [],
   "source": [
    "fib(8, start_a=-2, start_b=65)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "59f2dabe-1a23-498a-9ca8-4a311cd00598",
   "metadata": {},
   "outputs": [],
   "source": [
    "fib(7, start_a=17, start_b=42)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dcd6f0ae-1070-43d5-9c4a-4c5b5dfe3384",
   "metadata": {},
   "outputs": [],
   "source": [
    "fib(7, 17, 42)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ebe6fbdc-dfa8-4cb3-870b-4601f64b38f6",
   "metadata": {},
   "outputs": [],
   "source": [
    "fib(start_b=42, n=7, start_a=17)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "206dd7cd-285f-4f34-a933-b905ca5d954b",
   "metadata": {},
   "outputs": [],
   "source": [
    "fib(7,0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4a593341-f30d-4379-ab46-44d4b2626084",
   "metadata": {},
   "outputs": [],
   "source": [
    "fib(7, start_b=2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cbb37241-a746-47b8-86ad-05dfc159b9e7",
   "metadata": {},
   "outputs": [],
   "source": [
    "fib(start_b=42, start_a=17)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "464d6d1a-7d53-4305-8823-c23b8173cc7f",
   "metadata": {},
   "outputs": [],
   "source": [
    "fib(start_b=42, 7, start_a=17)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7dfac5c5-e3d7-4af0-a432-4fd7b4c9f0bd",
   "metadata": {},
   "outputs": [],
   "source": [
    "fib(7, 3.14, 8.9)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d9ac2925-fb24-406f-8e21-b1e33f2f787c",
   "metadata": {},
   "outputs": [],
   "source": [
    "fib(10000, 3.14, 8.9)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9bc79f00-105e-4583-8244-8c0a40f483bb",
   "metadata": {},
   "outputs": [],
   "source": [
    "fib(8, 'ha', 'hi')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ebeda06a-fc73-422f-acd3-af7bdeaa6bab",
   "metadata": {},
   "source": [
    "<details>\n",
    "<summary>Hint!</summary>\n",
    "`+` is overloaded and if its arguments are strings it denotes concatenation.\n",
    "</details>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c5f14f77-cd93-47d8-827a-c56c53671666",
   "metadata": {},
   "source": [
    "## Scoping"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5594f94e-4658-4858-8edd-f9a8019b8ecb",
   "metadata": {},
   "source": [
    "The *scope* of a variable is the textual region where its name is visible. It defines where a variable can be accessed in your code."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9fb4c2d8-6c40-4a2d-a6b8-a70582b5eb7b",
   "metadata": {},
   "outputs": [],
   "source": [
    "a = 42\n",
    "\n",
    "def foo():\n",
    "    print(a)\n",
    "\n",
    "foo()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "11ecd8ef-78a2-4355-892f-b386474056c4",
   "metadata": {},
   "outputs": [],
   "source": [
    "a = 42\n",
    "print(a)\n",
    "\n",
    "def foo():\n",
    "    a = 17 # this is a local variable! The assignment has no effect on the global variable a\n",
    "    print(a)\n",
    "\n",
    "foo()\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "175d7c7b-487e-44ee-aeb2-1d61f80931f5",
   "metadata": {},
   "outputs": [],
   "source": [
    "a = 42\n",
    "\n",
    "def bar():\n",
    "    print(a)\n",
    "    a = 17\n",
    "    print(a)\n",
    "\n",
    "bar()\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6ec280de-8378-4ac2-a329-37740614be15",
   "metadata": {},
   "outputs": [],
   "source": [
    "a = 42\n",
    "\n",
    "def bar():\n",
    "    global a # now all references to a in bar() refer to the global a\n",
    "    print(a)\n",
    "    a = 17\n",
    "    print(a)\n",
    "\n",
    "bar()\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "70062b40-f82b-4962-a308-f96f58a716ec",
   "metadata": {},
   "outputs": [],
   "source": [
    "a = 42\n",
    "\n",
    "def foo():\n",
    "    a = 11\n",
    "    def bar():\n",
    "        a = 7\n",
    "        print(\"In bar:\", a)\n",
    "    print(\"In foo:\", a)\n",
    "    bar()\n",
    "    \n",
    "foo()\n",
    "print(\"Outside:\", a)"
   ]
  }
 ],
 "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.12.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
