{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Chapitre 3 : \"Contrôle du flux d’instructions\"\n",
    "\n",
    "### <span class=\"bg-info\">« *Un programme sans boucle et sans structure de données ne vaut pas la peine d'être écrit.* »</span>\n",
    "\n",
    "Alan Jay Perlis $-$ Epigrams on Programming\n",
    "\n",
    "***"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### <span class=\"bg-success\">CE QU'IL FAUT RETENIR</span>\n",
    "\n",
    "- Instruction composée : un en-tête terminé par le caractère \"deux-points\", puis un bloc d'instructions indenté :\n",
    "    - *choisir* : `if [elif] [else]` ;\n",
    "    - *répéter* : la boucle `while` ;\n",
    "    - *parcourir* : la boucle `for`.\n",
    "- La *saisie filtrée* avec `while`.\n",
    "- Ruptures de flux : `break` et `continue`.\n",
    "- Gestion des erreurs : les exceptions.\n",
    "\n",
    "***"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo03_01 ✓\n",
    "Écrire un script qui détermine si une chaîne contient ou non le caractère `\"e\"`. Affichez son nombre d'occurrences.\n",
    "\n",
    "Utilisez une *boucle while*."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo03_01\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo03_02 ✓\n",
    "Écrire un script qui recopie une chaîne en insérant un astérisque entre ses caractères.\n",
    "\n",
    "Utilisez une *boucle while*.\n",
    "\n",
    "Par exemple `\"Gaston\"` deviendra `\"G*a*s*t*o*n\"`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo03_02\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo03_03  ✓✓\n",
    "Écrire un script qui recopie une chaîne en l'inversant et qui indique si elle est un palindrome.\n",
    "Utilisez une *boucle while*.\n",
    "\n",
    "Un [palindrome](https://fr.wikipedia.org/wiki/Palindrome) est un texte dont l'ordre des lettres permet  de le lire identiquement de gauche à droite ou de droite à gauche. Par exemple :\n",
    "\n",
    "chaîne de départ | chaîne transformée | palindrome ?\n",
    ":-: | :-: | :-:\n",
    "`\"zorglub\"` | `\"bulgroz\"` | `non`\n",
    "`\"radar\"` | `\"radar\"` | `oui`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo03_03\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo03_04 ✓\n",
    "Saisir une phrase (par exemple cet énoncé) et afficher le mot le plus long qu'elle contient."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo03_04\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo03_05 ✓✓✓\n",
    "Le programme suivant affiche les 8 premiers termes de la suite de Fibonacci, dont chaque terme est égal à la somme des deux précédents :\n",
    "\n",
    "```python\n",
    "a, b, c = 1, 1, 1\n",
    "while c < 9:\n",
    "    print b,\n",
    "    a, b, c = b, a+b, c+1\n",
    "```\n",
    "\n",
    "Pour bien comprendre le fonctionnement de cette boucle, ajouter à ce script l'affichage des valeurs permettant de construire **la table d'état** suivante :\n",
    "\n",
    "variable | `a` | `b` | `c`\n",
    ":- | :- | :- | :-\n",
    "valeur initiale | 1 | 1 | 1\n",
    "valeur au tour suivant | ... | ... | ...\n",
    "valeur au tour suivant | ... | ... | ...\n",
    "... | ... | ... | ..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo03_05\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo03_06 ✓\n",
    "À l'aide d'une boucle, écrire un script qui affiche sur une ligne une suite de 12 nombres dont chaque terme soit égal au triple du terme précédent."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo03_06\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo03_07 ✓\n",
    "Écrire un script qui calcule les 50 premiers termes de la table de multiplication par 13, mais n'affiche que les termes qui sont multiples de 7."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo03_07\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo03_08 ✓\n",
    "Écrire un script qui saisit des nombres et les stocke sous forme de flottants dans une liste, jusqu'à terminer par la saisie d'une chaîne vide en appuyant sur **`Entrée`**.  \n",
    "Afficher la liste résultante."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo03_08\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo03_09 ✓\n",
    "Écrire un script qui saisit deux bornes entières `a` et `b`, avec `a < b` (utiliser une *saisie filtrée*).\n",
    "\n",
    "Afficher la somme des nombres multiples de 3 et de 5 strictement compris entre ces bornes.\n",
    "\n",
    "Puis afficher la somme des nombres multiples de 3 ou de 5."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo03_09\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo03_10 ✓✓\n",
    "Écrire un script qui affiche, à l'aide de boucles, la suite de symboles suivante :\n",
    "\n",
    "```text\n",
    "*\n",
    "**\n",
    "***\n",
    "****\n",
    "*****\n",
    "******\n",
    "*******\n",
    "********\n",
    "*********\n",
    "**********\n",
    " *********\n",
    "  ********\n",
    "   *******\n",
    "    ******\n",
    "     *****\n",
    "      ****\n",
    "       ***\n",
    "        **\n",
    "         *\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo03_10\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo03_11 ✓✓\n",
    "Écrire un script qui affiche, à l'aide de boucles, la suite de symboles suivante :\n",
    "\n",
    "```text\n",
    "*                  *\n",
    "**                **\n",
    "***              ***\n",
    "****            ****\n",
    "*****          *****\n",
    "******        ******\n",
    "*******      *******\n",
    "********    ********\n",
    "*********  *********\n",
    "********************\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo03_11\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo03_12 ✓✓\n",
    "Écrire un script qui affiche, à l'aide de boucles, la suite de symboles suivante :\n",
    "\n",
    "```text\n",
    "********************\n",
    "*********  *********\n",
    "********    ********\n",
    "*******      *******\n",
    "******        ******\n",
    "*****          *****\n",
    "****            ****\n",
    "***              ***\n",
    "**                **\n",
    "*                  *\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo03_12\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo03_13 ✓✓\n",
    "\n",
    "Écrire un script qui affiche, à l'aide de boucles, la suite de symboles suivante :\n",
    "\n",
    "```text\n",
    "********************\n",
    "*********  *********\n",
    "********    ********\n",
    "*******      *******\n",
    "******        ******\n",
    "*****          *****\n",
    "****            ****\n",
    "***              ***\n",
    "**                **\n",
    "*                  *\n",
    "**                **\n",
    "***              ***\n",
    "****            ****\n",
    "*****          *****\n",
    "******        ******\n",
    "*******      *******\n",
    "********    ********\n",
    "*********  *********\n",
    "********************\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo03_13\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo03_14 ✓✓\n",
    "Que fait le programme ci-dessous, dans les quatre cas où l'on aurait défini au préalable que la variable `a` vaut 1, 2, 3 ou 15 ?\n",
    "\n",
    "```python\n",
    "if a != 2:\n",
    "    print('perdu')\n",
    "elif a == 3:\n",
    "    print('un instant, s.v.p.')\n",
    "else :\n",
    "    print('gagné’)\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo03_14\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo03_15 ✓✓\n",
    "Écrire un programme qui, étant données deux bornes entières `a` et `b`, additionne les nombres à la fois multiples de 3 et de 5 compris entre ces bornes.\n",
    "\n",
    "Pour, par exemple, `a = 0`, `b = 32`, on obtient : `0 + 15 + 30 = 45`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo03_15\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo03_16 ✓\n",
    "Écrire une boucle qui demande à l'utilisateur d'entrer des notes d'élèves. La boucle se terminera quand la saisie sera négative.\n",
    "\n",
    "Avec les notes ainsi entrées, construire progressivement une liste. Après chaque entrée d'une nouvelle note (et donc à chaque itération de la boucle), afficher la moyenne de toutes les notes déjà disponibles."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo03_16\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo03_17 ✓\n",
    "Écrire un script qui génère, à l'aide de boucles, la liste des carrés et des cubes des nombres de 20 à 40."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo03_17\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo03_18 ✓✓\n",
    "Écrire un script qui fasse saisir deux entiers `p` et `q`, puis qui affiche tous les couples `(x, y)`, `x` étant un entier compris entre `1` et `p` et `y` un entier compris entre `1` et `q`. \n",
    "\n",
    "L’affichage doit se faire comme sur l’exemple suivant, qui correspond à `p = 3` et `q = 5` :\n",
    "\n",
    "```python\n",
    "(1, 1)  (1, 2)  (1, 3)  (1, 4)  (1, 5) \n",
    "(2, 1)  (2, 2)  (2, 3)  (2, 4)  (2, 5) \n",
    "(3, 1)  (3, 2)  (3, 3)  (3, 4)  (3, 5)\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo03_18\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo03_19 ✓✓\n",
    "Écrire un script qui fasse saisir deux chaînes `s` et `t`, puis qui affiche tous les couples `xy`, où `x` est un caractère de `s` et `y` est un caractère de `t`.\n",
    "\n",
    "Exemple d’exécution avec `s = \"XYZ\"` et `t = \"abcde\"` :\n",
    "\n",
    "```python\n",
    "Xa  Xb  Xc  Xd  Xe \n",
    "Ya  Yb  Yc  Yd  Ye \n",
    "Za  Zb  Zc  Zd  Ze  \n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo03_19\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo03_20 ✓✓\n",
    "Écrire un script qui fasse saisir deux entiers `p` et `q`, puis qui affiche tous les couples `(x, y)`, `x` étant un entier compris entre `1` et `p` et `y` un entier compris entre `1` et `q`, **vérifiant `x ≤ y`**.\n",
    "\n",
    "L’affichage doit se faire comme sur l’exemple suivant, qui correspond à `p = 4` et `q = 6` :\n",
    "\n",
    "```python\n",
    "(1, 1)  (1, 2)  (1, 3)  (1, 4)  (1, 5)  (1, 6) \n",
    "(2, 2)  (2, 3)  (2, 4)  (2, 5)  (2, 6) \n",
    "(3, 3)  (3, 4)  (3, 5)  (3, 6) \n",
    "(4, 4)  (4, 5)  (4, 6) \n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo03_20\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo03_21 ✓\n",
    "\n",
    "Écrire un script permettant de saisir un entier positif $n$ (utiliser la *saisie filtrée*) et d'afficher `PAIR` si $n$ est divisible par 2, `IMPAIR` sinon."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo03_21"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo03_22 ✓✓\n",
    "\n",
    "Écrire un script qui fasse saisir deux mots et les compare pour trouver le premier selon l'ordre lexicographique, puis afficher le résultat. Mettre en place une *saisie filtrée* assurant qu'il n'y a pas d'accent et que tous les caractères sont en minuscule).\n",
    "\n",
    "**Rappel :** L’*ordre lexicographique* est celui du dictionnaire (les langues naturelles recèlent de nombreux pièges d'où la simplification dans l'exercice !)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo03_22"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo03_23 ✓✓\n",
    "On désire contrôler une enceinte pressurisée.\n",
    "\n",
    "Le constructeur a fixé une pression seuil (pSeuil = 2,23 × 10<sup>5</sup> Pa) et un volume seuil (vSeuil = 7,41 m<sup>3</sup>).\n",
    "\n",
    "Saisir la pression et le volume courants de l’enceinte et simuler le comportement suivant :\n",
    "\n",
    "- si le volume et la pression sont supérieurs aux seuils alors on affiche `\"Arrêt immédiat\"` ;\n",
    "- si seule la pression est supérieure à la pression seuil, le script demande d’augmenter le volume de l’enceinte ;\n",
    "- si seul le volume est supérieur au volume seuil, le script demande de diminuer le volume de l’enceinte ;\n",
    "- sinon le script affiche `\"fonctionnement nominal\"`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo03_23"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo03_24 ✓\n",
    "Créer un script qui affiche, dans une boucle `for` de 1 à 27 compris, les entiers impairs supérieure à 10. Utiliser l’instruction `break` pour interrompre la boucle afin de ne pas dépasser 20."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo03_24"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo03_25 ✓\n",
    "Créer un script qui affiche, dans une bouche `for` variant de 0 à 14, les indices pairs sauf ceux plus grands que 3 et plus petits que 9. Utiliser l’instruction `continue` pour passer les cas inintéressants."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo03_25"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo03_26 ✓✓\n",
    "Afficher, dans une boucle évoluant par valeur entière de $x = -7$ à $x = 7$ compris, la valeur du sinus cardinal : $$sinc(x) = \\frac{\\sin{\\pi.x}}{\\pi.x}$$\n",
    "\n",
    "Traiter l'exception produite par le cas particulier $x=0$ en faisant afficher $1$.\n",
    "\n",
    "**Note** : $sinc(0) = 1$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo03_26"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo03_27 ✓\n",
    "**Devinez un nombre !**\n",
    "\n",
    "L'ordinateur tire un entier aléatoire, la *cible*, dans l'intercalle [1, 100].\n",
    "\n",
    "Dans une boucle, l'utilisateur propose un nombre et l'ordinateur indique si la cible est plus grande ou plus petite. Essayez de deviner la cible en un nombre minimum d'essais.\n",
    "\n",
    "**Conseil :** Utiliser le concept de la *dichotomie* pour réduire l'intervalle de recherche. L'idée est de proposer le nombre demi somme de l'intervalle de recherche. Si, par exemple, la cible vaut 73, l'utilisateur propose en premier `(0 +100) / 2 = 50`. Si l'ordinateur répond `Le nombre tiré est plus grand`, le nouvel intervalle de recherche est [50, 100] alors que si l'ordinateur répond `Le nombre tiré est plus petit`, le nouvel intervalle de recherche devient [1, 50]. En réduisant ainsi en 2 l'intervalle de recherche (c'est la signification du mot « dichotomie ») on aboutit à la solution de façon optimale."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# exo03_27"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo03_28 ✓✓\n",
    "On se propose de coder une variante de l'exercice précédent où, cette fois-ci, c'est l'ordinateur qui fait la recherche dichotomique. Cet exercice prépare le *problème de la chèvre* que nous détaillerons au chapitre 11.\n",
    "\n",
    "Après avoir tiré aléatoirement une cible comme précédemment, nous mettons maintenant en œuvre la méthode de dichotomie décrite dans l'article de [wikipédia](https://fr.wikipedia.org/wiki/Recherche_dichotomique) :\n",
    "\n",
    "![dichotomie](../data/dichotomie.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# exo03_28"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.9.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
