{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Chapitre 6 : \"Modules et packages\" - 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": [
    "### exo06_01"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# exo06_01 - module\n",
    "from math import pi, sin, cos, hypot\n",
    "\n",
    "def rTest(theta):\n",
    "    \"Simple fonction sinus pour tester.\"\n",
    "    return math.sin(theta)\n",
    "\n",
    "def listePoints(pol, theta_ini, theta_fin, nb):\n",
    "    \"Échantillonage de la fonction pol().\"\n",
    "    dtheta = (theta_fin - theta_ini) / nb # calcul du pas\n",
    "    lst = []\n",
    "    for i in range(nb + 1):  # boucle pour nb+1 points\n",
    "        theta = theta_ini + i * dtheta\n",
    "        # calcul des coordonnées d'un point:\n",
    "        x = pol(theta) * cos(theta)\n",
    "        y = pol(theta) * sin(theta)\n",
    "        lst.append((x, y))\n",
    "    return lst\n",
    "    \n",
    "def dMax(lstpts):\n",
    "    \"Coordonnées des deux points les plus éloignés.\"\n",
    "    # on ne contrôle pas, mais la courbe doit avoir au moins\n",
    "    # deux points\n",
    "    # valeur de départ\n",
    "    x1_max, y1_max = lstpts[0][0], lstpts[0][1]\n",
    "    x2_max, y2_max = lstpts[1][0], lstpts[1][1]\n",
    "    d_max = hypot(x2_max-x1_max, y2_max-y1_max)\n",
    "    # boucle de parcours, pour chaque point de la courbe, sauf\n",
    "    # le dernier, on parcours tous les points qui le suivent\n",
    "    for i in range(len(lstpts)-1):\n",
    "        x1 , y1 = lstpts[i][0], lstpts[i][1]\n",
    "        for j in range(i, len(lstpts)):\n",
    "            # à chaque fois on calcule la distance, et si on\n",
    "            # a trouvé une nouvelle distance max, on la mémorise\n",
    "            x2 , y2 = lstpts[j][0], lstpts[j][1]\n",
    "            d = hypot(x2-x1, y2-y1)\n",
    "            if d > d_max:\n",
    "                x1_max, y1_max = x1, y1\n",
    "                x2_max, y2_max = x2, y2\n",
    "                d_max = d\n",
    "    # points les plus éloignés trouvés\n",
    "    return (x1_max, y1_max), (x2_max, y2_max)\n",
    "\n",
    "\n",
    "points = listePoints(rTest, 0, pi/4, 4)\n",
    "x, y = dMax(points)\n",
    "print(\"Points les plus éloignes : ({:g}, {:g}) et ({:g}, {:g})\".format(*x, *y))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# exo06_01 - programme principal\n",
    "\n",
    "# fonction\n",
    "def eqpol(theta):\n",
    "    return theta * sin(theta / 2)\n",
    "\n",
    "# programme principal -----------------------------------------------\n",
    "pts = listePoints(eqpol, 0, 2 * pi, 180)\n",
    "print(\"Points les plus éloignés : {}\".format(dMax(pts)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo06_02"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# exo06_02 - module\n",
    "\n",
    "# import ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n",
    "from random import randint\n",
    "from math import hypot\n",
    "\n",
    "# fonction ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n",
    "def creaPolyg(n) :\n",
    "    res = []\n",
    "    for i in range(n) :\n",
    "        res.append((randint(-10,10),randint(-10,10)))\n",
    "    return res\n",
    "\n",
    "def dmaxPolyg(pol) :\n",
    "    res = 0\n",
    "    for i in range(len(pol)-1) :\n",
    "        for j in range(i+1, len(pol)) :\n",
    "            d = hypot(pol[i][0]-pol[j][0], pol[i][1]-pol[j][1])\n",
    "            if d > res :\n",
    "                res = d\n",
    "    return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# exo06_02 - programme principal\n",
    "\n",
    "# programme principal ===============================================\n",
    "print (\"\\tPremier essai :\")\n",
    "p = [[0.0, 0.0], [0.0, 3.0], [4.0, 0.0]]\n",
    "print (\"Polygone de sommets : \",p)\n",
    "print (f\"Distance maximum d'un sommet a un autre : {dmaxPolyg(p):.2f}\")\n",
    "\n",
    "print (\"\\n\\tSecond essai :\")\n",
    "p = creaPolyg(5)\n",
    "print (\"Polygone de sommets : \", p)\n",
    "print (\"Distance maximum d'un sommet a un autre : {dmaxPolyg(p):.2f}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo06_03"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# exo06_03 - module\n",
    "\n",
    "# imports\n",
    "from random import randint\n",
    "\n",
    "# fonctions\n",
    "def creaListe(n) :\n",
    "    res = []\n",
    "    for i in range(n) :\n",
    "        res.append(randint(0, 20)/4)\n",
    "    return res\n",
    "\n",
    "def estTriangle(t) :\n",
    "    \"Retourne vrai si t contient 3 longueurs de côtés pouvant constituer un triangle\"\n",
    "    # cas d'un côté ne pouvant pas être une mesure d'un segment (non nul)\n",
    "    a, b, c = t\n",
    "    if a <= 0 or b <= 0 or c <= 0:\n",
    "        return False\n",
    "    # règle que le plus grand côté doit être inférieur ou égal à la somme\n",
    "    # des deux autres\n",
    "    cotes = sorted(t)\n",
    "    return cotes[2] <= (cotes[0] + cotes[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# exo06_02 - programme principal\n",
    "\n",
    "# programme principal -----------------------------------------------\n",
    "print (\"\\tPremier essai :\")\n",
    "t = [13, 4, 10]\n",
    "if estTriangle(t) :\n",
    "    print (t, \" est un triangle.\")\n",
    "else :\n",
    "    print (t, \" n'est pas un triangle.\")\n",
    "\n",
    "print (\"\\n\\tDeuxieme essai :\")\n",
    "t = [13, 4, 1]\n",
    "if estTriangle(t) :\n",
    "    print (t, \" est un triangle.\")\n",
    "else :\n",
    "    print (t, \" n'est pas un triangle.\")\n",
    "   \n",
    "print (\"\\n\\tTroisieme essai :\")\n",
    "t = creaListe(3)\n",
    "if estTriangle(t) :\n",
    "    print (t, \" est un triangle.\")\n",
    "else :\n",
    "    print (t, \" n'est pas un triangle.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo06_04"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# exo06_04 - module\n",
    "\n",
    "# imports\n",
    "from random import randint\n",
    "\n",
    "# fonctions\n",
    "def creaVec(n) :\n",
    "    \"Création d'un vecteur aléatoire de n coordonnées\"\n",
    "    return [randint(-20, 20)/2 for i in range(n)]\n",
    "\n",
    "def prodScal(u, v) :\n",
    "    \"Calcul du produit scalaire entre u et v\"\n",
    "    return sum([u[i] * v[i] for i in range(len(u))])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# exo06_04 - programme principal\n",
    "\n",
    "# programme principal -----------------------------------------------\n",
    "print (\"\\tTest 1 :\")\n",
    "u = [1.5 , 3.0 , 0.5]\n",
    "v = [2.0 , 0.0 , 2.0]\n",
    "print(u, \"x\", v)\n",
    "print (\"Le produit scalaire est :\", prodScal(u, v))\n",
    "\n",
    "print (\"\\n\\tTest 2 :\")\n",
    "u = [-1, 1]\n",
    "v = [1, 1]\n",
    "print(u, \"x\", v)\n",
    "print (\"Le produit scalaire est :\", prodScal(u, v))\n",
    "\n",
    "print (\"\\n\\tTest 3 :\")\n",
    "u, v = creaVec(2), creaVec(2)\n",
    "print(u, \"x\", v)\n",
    "print (\"Le produit scalaire est :\", prodScal(u, v))\n",
    "\n",
    "print (\"\\n\\tTest 4 :\")\n",
    "u, v = creaVec(3), creaVec(3)\n",
    "print(u, \"x\", v)\n",
    "print (\"Le produit scalaire est :\", prodScal(u, v))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo06_05"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# exo06_05 - module\n",
    "\n",
    "# imports\n",
    "from random import randint\n",
    "\n",
    "# fonctions\n",
    "def creaVec(n):\n",
    "    \"Création d'un vecteur aléatoire de n coordonnées\"\n",
    "    res = []\n",
    "    for i in range(n) :\n",
    "        res.append(randint(-20, 20)/2)\n",
    "    return res\n",
    "\n",
    "def prodVec(u,v):\n",
    "    \"Calcul du produit vectoriel entre u et v\"\n",
    "    rx = u[1]*v[2] - u[2]*v[1]\n",
    "    ry = u[2]*v[0] - u[0]*v[2]\n",
    "    rz = u[0]*v[1] - u[1]*v[0]\n",
    "    return [rx, ry, rz]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# exo06_05 - programme principal\n",
    "\n",
    "# programme principal -----------------------------------------------\n",
    "print (\"\\tPremier essai :\")\n",
    "u = [1.5 , 3.0 , 0.5]\n",
    "v = [2.0 , 0.0 , 2.0]\n",
    "print (\"Le produit vectoriel est :\", prodVec(u, v))\n",
    "\n",
    "print (\"\\n\\tDeuxieme essai :\")\n",
    "u = [1.5 , 3.0 , 0.5]\n",
    "v = [4.5 , 9.0 , 1.5]\n",
    "print (\"Le produit vectoriel est :\", prodVec(u, v))\n",
    "\n",
    "print (\"\\n\\tTroisieme essai :\")\n",
    "u = creaVec(3)\n",
    "v = creaVec(3)\n",
    "print (\"Le produit vectoriel est :\", prodVec(u, u))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo06_06"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# exo06_06 - module\n",
    "\n",
    "# procedure\n",
    "def table(base, debut, fin, inc):\n",
    "    \"\"\"Affiche la table des <base>, de <debut> a <fin>, de <inc> en <inc>.\"\"\"\n",
    "    n = debut\n",
    "    while n <= fin:\n",
    "        print(n, 'x', base, '=', n*base)\n",
    "        n = n + inc"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# exo06_06 - programme principal\n",
    "\n",
    "# programme principal -----------------------------------------------\n",
    "table(7, 2, 13, 2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo06_07"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# exo06_07 - module\n",
    "\n",
    "# fonctions\n",
    "def maFonction(x):\n",
    "    return 2 * x ** 3 + x - 5\n",
    "\n",
    "def tabuler(fonction, borneInf, borneSup, nbPas):\n",
    "    \"\"\"\n",
    "    Affiche les valeurs de <fonction>.\n",
    "    On doit avoir : (borneInf < borneSup) ET (nbPas > 0).\n",
    "    \"\"\"\n",
    "    h = (borneSup - borneInf) / float(nbPas)\n",
    "    x = borneInf\n",
    "    while x <= borneSup:\n",
    "        y = fonction(x)\n",
    "        print(f\"f({x:.2f}) = {y:.3f}\")\n",
    "        x += h"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# exo06_07 - programme principal\n",
    "\n",
    "# programme principal -----------------------------------------------\n",
    "a = float(input(\"Borne inférieure : \"))\n",
    "b = float(input(\"Borne superieure : \"))\n",
    "n = int(input(\"Nombre de pas : \"))\n",
    "\n",
    "tabuler(maFonction, a, b, n)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo06_08"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# exo06_08 - module\n",
    "from math import pi\n",
    "\n",
    "# fonction\n",
    "def volMasseEllipsoide(a=0.5, b=0.5, c=0.5, rho=1.0):\n",
    "    \"\"\"Retourne le volume et la masse d'un ellipsoide de demi-axes <a>, <b>, <c> et de densite <rho>.\"\"\"\n",
    "    vol = pi * a * b * c * 4 / 3\n",
    "    mas = vol * rho\n",
    "    return (vol, mas)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# exo06_08 - programme principal\n",
    "\n",
    "# programme principal -----------------------------------------------\n",
    "aa = float(input(\"demi-axe a : \"))\n",
    "bb = float(input(\"demi-axe b : \"))\n",
    "cc = float(input(\"demi-axe c : \"))\n",
    "dens = float(input(\"densité : \"))\n",
    "\n",
    "v, m = volMasseEllipsoide(aa, bb, cc, dens)\n",
    "print(f\"volume = {v:.2f} \\t masse = {m:.2f}\")\n",
    "print('-'*40)\n",
    "v, m = volMasseEllipsoide()\n",
    "print(f\"volume = {v:.2f} \\t masse = {m:.2f}\")\n",
    "print('-'*40)\n",
    "v, m = volMasseEllipsoide(rho=dens, b=bb)\n",
    "print(f\"volume = {v:.2f} \\t masse = {m:.2f}\")\n",
    "print('-'*40)\n",
    "v, m = volMasseEllipsoide()\n",
    "print(f\"volume = {v:.2f} \\t masse = {m:.2f}\")\n",
    "print('-'*40)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo06_09"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# exo06_09 - module\n",
    "\n",
    "# fonction\n",
    "def convert(mph):\n",
    "    \"\"\"Retourne <vitesse> en m/s et en km/h.\"\"\"\n",
    "    mps = mph * 1609 / 3600 # conversion en m/s\n",
    "    kmph = mph * 1.609      # conversion en km/h\n",
    "    return (mps, kmph)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# exo06_09 - programme principal\n",
    "\n",
    "# programme principal -----------------------------------------------\n",
    "print(convert(2.8))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo06_10"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# exo06_10 - module\n",
    "\n",
    "# import\n",
    "from random import randrange\n",
    "\n",
    "# fonction\n",
    "def deuxNombres():\n",
    "    \"\"\"Renvoie une saisie et un entier aleatoire.\"\"\"\n",
    "    n1 = randrange(101)\n",
    "    n2 = int(input(\"Votre nombre [0 .. 100] : \"))\n",
    "    while not(0 < n2 < 100):\n",
    "        n2 = int(input(\"Votre nombre [0 .. 100], SVP : \"))\n",
    "    \n",
    "    return (n1, n2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# exo06_10 - programme principal\n",
    "\n",
    "# programme principal -----------------------------------------------\n",
    "(a, b) = deuxNombres()\n",
    "print(\"\\nTirage au hazard :\", a)\n",
    "if b > a:\n",
    "    print(\"\\nVotre nombre est le plus grand\")\n",
    "elif b < a:\n",
    "    print(\"\\nVotre nombre est le plus petit\")\n",
    "else:\n",
    "    print(\"\\nLes deux nombres sont egaux\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo06_11"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# exo06_11 - module\n",
    "\n",
    "# fonction\n",
    "def afficheListe(liste):\n",
    "    \"\"\"Affiche les éléments et leur longueur.\"\"\"\n",
    "    for el in liste:\n",
    "        print(el, len(el))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# exo06_11 - programme principal\n",
    "\n",
    "# programme principal -----------------------------------------------\n",
    "mon_tuple = ('Jean-Michel', 'Marc', 'Maximilien', 'Alexandre-Benoît', 'Louise', 'Vanessa')\n",
    "afficheListe(mon_tuple)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo06_12"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# exo06_12 - module\n",
    "\n",
    "# Import ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n",
    "from random import seed, random\n",
    "\n",
    "# Définition de fonction ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n",
    "def listAleaFloat(n):\n",
    "    \"Retourne une liste de <n> flottants aléatoires\"\n",
    "    lst = []\n",
    "    for i in range(n):\n",
    "        lst.append(random() * 500)\n",
    "    return lst"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# exo06_12 - programme principal\n",
    "\n",
    "# Programme principal =========================================================\n",
    "n = int(input(\"Entrez un entier [2 .. 100] : \"))\n",
    "while not(n >= 2 and n <= 100):\n",
    "    n = int(input(\"Entrez un entier [2 .. 100], s.v.p. : \"))\n",
    "\n",
    "seed()                # initialise le générateur de nombres aléatoires\n",
    "t = listAleaFloat(n)  # construction de la liste\n",
    "\n",
    "print(f\"Amplitude : {max(t) - min(t):.2f}\")\n",
    "print(f\"Moyenne : {sum(t)/n:.2f}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo06_13"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# exo06_13 - module\n",
    "\n",
    "# Définition de fonction ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n",
    "def minMaxMoy(liste):\n",
    "    \"\"\"Renvoie le min, le max et la moyenne de la liste.\"\"\"\n",
    "    mini, maxi, som = liste[0], liste[0], liste[0]\n",
    "    for v in liste[1:]:\n",
    "        if v < mini:\n",
    "            mini = v\n",
    "        if v > maxi:\n",
    "            maxi = v\n",
    "        som += v\n",
    "    return mini, maxi, som / len(liste)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# exo06_13 - programme principal\n",
    "\n",
    "# Programme principal =========================================================\n",
    "lp = [10, 18, 14, 20, 12, 16]\n",
    "\n",
    "print(\"liste =\", lp)\n",
    "L = minMaxMoy(lp)\n",
    "print(f\"min : {L[0]}, max : {L[1]}, moy : {L[2]}\")"
   ]
  }
 ],
 "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": 2
}
