{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "841f16af",
   "metadata": {},
   "source": [
    "# TP 7 — Célérité des ultrasons : traitement des données\n",
    "\n",
    "Ce notebook accompagne l'énoncé papier. Il suit le même ordre :\n",
    "\n",
    "1. **Méthode 1** — coïncidences de phase : régression pour $\\lambda$, puis $c_1 = \\lambda\\nu$\n",
    "2. **Méthode 2** — temps de vol avec l'Arduino : incertitude de type A, puis régression pour $c_2$\n",
    "3. **Newton ou Laplace ?** — propagation Monte-Carlo et écarts normalisés\n",
    "\n",
    "**Comment travailler.** Exécutez les cellules dans l'ordre (`Maj + Entrée`).\n",
    "Les cellules marquées ✏️ **À COMPLÉTER** contiennent des `...` à remplacer.\n",
    "Les graphiques sont déjà programmés : concentrez-vous sur la physique.\n",
    "Les réponses rédigées vont dans les cellules « ✏️ Votre réponse »."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0be2622b",
   "metadata": {},
   "outputs": [],
   "source": [
    "import time\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "rng = np.random.default_rng()   # générateur de nombres aléatoires"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "587a3d83",
   "metadata": {},
   "source": [
    "## 0. Deux outils pour tout le TP\n",
    "\n",
    "`ecrire(x, u)` affiche un résultat avec deux chiffres significatifs sur l'incertitude (déjà écrite).\n",
    "\n",
    "L'**écart normalisé** entre deux résultats $(x_1, u_1)$ et $(x_2, u_2)$ vaut\n",
    "$$z = \\frac{|x_1 - x_2|}{\\sqrt{u_1^2 + u_2^2}}$$\n",
    "Les deux résultats sont jugés compatibles si $z < 2$.\n",
    "\n",
    "✏️ **À COMPLÉTER** : la fonction `ecart_normalise`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8dd148ce",
   "metadata": {},
   "outputs": [],
   "source": [
    "def ecrire(x, u):\n",
    "    # Écrit x ± u avec deux chiffres significatifs sur u.\n",
    "    rang = 1 - int(np.floor(np.log10(u)))\n",
    "    return f\"{round(x, rang):.{max(rang, 0)}f} ± {round(u, rang):.{max(rang, 0)}f}\"\n",
    "\n",
    "\n",
    "def ecart_normalise(x1, u1, x2, u2):\n",
    "    return ...   # ✏️ À COMPLÉTER\n",
    "\n",
    "\n",
    "# Vérification : on doit obtenir z = 2.0\n",
    "print(ecart_normalise(10.0, 0.3, 11.0, 0.4))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d887d7c4",
   "metadata": {},
   "source": [
    "---\n",
    "## 1. Méthode 1 : coïncidences de phase\n",
    "\n",
    "### 1.1 Régression linéaire avec incertitudes (outil fourni)\n",
    "\n",
    "On cherche la droite $y = a\\,x + b$ qui passe au mieux par les points. Pour obtenir\n",
    "l'incertitude sur $a$ et $b$, on utilise la **méthode de Monte-Carlo** :\n",
    "\n",
    "1. on tire au hasard un nouveau jeu de points, chacun déplacé selon son incertitude ;\n",
    "2. on ajuste une droite sur ce jeu ;\n",
    "3. on recommence quelques milliers de fois ;\n",
    "4. l'écart-type des pentes obtenues donne $u(a)$.\n",
    "\n",
    "Lisez la fonction ci-dessous et repérez ces quatre étapes, puis exécutez la cellule."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "612d2863",
   "metadata": {},
   "outputs": [],
   "source": [
    "def regression_mc(x, ux, y, uy, n_mc=5000):\n",
    "    # Renvoie les pentes et ordonnées à l'origine de n_mc ajustements Monte-Carlo.\n",
    "    a_mc = np.empty(n_mc)\n",
    "    b_mc = np.empty(n_mc)\n",
    "    for k in range(n_mc):\n",
    "        x_tire = x + ux * rng.standard_normal(x.size)       # étape 1\n",
    "        y_tire = y + uy * rng.standard_normal(y.size)\n",
    "        a_mc[k], b_mc[k] = np.polyfit(x_tire, y_tire, 1)    # étape 2 (droite)\n",
    "    return a_mc, b_mc                                       # étapes 3 et 4 : à exploiter\n",
    "\n",
    "\n",
    "def tracer_regression(x, ux, y, uy, a, b, titres):\n",
    "    # Données + droite, puis résidus normalisés.\n",
    "    residus = (y - (a * x + b)) / np.sqrt(uy**2 + (a * ux) ** 2)\n",
    "    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(11, 3.8))\n",
    "    ax1.errorbar(x, y, xerr=ux, yerr=uy, fmt=\"o\", ms=4, capsize=3, label=\"mesures\")\n",
    "    xx = np.linspace(x.min(), x.max(), 100)\n",
    "    ax1.plot(xx, a * xx + b, \"r-\", label=\"modèle affine\")\n",
    "    ax1.set_xlabel(titres[0]); ax1.set_ylabel(titres[1]); ax1.legend()\n",
    "    ax2.axhspan(-2, 2, color=\"green\", alpha=0.12, label=\"|résidu| < 2\")\n",
    "    ax2.axhline(0, color=\"black\", lw=0.8)\n",
    "    ax2.plot(x, residus, \"o\")\n",
    "    ax2.set_xlabel(titres[0]); ax2.set_ylabel(\"résidu normalisé\"); ax2.legend()\n",
    "    fig.tight_layout(); plt.show()\n",
    "\n",
    "\n",
    "def tracer_histogramme(tirages, nom, unite):\n",
    "    m, u = np.mean(tirages), np.std(tirages, ddof=1)\n",
    "    plt.figure(figsize=(6, 3.5))\n",
    "    plt.hist(tirages, bins=50, color=\"lightsteelblue\", edgecolor=\"black\")\n",
    "    for pos, style in ((m, \"-\"), (m - u, \"--\"), (m + u, \"--\")):\n",
    "        plt.axvline(pos, color=\"red\", ls=style)\n",
    "    plt.xlabel(f\"{nom} ({unite})\"); plt.ylabel(\"nombre de tirages\")\n",
    "    plt.title(f\"{nom} = ({ecrire(m, u)}) {unite}\")\n",
    "    plt.tight_layout(); plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f409a7c2",
   "metadata": {},
   "source": [
    "### 1.2 Longueur d'onde $\\lambda$\n",
    "\n",
    "Remplacez les valeurs d'exemple par vos mesures : rang $i$ de la coïncidence,\n",
    "distance $d_i$ à la référence (en mm) et incertitude-type $u(d_i)$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1c19df2a",
   "metadata": {},
   "outputs": [],
   "source": [
    "i = np.arange(11, dtype=float)                 # rang des coïncidences\n",
    "u_i = np.zeros_like(i)                         # le rang est connu exactement\n",
    "d = np.array([0.0, 8.7, 17.1, 25.8, 34.3, 42.8,\n",
    "              51.6, 60.0, 68.7, 77.1, 85.9])   # d_i (mm) — EXEMPLE, à remplacer\n",
    "u_d = np.full_like(d, 0.5)                     # u(d_i) (mm) — à estimer"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b645313d",
   "metadata": {},
   "source": [
    "✏️ **À COMPLÉTER** : à partir des tirages `a_mc`, calculez la valeur retenue de\n",
    "$\\lambda$ (moyenne) et son incertitude-type (écart-type expérimental : `np.std(..., ddof=1)`)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f825b69c",
   "metadata": {},
   "outputs": [],
   "source": [
    "a_mc, b_mc = regression_mc(i, u_i, d, u_d)\n",
    "\n",
    "lam = ...       # ✏️ λ (mm)\n",
    "u_lam = ...     # ✏️ u(λ) (mm)\n",
    "d0, u_d0 = np.mean(b_mc), np.std(b_mc, ddof=1)\n",
    "\n",
    "print(f\"λ  = ({ecrire(lam, u_lam)}) mm\")\n",
    "print(f\"d0 = ({ecrire(d0, u_d0)}) mm\")\n",
    "tracer_regression(i, u_i, d, u_d, lam, d0, (\"rang i\", \"d_i (mm)\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "422295d4",
   "metadata": {},
   "source": [
    "**Question.** Le modèle $d_i = \\lambda\\, i + d_0$ est-il validé par les résidus normalisés ?\n",
    "L'ordonnée à l'origine $d_0$ est-elle compatible avec la valeur attendue ?"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e0e01210",
   "metadata": {},
   "source": [
    "> ✏️ *Votre réponse :*\n",
    ">\n",
    "> "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a5692550",
   "metadata": {},
   "source": [
    "### 1.3 Célérité $c_1 = \\lambda\\,\\nu$\n",
    "\n",
    "Renseignez la fréquence mesurée et la demi-largeur $\\Delta\\nu$ estimée à l'oscilloscope.\n",
    "Une incertitude de type B à répartition uniforme vaut $u = \\Delta/\\sqrt{3}$.\n",
    "\n",
    "Pour un produit, les incertitudes relatives se composent :\n",
    "$$\\frac{u(c_1)}{c_1} = \\sqrt{\\left(\\frac{u(\\lambda)}{\\lambda}\\right)^2 + \\left(\\frac{u(\\nu)}{\\nu}\\right)^2}$$\n",
    "\n",
    "✏️ **À COMPLÉTER** : $u(\\nu)$, $c_1$ et $u(c_1)$ par la formule. Attention aux unités : on veut $c_1$ en m/s."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e8def33e",
   "metadata": {},
   "outputs": [],
   "source": [
    "nu = 40.00e3          # Hz — à remplacer\n",
    "delta_nu = 0.05e3     # Hz, demi-largeur — à estimer\n",
    "\n",
    "u_nu = ...            # ✏️\n",
    "c1 = ...              # ✏️ (m/s) — λ est en mm !\n",
    "u_c1 = ...            # ✏️ formule du produit\n",
    "\n",
    "print(f\"c1 = ({ecrire(c1, u_c1)}) m/s   [formule du produit]\")\n",
    "print(f\"u(λ)/λ = {u_lam / lam:.1e}    u(ν)/ν = {u_nu / nu:.1e}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8e8df6b6",
   "metadata": {},
   "source": [
    "On vérifie par Monte-Carlo : on tire $\\lambda$ (loi normale) et $\\nu$ (loi uniforme),\n",
    "et l'on calcule $c_1$ pour chaque tirage.\n",
    "\n",
    "✏️ **À COMPLÉTER** : la ligne qui calcule les tirages de $c_1$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "313e5ca0",
   "metadata": {},
   "outputs": [],
   "source": [
    "N = 100_000\n",
    "lam_tirages = rng.normal(lam, u_lam, N)                       # mm\n",
    "nu_tirages = rng.uniform(nu - delta_nu, nu + delta_nu, N)     # Hz\n",
    "\n",
    "c1_tirages = ...    # ✏️ (m/s)\n",
    "\n",
    "tracer_histogramme(c1_tirages, \"c1\", \"m/s\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "859c76a6",
   "metadata": {},
   "source": [
    "**Question.** Les deux méthodes donnent-elles la même incertitude ?\n",
    "Quelle grandeur limite la précision de $c_1$ ? Où faudrait-il faire porter l'effort\n",
    "pour améliorer la mesure ?"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e487667d",
   "metadata": {},
   "source": [
    "> ✏️ *Votre réponse :*\n",
    ">\n",
    "> "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "89a6b57c",
   "metadata": {},
   "source": [
    "---\n",
    "## 2. Méthode 2 : temps de vol avec l'Arduino\n",
    "\n",
    "### 2.1 Mesures répétées : incertitude de type A\n",
    "\n",
    "L'Arduino (programme `acquisition_hcsr04.ino`) envoie une durée en µs par ligne.\n",
    "\n",
    "* Renseignez le port série (menu *Outils > Port* de l'IDE Arduino) et **fermez le moniteur série** de l'IDE.\n",
    "* Sans carte, mettez `DEMO = True` pour travailler sur des données simulées."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3c27a676",
   "metadata": {},
   "outputs": [],
   "source": [
    "PORT = \"COM3\"        # Windows : \"COM3\"… ; Linux : \"/dev/ttyACM0\" ; macOS : \"/dev/cu.usbmodem…\"\n",
    "DEMO = False         # True : données simulées, sans Arduino\n",
    "\n",
    "\n",
    "def acquerir(n, port=PORT, demo=DEMO):\n",
    "    # Renvoie n durées d'aller-retour (µs).\n",
    "    if demo:\n",
    "        return np.round(rng.normal(1772.0, 3.0, n))\n",
    "    import serial\n",
    "    mesures = []\n",
    "    with serial.Serial(port, 115200, timeout=2) as liaison:\n",
    "        time.sleep(2)                    # l'ouverture du port redémarre la carte\n",
    "        liaison.reset_input_buffer()\n",
    "        while len(mesures) < n:\n",
    "            ligne = liaison.readline().decode(errors=\"ignore\").strip()\n",
    "            try:\n",
    "                t = float(ligne)\n",
    "            except ValueError:\n",
    "                continue                 # ligne vide ou incomplète\n",
    "            if t > 0:                    # 0 : aucun écho reçu\n",
    "                mesures.append(t)\n",
    "    return np.array(mesures)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "da114563",
   "metadata": {},
   "source": [
    "Placez la plaque à environ 30 cm, puis lancez l'acquisition de 100 mesures.\n",
    "\n",
    "✏️ **À COMPLÉTER** : la moyenne $\\bar t$, l'écart-type expérimental $s$\n",
    "(`np.std(..., ddof=1)`) et l'incertitude-type sur la moyenne $u(\\bar t) = s/\\sqrt{N}$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1980dc1a",
   "metadata": {},
   "outputs": [],
   "source": [
    "t = acquerir(100)\n",
    "np.savetxt(\"mesures_t.csv\", t, fmt=\"%g\", header=\"t (µs)\")\n",
    "\n",
    "t_moy = ...     # ✏️\n",
    "s = ...         # ✏️\n",
    "u_t = ...       # ✏️\n",
    "\n",
    "print(f\"N = {len(t)} ;  t̄ = {t_moy:.1f} µs ;  s = {s:.2f} µs\")\n",
    "print(f\"t̄ = ({ecrire(t_moy, u_t)}) µs\")\n",
    "\n",
    "plt.figure(figsize=(6, 3.5))\n",
    "plt.hist(t, bins=np.arange(t.min() - 0.5, t.max() + 1.5), color=\"lightsteelblue\", edgecolor=\"black\")\n",
    "plt.axvline(t_moy, color=\"red\")\n",
    "plt.axvline(t_moy - s, color=\"red\", ls=\"--\"); plt.axvline(t_moy + s, color=\"red\", ls=\"--\")\n",
    "plt.xlabel(\"durée de l'aller-retour t (µs)\"); plt.ylabel(\"nombre de mesures\")\n",
    "plt.tight_layout(); plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d80a4d51",
   "metadata": {},
   "source": [
    "**Question.** Quelle est la différence entre $s$ et $u(\\bar t)$ ? Laquelle caractérise\n",
    "*une* mesure, laquelle caractérise *la moyenne* de 100 mesures ?"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4156c63c",
   "metadata": {},
   "source": [
    "> ✏️ *Votre réponse :*\n",
    ">\n",
    "> "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e8cd871d",
   "metadata": {},
   "source": [
    "### 2.2 Une première valeur de $c$\n",
    "\n",
    "Mesurez la distance $d$ entre le capteur et la plaque et estimez sa demi-largeur $\\Delta d$.\n",
    "\n",
    "✏️ **À COMPLÉTER** : $c = 2d/\\bar t$ en m/s, et $u(c)$ par la formule du quotient (même forme que pour un produit)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "75cb8fdf",
   "metadata": {},
   "outputs": [],
   "source": [
    "d_un = 30.0           # cm — à remplacer\n",
    "delta_d = 0.5         # cm — à estimer : où est l'origine sur le capteur ?\n",
    "u_d_un = delta_d / np.sqrt(3)\n",
    "\n",
    "c_un = ...            # ✏️ (m/s)\n",
    "u_c_un = ...          # ✏️\n",
    "\n",
    "print(f\"c = ({ecrire(c_un, u_c_un)}) m/s\")\n",
    "print(f\"u(d)/d = {u_d_un / d_un:.1e}    u(t)/t = {u_t / t_moy:.1e}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6ff10262",
   "metadata": {},
   "source": [
    "**Question.** Quelle source d'incertitude domine ? Que penser de l'origine des distances sur le capteur ?"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "af867ac9",
   "metadata": {},
   "source": [
    "> ✏️ *Votre réponse :*\n",
    ">\n",
    "> "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "34b29d60",
   "metadata": {},
   "source": [
    "### 2.3 Régression $t = a\\,d + b$\n",
    "\n",
    "Pour chaque distance (repérée depuis une origine arbitraire mais fixe), faites 20 mesures\n",
    "avec `acquerir(20)` et reportez $\\bar t$ et $u(\\bar t)$.\n",
    "\n",
    "✏️ **À COMPLÉTER** : la fonction `c_depuis_pente`. Le modèle est $t = \\frac{2}{c}\\,d + b$,\n",
    "avec $t$ en µs et $d$ en cm : faites attention à la conversion d'unités."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0d1391a5",
   "metadata": {},
   "outputs": [],
   "source": [
    "dist = np.array([10, 15, 20, 25, 30, 35, 40, 45, 50], dtype=float)                 # cm — EXEMPLE\n",
    "u_dist = np.full_like(dist, 0.2)                                                   # cm\n",
    "tv = np.array([605, 897, 1186, 1480, 1769, 2063, 2351, 2645, 2934], dtype=float)   # µs — EXEMPLE\n",
    "u_tv = np.full_like(tv, 2.0)                                                       # µs\n",
    "\n",
    "\n",
    "def c_depuis_pente(a):\n",
    "    # a en µs/cm  ->  c en m/s\n",
    "    return ...   # ✏️\n",
    "\n",
    "\n",
    "a_mc, b_mc = regression_mc(dist, u_dist, tv, u_tv)\n",
    "c2_tirages = c_depuis_pente(a_mc)\n",
    "c2, u_c2 = np.mean(c2_tirages), np.std(c2_tirages, ddof=1)\n",
    "b, u_b = np.mean(b_mc), np.std(b_mc, ddof=1)\n",
    "\n",
    "print(f\"pente a = ({ecrire(np.mean(a_mc), np.std(a_mc, ddof=1))}) µs/cm\")\n",
    "print(f\"b       = ({ecrire(b, u_b)}) µs\")\n",
    "print(f\"c2      = ({ecrire(c2, u_c2)}) m/s\")\n",
    "tracer_regression(dist, u_dist, tv, u_tv, np.mean(a_mc), b, (\"d (cm)\", \"t (µs)\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8e4ac1a1",
   "metadata": {},
   "source": [
    "**Question.** Interprétez l'ordonnée à l'origine $b$ et convertissez-la en distance.\n",
    "Pourquoi la régression permet-elle de s'en affranchir ?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "eac646ce",
   "metadata": {},
   "outputs": [],
   "source": [
    "d_b = ...    # ✏️ distance équivalente (mm) : d_b = c·b/2\n",
    "print(f\"d_b = {d_b:.1f} mm\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e43d2665",
   "metadata": {},
   "source": [
    "> ✏️ *Votre réponse :*\n",
    ">\n",
    "> "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cfe2d011",
   "metadata": {},
   "source": [
    "---\n",
    "## 3. Newton ou Laplace ?\n",
    "\n",
    "### 3.1 Exemple guidé (document 4)\n",
    "\n",
    "On veut l'incertitude sur la diagonale $D = \\sqrt{\\ell^2 + h^2}$ avec\n",
    "$\\ell = (3{,}0 \\pm 0{,}1)$ cm et $h = (2{,}2 \\pm 0{,}2)$ cm (demi-largeurs, loi uniforme).\n",
    "Exécutez la cellule et observez la méthode : c'est le modèle pour la suite."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "00f45cbf",
   "metadata": {},
   "outputs": [],
   "source": [
    "l_tirages = rng.uniform(3.0 - 0.1, 3.0 + 0.1, N)\n",
    "h_tirages = rng.uniform(2.2 - 0.2, 2.2 + 0.2, N)\n",
    "D_tirages = np.sqrt(l_tirages**2 + h_tirages**2)\n",
    "\n",
    "tracer_histogramme(D_tirages, \"D\", \"cm\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d2dafddf",
   "metadata": {},
   "source": [
    "### 3.2 Célérités théoriques\n",
    "\n",
    "Données : $\\gamma = 7/5$, $R = 8{,}314$ J·K⁻¹·mol⁻¹, $M(\\mathrm{N}) = 14{,}0$ g/mol,\n",
    "$M(\\mathrm{O}) = 16{,}0$ g/mol, $M(\\mathrm{Ar}) = 39{,}9$ g/mol ;\n",
    "air sec : 78 % de N₂, 21 % de O₂, 1 % d'argon.\n",
    "\n",
    "$$c_N = \\sqrt{\\frac{RT}{M_\\mathrm{air}}} \\qquad\\qquad c_L = \\sqrt{\\gamma\\,\\frac{RT}{M_\\mathrm{air}}}$$\n",
    "\n",
    "✏️ **À COMPLÉTER** : $M_\\mathrm{air}$ (en kg/mol), puis les tirages de $c_N$ et $c_L$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7dc40aea",
   "metadata": {},
   "outputs": [],
   "source": [
    "T_celsius = 21.0      # °C — mesurée\n",
    "delta_T = 0.5         # °C — demi-largeur (notice du thermomètre)\n",
    "\n",
    "R = 8.314\n",
    "gamma = 7 / 5\n",
    "M_air = ...           # ✏️ (kg/mol)\n",
    "\n",
    "T_tirages = rng.uniform(T_celsius - delta_T, T_celsius + delta_T, N) + 273.15   # K\n",
    "cN_tirages = ...      # ✏️\n",
    "cL_tirages = ...      # ✏️\n",
    "\n",
    "cN, u_cN = np.mean(cN_tirages), np.std(cN_tirages, ddof=1)\n",
    "cL, u_cL = np.mean(cL_tirages), np.std(cL_tirages, ddof=1)\n",
    "print(f\"M_air = {M_air * 1e3:.2f} g/mol\")\n",
    "print(f\"Newton  : c_N = ({ecrire(cN, u_cN)}) m/s\")\n",
    "print(f\"Laplace : c_L = ({ecrire(cL, u_cL)}) m/s\")\n",
    "tracer_histogramme(cL_tirages, \"c_L\", \"m/s\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a784712f",
   "metadata": {},
   "source": [
    "**Question.** L'incertitude sur $c_L$ est très petite. Toutes les sources d'écart entre\n",
    "le modèle et la réalité sont-elles prises en compte ?"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e17dd648",
   "metadata": {},
   "source": [
    "> ✏️ *Votre réponse :*\n",
    ">\n",
    "> "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7b48925f",
   "metadata": {},
   "source": [
    "### 3.3 Le verdict\n",
    "\n",
    "Le tableau ci-dessous calcule tous les écarts normalisés. Rien à compléter si\n",
    "`ecart_normalise` est correcte."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3ba095ea",
   "metadata": {},
   "outputs": [],
   "source": [
    "resultats = {\n",
    "    \"c1 (phase)\": (c1, u_c1),\n",
    "    \"c2 (temps de vol)\": (c2, u_c2),\n",
    "    \"c_L (Laplace)\": (cL, u_cL),\n",
    "    \"c_N (Newton)\": (cN, u_cN),\n",
    "}\n",
    "for nom, (v, u) in resultats.items():\n",
    "    print(f\"{nom:>18} : ({ecrire(v, u)}) m/s\")\n",
    "print()\n",
    "noms = list(resultats)\n",
    "for k, n1 in enumerate(noms):\n",
    "    for n2 in noms[k + 1:]:\n",
    "        if {n1, n2} == {\"c_L (Laplace)\", \"c_N (Newton)\"}:\n",
    "            continue          # comparer deux modèles entre eux n'a pas de sens\n",
    "        z = ecart_normalise(*resultats[n1], *resultats[n2])\n",
    "        verdict = \"compatibles\" if z < 2 else \"NON compatibles\"\n",
    "        print(f\"{n1:>18} / {n2:<16} z = {z:7.2f}  ->  {verdict}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "339782f2",
   "metadata": {},
   "source": [
    "**Question.** Les deux méthodes expérimentales sont-elles compatibles ? Quel modèle\n",
    "retenez-vous ? Votre mesure était-elle assez précise pour trancher ?"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d8f1be6b",
   "metadata": {},
   "source": [
    "> ✏️ *Votre réponse :*\n",
    ">\n",
    "> "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "13b8c2c2",
   "metadata": {},
   "source": [
    "---\n",
    "## Bilan\n",
    "\n",
    "En quelques phrases : quelle différence faites-vous entre une incertitude de type A\n",
    "et de type B ? Quelle source d'incertitude dominait dans chacune des deux méthodes ?\n",
    "Qu'est-ce que la régression linéaire vous a permis d'éliminer ?"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d44a5dca",
   "metadata": {},
   "source": [
    "> ✏️ *Votre réponse :*\n",
    ">\n",
    "> "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
