{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "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.8.5"
    },
    "colab": {
      "provenance": [],
      "collapsed_sections": [
        "wugqn01Eo6uK"
      ]
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "kon_YiKko6tH"
      },
      "source": [
        "# CS221 Python Review Tutorial\n",
        "\n",
        "Presenter: Dilara\n",
        "\n",
        "Hi! In this tutorial, we will review the basics of Python. This tutorial is largely based on the [CS224N Python Tutorial](http://web.stanford.edu/class/cs224n/readings/cs224n-python-review-code-updated.zip), prepared by Angelica Sun, as well as the [W3Schools Python Tutorial](https://www.w3schools.com/python/).\n",
        "\n",
        "## Contents\n",
        "\n",
        "* Fundamentals\n",
        "* Control Flows\n",
        "* Functions\n",
        "* Classes\n",
        "* Iterables\n",
        "*  Q&A"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "g5MyzBMeo6tW"
      },
      "source": [
        "## Fundamentals\n",
        "\n",
        "### Syntax\n",
        "\n",
        "We can run a Python file through the command line as follows:\n",
        "\n",
        "```\n",
        "python example.py\n",
        "```\n",
        "\n",
        "This line of code will call the `Python` version that is bound to `python` alias in the command line environment. You would sometimes get `Module Not Found` errors. One of the first troubleshooting steps you can do is to actually check whether you are using the correct `Python` binary. To learn which `Python` is being called, you can run:\n",
        "\n",
        "```\n",
        "which python\n",
        "```\n",
        "\n",
        "Let's start with printing \"Hello World!\""
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "bS-2lFSmRicu",
        "outputId": "ba75ed43-ae72-4982-ad58-ca454cba5697"
      },
      "source": [
        "# Printing Hello World!\n",
        "print(\"Hello World!\")"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Hello World!\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "SKPRPmIJTWD0"
      },
      "source": [
        "Indentation is important in `Python`. Lines of code that are in the same block of code should be indented with the same number of spaces."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 132
        },
        "id": "Ly6ZxRUCTVbd",
        "outputId": "734a3e78-10ee-435e-bbbc-b0084dd08901"
      },
      "source": [
        "# Example of an Indentation Error\n",
        "print(\"Hello\")\n",
        "    print(\"Hello World!\")"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "error",
          "ename": "IndentationError",
          "evalue": "ignored",
          "traceback": [
            "\u001b[0;36m  File \u001b[0;32m\"<ipython-input-4-de16869d016e>\"\u001b[0;36m, line \u001b[0;32m3\u001b[0m\n\u001b[0;31m    print(\"Hello World!\")\u001b[0m\n\u001b[0m    ^\u001b[0m\n\u001b[0;31mIndentationError\u001b[0m\u001b[0;31m:\u001b[0m unexpected indent\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "9FsiH-Z4Ul3c"
      },
      "source": [
        "You can use line comments or block comments to comment code in `Python`."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "xbl9Q9ECUlTW",
        "outputId": "7903b8e5-08a7-437b-e408-5e0d8d7f63e8"
      },
      "source": [
        "# Line comment\n",
        "\n",
        "\"\"\"\n",
        "Block comment\n",
        "\"\"\"\n",
        "\n",
        "print(\"Hi!\")"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Hi!\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "0ObB8VtCUEsP"
      },
      "source": [
        "### Variables\n",
        "\n",
        "In `Python`, variables are defined by assigning value to them. There is no need to explicitly declare the type of a variable."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "wZFgDcM4o6te",
        "outputId": "802cacd1-078a-44e1-ad6d-560adb168a78"
      },
      "source": [
        "# str, immutable\n",
        "var = \"hello\" # ''\n",
        "print(type(var))"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "<class 'str'>\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "PqdLmxccXCGa",
        "outputId": "ab83ac06-17dd-4ec6-ac11-822fe13fafe6"
      },
      "source": [
        "# int, immutable\n",
        "var = 10\n",
        "print(type(var))"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "<class 'int'>\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "ZmvDAvPbWzBg",
        "outputId": "0e27eafa-ef5c-4c9d-a4fe-a03e20dd0a4a"
      },
      "source": [
        "# float, immutable\n",
        "var = 10.0\n",
        "print(type(var))"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "<class 'float'>\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "ADVFU3l-XGW8",
        "outputId": "1d1af822-e407-4ae3-8bf9-ed289645c98d"
      },
      "source": [
        "# bool, immutable\n",
        "var = True # False\n",
        "print(type(var))"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "<class 'bool'>\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "H3iFhJRlylvB",
        "outputId": "847101a5-35f6-4b8d-8cf3-8f6a42e73ca1"
      },
      "source": [
        "# tuple, immutable\n",
        "# collections of objects\n",
        "var = (8,9)\n",
        "print(type(var))"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "<class 'tuple'>\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "kQldl4vcXJl9",
        "outputId": "0e4f4179-8861-4552-f700-9554064bb118"
      },
      "source": [
        "# list\n",
        "var = [1,2,3]\n",
        "print(type(var))"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "<class 'list'>\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "e7rA5rhlW2Ua",
        "outputId": "7312dbe9-37b6-4284-89bd-874efea1bc7b"
      },
      "source": [
        "# None\n",
        "var = None\n",
        "print(type(var))"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "<class 'NoneType'>\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "b5bFUVlGV2IH"
      },
      "source": [
        "We can re-assign a variable to a different type."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "zYyhlcEJV6RK",
        "outputId": "44ace863-6982-4335-84e3-61981787fe75"
      },
      "source": [
        "var = 10\n",
        "print(type(var))\n",
        "var = \"Hi 221!\"\n",
        "print(type(var))"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "<class 'int'>\n",
            "<class 'str'>\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "pXsTTdxhXczT"
      },
      "source": [
        "We can cast variables to different types."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "sDtG68Vqo6tf",
        "outputId": "d6a54576-fdcd-4b84-8c35-628c8c9155dc"
      },
      "source": [
        "a = 10\n",
        "print(a, type(a))\n",
        "\n",
        "b = str(a)\n",
        "print(b, type(b))\n",
        "\n",
        "c = int(b)\n",
        "print(c, type(c))\n",
        "\n",
        "d = float(c)\n",
        "print(d, type(d))"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "10 <class 'int'>\n",
            "10 <class 'str'>\n",
            "10 <class 'int'>\n",
            "10.0 <class 'float'>\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "d88q8KFiYkU5"
      },
      "source": [
        "Variable names are sensitive to case."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "Z35h7buwYnkK",
        "outputId": "5eadd3bd-fb31-40ec-ca57-7bbcca27501f"
      },
      "source": [
        "a = 10\n",
        "A = \"221\"\n",
        "print(a == A)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "False\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "EQ9WzOLpY7D5"
      },
      "source": [
        "We can assign values to multiple variables in one line."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "CgTUIBXKY-K8",
        "outputId": "3201e9c7-d630-481a-e7ed-4a1de5774847"
      },
      "source": [
        "a, b, c = \"I\", \"love\", \"CS221\"\n",
        "print(a)\n",
        "print(b)\n",
        "print(c)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "I\n",
            "love\n",
            "CS221\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "AJjUP9Laac2E"
      },
      "source": [
        "We can also print multiple variables in one `print` statement by seperating them with a comma."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "_GZ7VQXEaelm",
        "outputId": "2fd59fc9-0bf7-4429-820d-34c9d7008bb1"
      },
      "source": [
        "a, b, c = \"I\", \"love\", \"CS221\"\n",
        "print(a, b, c)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "I love CS221\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "GeHeASLcZpcu"
      },
      "source": [
        "### Operations\n",
        "\n",
        "#### Number Operations\n",
        "\n",
        "You can use math operators on variables and literals."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "V5sP_1QQba1U",
        "outputId": "f68059e7-0bde-43e9-e59b-7d120f7def6d"
      },
      "source": [
        "var = 10\n",
        "print(var + 4)\n",
        "print(var - 4)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "14\n",
            "6\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "Wef3S0VdbofN",
        "outputId": "b603e23d-a790-4b58-f8ea-ca9374ea7d6d"
      },
      "source": [
        "# Multiply with *\n",
        "print(var * 4)\n",
        "\n",
        "# Raise power with **\n",
        "print(var ** 4)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "40\n",
            "10000\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "nr4ZbHlZbgTJ",
        "outputId": "7603c928-5570-4a3f-f637-e80a874148b9"
      },
      "source": [
        "# Float division with /\n",
        "print(var / 4)\n",
        "\n",
        "# Integer division with //\n",
        "print(var // 4)\n",
        "\n",
        "# Integer division is the same as dividing then casting\n",
        "print(int(var / 4))"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "2.5\n",
            "2\n",
            "2\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "wjSXnKMtcS1I"
      },
      "source": [
        "We can also use compounding operators for each."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "l304SQEdcSIn",
        "outputId": "17c253fa-486a-4ca5-a693-84aa588ee8cd"
      },
      "source": [
        "print(var)\n",
        "var **= 4\n",
        "print(var)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "10\n",
            "10000\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 167
        },
        "id": "4_d5vlWNiBke",
        "outputId": "284aa733-ea39-4d36-b5d6-dd4dbe27345b"
      },
      "source": [
        "--a"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "error",
          "ename": "TypeError",
          "evalue": "ignored",
          "traceback": [
            "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
            "\u001b[0;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
            "\u001b[0;32m<ipython-input-22-8076006b0952>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0ma\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
            "\u001b[0;31mTypeError\u001b[0m: can only concatenate str (not \"int\") to str"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "NTSog3DUco7f"
      },
      "source": [
        "#### Boolean Operations\n",
        "\n",
        "Boolean operations are `not`, `and`, and `or`."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "aP6-LpBIo6tj",
        "outputId": "9cee0dd9-a185-4339-989b-331ebb46909a"
      },
      "source": [
        "print(not True)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "False\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "6vYrzWqkc70o",
        "outputId": "792ba493-b264-4fba-f5af-7508920a21a1"
      },
      "source": [
        "print(True and False)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "False\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "cKIDh4cYdCct",
        "outputId": "45a78590-cbfe-4f22-eea3-24c287911476"
      },
      "source": [
        "var = True or False\n",
        "print(var)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "True\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "DjDQFW7bdclb"
      },
      "source": [
        "`==` checks value equality. `!=` checks inequality."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "iHCGui23difG",
        "outputId": "4e075454-60f0-4740-efe4-2d4faca6c171"
      },
      "source": [
        "a = \"221\"\n",
        "b = \"221\"\n",
        "print(a == b)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "True\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "9z0wa6SweCIO"
      },
      "source": [
        "Operations `>=` and `<=` are available when the order is defined. Refer to this [link](https://www.geeksforgeeks.org/sorting-objects-of-user-defined-class-in-python/) to learn how to define order for user defined classes."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "2LJGhoBQeHd0",
        "outputId": "a7a612c3-003c-4cd3-ff12-dc40a20d0878"
      },
      "source": [
        "a = 6\n",
        "b = 8\n",
        "print(b >= a)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "True\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "SZ6GfhgOdQz5"
      },
      "source": [
        "#### String Operations\n",
        "\n",
        "For strings, double quotes and single quotes are equivalent."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "i-EFzJA7XhKg",
        "outputId": "7050fbaf-5f19-44cb-e049-b46bdb5c5fab"
      },
      "source": [
        "a = \"221\"\n",
        "b = '221'\n",
        "print(a >= b)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "True\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "WL3TFqR5e-ux"
      },
      "source": [
        "We can get the length of a string. `len` function can be used on any `iterable`. Strings are iterables in `Python`, so they can just be treated as arrays."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "1W1ORPaLfDul",
        "outputId": "b0f41e82-8750-4b72-b7ba-a53a61af281b"
      },
      "source": [
        "a = \"I love CS221!\"\n",
        "print(len(a))"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "13\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "aL2NGVmHfLPs"
      },
      "source": [
        "We can access specific elements of a string through their indices."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "1f7zboZGfYOJ",
        "outputId": "3467d97e-5514-48a9-e120-c6c15b59098f"
      },
      "source": [
        "print(a[0])"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "I\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "ZguxFX8HffQT",
        "outputId": "228df4b1-de4e-4aa2-ee31-86de5cd498f9"
      },
      "source": [
        "# [start_index, end_index)\n",
        "print(a[2:6])"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "love\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "pr1qCjllhORU"
      },
      "source": [
        "We can lower all the charaters in a string."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "Kulr99AshNfA",
        "outputId": "6e8703b9-8a4c-460e-fc5c-abb41adf0d60"
      },
      "source": [
        "print(a.lower())"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "i love cs221!\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "VYznaNf0hZtX"
      },
      "source": [
        "We can multiply a string."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "SGaBRMZlhdYr",
        "outputId": "38405ae2-1eb4-42bc-e1af-80b96f5c1b7c"
      },
      "source": [
        "print(a * 4)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "I love CS221!I love CS221!I love CS221!I love CS221!\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "SsyUJxalhgKj"
      },
      "source": [
        "We can concatenate strings."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "-kNbX0ZOhsGz",
        "outputId": "2838a2c7-7e84-404f-a1cc-6777dde5d1d7"
      },
      "source": [
        "b = \"How about you?\"\n",
        "c = a + \" \" + b\n",
        "print(c)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "I love CS221! How about you?\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "1eWp-_bdh4xg"
      },
      "source": [
        "We can check if a substring exists in a string. We can also get the start index of the first occurence of a substring."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "z-KZ6PsVh5cc",
        "outputId": "713b0b71-c603-46a2-97c3-b9e395bc8dfd"
      },
      "source": [
        "print(\"love\" in a)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "True\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "UYaExPmsi3M2"
      },
      "source": [
        "if \"love\" not in a:\n",
        "  print(\"yeyyy\")"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "b8Y9YInEkj8U",
        "outputId": "ea09a33a-c5f5-4177-808d-ed384315e82a"
      },
      "source": [
        "print(\"love\" not in a)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "False\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "bfB_vufGiHNE",
        "outputId": "113b4cc4-5300-4b6a-9a9b-45c61fd5de05"
      },
      "source": [
        "a.index(\"love\")"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "2"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 34
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "lGD4FEI7iMM7"
      },
      "source": [
        "We can split a string."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "IlmNdwM1iN04",
        "outputId": "c8e2cc05-d4e7-41d0-eddd-f55bf2bf7c2b"
      },
      "source": [
        "# The default delimiter is a space, but we can pass a different delimiter\n",
        "a.split()\n"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "['I', 'love', 'CS221!']"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 35
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "l80WOUvBjt0G",
        "outputId": "7bb6ab9d-60ac-4057-d288-7ff218568541"
      },
      "source": [
        "a.split('2')"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "['I love CS', '', '1!']"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 36
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "-r8JrMpLiz2g"
      },
      "source": [
        "We can combine a list."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "Vs7mynmvi5Mk",
        "outputId": "e2dc4469-f0c4-4bb2-c8c3-58a0efd6b0fa"
      },
      "source": [
        "a_splitted = a.split()\n",
        "print(a_splitted)\n",
        "\n",
        "a_joined = '-'.join(a_splitted)\n",
        "print(a_joined)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "['I', 'love', 'CS221!']\n",
            "I-love-CS221!\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "_eZIL5U6jJUj"
      },
      "source": [
        "We can format variables in strings."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "ftkUo2kho6tk",
        "outputId": "d03decbb-8110-4d19-ba38-d80432d26238"
      },
      "source": [
        "pi = 3.14159\n",
        "print(\"Pi is %.2f!\"%(pi))\n"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Pi is 3.14!\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 35
        },
        "id": "VVZolJWRkJjR",
        "outputId": "c90054be-475f-42ad-da18-48105c9df6c2"
      },
      "source": [
        "f\"Pi is {pi}!\""
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "application/vnd.google.colaboratory.intrinsic+json": {
              "type": "string"
            },
            "text/plain": [
              "'Pi is 3.14159!'"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 42
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "RMivqfyxkBVj"
      },
      "source": [
        "## Control Flows\n",
        "\n",
        "### For Loops\n",
        "\n",
        "We can use loops to iterate over iterables, such as strings or arrays."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "cHziqbEQkWab",
        "outputId": "b2d43fd1-c8ba-49ea-b70b-7a869159c6e9"
      },
      "source": [
        "s = \"I love 221!\"\n",
        "for character in s:\n",
        "  print(character)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "I\n",
            " \n",
            "l\n",
            "o\n",
            "v\n",
            "e\n",
            " \n",
            "2\n",
            "2\n",
            "1\n",
            "!\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "bbuQrxDQkuaK",
        "outputId": "c958107a-6351-4c3e-d504-9b2cf1b1e4e0"
      },
      "source": [
        "arr = ['a','b','c','d','e','f']\n",
        "index = 0\n",
        "for char in arr:\n",
        "  print(char)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "a\n",
            "b\n",
            "c\n",
            "d\n",
            "e\n",
            "f\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "1BmvK_0Nlmhr"
      },
      "source": [
        "If we also want to keep track of the iteration number, we can use the `enumerate` function."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "77WtGYRDlr4x",
        "outputId": "95d459e9-5247-4a39-bfac-df117527a840"
      },
      "source": [
        "for i, char in enumerate(a):\n",
        "  print(i, char)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "0 I\n",
            "1  \n",
            "2 l\n",
            "3 o\n",
            "4 v\n",
            "5 e\n",
            "6  \n",
            "7 C\n",
            "8 S\n",
            "9 2\n",
            "10 2\n",
            "11 1\n",
            "12 !\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "l8C5T16Pk2sJ"
      },
      "source": [
        "We can iterate a set number of times using the `range` function."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "_m_pGCQfkdyZ",
        "outputId": "4c4a5861-2d09-40b4-a998-b3b318adf1b9"
      },
      "source": [
        "# Same as for (int i = 0; i < 4; i++)\n",
        "for i in range(4):\n",
        "  print(i)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "0\n",
            "1\n",
            "2\n",
            "3\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "b4GtKTHnmKoF"
      },
      "source": [
        "We can use different ranges as well. `range` function can take 3 parameters:\n",
        "\n",
        "`range(start-inclusive, stop-exclusive, step)`"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "hm4pCCORmOR4",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "749a7f96-144f-42bd-bfbe-c195caf3ce9c"
      },
      "source": [
        "# Same as for (int = 2; i > -3, i =- 2)\n",
        "for i in range(2, -3, -2):\n",
        "    print(i)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "2\n",
            "0\n",
            "-2\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "N9w2GNvtm7VA"
      },
      "source": [
        "### While Loops\n",
        "\n",
        "We can also use `while` loops.\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "LnHP2aTYo6tm",
        "outputId": "7ee3f625-37e7-4b8c-c172-9e71cb5e60c0"
      },
      "source": [
        "ind = 0\n",
        "while ind < 5:\n",
        "    print(ind)\n",
        "    ind +=1\n",
        "    break"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "0\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "z05_SKqQnPms"
      },
      "source": [
        "### If Condition\n",
        "\n",
        "We can execute a portion of code based on conditions."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "WCqQE7_To6tk",
        "outputId": "e3bc2173-c53f-4cc6-bb82-155fed8723bc"
      },
      "source": [
        "operation = \"add\"\n",
        "num = 6\n",
        "if operation == \"add\":\n",
        "    print(\"Adding: \", num + num)\n",
        "elif operation == \"multiply\":\n",
        "    print(\"Multiplying: \", num * num)\n",
        "\n",
        "elif\n",
        "\n",
        "elif ...\n",
        "else:\n",
        "    print(\"Operation is not defined.\")"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Adding:  12\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "xeDkzJBXoTZD"
      },
      "source": [
        "We can check for `None` objects with `if`."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "blav1CAeoZfS",
        "outputId": "96ebb6a8-d717-439b-c67b-8fcf09b7706a"
      },
      "source": [
        "a = None\n",
        "if a:\n",
        "  print(\"not None\")\n",
        "else:\n",
        "  print(\"None\")"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "None\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "1e29DwZ1leiE",
        "outputId": "1ad59c56-e3ca-466f-83e7-d0f6ad47e967"
      },
      "source": [
        "if a is None:\n",
        "  print('yes')"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "yes\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "iWdhY8sRorom"
      },
      "source": [
        "We can check for empty arrays or strings of length 0 with `if`."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "MQxr8Gy-oqwT"
      },
      "source": [
        "arr = ''\n",
        "if arr:\n",
        "  print(\"not empty\")"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "XqWq5ddao4oX",
        "outputId": "87cbc6c2-52ad-4b48-d850-b834e5dfa264"
      },
      "source": [
        "s = ''\n",
        "if s:\n",
        "  print(\"not empty\")\n",
        "else:\n",
        "  print(\"empty\")"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "empty\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "TukPtGOppEhE"
      },
      "source": [
        "## Functions\n",
        "\n",
        "We can define functions as shown in the following code block. Make sure to define your functions before calling them!"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "l4LLGV4po6to"
      },
      "source": [
        "# Define the function\n",
        "def example_func(a, b):\n",
        "    pass\n",
        "\n",
        "# Call the function\n",
        "example_func(5, 10)"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "8M_JaXHupamx"
      },
      "source": [
        "Functions may have optional parameters."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "0IdV7JXdo6to",
        "outputId": "3d6f610f-8172-4705-9f48-ef1d2fd1a569"
      },
      "source": [
        "# Function checking whether the variable is withing a range\n",
        "def check_range(a, min_val = 0, max_val=10):\n",
        "    return min_val < a < max_val\n",
        "\n",
        "# Calling the function\n",
        "check_range(5, max_val=3)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "False"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 60
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "K3_NJKzJF813"
      },
      "source": [
        "Params of immutable types are passed by value. Mutable types are passed by reference."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "RFNeNP_cGGSt",
        "outputId": "5bb98afa-7b54-4f06-ff14-9cc96b79d5d3"
      },
      "source": [
        "def example_function(variable):\n",
        "  variable = 10\n",
        "  print(variable)\n",
        "\n",
        "a = 15\n",
        "print(a)\n",
        "example_function(a)\n",
        "print(a)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "15\n",
            "10\n",
            "15\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "duEddPKxGUBC",
        "outputId": "9ad4f58c-60eb-4203-d772-00b4b586b24a"
      },
      "source": [
        "def example_function(variable):\n",
        "  variable[0] = 10\n",
        "  print(variable)\n",
        "\n",
        "a = [0,1,2,3,4]\n",
        "print(a)\n",
        "example_function(a)\n",
        "print(a)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "[0, 1, 2, 3, 4]\n",
            "[10, 1, 2, 3, 4]\n",
            "[10, 1, 2, 3, 4]\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "1V2GEx-4G8-j"
      },
      "source": [
        "If you want to prevent your function from the original variables, you can make a deep copy inside your function before using your parameters."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "H8qXvx1zHJIV",
        "outputId": "5014ab82-4590-48ba-8d19-c18a67928b18"
      },
      "source": [
        "import copy\n",
        "\n",
        "def example_function(variable):\n",
        "  # Alternative 1\n",
        "  variable = variable[:]\n",
        "\n",
        "  # Alternative 2\n",
        "  variable = copy.deepcopy(variable)\n",
        "\n",
        "  variable[0] = 10\n",
        "  print(variable)\n",
        "\n",
        "a = [0,1,2,3,4]\n",
        "print(a)\n",
        "example_function(a)\n",
        "print(a)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "[0, 1, 2, 3, 4]\n",
            "[10, 1, 2, 3, 4]\n",
            "[0, 1, 2, 3, 4]\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Au7--qehqJs-"
      },
      "source": [
        "Functions can access variables in their parent block's scope."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "A_ZbpCQYqQFO",
        "outputId": "f7c02e87-59d9-4e8c-8185-1048869c0582"
      },
      "source": [
        "outside_variable = \"This is an outside variable!\"\n",
        "\n",
        "def some_function():\n",
        "  print(outside_variable)\n",
        "\n",
        "print(outside_variable)\n",
        "some_function()"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "This is an outside variable!\n",
            "This is an outside variable!\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Cbl0hCogskjY"
      },
      "source": [
        "Functions can't change the values of the outside variables the same way."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 340
        },
        "id": "U7gZBMKgskCB",
        "outputId": "216999cf-c717-4c00-a3b6-96fce6a11d93"
      },
      "source": [
        "outside_variable = \"This is an outside variable!\"\n",
        "\n",
        "def some_function():\n",
        "  print(outside_variable)\n",
        "  outside_variable = \"Function changed the outside variable\"\n",
        "\n",
        "print(outside_variable)\n",
        "some_function()"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "This is an outside variable!\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "error",
          "ename": "UnboundLocalError",
          "evalue": "ignored",
          "traceback": [
            "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
            "\u001b[0;31mUnboundLocalError\u001b[0m                         Traceback (most recent call last)",
            "\u001b[0;32m<ipython-input-64-304d37abea01>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      6\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      7\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0moutside_variable\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 8\u001b[0;31m \u001b[0msome_function\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
            "\u001b[0;32m<ipython-input-64-304d37abea01>\u001b[0m in \u001b[0;36msome_function\u001b[0;34m()\u001b[0m\n\u001b[1;32m      2\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      3\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0msome_function\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m   \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0moutside_variable\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      5\u001b[0m   \u001b[0moutside_variable\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m\"Function changed the outside variable\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      6\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;31mUnboundLocalError\u001b[0m: local variable 'outside_variable' referenced before assignment"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ehsOEdqrs2jE"
      },
      "source": [
        "We can resolve this error using the `global` key."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "DYGLidivs9nC",
        "outputId": "d6096b55-3ade-4a53-fe8d-7dca850b3abc"
      },
      "source": [
        "outside_variable = \"This is an outside variable!\"\n",
        "\n",
        "def some_function():\n",
        "  global outside_variable\n",
        "  outside_variable = \"Function changed the outside variable!\"\n",
        "\n",
        "print(outside_variable)\n",
        "some_function()\n",
        "print(outside_variable)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "This is an outside variable!\n",
            "Function changed the outside variable!\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ibT51hVsrhlj"
      },
      "source": [
        "If a variable of the same name is defined in a function, the later definition overwrites the former only in the function scope."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "JuZRURz4rgph",
        "outputId": "9fc8f387-55c4-410f-f75a-13af6486d1e8"
      },
      "source": [
        "variable = \"This is an outside variable!\"\n",
        "\n",
        "def some_function(variable=\"Function variable.\"):\n",
        "  print(variable)\n",
        "\n",
        "print(variable)\n",
        "some_function()\n",
        "print(variable)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "This is an outside variable!\n",
            "Function variable.\n",
            "This is an outside variable!\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "AKxBN3tGrZut"
      },
      "source": [
        "Variables defined in a function can't be accessed outside."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 219
        },
        "id": "xqNHhmaAr8qx",
        "outputId": "39811601-8c0c-4bb0-c6b2-6857b43fd3df"
      },
      "source": [
        "def some_function():\n",
        "  function_variable = \"This is a function variable!\"\n",
        "  print(function_variable)\n",
        "\n",
        "some_function()\n",
        "function_variable"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "This is a function variable!\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "error",
          "ename": "NameError",
          "evalue": "ignored",
          "traceback": [
            "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
            "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
            "\u001b[0;32m<ipython-input-94-9c38147d2171>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      5\u001b[0m \u001b[0msome_function\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m \u001b[0mfunction_variable\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
            "\u001b[0;31mNameError\u001b[0m: name 'function_variable' is not defined"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Qw-hVhH2qm37"
      },
      "source": [
        "Functions can also define variables to be used in the global scope, using the `global` key."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "uOIZC5K-qrYO",
        "outputId": "a9766d22-09a1-4969-8d1c-080f3e9a22de"
      },
      "source": [
        "def foo():\n",
        "  global global_variable\n",
        "  # If we try printing global_variable here, we would get a not defined error\n",
        "  global_variable = \"This is a global variable!\"\n",
        "  print(global_variable)\n",
        "\n",
        "def bar():\n",
        "  print(global_variable)\n",
        "\n",
        "foo()\n",
        "bar()"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "This is a global variable!\n",
            "This is a global variable!\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "YL4llM39tyT8"
      },
      "source": [
        "We can define functions within functions."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "D4B3iAjMtxkB",
        "outputId": "bf6907d2-d5da-4249-eed7-567fca62244d"
      },
      "source": [
        "def main_function(a):\n",
        "\n",
        "  def helper_function(a):\n",
        "    return int(a)\n",
        "\n",
        "  print(a)\n",
        "  b = helper_function(a)\n",
        "  print(b)\n",
        "\n",
        "# Calling the main function\n",
        "main_function(2.0)\n",
        "helper"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "2.0\n",
            "2\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "b-2jwYYrDfBk"
      },
      "source": [
        "Functions can take in functions as variables."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "i8spJVIcDh-q",
        "outputId": "62960e80-7965-485a-b33f-538e4cec4910"
      },
      "source": [
        "def function_taker(a, func):\n",
        "  return func(a)\n",
        "\n",
        "function_taker(1.0, int)\n",
        "\n",
        "int(1.0)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "1"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 70
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Esm5wFH7DtZY"
      },
      "source": [
        "We can seperately define the function we need to pass."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "bXQl4FYNDxkc",
        "outputId": "91215438-b79e-4292-9b20-5061e34a466a"
      },
      "source": [
        "def parameter_function(x):\n",
        "  return x + 5\n",
        "\n",
        "def function_taker(a, func):\n",
        "  return func(a)\n",
        "\n",
        "function_taker(1.0, parameter_function)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "6.0"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 71
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "c5Qy2L5MECoy"
      },
      "source": [
        "We can also use `lambda` functions."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "6fgwBmOPEExC",
        "outputId": "cc962a91-ed87-43bc-954d-acf91f100304"
      },
      "source": [
        "def function_taker(a, func):\n",
        "  return func(a)\n",
        "\n",
        "function_taker(1.0, lambda x: x + 5)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "6.0"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 72
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "hQYjc2UOEPpX"
      },
      "source": [
        "`lambda` functions can use variables in their parent scope."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "m18mroJjEVWW",
        "outputId": "134166b8-cf52-4875-a13c-dd022bfb344d"
      },
      "source": [
        "num_to_add = 10\n",
        "\n",
        "def function_taker(a, func):\n",
        "  return func(a)\n",
        "\n",
        "function_taker(1.0, lambda x: x + num_to_add)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "11.0"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 73
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "z2XL4mZrE5fO"
      },
      "source": [
        "We can also have recursive functions."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "7exW7ny2E8x5",
        "outputId": "f5aefd16-d3ee-49f7-91ba-75e50195b3eb"
      },
      "source": [
        "def print_positive_numbers(num):\n",
        "  if num <= 0:\n",
        "    print(\"Done!\")\n",
        "  else:\n",
        "    print(num)\n",
        "    print_positive_numbers(num-1)\n",
        "\n",
        "print_positive_numbers(10)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "10\n",
            "9\n",
            "8\n",
            "7\n",
            "6\n",
            "5\n",
            "4\n",
            "3\n",
            "2\n",
            "1\n",
            "Done!\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "02E4_aVwAiAu"
      },
      "source": [
        "## Classes\n",
        "\n",
        "We can define classes ourselves as well."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "BeQle4jYo6tp",
        "outputId": "c9b68fb0-fc5c-4d25-933d-dd8dac0c5ca1"
      },
      "source": [
        "class Foo():\n",
        "    # Alternative: class Foo(object) - all Python classes inherits 'object'\n",
        "    class_variable = 'same' # class variable\n",
        "\n",
        "    # Optional constructor\n",
        "    def __init__(self, x):\n",
        "        # first parameter \"self\" for instance reference, like \"this\" in JAVA\n",
        "        self.x = x\n",
        "\n",
        "    # instance method\n",
        "    def print_x(self): # instance reference is required for all instance variables\n",
        "        print(self.x)\n",
        "\n",
        "    # class method\n",
        "    @classmethod\n",
        "    def modify_class_variable(cls):\n",
        "        cls.class_variable = 'changed'\n",
        "\n",
        "    # static method\n",
        "    @staticmethod\n",
        "    def print_hello():\n",
        "        print(\"Hello!\")\n",
        "\n",
        "print(Foo.class_variable)\n",
        "\n",
        "obj1 = Foo(6)\n",
        "obj1.print_x()\n",
        "print(obj1.class_variable)\n",
        "\n",
        "obj2 = Foo(5)\n",
        "obj2.print_x()\n",
        "print(obj2.class_variable)\n",
        "\n",
        "obj1.modify_class_variable()\n",
        "print(obj1.class_variable)\n",
        "print(obj2.class_variable)\n",
        "print(Foo.class_variable)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "same\n",
            "6\n",
            "same\n",
            "5\n",
            "same\n",
            "changed\n",
            "changed\n",
            "changed\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "SHUx7oQLDBrb"
      },
      "source": [
        "We can also inherit classes."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "t36HuUmqo6tp",
        "outputId": "92b5170f-623a-4e7b-86d8-3ec5ee1b87f4"
      },
      "source": [
        "# Inherits variables and methods\n",
        "class Bar(Foo):\n",
        "    pass\n",
        "\n",
        "obj = Bar(3)\n",
        "obj.print_x()"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "3\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Qx7hqK-Co6tq"
      },
      "source": [
        "## Iterables\n",
        "\n",
        "There are several different built-in iterable objects in `Python`."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "V3gtHrbdzkJD"
      },
      "source": [
        "# immutable iterables, with fixed size\n",
        "astring = str()\n",
        "atuple = tuple()\n",
        "\n",
        "# mutable iterables, not fixed size\n",
        "alist = list()  # linear\n",
        "adict = dict()  # hash table, stores (key, value) pairs\n",
        "aset = set()    # hash table, like dict but only stores keys"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "8DMKgRW_z6Vr"
      },
      "source": [
        "Size of any iterable can be obtained with `len`."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "JTJu6az0o6tq",
        "outputId": "771e1f1e-b717-4e31-ea2e-c7cca396db87"
      },
      "source": [
        "print(len(alist))"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "0\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "WfWoqlvG2rpR"
      },
      "source": [
        "### List\n",
        "\n",
        "Lists store an ordered list of elements."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "1BVNv_Clo6tr"
      },
      "source": [
        "\"\"\"\n",
        "List:\n",
        "\n",
        "  mutable - not hashable: can't be used as dictionary keys\n",
        "  dynamic size\n",
        "  allows duplicates and inconsistent element types\n",
        "  dynamic array implementation\n",
        "\"\"\"\n",
        "alist = [] # equivalent to list()\n",
        "alist = [1,2,3,4,5] # initialized list"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Drqeatru3clX"
      },
      "source": [
        "We can access and modify list elements, similar to strings."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "YzP2qig73aip",
        "outputId": "4dfb5815-b940-45d8-aae7-2bc21a5a370e"
      },
      "source": [
        "print(alist[0])\n",
        "alist[0] = 5\n",
        "print(alist)\n",
        "\n",
        "print(\"-\"*10)\n",
        "# list indexing\n",
        "print(alist[0]) # get first element (at index 0)\n",
        "print(alist[-2]) # get 2nd to last element (at index len-1)\n",
        "print(alist[3:]) # get elements starting from index 3 (inclusive)\n",
        "print(alist[:3]) # get elements stopping at index 3 (exclusive)\n",
        "print(alist[2:4]) # get elements within index range [2,4)\n",
        "print(alist[6:]) # prints nothing because index is out of range"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "5\n",
            "[5, 2, 3, 4, 5]\n",
            "----------\n",
            "5\n",
            "4\n",
            "[4, 5]\n",
            "[5, 2, 3]\n",
            "[3, 4]\n",
            "[]\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "u5RQCObM3seH"
      },
      "source": [
        "We can reverse a list."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "NBDj-DxF30CT",
        "outputId": "a6550485-3a95-4177-cc93-a06fd065dec5"
      },
      "source": [
        "alist[::-1] # returns a reversed list"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "[5, 4, 3, 2, 5]"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 84
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "QzpmPx0j32R-"
      },
      "source": [
        "We can call methods on a list."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "dyaIpKgW36bI",
        "outputId": "653230a9-b8ed-4102-bd8a-7c7a66b4fef7"
      },
      "source": [
        "alist.append(\"new item\") # insert at end\n",
        "alist.insert(0, \"new item\") # insert at index 0\n",
        "alist.extend([2,3,4]) # concatenate lists\n",
        "# above line is equivalent to alist += [2,3,4]\n",
        "alist.index(\"new item\") # search by content\n",
        "alist.remove(\"new item\") # remove by content\n",
        "popped = alist.pop(0) # remove by index\n",
        "print(alist)\n",
        "print(popped)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "[2, 3, 4, 5, 'new item', 2, 3, 4]\n",
            "5\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "0c8id4IG4jpB"
      },
      "source": [
        "We can check if an element is contained in a list."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "9IJJhB1y3s_r",
        "outputId": "3cd7e583-4fbc-4f56-f865-6b404abb469a"
      },
      "source": [
        "if \"new item\" in alist:\n",
        "    print(\"found\")"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "found\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "6pinHv3t0B5B"
      },
      "source": [
        "### Tuples\n",
        "\n",
        "Tuples allow us to store immutable lists."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "_ec4BTva0eqw"
      },
      "source": [
        "\"\"\"\n",
        "Tuple:\n",
        "\n",
        "  immutable - hashable: can be used as a dictionary key\n",
        "  fixed size: no insertion or deletion\n",
        "\"\"\"\n",
        "atuple = (1,2,3,4,5)"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "mOv1HOqlq00b"
      },
      "source": [
        "atuple = (1)"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "PByClj1mrCCf",
        "outputId": "08538db3-c458-4831-85d2-38ef329f4835"
      },
      "source": [
        "type(atuple)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "int"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 93
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "6ZOInlx72J1Z"
      },
      "source": [
        "Indexing or traversal of a `tuple` is the same as that of a `list`."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "6AaRSa-82JMN"
      },
      "source": [
        "# Defining tuple from a list\n",
        "atuple = tuple([1,2,3])"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "xsscT5XJ2Jci"
      },
      "source": [
        "We can use tuples as dictionary keys.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "4d0__BN6o6tq"
      },
      "source": [
        "ngram = (\"a\", \"cat\")\n",
        "d = dict()\n",
        "d[ngram] = 10\n",
        "d[ngram] += 1"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "U-a6t5xc4rG6"
      },
      "source": [
        "We can use named tuples to improve readability."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "rdRo7jvio6t4",
        "outputId": "f47d9aa0-3c66-48cc-9449-ee00b9466f6a"
      },
      "source": [
        "from collections import namedtuple\n",
        "Point = namedtuple('Point', 'x y')\n",
        "pt1 = Point(1.0, 5.0)\n",
        "pt2 = Point(2.5, 1.5)\n",
        "print(pt1.x, pt1.y)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "1.0 5.0\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "2MeHbcuu493p"
      },
      "source": [
        "### Dictionary\n",
        "\n",
        "Dictionaries are useful for storing key - value pairs."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "FgjMce7lo6t6",
        "outputId": "4af30c7b-f520-404b-cab0-32b650d13d07"
      },
      "source": [
        "\"\"\"\n",
        "Dict:\n",
        "\n",
        "  not hashable\n",
        "  dynamic size\n",
        "  no duplicates allowed\n",
        "  hash table implementation which is fast for searching\n",
        "\n",
        "\"\"\"\n",
        "adict = {} # same as dict()\n",
        "adict = {'dog': 10, 'bird': 5, 'lion': 8}\n",
        "print(adict)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "{'dog': 10, 'bird': 5, 'lion': 8}\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "qDbczIwk5Y_6"
      },
      "source": [
        "We can get keys, values or items in a dictionary."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "uaLYZomJ5f6s",
        "outputId": "e3d4fd76-b291-4e37-9fc5-5b0c3c5f782c"
      },
      "source": [
        "print(adict.keys())\n",
        "print(adict.values())\n",
        "print(adict.items())"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "dict_keys(['dog', 'bird', 'lion'])\n",
            "dict_values([10, 5, 8])\n",
            "dict_items([('dog', 10), ('bird', 5), ('lion', 8)])\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "bSvTjzwa5za7"
      },
      "source": [
        "We can access an item with a specific key."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "1DAetNu452bQ",
        "outputId": "7df7eb6b-ff2e-4773-e4ac-17d9e881ec8e"
      },
      "source": [
        "print(adict['lion'])"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "8\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "YYc3kd4L6NWA"
      },
      "source": [
        "We can check if a key exists in a dictionary. This is needed since accessing non-existent keys throws an error."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 167
        },
        "id": "FHM5P_3Q6aSr",
        "outputId": "2db8e3ce-7aff-462b-e60e-ca8ba41b3566"
      },
      "source": [
        "adict['tiger']"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "error",
          "ename": "KeyError",
          "evalue": "ignored",
          "traceback": [
            "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
            "\u001b[0;31mKeyError\u001b[0m                                  Traceback (most recent call last)",
            "\u001b[0;32m<ipython-input-98-52009ea6fcff>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0madict\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'tiger'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
            "\u001b[0;31mKeyError\u001b[0m: 'tiger'"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "tsgXho126QD5",
        "outputId": "da00a688-d2e6-40c0-b1ad-f338a019b47d"
      },
      "source": [
        "if 'tiger' in adict:\n",
        "  print(adict[key])\n",
        "else:\n",
        "  print('Key not found.')"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Key not found.\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "UGE08yH96mp7"
      },
      "source": [
        "Insert new keys."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "JicEI5sj6oFb"
      },
      "source": [
        "adict['tiger'] = 1"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "h16DZ3uk6rec"
      },
      "source": [
        "Modify existing keys."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "_oCgyCAP6yQF"
      },
      "source": [
        "adict['lion'] = 20"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "79kmfD1L6tvR"
      },
      "source": [
        "Traversing dictionaries.\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "0mShrqZI5Rco",
        "outputId": "924011d9-192e-4bb2-b6b0-71db73585535"
      },
      "source": [
        "for key in adict:\n",
        "    print(key, adict[key])"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "dog 10\n",
            "bird 5\n",
            "lion 8\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "0Oarhwm87Bsf"
      },
      "source": [
        "Traversing key, value pairs together."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "asfYaluB7Ebn",
        "outputId": "978f1123-93ed-48e3-d8b8-57f8bebb31ee"
      },
      "source": [
        "for key, val in adict.items():\n",
        "  print(key, val)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "dog 10\n",
            "bird 5\n",
            "lion 20\n",
            "tiger 1\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "f6wWiDFs7aPU"
      },
      "source": [
        "### DefaultDict\n",
        "\n",
        "`DefaultDict` is a special dictionary that returns a default value when a key queried isn't found."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "wm4eqxU67xJY",
        "outputId": "b739fdc0-8a73-4263-d588-f7f6c3e6f1fe"
      },
      "source": [
        "from collections import defaultdict\n",
        "\n",
        "adict = defaultdict(int)\n",
        "adict['cat'] = 5\n",
        "print(adict['cat'])\n",
        "print(adict['dog'])"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "5\n",
            "0\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "PlHxXbUg77XJ"
      },
      "source": [
        "It is also possible to pass a custom function."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "iPEZbjpn7ney",
        "outputId": "63deabcc-acad-4ede-d2dc-85461013ffa0"
      },
      "source": [
        "from collections import defaultdict\n",
        "adict = defaultdict(lambda: 'unknown')\n",
        "adict['cat'] = 'feline'\n",
        "print(adict['cat'])\n",
        "print(adict['dog'])"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "feline\n",
            "unknown\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "lYQI1E858MF2"
      },
      "source": [
        "### Counter\n",
        "\n",
        "`Counter` is a dictionary with default value of 0."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "Z14YHrWyo6t8",
        "outputId": "4fa122e0-6d45-4968-ff1e-ca4348bd68cb"
      },
      "source": [
        "from collections import Counter\n",
        "\n",
        "# initialize and modify empty counter\n",
        "counter1 = Counter()\n",
        "counter1['t'] = 10\n",
        "counter1['t'] += 1\n",
        "counter1['e'] += 1\n",
        "print(counter1)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Counter({'t': 11, 'e': 1})\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "94SMZI9y8W_I"
      },
      "source": [
        "We can initialize counters from other iterables."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "7GltlZgl8acL",
        "outputId": "c699aede-d9bd-4a61-9e0e-7e1fe3ee72be"
      },
      "source": [
        "counter2 = Counter(\"letters to be counted\")\n",
        "print(counter2)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Counter({'e': 4, 't': 4, ' ': 3, 'o': 2, 'l': 1, 'r': 1, 's': 1, 'b': 1, 'c': 1, 'u': 1, 'n': 1, 'd': 1})\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "TCajDMH98hIZ"
      },
      "source": [
        "We can perform operations between counters."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "HxGq9Ex18f3l",
        "outputId": "9540d335-9645-4bae-bf90-2f1896298ffa"
      },
      "source": [
        "print(\"1\", counter1 + counter2)\n",
        "print(\"2\", counter1 - counter2)\n",
        "print(\"3\", counter1 or counter2) # or for intersection, and for union"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "1 Counter({'t': 15, 'e': 5, ' ': 3, 'o': 2, 'l': 1, 'r': 1, 's': 1, 'b': 1, 'c': 1, 'u': 1, 'n': 1, 'd': 1})\n",
            "2 Counter({'t': 7})\n",
            "3 Counter({'t': 11, 'e': 1})\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "mdlqrgDF81yr"
      },
      "source": [
        "We can use other special methods on counters. Check out the docs for more!"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "Fxgl9n7N86ic",
        "outputId": "61e41917-25ab-44bd-bdc2-964bd137e49a"
      },
      "source": [
        "counter2.most_common(5)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "[('e', 4), ('t', 4), (' ', 3), ('o', 2), ('l', 1)]"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 107
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "2s8_am1J9PwW"
      },
      "source": [
        "We can iterate list of tuples."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "xWANB8hj9UY0",
        "outputId": "2fbd266e-1c26-495b-87b1-d39301c14f0b"
      },
      "source": [
        "for k,v in counter2.most_common(5):\n",
        "  print(k, v)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "e 4\n",
            "t 4\n",
            "  3\n",
            "o 2\n",
            "l 1\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "YTgf-Qwj7Kpw"
      },
      "source": [
        "### Set\n",
        "\n",
        "Set is a special dictionary without values."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "wmhE3Zmeo6t7",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "42b54c03-c921-439f-fcb9-e70cc932c742"
      },
      "source": [
        "aset = set()\n",
        "aset.add('a')\n",
        "aset"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "{'a'}"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 109
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "oAVaGb2g7SLC"
      },
      "source": [
        "We can use sets to remove duplicates from a list."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "5qyT88U37VWR",
        "outputId": "697c6108-614f-455e-8245-040f388bb87f"
      },
      "source": [
        "alist = [5,2,3,3,3,4,3]\n",
        "alist = list(set(alist))\n",
        "print(alist)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "[2, 3, 4, 5]\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "mWuYLCwutwPN",
        "outputId": "e0dd8d5a-f04e-444f-f5cd-b16e3458ec71"
      },
      "source": [
        "set(alist)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "{2, 3, 4, 5}"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 116
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "Sh6-iKkUtcv4",
        "outputId": "fe3824bc-5d83-494b-bd9c-824e7b0a0f0e"
      },
      "source": [
        "list(set(alist))"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "[2, 3, 4, 5]"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 115
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "IEG17z-39dkT"
      },
      "source": [
        "### Sorting\n",
        "\n",
        "We can sort iterables."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "yr0Npa5do6t8",
        "outputId": "72da5b12-d851-49c5-be0b-fd7cd6385a7c"
      },
      "source": [
        "a = [4,6,1,7,0,5,1,8,9]\n",
        "a = sorted(a)\n",
        "print(a)\n",
        "a = sorted(a, reverse=True)\n",
        "print(a)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "[0, 1, 1, 4, 5, 6, 7, 8, 9]\n",
            "[9, 8, 7, 6, 5, 4, 1, 1, 0]\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "N6sPZZUV9k-X"
      },
      "source": [
        "We can sort iterables containing tuples."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "fvdUq_7Lo6t8",
        "outputId": "91e3ad57-3dce-4fac-e49c-55d03d88f81f"
      },
      "source": [
        "# sorting\n",
        "a = [(\"cat\",1), (\"dog\", 3), (\"bird\", 2)]\n",
        "a = sorted(a)\n",
        "print(a)\n",
        "b = sorted(a, key=lambda item: item[1])\n",
        "print(b)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "[('bird', 2), ('cat', 1), ('dog', 3)]\n",
            "[('cat', 1), ('bird', 2), ('dog', 3)]\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Z88BCni79v-Q"
      },
      "source": [
        "We can pass a function we define outside instead of a lambda function."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "jCM6jPbv91xH",
        "outputId": "117216f7-2c49-412b-f866-269d3ef76e47"
      },
      "source": [
        "def sorting_key(item):\n",
        "  return item[1]\n",
        "\n",
        "sorted(a, key=sorting_key)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "[('cat', 1), ('bird', 2), ('dog', 3)]"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 167
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "HDG7xi4M-U_t"
      },
      "source": [
        "We can sort dictionaries the same way."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "19oDadMwo6t-",
        "outputId": "14abc53b-d069-4a3c-dc41-9b0a9235c2ab"
      },
      "source": [
        "adict = {'cat':3, 'bird':1}\n",
        "print(sorted(adict.items(), key=lambda x:x[1]))"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "[('bird', 1), ('cat', 3)]\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "aQywFVev-ZzH"
      },
      "source": [
        "### List Comprehension\n",
        "\n",
        "Instead of using `for` loops every time, we can use list comprehensions to create new lists or other iterables."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "8eGjNjf2o6t_",
        "outputId": "3f774852-8a93-4bfa-df5c-a562fc64cf28"
      },
      "source": [
        "\"\"\"\n",
        "for i in range(len(sent)):\n",
        "    sent[i] = sent[i].lower().split(\" \")\n",
        "\"\"\"\n",
        "\n",
        "sent = [\"i am good\", \"a beautiful day\", \"HELLO FRIEND\"]\n",
        "sent1 = [s.lower().split(\" \") for s in sent]\n",
        "print(sent1)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "[['i', 'am', 'good'], ['a', 'beautiful', 'day'], ['hello', 'friend']]\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "JL9NYWLg-1nx"
      },
      "source": [
        "We can have conditions."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "dNedRQmK-uG0",
        "outputId": "a1dfab90-c565-4115-f51e-46a59cf5a035"
      },
      "source": [
        "sent2 = [s.lower().split(\" \") for s in sent if len(s) > 10]\n",
        "print(sent2)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "[['a', 'beautiful', 'day'], ['hello', 'friend']]\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "y3nTEdUU--QQ"
      },
      "source": [
        "We can create other iterables the same way."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "0LMW-AFv_GPy",
        "outputId": "bb1da3f4-2e21-488e-a712-efa6c2896dde"
      },
      "source": [
        "keys = ['a', 'b', 'c']\n",
        "dict1 = {k: i for i, k in enumerate(keys)}\n",
        "print(dict1)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "{'a': 0, 'b': 1, 'c': 2}\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Yio2kKK5_SQi"
      },
      "source": [
        "Another useful function we can use is `zip`."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "_u3k-7Xr_eH0",
        "outputId": "9270494d-c9f2-4fc5-fa39-53fca8351bd6"
      },
      "source": [
        "keys = ['a', 'b', 'c']\n",
        "values = [10, 5, 30]\n",
        "zipped = zip(keys, values)\n",
        "print(zipped)        # zip object\n",
        "print(list(zipped))  # pass to list to unzip\n",
        "\n",
        "for k, v in zip(keys, values):\n",
        "  print(k, v)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "<zip object at 0x7fc747a65640>\n",
            "[('a', 10), ('b', 5), ('c', 30)]\n",
            "a 10\n",
            "b 5\n",
            "c 30\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "wugqn01Eo6uK"
      },
      "source": [
        "## Q&A\n",
        "\n",
        "Question time!"
      ]
    }
  ]
}