{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Chapitre 11 : \"L'écosystème Python\" - solutions\n",
    "\n",
    "---\n",
    "\n",
    "<table class=\"appbclp1\">\n",
    "<tr> <td style=\"font-weight: bold!;\">auteurs :</td><td style=\"text-align: left!;\">Laurent Pointal &lt;<a href=\"mailtp:laurent.pointal@limsi.fr\">laurent.pointal@limsi.fr</a>&gt; &amp; Bob Cordeau &lt;<a href=\"pycours@kordeo.eu\">pycours@kordeo.eu</a>&gt; </td> </tr>\n",
    "<tr> <td style=\"font-weight: bold!;\">licence :</td><td style=\"text-align: left!;\">Creative Commons Attribution-ShareAlike 4.0 International Public License (CC BY-SA 4.0) </td> </tr>\n",
    "<tr> <td style=\"font-weight: bold!;\">source :</td><td style=\"text-align: left!;\"><a href=\"https://github.com/lpointal/appbclp\">https://github.com/lpointal/appbclp</a></td> </tr>\n",
    "<tr> <td style=\"font-weight: bold!;\">description :</td><td style=\"text-align: left!;\">Les programmes dans ce Notebook Jupyter servent de support au livre <span style=\"font-style: italic!;\">« Python 3 - Apprendre à  programmer dans l'écosystème Python»</span>, édition Dunod, dans lequel les différentes sections sont expliquées </td> </tr>\n",
    "<tr> <td style=\"font-weight: bold!;\">url :</td><td style=\"text-align: left!;\"><a href=\"https://www.dunod.com/sciences-techniques/python-3\">https://www.dunod.com/EAN/9782100809141</a></td> </tr>\n",
    "</table>\n",
    "\n",
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo11_01"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# exo11_01\n",
    "\n",
    "import numpy as np\n",
    "\n",
    "liste = [14.0, 7.6, 11.2, 12.8, 12.5, 9.9, 14.9, 9.4, 16.9, 10.2, 14.9, 18.1, 7.3, 9.8, 10.9,12.2, 9.9, 2.9, 2.8, 15.4, 15.7, 9.7, 13.1, 13.2, 12.3, 11.7, 16.0, 12.4, 17.9, 12.2, 16.2, 18.7, 8.9, 11.9, 12.1, 14.6, 12.1, 4.7, 3.9, 16.9, 16.8, 11.3, 14.4, 15.7, 14.0, 13.6, 18.0, 13.6, 19.9, 13.7, 17.0, 20.5, 9.9, 12.5, 13.2, 16.1, 13.5, 6.3, 6.4, 17.6, 19.1, 12.8, 15.5, 16.3, 15.2, 14.6, 19.1, 14.4, 21.4, 15.1, 19.6, 21.7, 11.3, 15.0, 14.3, 16.8, 14.0, 6.8, 8.2, 19.9, 20.4, 14.6, 16.4, 18.7, 16.8, 15.8, 20.4, 15.8, 22.4, 16.2, 20.3, 23.4, 12.1, 15.5, 15.4, 18.4, 15.7, 10.2, 8.9, 21.0]\n",
    "a = np.array(liste)\n",
    "\n",
    "print(f\"moyenne {np.mean(a):.2f}\")\n",
    "print(f\"écart-type corrigé {np.std(a, ddof=1):.2f}\")\n",
    "print(f\"minimun {np.amin(a):.2f}\")\n",
    "print(f\"médiane {np.median(a):.2f}\")\n",
    "print(f\"maximun {np.amax(a):.2f}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo11_02"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# exo11_01\n",
    "\n",
    "import numpy as np\n",
    "%matplotlib inline\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "liste = [14.0, 7.6, 11.2, 12.8, 12.5, 9.9, 14.9, 9.4, 16.9, 10.2, 14.9, 18.1, 7.3, 9.8, 10.9,12.2, 9.9, 2.9, 2.8, 15.4, 15.7, 9.7, 13.1, 13.2, 12.3, 11.7, 16.0, 12.4, 17.9, 12.2, 16.2, 18.7, 8.9, 11.9, 12.1, 14.6, 12.1, 4.7, 3.9, 16.9, 16.8, 11.3, 14.4, 15.7, 14.0, 13.6, 18.0, 13.6, 19.9, 13.7, 17.0, 20.5, 9.9, 12.5, 13.2, 16.1, 13.5, 6.3, 6.4, 17.6, 19.1, 12.8, 15.5, 16.3, 15.2, 14.6, 19.1, 14.4, 21.4, 15.1, 19.6, 21.7, 11.3, 15.0, 14.3, 16.8, 14.0, 6.8, 8.2, 19.9, 20.4, 14.6, 16.4, 18.7, 16.8, 15.8, 20.4, 15.8, 22.4, 16.2, 20.3, 23.4, 12.1, 15.5, 15.4, 18.4, 15.7, 10.2, 8.9, 21.0]\n",
    "a = np.array(liste)\n",
    "\n",
    "plt.plot(a)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plt.hist(a)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo11_03"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# exo11_03\n",
    "\n",
    "# Import ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n",
    "import math\n",
    "\n",
    "# Globales ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n",
    "b = math.sqrt(89)  # x max pour BG = (4 * BC)/5 = 8\n",
    "a = math.sqrt(29)  # x min pour BG = BC/5 = 2\n",
    "\n",
    "# Définition de fonction ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n",
    "def f(x):\n",
    "    \"\"\"aire_broutée(x) - moitié de l'aire du champ.\"\"\"\n",
    "\n",
    "    # Angles\n",
    "    beta = math.acos(5/x)\n",
    "    alpha = math.pi - (2 * beta)\n",
    "    \n",
    "    # Aire du demi disque de rayon x\n",
    "    aire_dd = math.pi * x**2 / 2\n",
    "    \n",
    "    # Aire du segment circulaire d'angle AEF et de rayon x\n",
    "    aire_sc = (alpha  * x**2 / 2) - (x**2 * math.sin(beta) / 2)\n",
    "    \n",
    "    # Aire broutée\n",
    "    aire_broutee = aire_dd - aire_sc\n",
    "    \n",
    "    return aire_broutee - 50\n",
    "\n",
    "# Programme principal =========================================================\n",
    "eps = float(input(\"\\nprécision : \"))\n",
    "\n",
    "while (b - a) > eps:\n",
    "    m = (a + b) / 2\n",
    "    if f(a) * f(m) <= 0:\n",
    "        b = m\n",
    "    else:\n",
    "        a = m\n",
    "\n",
    "## Affichage avec la précision de eps\n",
    "print(f\"Longueur de la corde : {round(m, int(-math.log10(eps)))} m\")\n",
    "\n",
    "\"\"\"\n",
    "Exemples d'exécution :\n",
    "\n",
    "précision : 0.01\n",
    "Longueur de la corde : 6.8 m\n",
    "\n",
    "précision : 0.001\n",
    "Longueur de la corde : 6.796 m\n",
    "\n",
    "précision : 1e-4\n",
    "Longueur de la corde : 6.7958 m\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo11_04"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# exo11_04 - module\n",
    "\n",
    "# import\n",
    "from math import cos, atan2, hypot\n",
    "\n",
    "# fonction\n",
    "def fonctionPol(theta):\n",
    "    \"\"\"Retourne le rayon polaire correspondant a l'angle <theta>.\"\"\"\n",
    "    return cos(3 * theta) ** 2\n",
    "\n",
    "def dedans(fonction, point):\n",
    "    \"\"\"Retourne 'True' si <point> est dans <fonction>, 'False' sinon.\"\"\"\n",
    "    # on retrouve l'angle et le rayon correspondants au point\n",
    "    rho = hypot(point[0], point[1])\n",
    "    theta = atan2(point[1], point[0])\n",
    "    # et on teste simplement le rayon du point par rapport à celui de la courbe\n",
    "    return rho <= fonction(theta)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# exo11_04 - programme principal\n",
    "\n",
    "# programme principal ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n",
    "p1 = (0., 0.)\n",
    "print(f\"Le point {p1} est dans la courbe : {dedans(fonctionPol, p1)}\")\n",
    "\n",
    "p2 = (0., 0.1)\n",
    "print(f\"Le point {p2} est dans la courbe : {dedans(fonctionPol, p2)}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo11_05"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# exo11_05 - module\n",
    "\n",
    "# import\n",
    "from math import sin, cos, atan2, hypot\n",
    "\n",
    "# fonction\n",
    "def fonctionPol(theta):\n",
    "    \"\"\"Retourne le rayon polaire correspondant a l'angle <theta>.\"\"\"\n",
    "    return sin(2 * theta) ** 2 + 2 * cos(3 * theta) ** 2\n",
    "\n",
    "def dedans(fonction, point):\n",
    "    \"\"\"Retourne 'True' si <point> est dans <fonction>, 'False' sinon.\"\"\"\n",
    "    # on retrouve l'angle et le rayon correspondants au point\n",
    "    rho = hypot(point[0], point[1])\n",
    "    theta = atan2(point[1], point[0])\n",
    "    # et on teste simplement le rayon du point par rapport à celui de la courbe\n",
    "    return rho <= fonction(theta)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# exo11_05 - programme principal\n",
    "\n",
    "# programme principal ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n",
    "p1 = (0., 0.)\n",
    "print(f\"Le point {p1} est dans la courbe : {dedans(fonctionPol, p1)}\")\n",
    "\n",
    "p2 = (0., 0.1)\n",
    "print(f\"Le point {p2} est dans la courbe : {dedans(fonctionPol, p2)}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo11_06"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# exo11_06\n",
    "\n",
    "# import ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n",
    "from math import log10\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "# définition de fonction ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n",
    "def benford(n):\n",
    "    return log10(n+1) - log10(n)\n",
    "\n",
    "# programme principal ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n",
    "X = list(range(1, 10))\n",
    "Y = [benford(i) for i in X]\n",
    "\n",
    "plt.bar(X, Y)\n",
    "plt.xticks(X)\n",
    "plt.title(\"Loi de Benford\")\n",
    "plt.xlabel(\"Nombre\")\n",
    "plt.ylabel(\"Fréquence\")\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo11_07"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# exo11_07\n",
    "\n",
    "# Import ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n",
    "from math import hypot, pi\n",
    "from random import uniform\n",
    "\n",
    "# Définition de fonction ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n",
    "def dedans(N):\n",
    "    n = 0\n",
    "    for i in range(N):\n",
    "        x, y = uniform(-1, 1), uniform(-1, 1)\n",
    "        if hypot(x, y) < R:\n",
    "            n += 1\n",
    "    return n\n",
    "\n",
    "# Programme principal =========================================================\n",
    "R = 1  # rayon du cercle inscrit\n",
    "for N in [1_000, 10_000, 100_000]:\n",
    "    n = dedans(N)\n",
    "    approx = 4 * n / N\n",
    "    print(f\"Pour {N} tirages,\", end='')\n",
    "    print(f\"approximation de pi : {approx:.5f}. \", end='')\n",
    "    print(f\"Erreur relative : {abs(pi - approx) / pi:.3%}\")"
   ]
  }
 ],
 "metadata": {
  "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.7.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
