{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "fe839e74-b29a-4474-bd76-040d5f1fefde",
   "metadata": {
    "slideshow": {
     "slide_type": ""
    },
    "tags": []
   },
   "source": [
    "# Theory 1\n",
    "## MSc Python Crash Course: Jupyter Notebooks, Logic, Control Structures, and Lambda Functions.\n",
    "\n",
    "MSc MATLAB Crash Course Originally written by Nick Hale, Oct. 2013.\n",
    "Extended by Asgeir Birkisson, Oct. 2014, 2015.\n",
    "Modified by Behnam Hashemi and Hadrien Montanelli, Sep. 2016.\n",
    "Python Crash Course by Benjamin Walker, Oct. 2025.\n",
    "\n",
    "## Introduction\n",
    "\n",
    "A Jupyter Notebook is an interactive environment, which allows you to write and execute Python code in cells. It is a flexible tool, which allows you to include formatted text, \n",
    "$$\n",
    "e^{i \\pi} = -1, \n",
    "$$\n",
    "and visualisations all in one document. Jupyter lets you experiment with and rerun individual pieces of code while preserving all outputs, like plots, tables, and variable states. \n",
    "\n",
    "## Installation\n",
    "\n",
    "```\n",
    "$ conda install jupyterlab\n",
    "$ jupyter-lab\n",
    "```\n",
    "\n",
    "## Basic Key Bindings for Jupyter Notebooks\n",
    "\n",
    "To work efficiently in Jupyter Notebook, it's helpful to learn some basic key bindings that allow you to quickly add, delete, and format cells:\n",
    "\n",
    "Adding a Cell:\n",
    "- Press a to add a new cell above the current cell.\n",
    "- Press b to add a new cell below the current cell.\n",
    "\n",
    "Deleting a Cell:\n",
    "- Press d twice to delete the selected cell.\n",
    "\n",
    "Changing a Cell to Markdown:\n",
    "- Press m to convert the selected cell into a Markdown cell, where you can write formatted text, headings, lists, and more.\n",
    "- Press y to convert the selected cell back to a code cell.\n",
    "\n",
    "Running a Cell:\n",
    "- Press Shift + Enter to run the selected cell and move to the next one.\n",
    "- Press Ctrl + Enter to run the selected cell without moving to the next one.\n",
    "\n",
    "Command vs. Edit Mode:\n",
    "- Press Esc to enter Command Mode, where these key bindings work.\n",
    "- Press Enter to enter Edit Mode, where you can type code or text inside a cell.\n",
    "\n",
    "## Order of Cells\n",
    "\n",
    "In a Jupyter Notebook, the order in which you run the cells matters because the state of variables is preserved across cells. This means that the value of x can change depending on when and how you run each cell.\n",
    "\n",
    "The numbers in the square brackets to the left of each cell (e.g., [1], [2]) indicate the order in which the cells were executed. This helps you track the sequence of operations and understand the current state of your variables."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "3cfe5d3f-cfd7-4a1a-9265-124ca5cdc28a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "/home/ben/anaconda3/envs/Intro2Py/bin/python\n"
     ]
    }
   ],
   "source": [
    "import sys\n",
    "print(sys.executable)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "3fee3879-e016-44a3-8519-ca317eebe291",
   "metadata": {},
   "outputs": [],
   "source": [
    "x = 4"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "abe8dd18-0052-43e7-bfed-d9db82187f12",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "4\n"
     ]
    }
   ],
   "source": [
    "print(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "37dca827-3004-49b5-b6e1-9e43f60ce9a6",
   "metadata": {},
   "outputs": [],
   "source": [
    "x = 5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "cd18efe6-7ad8-4532-b5c2-bb7dc92f5b45",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "7\n"
     ]
    }
   ],
   "source": [
    "print(x + 2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "13747d27-26d1-4131-9635-3d8b36a81dae",
   "metadata": {},
   "source": [
    "## Logic\n",
    "\n",
    "A boolean variable has two possible states, denoted `True` and `False` in python. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "afe4e684-7987-4693-b891-fcff93b68005",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "0e704674-461d-43a3-8e54-af153c90033e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "False"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6df16799-898a-4def-a340-2866c9031293",
   "metadata": {},
   "source": [
    "`a == b` will return True is `a` and `b` are the same value, and False otherwise"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "097a8fdb-2f50-4938-9f03-14c9ba137139",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n"
     ]
    }
   ],
   "source": [
    "a = 5\n",
    "b = 5\n",
    "print(a == b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "e5b0ea06-3ec9-4131-9c24-0f9dbc83c5af",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n"
     ]
    }
   ],
   "source": [
    "b = 6\n",
    "print(a == b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "86f5d655-6d1c-4ab0-8ee8-024fe24466d1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "a = (1, 2, 4)\n",
    "b = \"hello\"\n",
    "c = (1, 2, 4)\n",
    "print(a == b)\n",
    "print(a == c)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "09b9222f-4c44-41e3-92c6-bc254a048008",
   "metadata": {},
   "source": [
    "Conversely, `a != b` will return True when `a` and `b` are different, and False otherwise"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "5621cb5f-363a-4192-8738-9906eab22d0b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n"
     ]
    }
   ],
   "source": [
    "a = 5\n",
    "b = 5\n",
    "print(a != b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "d1c0333c-2de0-4030-b458-22abd2ee78ba",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n"
     ]
    }
   ],
   "source": [
    "b = 6\n",
    "print(a != b)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3779ff48-3b1a-4d69-86b7-32d255f1aaa1",
   "metadata": {},
   "source": [
    "Python has `not` for inverting booleans, and `and` and `or` for combining booleans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "43eb0d9a-a79b-4f7d-bd44-24c1a12a4721",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n",
      "False\n",
      "True\n",
      "False\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "print(not True) \n",
    "print(True and False)\n",
    "print(True or False)\n",
    "print(False or False)\n",
    "print(not (True and not (True or False))) "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4e14dde8-9dd5-4b01-9975-d376c50df443",
   "metadata": {},
   "source": [
    "Python also has bitwise versions of `and`, `or`, and `not`, which are `&`, `|`, and `~` respectively. However, they can have some unexpected effects on boolean values."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "a536b23c-e868-404a-bca3-db714b4e6a96",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n",
      "True\n",
      "-2\n"
     ]
    }
   ],
   "source": [
    "print(True & False)\n",
    "print(True | False)\n",
    "print(~True)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "03d844fb-e7b9-48fd-9c54-7521ecfedec6",
   "metadata": {},
   "source": [
    "Here is a hint:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "3fa24c61-6c43-45f6-a437-e4d662a44ca1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "True + True"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fc5ac549-b753-4889-8177-5c522a1815d4",
   "metadata": {},
   "source": [
    "The comparison operators, `<`, `>`, `<=`, `>=`, behave as you would expect"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "dcb9194e-3113-4045-9872-1ceb8721031b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "import math as m\n",
    "\n",
    "print(5 < 8)\n",
    "print(m.pi ** m.e > m.e ** m.pi)\n",
    "print(3 <= 3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "086e0435-fd52-46e2-82d2-f1ea9f4152b9",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n",
      "[ True  True  True]\n",
      "True\n",
      "False\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "x = [1, 1, 1]\n",
    "print(x == 1)\n",
    "x = np.array([1, 1, 1])\n",
    "print(x == 1)\n",
    "print(all(x == 1))\n",
    "print(any(x == 2))\n",
    "y = np.array([1, 2, 3])\n",
    "print(any(y == 2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "3a943a6d-3ef6-4d26-b94f-7e70f6ab9c2e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0.71808509 0.70097878 0.72697652 0.84671118]\n",
      " [0.99048321 0.21219192 0.30564519 0.12687097]\n",
      " [0.82185804 0.66902794 0.08545769 0.07743915]\n",
      " [0.74578337 0.04949813 0.67431679 0.14692683]]\n",
      "[[False False False False]\n",
      " [False  True  True  True]\n",
      " [False False  True  True]\n",
      " [False  True False  True]]\n",
      "[[0.71808509 0.70097878 0.72697652 0.84671118]\n",
      " [0.99048321 0.         0.         0.        ]\n",
      " [0.82185804 0.66902794 0.         0.        ]\n",
      " [0.74578337 0.         0.67431679 0.        ]]\n"
     ]
    }
   ],
   "source": [
    "A = np.random.rand(4, 4)\n",
    "print(A)\n",
    "print(A < 0.5)\n",
    "A[A < 0.5] = 0\n",
    "print(A)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bdf8a3ec",
   "metadata": {},
   "source": [
    "## Control Structures\n",
    "\n",
    "Python uses the same control structures as most other languages:\n",
    "- `if`\n",
    "- `while`\n",
    "- `for`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "348563b4",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x is not 3\n"
     ]
    }
   ],
   "source": [
    "x = 2\n",
    "if x == 3:\n",
    "    print(\"x is 3\")\n",
    "else:\n",
    "    print(\"x is not 3\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "78b76943",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x is 2\n"
     ]
    }
   ],
   "source": [
    "if x == 3:\n",
    "    print(\"x is 3\")\n",
    "elif x == 2:\n",
    "    print(\"x is 2\")\n",
    "else:\n",
    "    print(\"x is not 2 or 3\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "c1804354",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "2\n",
      "3\n",
      "4\n",
      "5\n",
      "6\n",
      "7\n",
      "8\n",
      "9\n",
      "10\n"
     ]
    }
   ],
   "source": [
    "i = 0;\n",
    "while i < 10:\n",
    "    i = i + 1\n",
    "    print(i)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "93c76abf",
   "metadata": {},
   "source": [
    "For loops work in Python by iterating through an iterable, such as a list, tuple, string, or range, and executing a block of code once for each element in that iterable. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "dc16f3af",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "4\n",
      "9\n"
     ]
    }
   ],
   "source": [
    "numbers = [1, 2, 3]\n",
    "for number in numbers:\n",
    "    print(number ** 2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "21476bb7",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "4\n",
      "5\n",
      "6\n",
      "7\n",
      "8\n"
     ]
    }
   ],
   "source": [
    "for x in range(4, 9):\n",
    "    print(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "d20fc76e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0.71808509 0.70097878 0.72697652 0.84671118]\n",
      "[0.99048321 0.         0.         0.        ]\n",
      "[0.82185804 0.66902794 0.         0.        ]\n",
      "[0.74578337 0.         0.67431679 0.        ]\n"
     ]
    }
   ],
   "source": [
    "for row in A:\n",
    "    print(row)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "5cca445b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "H\n",
      "e\n",
      "l\n",
      "l\n",
      "o\n",
      ",\n",
      " \n",
      "W\n",
      "o\n",
      "r\n",
      "l\n",
      "d\n",
      "!\n"
     ]
    }
   ],
   "source": [
    "string = \"Hello, World!\"\n",
    "for element in string:\n",
    "    print(element)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "4d5fd460",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n",
      "1\n",
      "3\n",
      "4\n",
      "5\n"
     ]
    }
   ],
   "source": [
    "for i in range(10):\n",
    "    if i == 2:\n",
    "        continue\n",
    "    print(i)\n",
    "    if i == 5:\n",
    "        break"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1a9fe497",
   "metadata": {},
   "source": [
    "## Lambda Functions\n",
    "\n",
    "In Python, simple functions which require only one line can be defined using `lambda`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "73241200",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n",
      "1\n",
      "4\n",
      "9\n",
      "16\n"
     ]
    }
   ],
   "source": [
    "f = lambda x: x ** 2\n",
    "for i in range(5):\n",
    "    print(f(i))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "1221c813",
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "must be real number, not list",
     "output_type": "error",
     "traceback": [
      "\u001b[31m---------------------------------------------------------------------------\u001b[39m",
      "\u001b[31mTypeError\u001b[39m                                 Traceback (most recent call last)",
      "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[27]\u001b[39m\u001b[32m, line 4\u001b[39m\n\u001b[32m      2\u001b[39m x = [\u001b[32m1\u001b[39m, \u001b[32m2\u001b[39m, \u001b[32m3\u001b[39m]\n\u001b[32m      3\u001b[39m y = [\u001b[32m4\u001b[39m, \u001b[32m5\u001b[39m, \u001b[32m6\u001b[39m]\n\u001b[32m----> \u001b[39m\u001b[32m4\u001b[39m \u001b[43mf\u001b[49m\u001b[43m(\u001b[49m\u001b[43mx\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43my\u001b[49m\u001b[43m)\u001b[49m\n",
      "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[27]\u001b[39m\u001b[32m, line 1\u001b[39m, in \u001b[36m<lambda>\u001b[39m\u001b[34m(x, y)\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m f = \u001b[38;5;28;01mlambda\u001b[39;00m x, y: \u001b[43mm\u001b[49m\u001b[43m.\u001b[49m\u001b[43mexp\u001b[49m\u001b[43m(\u001b[49m\u001b[43mx\u001b[49m\u001b[43m)\u001b[49m * y\n\u001b[32m      2\u001b[39m x = [\u001b[32m1\u001b[39m, \u001b[32m2\u001b[39m, \u001b[32m3\u001b[39m]\n\u001b[32m      3\u001b[39m y = [\u001b[32m4\u001b[39m, \u001b[32m5\u001b[39m, \u001b[32m6\u001b[39m]\n",
      "\u001b[31mTypeError\u001b[39m: must be real number, not list"
     ]
    }
   ],
   "source": [
    "f = lambda x, y: m.exp(x) * y\n",
    "x = [1, 2, 3]\n",
    "y = [4, 5, 6]\n",
    "f(x, y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "69d61e25",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 10.87312731,  36.94528049, 120.51322154])"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f = lambda x, y: np.exp(x) * y\n",
    "x = np.array([1, 2, 3])\n",
    "y = np.array([4, 5, 6])\n",
    "f(x, y)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2ca2a755-7d6b-4683-b2ed-9595f44ceb4a",
   "metadata": {},
   "source": [
    "This second approach works as numpy vectors are designed for vectorisation, where a function is applied to each element of the array."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "68a9bbca",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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OUcAAAAuie7l3gAAAI4hjgAAAFogjgAAAFogjgAAAFrwZRzdcccdGjdunLp3767MzMx2PcYYo4ULF6pfv37q1q2bCgsL9f7774dsc+jQIU2dOlXp6enKzMzUrFmzQj6aIN46un8ffPCBkpKS2rw9/vjjwe3a+v769etjcUjt0plxueiii1od05VXXhmyzd69ezVp0iR1795dffv21Y033qiGhoZoHkqHdPS4Dx06pGuuuUZDhw5Vt27ddOaZZ+raa69VVVVVyHY2jvfKlSs1YMAApaWlKT8/X1u2bAm7/eOPP66zzz5baWlpGj58uJ577rmQ77fn590GHTnuBx98UF//+tfVq1cv9erVS4WFha22nzFjRquxLS4ujvZhdFhHjnvdunWtjiktLfQXivtxvNv6NywpKUmTJk0KbmP7eL/yyiv61re+pdzcXCUlJenpp58+6WM2bdqkr371qwoEAhoyZIjWrVvXapuO/nvRpqj+5rY4WbhwobnnnntMSUlJu37prTHG3HnnnSYjI8M8/fTT5u9//7v59re/bQYOHGiOHj0a3Ka4uNiMHDnS/O1vfzP/+7//a4YMGWKuuOKKKB1Fx3V0/xoaGsy+fftCbosXLzY9e/Y0hw8fDm4nyaxduzZku5Z/LvHWmXEZP368mT17dsgxVVVVBb/f0NBgzj33XFNYWGi2bdtmnnvuOZOVlWUWLFgQ7cNpt44e91tvvWW+853vmGeffdbs2rXLlJaWmrPOOstcfvnlIdvZNt7r1683qampZs2aNeadd94xs2fPNpmZmaaioqLN7V999VWTkpJi7rrrLvPuu++aW265xXTt2tW89dZbwW3a8/Mebx097u9///tm5cqVZtu2bWbHjh1mxowZJiMjw3z88cfBbaZPn26Ki4tDxvbQoUOxOqR26ehxr1271qSnp4ccU3l5ecg2fhzvgwcPhhzz22+/bVJSUszatWuD29g+3s8995z5j//4D/Pkk08aSeapp54Ku/0//vEP0717d1NSUmLeffddc//995uUlBSzYcOG4DYd/XP04ss4arZ27dp2xVFTU5PJyckxd999d/C+yspKEwgEzG9/+1tjjDHvvvuukWRee+214DZ/+tOfTFJSkvnkk08ivu8dFan9GzVqlPm3f/u3kPva85c2Xjp73OPHjzc/+clPPL//3HPPmeTk5JB/ZH/5y1+a9PR0U1dXF5F9PxWRGu/f/e53JjU11dTX1wfvs228x44da66++urg142NjSY3N9csW7asze2/973vmUmTJoXcl5+fb/793//dGNO+n3cbdPS4T9TQ0GBOO+0089BDDwXvmz59urn00ksjvasR1dHjPtm/84ky3v/5n/9pTjvtNFNTUxO8z4Xxbtaef3duuukm85WvfCXkvsmTJ5uioqLg16f659jMl6fVOmrPnj0qLy9XYWFh8L6MjAzl5+errKxMklRWVqbMzEyNGTMmuE1hYaGSk5O1efPmmO/ziSKxf1u3btX27ds1a9asVt+7+uqrlZWVpbFjx2rNmjUylnw81qkc9yOPPKKsrCyde+65WrBggY4cORLyvMOHD1d2dnbwvqKiIlVXV+udd96J/IF0UKT+PlZVVSk9PV1duoT+JiFbxvv48ePaunVryM9mcnKyCgsLgz+bJyorKwvZXvp87Jq3b8/Pe7x15rhPdOTIEdXX17f67eWbNm1S3759NXToUF111VU6ePBgRPf9VHT2uGtqatS/f3/l5eXp0ksvDfkZTZTxXr16taZMmaIePXqE3G/zeHfUyX62I/Hn2KxDv1vNr8rLyyUpZCJs/rr5e+Xl5erbt2/I97t06aLevXsHt4mnSOzf6tWrdc4552jcuHEh9y9ZskTf/OY31b17d73wwgv68Y9/rJqaGl177bUR2//O6uxxf//731f//v2Vm5urN998UzfffLN27typJ598Mvi8bf19aP5evEVivA8cOKClS5dqzpw5IffbNN4HDhxQY2Njm2Px3nvvtfkYr7Fr+bPcfJ/XNvHWmeM+0c0336zc3NyQiaK4uFjf+c53NHDgQO3evVs//elPdfHFF6usrEwpKSkRPYbO6MxxDx06VGvWrNGIESNUVVWlFStWaNy4cXrnnXd0xhlnJMR4b9myRW+//bZWr14dcr/t491RXj/b1dXVOnr0qP75z3+e8s9NM2fiaP78+Vq+fHnYbXbs2KGzzz47RnsUG+097lN19OhRPfroo7r11ltbfa/lfeedd55qa2t19913R3WyjPZxtwyC4cOHq1+/fpowYYJ2796twYMHd/p5T1Wsxru6ulqTJk3SsGHDdNttt4V8Lx7jjci68847tX79em3atCnk4uQpU6YE/3v48OEaMWKEBg8erE2bNmnChAnx2NVTVlBQoIKCguDX48aN0znnnKNf/epXWrp0aRz3LHZWr16t4cOHa+zYsSH3+3G8Y8WZOJo3b17wd7B5GTRoUKeeOycnR5JUUVGhfv36Be+vqKjQqFGjgtvs378/5HENDQ06dOhQ8PHR0N7jPtX9e+KJJ3TkyBFNmzbtpNvm5+dr6dKlqquri9ov/4vVcTfLz8+XJO3atUuDBw9WTk5Oq3c4VFRUSJLz43348GEVFxfrtNNO01NPPaWuXbuG3T4W4+0lKytLKSkpwT/7ZhUVFZ7HmZOTE3b79vy8x1tnjrvZihUrdOedd+rFF1/UiBEjwm47aNAgZWVladeuXVZMlqdy3M26du2q8847T7t27ZLk//Gura3V+vXrtWTJkpO+jm3j3VFeP9vp6enq1q2bUlJSTvnvT1CHrlByTEcvyF6xYkXwvqqqqjYvyH799deD2zz//PPWXZDd2f0bP358q3ctebn99ttNr169Or2vkRSpcfnLX/5iJJm///3vxpgvLshu+Q6HX/3qVyY9Pd0cO3YscgfQSZ097qqqKnP++eeb8ePHm9ra2na9VrzHe+zYsWbu3LnBrxsbG83pp58e9oLsf/mXfwm5r6CgoNUF2eF+3m3Q0eM2xpjly5eb9PR0U1ZW1q7X+Oijj0xSUpJ55plnTnl/I6Uzx91SQ0ODGTp0qLn++uuNMf4eb2M+n+cCgYA5cODASV/DxvFupnZekH3uueeG3HfFFVe0uiD7VP7+BPenQ1s74sMPPzTbtm0Lvi1927ZtZtu2bSFvTx86dKh58skng1/feeedJjMz0zzzzDPmzTffNJdeemmbb+U/77zzzObNm81f/vIXc9ZZZ1n3Vv5w+/fxxx+boUOHms2bN4c87v333zdJSUnmT3/6U6vnfPbZZ82DDz5o3nrrLfP++++bX/ziF6Z79+5m4cKFUT+e9uroce/atcssWbLEvP7662bPnj3mmWeeMYMGDTIXXnhh8DHNb+WfOHGi2b59u9mwYYPp06ePdW/l78hxV1VVmfz8fDN8+HCza9eukLf3NjQ0GGPsHO/169ebQCBg1q1bZ959910zZ84ck5mZGXwn4Q9/+EMzf/784Pavvvqq6dKli1mxYoXZsWOHWbRoUZtv5T/Zz3u8dfS477zzTpOammqeeOKJkLFt/nfv8OHD5oYbbjBlZWVmz5495sUXXzRf/epXzVlnnWVF8Dfr6HEvXrzYPP/882b37t1m69atZsqUKSYtLc288847wW38ON7NLrjgAjN58uRW97sw3ocPHw7Oz5LMPffcY7Zt22Y+/PBDY4wx8+fPNz/84Q+D2ze/lf/GG280O3bsMCtXrmzzrfzh/hzby5dxNH36dCOp1e3ll18ObqP/+yyXZk1NTebWW2812dnZJhAImAkTJpidO3eGPO/BgwfNFVdcYXr27GnS09PNzJkzQ4Ir3k62f3v27Gn152CMMQsWLDB5eXmmsbGx1XP+6U9/MqNGjTI9e/Y0PXr0MCNHjjSrVq1qc9t46ehx792711x44YWmd+/eJhAImCFDhpgbb7wx5HOOjDHmgw8+MBdffLHp1q2bycrKMvPmzQt5y3u8dfS4X3755TZ/LiSZPXv2GGPsHe/777/fnHnmmSY1NdWMHTvW/O1vfwt+b/z48Wb69Okh2//ud78zX/7yl01qaqr5yle+Yv74xz+GfL89P+826Mhx9+/fv82xXbRokTHGmCNHjpiJEyeaPn36mK5du5r+/fub2bNnd3jSiIWOHPd1110X3DY7O9tccskl5o033gh5Pj+OtzHGvPfee0aSeeGFF1o9lwvj7fVvUvNxTp8+3YwfP77VY0aNGmVSU1PNoEGDQubxZuH+HNsryRhL3pMNAABgAT7nCAAAoAXiCAAAoAXiCAAAoAXiCAAAoAXiCAAAoAXiCAAAoAXiCAAAoAXiCAAAoAXiCAAAoAXiCAAAoAXiCAAAoIX/DydH8wzEYyqpAAAAAElFTkSuQmCC",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "\n",
    "x = np.linspace(-1, 1, 100)\n",
    "y = np.linspace(-1, 1, 100)\n",
    "XX, YY = np.meshgrid(x, y)\n",
    "plt.contourf(XX, YY, f(XX, YY), 20)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cbf54474-722c-490f-be85-ad710132ac9e",
   "metadata": {},
   "source": [
    "## Functions\n",
    "\n",
    "For any function longer than one line, you should use the following syntax"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a81242f4-092c-44f9-beac-bcc120ce2260",
   "metadata": {},
   "outputs": [],
   "source": [
    "import math\n",
    "\n",
    "def solve_quadratic(a, b, c):\n",
    "    \"\"\"\n",
    "    Returns the two real roots of a quadratic equation (ax² + bx + c = 0).\n",
    "    Assumes the discriminant is non-negative.\n",
    "    \"\"\"\n",
    "    discriminant = (b**2) - (4 * a * c)\n",
    "    root1 = (-b - math.sqrt(discriminant)) / (2 * a)\n",
    "    root2 = (-b + math.sqrt(discriminant)) / (2 * a)\n",
    "    return root1, root2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2ad0883e-ef2c-439e-bb72-50115eba0c69",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(solve_quadratic(1, 5, 6))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b344910e",
   "metadata": {},
   "source": [
    "## Floating Point Numbers"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d0e6eedd",
   "metadata": {},
   "outputs": [],
   "source": [
    "import sys\n",
    "eps = sys.float_info.epsilon\n",
    "print(eps)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "6c3144ca",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2.220446049250313e-16\n",
      "0.0\n",
      "0.0\n",
      "0.0\n",
      "4.440892098500626e-16\n",
      "1.1102230246251565e-16\n"
     ]
    }
   ],
   "source": [
    "print((1 + eps) - 1)\n",
    "print((1 + eps/2) - 1)\n",
    "print((1 + eps/2 + eps/2) - 1)\n",
    "print((2 + eps) - 2)\n",
    "print((2 + 2*eps) - 2)\n",
    "print((0.9 + eps/2) - 0.9)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "db36ff70-0dab-4344-a348-382c45ce911a",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "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.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
