{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "0ba6d314",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Imports\n",
    "\n",
    "from IPython.display import display, Markdown\n",
    "from scipy.stats import chi2_contingency\n",
    "from scipy.stats import t as t_test\n",
    "import numpy as np\n",
    "import math\n",
    "t_value = t_test.isf\n",
    "\n",
    "def _display_table(data_array, row_names=None, col_names=None):\n",
    "    _row_num = len(data_array)\n",
    "    _col_num = len(data_array[0])\n",
    "    _rows = []\n",
    "    for i in range(_row_num):\n",
    "        row = f'| {row_names[i]} |'\n",
    "        for j in range(_col_num):\n",
    "            row += f' {data_array[i][j]:.1f} |'\n",
    "        row += f' {sum(data_array[i]):.0f} |'\n",
    "        _rows.append(row)\n",
    "    _total_row = '| **Total** |'\n",
    "    _col_tots = 0\n",
    "    for i in range(_col_num):\n",
    "        col_tot = 0\n",
    "        for j in range(_row_num):\n",
    "            col_tot += data_array[j][i]\n",
    "        _col_tots += col_tot\n",
    "        _total_row += f' **{col_tot:.0f}** |'\n",
    "    _total_row += f' **{_col_tots:.0f}** |'\n",
    "    display(Markdown(\n",
    "    rf\"\"\"\n",
    "| | {' | '.join(col_names + ['Total'])} |\n",
    "{'|-'*(len(row_names) + 2)} |\n",
    "{'\\n'.join(_rows)}\n",
    "{_total_row}\n",
    "\"\"\"\n",
    "))\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e0a72880",
   "metadata": {},
   "source": [
    "# Uparret t-test\n",
    "\n",
    "$$\n",
    "SD_{fælles} = \\sqrt{\\frac{(n_1-1)\\cdot SD_1^2 + (n_2-1)\\cdot SD_2^2}{n_1 + n_2 - 2}}\n",
    "$$\n",
    "\n",
    "$$\n",
    "se(\\bar{x}_1 - \\bar{x}_2) = \\sqrt{\\frac{1}{n_1} + \\frac{1}{n_2}} \\cdot SD_{fælles}\n",
    "$$\n",
    "\n",
    "$$\n",
    "t(x) = \\frac{\\bar{x}_1 - \\bar{x}_2}{se(\\bar{x}_1 - {\\bar{x}_2})}\n",
    "$$\n",
    "\n",
    "$$\n",
    "df = n_1 + n_2 - 2\n",
    "$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7e734740",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "\n",
       "Middeldifference: $\\bar{x} = \\bar{x}_1 - \\bar{x}_2 = 1.44 - 1.26 = 0.180$\n",
       "\n",
       "$H_0: \\mu_1 = \\mu_2 \\Rightarrow \\mu_1 - \\mu_2 = 0$\n",
       "\n",
       "Test: uparret t-test med $df = 36 + 36 - 2 = 70$ frihedsgrader\n",
       "\n",
       "$SD_{fælles} = \\sqrt{ \\frac{ (n_1 - 1)\\cdot SD_1^2 + (n_2-1) \\cdot SD_2^2 }{ n_1 + n_2 - 2 } } =  \\sqrt{ \\frac{ (36 - 1)\\cdot 0.25^2 + (36-1) \\cdot 0.32^2 }{ 36 + 36 - 2 } } = 0.2871$\n",
       "\n",
       "$se(\\bar{x_1} - \\bar{x_2}) = \\sqrt{\\frac{1}{n_1} + \\frac{1}{n_2}} \\cdot SD_{fælles} = \\sqrt{\\frac{1}{36} + \\frac{1}{36}} \\cdot 0.2871 = 0.0677$\n",
       "\n",
       "$t(x) = \\frac{\\bar{x_1} - \\bar{x_2}}{se(\\bar{x_1} - \\bar{x_2})} = \\frac{1.44 - 1.26}{0.0677} = 2.6596$\n",
       "\n",
       "p-værdi for $|t(x)|$ ved 70 frihedsgrader: 0.0097 $\\lt 0.05$\n"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "\n",
       "Da $p$ $\\lt 0.05$, kan nulhypotesen $H_0: \\mu_1 - \\mu_2 = 0$ forkastes. Der er altså statistisk signifikant forskel mellem middelværdierne.\n"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "middel1 = 1.44\n",
    "n1 = 36\n",
    "sd1 = 0.25\n",
    "\n",
    "middel2 = 1.26\n",
    "n2 = 36\n",
    "sd2 = 0.32\n",
    "\n",
    "\n",
    "\n",
    "###############################\n",
    "dof = n1 + n2 - 2\n",
    "sd_fælles = math.sqrt(((n1-1)*sd1**2 + (n2-1)*sd2**2) / (n1 + n2 - 2))\n",
    "se_fælles = math.sqrt(1/n1 + 1/n2) * sd_fælles\n",
    "t_x = (middel1 - middel2)/(se_fælles)\n",
    "p_threshold = 0.05\n",
    "p_værdi = (1 - t_test.cdf(t_x, dof))*2\n",
    "match p_værdi:\n",
    "    case p_værdi if p_værdi >= p_threshold:\n",
    "        p_text = f'$\\ge {p_threshold}$'\n",
    "    case p_værdi if p_værdi < p_threshold/100:\n",
    "        p_text = f'$\\ll {p_threshold}$'\n",
    "    case _:\n",
    "        p_text = f'$\\lt {p_threshold}$'\n",
    "\n",
    "display(Markdown(\n",
    "    rf\"\"\"\n",
    "Middeldifference: $\\bar{{x}} = \\bar{{x}}_1 - \\bar{{x}}_2 = {middel1} - {middel2} = {middel1 - middel2:.3f}$\n",
    "\n",
    "$H_0: \\mu_1 = \\mu_2 \\Rightarrow \\mu_1 - \\mu_2 = 0$\n",
    "\n",
    "Test: uparret t-test med $df = {n1} + {n2} - 2 = {dof}$ frihedsgrader\n",
    "\n",
    "$SD_{{fælles}} = \\sqrt{{ \\frac{{ (n_1 - 1)\\cdot SD_1^2 + (n_2-1) \\cdot SD_2^2 }}{{ n_1 + n_2 - 2 }} }} =  \\sqrt{{ \\frac{{ ({n1} - 1)\\cdot {sd1}^2 + ({n2}-1) \\cdot {sd2}^2 }}{{ {n1} + {n2} - 2 }} }} = {sd_fælles:.4f}$\n",
    "\n",
    "$se(\\bar{{x_1}} - \\bar{{x_2}}) = \\sqrt{{\\frac{{1}}{{n_1}} + \\frac{{1}}{{n_2}}}} \\cdot SD_{{fælles}} = \\sqrt{{\\frac{{1}}{{{n1}}} + \\frac{{1}}{{{n2}}}}} \\cdot {sd_fælles:.4f} = {se_fælles:.4f}$\n",
    "\n",
    "$t(x) = \\frac{{\\bar{{x_1}} - \\bar{{x_2}}}}{{se(\\bar{{x_1}} - \\bar{{x_2}})}} = \\frac{{{middel1} - {middel2}}}{{{se_fælles:.4f}}} = {t_x:.4f}$\n",
    "\n",
    "p-værdi for $|t(x)|$ ved {dof} frihedsgrader: {p_værdi:.4f} {p_text} (fundet ved brug af Python-biblioteket `scipy.stats.t`)\n",
    "\"\"\"\n",
    "))\n",
    "\n",
    "if p_værdi < p_threshold:\n",
    "    display(Markdown(\n",
    "        rf\"\"\"\n",
    "Da $p$ {p_text}, kan nulhypotesen $H_0: \\mu_1 - \\mu_2 = 0$ forkastes. Der er altså statistisk signifikant forskel mellem middelværdierne.\n",
    "\"\"\"\n",
    "    ))\n",
    "else:\n",
    "    display(Markdown(\n",
    "        rf\"\"\"\n",
    "Da $p$ {p_text}, kan nulhypotesen $H_0: \\mu_1 - \\mu_2 = 0$ ikke forkastes. Der kan altså ikke siges at være statistisk signifikant forskel mellem middelværdierne.\n",
    "\"\"\"\n",
    "    ))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2ad5beff",
   "metadata": {},
   "source": [
    "# Konfidensintervallet for forskellen på middelværdierne\n",
    "\n",
    "$$\n",
    "95\\%  CI(\\mu_1 - \\mu_2) = \\bar{x}_1 - \\bar{x}_2 \\pm t' \\cdot se(\\bar{x}_1 - \\bar{x}_2)\n",
    "$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "id": "c4d47453",
   "metadata": {},
   "outputs": [],
   "source": [
    "middel1 = 21.9\n",
    "n1 = 150\n",
    "sd1 = 1.7\n",
    "\n",
    "middel2 = 21.6\n",
    "n2 = 300\n",
    "sd2 = 1.8\n",
    "\n",
    "dof = n1 + n2 - 2\n",
    "sd_fælles = math.sqrt(((n1-1)*sd1**2 + (n2-1)*sd2**2) / (n1 + n2 - 2))\n",
    "se_fælles = math.sqrt(1/n1 + 1/n2) * sd_fælles"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "bdc8cd82",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "\n",
       "$\\bar{x}_1 = 1.44$\n",
       "\n",
       "$\\bar{x}_2 = 1.26$\n",
       "\n",
       "Eksakt formel:\n",
       "\n",
       "$SD_{fælles} = \\sqrt{ \\frac{ (n_1 - 1)\\cdot SD_1^2 + (n_2-1) \\cdot SD_2^2 }{ n_1 + n_2 - 2 } } =  \\sqrt{ \\frac{ (36 - 1)\\cdot 0.25^2 + (36-1) \\cdot 0.32^2 }{ 36 + 36 - 2 } } = 0.2871$\n",
       "\n",
       "$se(\\bar{x_1} - \\bar{x_2}) = \\sqrt{\\frac{1}{n_1} + \\frac{1}{n_2}} \\cdot SD_{fælles} = \\sqrt{\\frac{1}{36} + \\frac{1}{36}} \\cdot 0.2871 = 0.0677$\n",
       "\n",
       "$95\\%  CI(\\mu_1 - \\mu_2) = \\bar{x}_1 - \\bar{x}_2 \\pm t' \\cdot se(\\bar{x}_1 - \\bar{x}_2)$\n",
       "\n",
       "$= 1.44 - 1.26 \\pm 1.994 \\cdot 0.068$\n",
       "\n",
       "$= 0.180 \\pm 0.135 = \\left[0.045\\ ;\\ 0.315\\right]$\n"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "\n",
       "Da $0$ ikke er inkluderet i $95\\%CI$, kan der siges at være signifikant forskel på middelværdierne.\n"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "####################################\n",
    "t_værdi = t_value(0.025, dof)\n",
    "t_se = t_værdi * se_fælles\n",
    "middel_dif = middel1 - middel2\n",
    "interval_lav = middel_dif - t_se\n",
    "interval_høj = middel_dif + t_se\n",
    "\n",
    "display(Markdown(\n",
    "    rf\"\"\"\n",
    "$\\bar{{x}}_1 = {middel1}$\n",
    "\n",
    "$\\bar{{x}}_2 = {middel2}$\n",
    "\n",
    "Eksakt formel:\n",
    "\n",
    "$SD_{{fælles}} = \\sqrt{{ \\frac{{ (n_1 - 1)\\cdot SD_1^2 + (n_2-1) \\cdot SD_2^2 }}{{ n_1 + n_2 - 2 }} }} =  \\sqrt{{ \\frac{{ ({n1} - 1)\\cdot {sd1}^2 + ({n2}-1) \\cdot {sd2}^2 }}{{ {n1} + {n2} - 2 }} }} = {sd_fælles:.4f}$\n",
    "\n",
    "$se(\\bar{{x_1}} - \\bar{{x_2}}) = \\sqrt{{\\frac{{1}}{{n_1}} + \\frac{{1}}{{n_2}}}} \\cdot SD_{{fælles}} = \\sqrt{{\\frac{{1}}{{{n1}}} + \\frac{{1}}{{{n2}}}}} \\cdot {sd_fælles:.4f} = {se_fælles:.4f}$\n",
    "\n",
    "$95\\%  CI(\\mu_1 - \\mu_2) = \\bar{{x}}_1 - \\bar{{x}}_2 \\pm t' \\cdot se(\\bar{{x}}_1 - \\bar{{x}}_2)$\n",
    "\n",
    "$= {middel1} - {middel2} \\pm {t_værdi:.3f} \\cdot {se_fælles:.3f}$\n",
    "\n",
    "$= {middel_dif:.3f} \\pm {t_se:.3f} = \\left[{middel_dif - t_se:.3f}\\ ;\\ {middel_dif + t_se:.3f}\\right]$\n",
    "\"\"\"\n",
    "))\n",
    "\n",
    "if np.sign(interval_lav) != np.sign(interval_høj):\n",
    "    display(Markdown(\n",
    "        rf\"\"\"\n",
    "Da $0$ er inkluderet i $95\\%CI$, kan der ikke siges at være signifikant forskel på middelværdierne.\n",
    "\"\"\"\n",
    "    ))\n",
    "else:\n",
    "    display(Markdown(\n",
    "        rf\"\"\"\n",
    "Da $0$ ikke er inkluderet i $95\\%CI$, kan der siges at være signifikant forskel på middelværdierne.\n",
    "\"\"\"\n",
    "    ))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "984d104a",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "base",
   "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.13.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
