{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "31c8588b",
   "metadata": {},
   "source": [
    "# Week 6 Lab — Commonly Used Distributions and the Central Limit Theorem\n",
    "\n",
    "In this lab, we will:\n",
    "\n",
    "1. work with Bernoulli, Binomial, Poisson, Normal, and Exponential distributions,\n",
    "2. compute probabilities numerically,\n",
    "3. simulate random samples,\n",
    "4. compare theory and simulation,\n",
    "5. visualize the Central Limit Theorem (CLT).\n",
    "\n",
    "We will use Python, NumPy, Matplotlib, and SciPy."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "62fc7999",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from scipy.stats import binom, poisson, norm, expon\n",
    "\n",
    "np.random.seed(42)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "52e8c8bb",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "P(X=1) = 0.7\n",
      "P(X=0) = 0.30000000000000004\n",
      "Mean = 0.7\n",
      "Variance = 0.21000000000000002\n"
     ]
    }
   ],
   "source": [
    "# Bernoulli distribution\n",
    "p = 0.7\n",
    "\n",
    "print(\"P(X=1) =\", p)\n",
    "print(\"P(X=0) =\", 1 - p)\n",
    "print(\"Mean =\", p)\n",
    "print(\"Variance =\", p * (1 - p))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "e8285330",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "First 20 observations:\n",
      "[1 0 0 1 1 1 1 0 1 0 1 0 0 1 1 1 1 1 1 1]\n",
      "Sample mean: 0.712\n",
      "Sample variance: 0.20526126126126118\n"
     ]
    }
   ],
   "source": [
    "# Now we simulate Bernoulli observations.  \n",
    "#This is equivalent to repeating a success/failure experiment many times.\n",
    "\n",
    "#For example:\n",
    "#- success = component passes,\n",
    "#- failure = component fails.\n",
    "\n",
    "p = 0.7\n",
    "n_samples = 1000\n",
    "\n",
    "bernoulli_data = np.random.binomial(1, p, size=n_samples)\n",
    "\n",
    "print(\"First 20 observations:\")\n",
    "print(bernoulli_data[:20])\n",
    "\n",
    "print(\"Sample mean:\", bernoulli_data.mean())\n",
    "print(\"Sample variance:\", bernoulli_data.var(ddof=1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "02a6d407",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 18056 characters]",
      "text/plain": [
       "<Figure size 600x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "values, counts = np.unique(bernoulli_data, return_counts=True)\n",
    "\n",
    "plt.figure(figsize=(6,4))\n",
    "plt.bar(values, counts / n_samples, width=0.4)\n",
    "plt.xticks([0, 1])\n",
    "plt.xlabel(\"Outcome\")\n",
    "plt.ylabel(\"Relative frequency\")\n",
    "plt.title(\"Simulated Bernoulli Distribution\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a0ce65a2",
   "metadata": {},
   "source": [
    "## Part 3 — Binomial Distribution\n",
    "\n",
    "The Binomial distribution counts the number of successes in `n` independent Bernoulli trials.\n",
    "\n",
    "If `X ~ Binomial(n, p)`, then:\n",
    "\n",
    "- `P(X = k) = C(n,k) p^k (1-p)^(n-k)`\n",
    "- `E[X] = np`\n",
    "- `Var(X) = np(1-p)`\n",
    "\n",
    "Example:\n",
    "Let `X` be the number of defective components in a sample of 20, if the defect probability is `0.08`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "51dd4e92",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "P(X=2) = 0.271091\n",
      "Mean = 1.6\n",
      "Variance = 1.4720000000000002\n"
     ]
    }
   ],
   "source": [
    "n = 20\n",
    "p = 0.08\n",
    "\n",
    "k = 2\n",
    "prob_k2 = binom.pmf(k, n, p)\n",
    "\n",
    "print(f\"P(X=2) = {prob_k2:.6f}\")\n",
    "print(\"Mean =\", n * p)\n",
    "print(\"Variance =\", n * p * (1 - p))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "41a6efb0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 21332 characters]",
      "text/plain": [
       "<Figure size 800x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "x = np.arange(0, n + 1)\n",
    "pmf = binom.pmf(x, n, p)\n",
    "\n",
    "plt.figure(figsize=(8,4))\n",
    "plt.bar(x, pmf, width=0.7)\n",
    "plt.xlabel(\"Number of successes\")\n",
    "plt.ylabel(\"Probability\")\n",
    "plt.title(\"Binomial Distribution: n=20, p=0.08\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e2da1d97",
   "metadata": {},
   "source": [
    "## Part 4 — Binomial Simulation\n",
    "\n",
    "Now we compare the theoretical Binomial model with simulation."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "741ee2d7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Simulated mean: 1.5818\n",
      "Theoretical mean: 1.6\n",
      "Simulated variance: 1.4380525652565255\n",
      "Theoretical variance: 1.4720000000000002\n"
     ]
    }
   ],
   "source": [
    "n = 20\n",
    "p = 0.08\n",
    "n_sim = 10000\n",
    "\n",
    "binom_sim = np.random.binomial(n, p, size=n_sim)\n",
    "\n",
    "print(\"Simulated mean:\", binom_sim.mean())\n",
    "print(\"Theoretical mean:\", n * p)\n",
    "\n",
    "print(\"Simulated variance:\", binom_sim.var(ddof=1))\n",
    "print(\"Theoretical variance:\", n * p * (1 - p))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "bc6f1103",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 26972 characters]",
      "text/plain": [
       "<Figure size 800x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(8,4))\n",
    "plt.hist(binom_sim, bins=np.arange(-0.5, n + 1.5, 1), density=True)\n",
    "plt.plot(x, pmf, 'o')\n",
    "plt.xlabel(\"Number of successes\")\n",
    "plt.ylabel(\"Relative frequency / probability\")\n",
    "plt.title(\"Binomial: Simulation vs Theory\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "71218a6b",
   "metadata": {},
   "source": [
    "## Part 5 — Poisson Distribution\n",
    "\n",
    "The Poisson distribution models counts of events in a fixed interval.\n",
    "\n",
    "If `X ~ Poisson(λ)`, then:\n",
    "\n",
    "- `P(X=k) = exp(-λ) λ^k / k!`\n",
    "- `E[X] = λ`\n",
    "- `Var(X) = λ`\n",
    "\n",
    "Example:\n",
    "Let `X` be the number of flaws per meter of cable, with average rate `λ = 3`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "d6d2a5f6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "P(X=0) = 0.049787068367863944\n",
      "P(X=2) = 0.22404180765538775\n",
      "Mean = 3\n",
      "Variance = 3\n"
     ]
    }
   ],
   "source": [
    "lam = 3\n",
    "\n",
    "print(\"P(X=0) =\", poisson.pmf(0, lam))\n",
    "print(\"P(X=2) =\", poisson.pmf(2, lam))\n",
    "print(\"Mean =\", lam)\n",
    "print(\"Variance =\", lam)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "262e9381",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 17880 characters]",
      "text/plain": [
       "<Figure size 800x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "x = np.arange(0, 15)\n",
    "pmf_poisson = poisson.pmf(x, lam)\n",
    "\n",
    "plt.figure(figsize=(8,4))\n",
    "plt.bar(x, pmf_poisson, width=0.7)\n",
    "plt.xlabel(\"Count\")\n",
    "plt.ylabel(\"Probability\")\n",
    "plt.title(\"Poisson Distribution: lambda = 3\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8033a3c6",
   "metadata": {},
   "source": [
    "## Part 6 — Poisson Simulation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "f241431b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Simulated mean: 3.0051\n",
      "Theoretical mean: 3\n",
      "Simulated variance: 3.0315771477147715\n",
      "Theoretical variance: 3\n"
     ]
    }
   ],
   "source": [
    "lam = 3\n",
    "n_sim = 10000\n",
    "\n",
    "poisson_sim = np.random.poisson(lam, size=n_sim)\n",
    "\n",
    "print(\"Simulated mean:\", poisson_sim.mean())\n",
    "print(\"Theoretical mean:\", lam)\n",
    "\n",
    "print(\"Simulated variance:\", poisson_sim.var(ddof=1))\n",
    "print(\"Theoretical variance:\", lam)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "2f9e2a0c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 23904 characters]",
      "text/plain": [
       "<Figure size 800x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(8,4))\n",
    "plt.hist(poisson_sim, bins=np.arange(-0.5, 15.5, 1), density=True)\n",
    "plt.plot(np.arange(0, 15), poisson.pmf(np.arange(0, 15), lam), 'o')\n",
    "plt.xlabel(\"Count\")\n",
    "plt.ylabel(\"Relative frequency / probability\")\n",
    "plt.title(\"Poisson: Simulation vs Theory\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0583b2a0",
   "metadata": {},
   "source": [
    "## Part 7 — Normal Distribution\n",
    "\n",
    "The Normal distribution is a continuous distribution used widely in science and engineering.\n",
    "\n",
    "If `X ~ N(μ, σ²)`, then:\n",
    "- `μ` is the mean,\n",
    "- `σ` is the standard deviation.\n",
    "\n",
    "Example:\n",
    "Suppose a sensor output is normally distributed with mean `50` and standard deviation `4`.\n",
    "We compute the probability that the output is less than `58`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "c73731b8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Z-score = 2.0\n",
      "P(X < 58) = 0.9772498680518208\n"
     ]
    }
   ],
   "source": [
    "mu = 50\n",
    "sigma = 4\n",
    "\n",
    "prob_less_58 = norm.cdf(58, loc=mu, scale=sigma)\n",
    "z_score = (58 - mu) / sigma\n",
    "\n",
    "print(\"Z-score =\", z_score)\n",
    "print(\"P(X < 58) =\", prob_less_58)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "e28013a8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 32064 characters]",
      "text/plain": [
       "<Figure size 800x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "x = np.linspace(mu - 4*sigma, mu + 4*sigma, 400)\n",
    "pdf = norm.pdf(x, loc=mu, scale=sigma)\n",
    "\n",
    "plt.figure(figsize=(8,4))\n",
    "plt.plot(x, pdf)\n",
    "plt.axvline(58, linestyle='--')\n",
    "plt.xlabel(\"x\")\n",
    "plt.ylabel(\"Density\")\n",
    "plt.title(\"Normal Distribution\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bcf3b558",
   "metadata": {},
   "source": [
    "## Part 8 — Simulating Normal Data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "9617ab65",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Simulated mean: 50.002185302479354\n",
      "Theoretical mean: 50\n",
      "Simulated std: 3.9891411700286694\n",
      "Theoretical std: 4\n"
     ]
    }
   ],
   "source": [
    "mu = 50\n",
    "sigma = 4\n",
    "n_sim = 10000\n",
    "\n",
    "normal_sim = np.random.normal(loc=mu, scale=sigma, size=n_sim)\n",
    "\n",
    "print(\"Simulated mean:\", normal_sim.mean())\n",
    "print(\"Theoretical mean:\", mu)\n",
    "\n",
    "print(\"Simulated std:\", normal_sim.std(ddof=1))\n",
    "print(\"Theoretical std:\", sigma)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "f3182d6f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 31840 characters]",
      "text/plain": [
       "<Figure size 800x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(8,4))\n",
    "plt.hist(normal_sim, bins=30, density=True)\n",
    "plt.plot(x, pdf)\n",
    "plt.xlabel(\"Value\")\n",
    "plt.ylabel(\"Density\")\n",
    "plt.title(\"Normal: Simulation vs Theory\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fc269da3",
   "metadata": {},
   "source": [
    "## Part 9 — Exponential Distribution\n",
    "\n",
    "The Exponential distribution is often used to model waiting times.\n",
    "\n",
    "If `X ~ Exponential(λ)`, then:\n",
    "- mean = `1/λ`\n",
    "\n",
    "Example:\n",
    "Suppose machine failures occur at rate `λ = 0.5` failures per hour.\n",
    "Then the average waiting time until the next failure is `1/0.5 = 2` hours."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "8917aabe",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Mean waiting time = 2.0\n",
      "P(X < 2) = 0.6321205588285577\n"
     ]
    }
   ],
   "source": [
    "lam = 0.5\n",
    "\n",
    "print(\"Mean waiting time =\", 1 / lam)\n",
    "print(\"P(X < 2) =\", expon.cdf(2, scale=1/lam))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "37a5afbd",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 26512 characters]",
      "text/plain": [
       "<Figure size 800x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "x = np.linspace(0, 12, 400)\n",
    "pdf_exp = expon.pdf(x, scale=1/lam)\n",
    "\n",
    "plt.figure(figsize=(8,4))\n",
    "plt.plot(x, pdf_exp)\n",
    "plt.xlabel(\"Waiting time\")\n",
    "plt.ylabel(\"Density\")\n",
    "plt.title(\"Exponential Distribution\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "34e1dc63",
   "metadata": {},
   "source": [
    "## Part 10 — Central Limit Theorem\n",
    "\n",
    "The Central Limit Theorem states that the sampling distribution of the sample mean becomes approximately normal as the sample size increases.\n",
    "\n",
    "This is true even when the original population is not normal, provided the sample size is sufficiently large.\n",
    "\n",
    "We will demonstrate this using a strongly skewed population."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "cd561dd9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 16312 characters]",
      "text/plain": [
       "<Figure size 800x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "population = np.random.exponential(scale=2, size=100000)\n",
    "\n",
    "plt.figure(figsize=(8,4))\n",
    "plt.hist(population, bins=100, density=True)\n",
    "plt.xlabel(\"Value\")\n",
    "plt.ylabel(\"Density\")\n",
    "plt.title(\"Original Population (Skewed)\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "74402ec4",
   "metadata": {},
   "source": [
    "## Part 11 — Sampling Distribution of the Mean\n",
    "\n",
    "We now repeatedly draw samples and compute their means.\n",
    "\n",
    "We will compare:\n",
    "- sample size `n = 5`\n",
    "- sample size `n = 30`\n",
    "- sample size `n = 100`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "d1dc040d",
   "metadata": {},
   "outputs": [],
   "source": [
    "def sample_means(population, sample_size, n_reps=5000):\n",
    "    means = []\n",
    "    for _ in range(n_reps):\n",
    "        sample = np.random.choice(population, size=sample_size, replace=True)\n",
    "        means.append(sample.mean())\n",
    "    return np.array(means)\n",
    "\n",
    "means_5 = sample_means(population, 5)\n",
    "means_30 = sample_means(population, 30)\n",
    "means_100 = sample_means(population, 100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "d2c74f8f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 18784 characters]",
      "text/plain": [
       "<Figure size 800x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(8,4))\n",
    "plt.hist(means_5, bins=40, density=True)\n",
    "plt.xlabel(\"Sample mean\")\n",
    "plt.ylabel(\"Density\")\n",
    "plt.title(\"Sampling Distribution of the Mean (n = 5)\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "10f26d72",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 19512 characters]",
      "text/plain": [
       "<Figure size 800x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(8,4))\n",
    "plt.hist(means_30, bins=40, density=True)\n",
    "plt.xlabel(\"Sample mean\")\n",
    "plt.ylabel(\"Density\")\n",
    "plt.title(\"Sampling Distribution of the Mean (n = 30)\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "f38c622b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 23184 characters]",
      "text/plain": [
       "<Figure size 800x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(8,4))\n",
    "plt.hist(means_100, bins=40, density=True)\n",
    "plt.xlabel(\"Sample mean\")\n",
    "plt.ylabel(\"Density\")\n",
    "plt.title(\"Sampling Distribution of the Mean (n = 100)\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1a99848c",
   "metadata": {},
   "source": [
    "## Part 12 — Numerical Check of the CLT\n",
    "\n",
    "For an exponential population with scale = 2:\n",
    "\n",
    "- population mean should be about 2,\n",
    "- population variance should be about 4,\n",
    "- variance of the sample mean should be about `4/n`.\n",
    "\n",
    "We compare this with simulation."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "55007845",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Population mean (approx.): 2.0012337957358866\n",
      "Population variance (approx.): 3.983317421944735\n",
      "\n",
      "For n = 5\n",
      "Mean of sample means: 2.001016205586466\n",
      "Variance of sample means: 0.7806365493596817\n",
      "Theoretical variance approx.: 0.8\n",
      "\n",
      "For n = 30\n",
      "Mean of sample means: 2.006761294144693\n",
      "Variance of sample means: 0.12896356422754562\n",
      "Theoretical variance approx.: 0.13333333333333333\n",
      "\n",
      "For n = 100\n",
      "Mean of sample means: 2.0015222052034187\n",
      "Variance of sample means: 0.040359743223367446\n",
      "Theoretical variance approx.: 0.04\n"
     ]
    }
   ],
   "source": [
    "print(\"Population mean (approx.):\", population.mean())\n",
    "print(\"Population variance (approx.):\", population.var())\n",
    "\n",
    "print(\"\\nFor n = 5\")\n",
    "print(\"Mean of sample means:\", means_5.mean())\n",
    "print(\"Variance of sample means:\", means_5.var(ddof=1))\n",
    "print(\"Theoretical variance approx.:\", 4/5)\n",
    "\n",
    "print(\"\\nFor n = 30\")\n",
    "print(\"Mean of sample means:\", means_30.mean())\n",
    "print(\"Variance of sample means:\", means_30.var(ddof=1))\n",
    "print(\"Theoretical variance approx.:\", 4/30)\n",
    "\n",
    "print(\"\\nFor n = 100\")\n",
    "print(\"Mean of sample means:\", means_100.mean())\n",
    "print(\"Variance of sample means:\", means_100.var(ddof=1))\n",
    "print(\"Theoretical variance approx.:\", 4/100)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3a8dadb5",
   "metadata": {},
   "source": [
    "## Part 13 — Final Questions\n",
    "\n",
    "Answer the following after running the notebook:\n",
    "\n",
    "1. What is the difference between a Bernoulli and a Binomial random variable?\n",
    "2. When is the Poisson model appropriate?\n",
    "3. Why is the Normal model so important in applications?\n",
    "4. What does a Z-score represent?\n",
    "5. What does the Central Limit Theorem say precisely?\n",
    "6. Does the CLT apply to raw data or to sample means?"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv (3.14.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.14.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
