{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "6066a3b7",
      "metadata": {
        "id": "6066a3b7"
      },
      "source": [
        "# Application Session 4 (Unit 2)\n",
        "## Computational Probability with Python\n",
        "\n",
        "**Session goals:**\n",
        "- Represent sample spaces and events using Python\n",
        "- Build frequency tables from data and convert them into probability tables\n",
        "- Compute theoretical probabilities using counting\n",
        "- Use simulation to estimate probabilities and compare them with theoretical results\n",
        "- Use Python for counting techniques (permutations and combinations)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f8cc3900",
      "metadata": {
        "id": "f8cc3900"
      },
      "source": [
        "### Step 1: Import libraries\n",
        "\n",
        "We will use:\n",
        "- **pandas** for simple frequency tables (counts)\n",
        "- **random** for simulation\n",
        "- **math** for permutations / combinations\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "b13ec0cd",
      "metadata": {
        "id": "b13ec0cd"
      },
      "outputs": [],
      "source": [
        "import pandas as pd\n",
        "import random\n",
        "import math"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "2ca594bf",
      "metadata": {
        "id": "2ca594bf"
      },
      "source": [
        "---\n",
        "### Step  2: From data to probabilities (frequency table → probability table)\n",
        "\n",
        "Example: Data Packet Transmission\n",
        "A network system transmits data packets.\n",
        "For each packet we record:\n",
        "- connection type: WiFi or Ethernet\n",
        "- result: Success or Corrupted\n",
        "\n",
        "We will build a **frequency table** then a **probability table**.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "3b1c6646",
      "metadata": {
        "id": "3b1c6646",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "71d54eb6-44d3-4280-8d76-beccda686640"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Number of packets = 24\n"
          ]
        }
      ],
      "source": [
        "# Each record is: (connection_type, result)\n",
        "records = [\n",
        "    ('WiFi', 'Success'), ('WiFi', 'Success'), ('WiFi', 'Corrupted'),\n",
        "    ('Ethernet', 'Success'), ('Ethernet', 'Success'), ('Ethernet', 'Corrupted'),\n",
        "    ('WiFi', 'Success'), ('Ethernet', 'Success'), ('WiFi', 'Corrupted'),\n",
        "    ('WiFi', 'Success'), ('Ethernet', 'Corrupted'), ('Ethernet', 'Success'),\n",
        "    ('WiFi', 'Success'), ('Ethernet', 'Success'),  ('Ethernet', 'Success'), ('WiFi', 'Corrupted'),\n",
        "    ('WiFi', 'Success'), ('Ethernet', 'Success'), ('Ethernet', 'Success'), ('WiFi', 'Corrupted'),\n",
        "    ( 'WiFi', 'Success'), ('Ethernet', 'Success'), ('Ethernet', 'Success'), ('WiFi', 'Corrupted'),\n",
        "]\n",
        "\n",
        "n = len(records)\n",
        "print('Number of packets =', n)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "566b8f21",
      "metadata": {
        "id": "566b8f21"
      },
      "source": [
        "#### 2.1 Build a frequency table"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "2a24968e",
      "metadata": {
        "id": "2a24968e",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "8cd9da67-b96b-40dd-b483-5a6309d790b2"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "connection  result   \n",
            "Ethernet    Success      10\n",
            "WiFi        Success       7\n",
            "            Corrupted     5\n",
            "Ethernet    Corrupted     2\n",
            "Name: count, dtype: int64\n"
          ]
        }
      ],
      "source": [
        "df = pd.DataFrame(records, columns=['connection', 'result'])\n",
        "freq = df.value_counts()\n",
        "print(freq)\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "508ea16d",
      "metadata": {
        "id": "508ea16d"
      },
      "source": [
        "#### 2.2 Probability Table (relative frequency)\n",
        "\n",
        "Probability for a category is:\n",
        "\n",
        "$$\n",
        "P(\\text{category}) = \\frac{\\text{count(category)}}{\\text{total}}\n",
        "$$\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "id": "5e6213c7",
      "metadata": {
        "id": "5e6213c7",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 241
        },
        "outputId": "c48d1165-7c98-416e-ad75-d6b660e2e69b"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "connection  result   \n",
              "Ethernet    Success      0.416667\n",
              "WiFi        Success      0.291667\n",
              "            Corrupted    0.208333\n",
              "Ethernet    Corrupted    0.083333\n",
              "Name: count, dtype: float64"
            ],
            "text/html": [
              "<div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th>count</th>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>connection</th>\n",
              "      <th>result</th>\n",
              "      <th></th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>Ethernet</th>\n",
              "      <th>Success</th>\n",
              "      <td>0.416667</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th rowspan=\"2\" valign=\"top\">WiFi</th>\n",
              "      <th>Success</th>\n",
              "      <td>0.291667</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>Corrupted</th>\n",
              "      <td>0.208333</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>Ethernet</th>\n",
              "      <th>Corrupted</th>\n",
              "      <td>0.083333</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div><br><label><b>dtype:</b> float64</label>"
            ]
          },
          "metadata": {},
          "execution_count": 12
        }
      ],
      "source": [
        "prob = freq / len(df)\n",
        "prob"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "160d3db3",
      "metadata": {
        "id": "160d3db3"
      },
      "source": [
        "### 2.3 Compute Event Probabilities from Data\n",
        "\n",
        "Example event probabilities from the transmission log\n",
        "Let:\n",
        "- **C**: packet is corrupted\n",
        "- **W**: packet sent over WiFi\n",
        "\n",
        "and we want to compute:\n",
        "- P(C)\n",
        "- P(W)\n",
        "- P(C ∩ W)\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "id": "4137deed",
      "metadata": {
        "id": "4137deed",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "b5f8c243-4ad0-404d-885b-3899c656ca35"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "P(Corrupted) = 0.2916666666666667\n",
            "P(WiFi) = 0.5\n",
            "P(Corrupted and WiFi) = 0.20833333333333334\n"
          ]
        }
      ],
      "source": [
        "count_corrupted = (df['result'] == 'Corrupted').sum()\n",
        "total = len(df)\n",
        "P_C = count_corrupted / total\n",
        "\n",
        "count_wifi = (df['connection'] == 'WiFi').sum()\n",
        "total = len(df)\n",
        "P_W = count_wifi / total\n",
        "\n",
        "count_both = ((df['result'] == 'Corrupted') & (df['connection'] == 'WiFi')).sum()\n",
        "total = len(df)\n",
        "P_C_and_W = count_both / total\n",
        "\n",
        "print('P(Corrupted) =', P_C)\n",
        "print('P(WiFi) =', P_W)\n",
        "print('P(Corrupted and WiFi) =', P_C_and_W)\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "02e9690a",
      "metadata": {
        "id": "02e9690a"
      },
      "source": [
        "### Step 3: Theoretical Probability\n",
        "When all outcomes are equally likely, we compute probability using counting.\n",
        "\n",
        "Example: Consider rolling a fair die.\n",
        "\n",
        "Sample space: S = \\{1,2,3,4,5,6\\}\n",
        "\n",
        "Event:\n",
        "- **A**: roll an even number\n",
        "- **B**: greater than 4\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 16,
      "id": "bbe36ce5",
      "metadata": {
        "id": "bbe36ce5",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "7dff6f7b-e164-4f12-c8b0-ce1bd5124fff"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "P(A) = 0.5\n",
            "P(B) = 0.3333333333333333\n"
          ]
        }
      ],
      "source": [
        "S = [1, 2, 3, 4, 5, 6]\n",
        "\n",
        "A = []\n",
        "for x in S:\n",
        "    if x % 2 == 0:\n",
        "        A.append(x)\n",
        "\n",
        "B = []\n",
        "for x in S:\n",
        "    if x > 4:\n",
        "        B.append(x)\n",
        "\n",
        "\n",
        "P_A = len(A) / len(S)\n",
        "P_B = len(B) / len(S)\n",
        "\n",
        "print('P(A) =', P_A)\n",
        "print('P(B) =', P_B)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "380036a7",
      "metadata": {
        "id": "380036a7"
      },
      "source": [
        "### Step 4: Simulation as a check\n",
        "\n",
        "#### What does simulation mean?\n",
        "\n",
        "**Simulation** means using the computer to repeat an experiment many times artificially. So instead of solving everything using formulas only, we:\n",
        "- Generate many random outcomes using Python\n",
        "- Count how often an event happens\n",
        "- Use the relative frequency as an estimate of probability\n",
        "\n",
        "Now we simulate the same die experiment. As the number of simulation trials increases, the simulated probability gets closer to the theoretical probability."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "id": "22d00899",
      "metadata": {
        "id": "22d00899",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "c969fbe0-401e-4c61-f217-560b2918f879"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Simulated P(A) = 0.5045\n",
            "Simulated P(B) = 0.3284\n"
          ]
        }
      ],
      "source": [
        "trials = 10000\n",
        "\n",
        "count_A = 0\n",
        "count_B = 0\n",
        "\n",
        "for _ in range(trials):\n",
        "    roll = random.randint(1, 6)\n",
        "    if roll % 2 == 0:\n",
        "        count_A += 1\n",
        "    if roll > 4:\n",
        "        count_B += 1\n",
        "\n",
        "P_A_sim = count_A / trials\n",
        "P_B_sim = count_B / trials\n",
        "\n",
        "print(\"Simulated P(A) =\", P_A_sim)\n",
        "print(\"Simulated P(B) =\", P_B_sim)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "4a655db0",
      "metadata": {
        "id": "4a655db0"
      },
      "source": [
        "### Step 5: Counting with Python (Permutations and Combinations)\n",
        "\n",
        "Use Python to compute:\n",
        "- **Permutations** (order matters): math.perm(n, r)\n",
        "- **Combinations** (order does not matter): math.comb(n, r)\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "b32317e0",
      "metadata": {
        "id": "b32317e0"
      },
      "outputs": [],
      "source": [
        "# Example 1: choose 3 distinct passwords characters from 10 symbols (order matters)\n",
        "math.perm(10, 3)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "2d4b650f",
      "metadata": {
        "id": "2d4b650f"
      },
      "outputs": [],
      "source": [
        "# Example 2: choose 3 team members from 10 students (order does NOT matter)\n",
        "math.comb(10, 3)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "98474791",
      "metadata": {
        "id": "98474791"
      },
      "source": [
        "### Step 6: Task\n",
        "\n",
        "A 6-digit PIN uses digits 0–9 **without repetition**.\n",
        "\n",
        "1) How many possible PINs are there?  \n",
        "2) What is the probability of guessing the PIN correctly in one try?\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "fb111243",
      "metadata": {
        "id": "fb111243"
      },
      "source": [
        "\n",
        "## Summary:\n",
        "You can now:\n",
        "- build frequency table and probablity table from data,\n",
        "- compute event probabilities,\n",
        "- estimate probabilities using simulation.\n",
        "- and use Python for counting.\n",
        "\n",
        "Next session: **conditional probability, independence, and Bayes**.\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
}