{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "25311679",
      "metadata": {
        "id": "25311679"
      },
      "source": [
        "# Application Session 6 (Unit 3)\n",
        "\n",
        "## Traffic Light Stops on the Way to University\n",
        "\n",
        "A student passes through **5 traffic lights** on the way to university.  \n",
        "At each light, the car either **stops** or **does not stop**.\n",
        "\n",
        "Let the random variable **X = number of stops**.\n",
        "\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "KeNcmgWChCqV",
      "metadata": {
        "id": "KeNcmgWChCqV"
      },
      "source": [
        "## Session Goals\n",
        "\n",
        "This session aims to help students:\n",
        "- define a discrete random variable from a real-life example\n",
        "- compute a PMF using Python\n",
        "- compute a CDF using Python\n",
        "- calculate the mean, variance, and standard deviation of a discrete random variable\n",
        "- compare empirical results with theoretical results\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e8f13635",
      "metadata": {
        "id": "e8f13635"
      },
      "source": [
        "## Step 1: Import libraries and define the scenario"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "80256b59",
      "metadata": {
        "id": "80256b59"
      },
      "outputs": [],
      "source": [
        "import numpy as np\n",
        "import matplotlib.pyplot as plt\n",
        "from math import comb\n",
        "\n",
        "n_lights = 5\n",
        "p_stop = 0.4\n",
        "num_trips = 300"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "8a3ef464",
      "metadata": {
        "id": "8a3ef464"
      },
      "source": [
        "## Step 2: Simulate trips\n",
        "\n",
        "Each trip has 5 traffic lights:\n",
        "- **1** means stop\n",
        "- **0** means no stop\n",
        "\n",
        "Then we add the 5 values to get **X**, the number of stops.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "472187ed",
      "metadata": {
        "id": "472187ed"
      },
      "outputs": [],
      "source": [
        "trips = np.random.binomial(1, p_stop, size=(num_trips, n_lights))\n",
        "\n",
        "X = []\n",
        "for trip in trips:\n",
        "    X.append(int(sum(trip)))\n",
        "\n",
        "print(\"First 10 trips (number of stops):\")\n",
        "print(X[:10])"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "6ebb7439",
      "metadata": {
        "id": "6ebb7439"
      },
      "source": [
        "## Step 3: Build the PMF\n",
        "\n",
        "From Unit 3:\n",
        "\n",
        "$$\n",
        "p(x) = P(X = x)\n",
        "$$\n",
        "\n",
        "We count how often each value of **X** appears, then divide by the total number of trips.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "34a277a3",
      "metadata": {
        "id": "34a277a3"
      },
      "outputs": [],
      "source": [
        "x = np.arange(0, n_lights + 1)  # x = [0, 1, 2, 3, 4, 5]\n",
        "\n",
        "pmf = []\n",
        "for i in x:\n",
        "    probability = sum(X == i) / len(X)\n",
        "    pmf.append(probability)\n",
        "    \n",
        "pmf = np.array(pmf)\n",
        "\n",
        "print(\"x =\", x)\n",
        "print(\"PMF =\", np.round(pmf, 3))\n",
        "print(\"Sum of PMF =\", pmf.sum())"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "b1dd6cb3",
      "metadata": {
        "id": "b1dd6cb3"
      },
      "outputs": [],
      "source": [
        "plt.bar(x, pmf)\n",
        "plt.xticks(x)\n",
        "plt.xlabel(\"Number of stops (X)\")\n",
        "plt.ylabel(\"p(x)\")\n",
        "plt.title(\"PMF of X\")\n",
        "plt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "03d7b9be",
      "metadata": {
        "id": "03d7b9be"
      },
      "source": [
        "## Step 4: Build the CDF\n",
        "\n",
        "From Unit 3:\n",
        "\n",
        "$$\n",
        "F(x) = P(X \\le x)\n",
        "$$\n",
        "\n",
        "The CDF is found by cumulative addition of the PMF.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "ced1e32a",
      "metadata": {
        "id": "ced1e32a"
      },
      "outputs": [],
      "source": [
        "cdf = np.cumsum(pmf)\n",
        "\n",
        "print(\"CDF =\", np.round(cdf, 3))\n",
        "plt.step(x, cdf, where=\"post\")\n",
        "plt.xticks(x)\n",
        "plt.ylim(0, 1.05)\n",
        "plt.xlabel(\"Number of stops (X)\")\n",
        "plt.ylabel(\"F(x)\")\n",
        "plt.title(\"CDF of X\")\n",
        "plt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "6878539d",
      "metadata": {
        "id": "6878539d"
      },
      "source": [
        "## Step 5: Compute the mean (expected value), variance, and Standard Deviation\n",
        "\n",
        "From Unit 3:\n",
        "\n",
        "$$\n",
        "E(X) = \\sum x\\,p(x)\n",
        "$$\n",
        "\n",
        "$$\n",
        "\\mathrm{Var}(X) = E(X^2) - [E(X)]^2\n",
        "$$\n",
        "\n",
        "$$\n",
        "\\mathrm{SD}(X) = \\sqrt{\\mathrm{Var}(X)}\n",
        "$$"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "bc604989",
      "metadata": {
        "id": "bc604989"
      },
      "outputs": [],
      "source": [
        "mean_X = sum(x * pmf)\n",
        "E_X2 = sum((x**2) * pmf)\n",
        "var_X = E_X2 - (mean_X**2)\n",
        "std_X = np.sqrt(var_X)\n",
        "\n",
        "print(\"Expected value =\", round(mean_X, 3))\n",
        "print(\"Variance =\", round(var_X, 3))\n",
        "print(\"Standard deviation =\", round(std_X, 3))"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "416db883",
      "metadata": {
        "id": "416db883"
      },
      "source": [
        "## Step 6: Connect the example to the binomial distribution\n",
        "\n",
        "This example is binomial because:\n",
        "- the number of trials is fixed (**5 lights**)\n",
        "- each trial has two outcomes (**stop / no stop**)\n",
        "- the probability of stop is the same\n",
        "- the trials are treated as independent\n",
        "\n",
        "So the theoretical PMF is:\n",
        "\n",
        "$$\n",
        "P(X = x) = \\binom{n}{x} p^x q^{n-x}\n",
        "$$"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "e223ab37",
      "metadata": {
        "id": "e223ab37"
      },
      "outputs": [],
      "source": [
        "def binomial_pmf(z, n, p, q):\n",
        "    probability = comb(n, z) * (p ** z) * (q ** (n - z))\n",
        "    return probability\n",
        "\n",
        "pmf_theory = []\n",
        "for i in x:\n",
        "    pmf_theory.append(binomial_pmf(i, n_lights, p_stop, 1-p_stop))\n",
        "\n",
        "print(\"Binomial PMF =\", np.round(pmf_theory, 3))\n",
        "print(\"Theoretical mean =\", n_lights * p_stop)\n",
        "print(\"Theoretical variance =\", n_lights * p_stop * (1 - p_stop))"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "395b4339",
      "metadata": {},
      "source": [
        "## Step 7: Compare the empirical and theoretical PMF\n",
        "\n",
        "In this step, we compare:\n",
        "\n",
        "- the empirical PMF from the simulated trips\n",
        "- the theoretical PMF from the binomial formula\n",
        "\n",
        "If the simulation is large enough, the two graphs should be close."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "ccd50b09",
      "metadata": {},
      "outputs": [],
      "source": [
        "plt.figure(figsize=(8, 5))\n",
        "\n",
        "plt.bar(x - 0.2, pmf, width=0.4, label=\"Empirical PMF\")\n",
        "plt.bar(x + 0.2, pmf_theory, width=0.4, label=\"Theoretical Binomial PMF\")\n",
        "\n",
        "plt.xlabel(\"Number of stops\")\n",
        "plt.ylabel(\"Probability\")\n",
        "plt.title(\"Empirical vs Theoretical PMF\")\n",
        "plt.xticks(x)\n",
        "plt.legend()\n",
        "plt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cdc7627c",
      "metadata": {
        "id": "cdc7627c"
      },
      "source": [
        "### Task:\n",
        "\n",
        "Change the model so the student passes through 8 traffic lights instead of 5.\n",
        "Keep p_stop = 0.4.\n",
        "\n",
        "Using Python:\n",
        "\n",
        "- find the empirical PMF\n",
        "- find the theoretical binomial PMF\n",
        "- compare the two graphs\n",
        "- Then write one sentence explaining what changed when the number of traffic lights increased."
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e0c38627",
      "metadata": {
        "id": "e0c38627"
      },
      "source": [
        "## Summary\n",
        "\n",
        "In this session, Python was used to apply the Unit 3 theory:\n",
        "- **X** is a discrete random variable\n",
        "- the **PMF** gives the probability of each value of X\n",
        "- the **CDF** gives cumulative probabilities\n",
        "- the **expected value**, **variance**, and **standard deviation** describe the center and spread\n",
        "- the traffic light example can be modeled using the **binomial distribution**\n"
      ]
    }
  ],
  "metadata": {
    "colab": {
      "provenance": []
    },
    "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.12.6"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 5
}
