diff --git a/Notebooks/06_Les_conditions.ipynb b/Notebooks/06_Les_conditions.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..1de04da512dc963e104f1e74b6d6d3c0b3a18ca6 --- /dev/null +++ b/Notebooks/06_Les_conditions.ipynb @@ -0,0 +1,901 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<div style=\"padding:20px;background-color:papayawhip;\" > \n", + "<h3 style=\"color:chocolate\"> <i class=\"fa fa-info\" aria-hidden=\"true\"> </i> Remarque introductive <i class=\"fa fa-info\" aria-hidden=\"true\"></h3> \n", + "<p> Ce fichier est fait pour être lu sur le site <a href=\"https://notebook.basthon.fr/\"><img src='https://notebook.basthon.fr/assets/efede5218c9087496f16.png' style=\"border: 0; display:inline; margin: 0 5px; height:30px\" alt=\"Basthon\"/></a>. <br>\n", + " \n", + "Si vous l'avez ouvert avec un autre programme, comme Jupyter notebook, vous riquez de rencontrer quelques bugs. <br>\n", + "Veuillez cliquez sur <a href=\"https://notebook.basthon.fr/\">ce lien</a> et y charger ce fichier à l'aide du bouton \"Ouvrir\" <i class=\"fa fa-folder\" aria-hidden=\"true\"> </i>\n", + "</p> </div> " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Décider - `if`\n", + "\n", + "Dans ce chapitre, nous allons voir comment un programme peut faire des choix, et comment il peut exécuter du code de façon sélective. Nous allons voir que :\n", + "\n", + "- le mot-clé `if` permet une exécution conditionnelle,\n", + "- le mot-clé `if-else` permet de choisir entre deux alternatives,\n", + "- le mot-clé `elif` (else if) permet d'ajouter différentes conditions.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h3 style=\"color:chocolate;background-color:papayawhip;\" > <i class=\"fa fa-question\" aria-hidden=\"true\"> </i> Quizz </h3> \n", + " \n", + "```\n", + "En Python, `if` est suivi\n", + "\n", + "A) d'un bloc\n", + "B) d'une condition\n", + "C) de parenthèses\n", + "D) d'un deux-points\n", + "```" + ] + }, + { + "cell_type": "raw", + "metadata": {}, + "source": [ + "Ma réponse : " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<details>\n", + "<summary style=\"border-left:3px solid #3c763d; border-radius:2pt; width:100%; color:#3c763d; padding:6px; background-color: #dff0d8\"> \n", + "Réponse\n", + "</summary> \n", + "\n", + "<div style=\"border-left:3px solid #3c763d; border-radius:2pt; color:#3c763d; padding:6px; background-color: #eff0e8\">B) d'une condition\n", + "</div>\n", + "</details>\n", + " \n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Comparer\n", + "\n", + "Un programme doit parfois comparer deux valeurs.\n", + "Python connait six types de comparaisons :\n", + "\n", + "- plus petit (`<`),\n", + "- plus petit ou égal (`<=`),\n", + "- égal (`==`),\n", + "- différent (`!=`),\n", + "- plus grand (`>`),\n", + "- plus grand ou égal (`>=`).\n", + "\n", + "Dans des formules mathématiques nous utilisons les symboles ≤, ≥ et ≠. En Python vous devez utiliser deux symboles: `<=`, `>=` et `!=` à la place.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h3 style=\"color:teal;background-color:azure;\" > <i class=\"fa fa-pencil\" aria-hidden=\"true\"> </i> Exercice 1 </h3>Ajoutez des exemples avec les autres 5 comparateurs.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "x = 3\n", + "(x < 2) = False\n" + ] + } + ], + "source": [ + "x = 3\n", + "print('x =', x)\n", + "print('(x < 2) =', x < 2)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h3 style=\"color:chocolate;background-color:papayawhip;\" > <i class=\"fa fa-question\" aria-hidden=\"true\"> </i> Quizz </h3> \n", + " \n", + "```\n", + "L'expression `x == 2`\n", + "\n", + "A) met la valeur 2 dans la variable x\n", + "B) compare deux valeurs\n", + "C) affecte la variable x avec une valeur\n", + "D) retourne True ou False\n", + "```" + ] + }, + { + "cell_type": "raw", + "metadata": {}, + "source": [ + "Ma réponse : " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<details>\n", + "<summary style=\"border-left:3px solid #3c763d; border-radius:2pt; width:100%; color:#3c763d; padding:6px; background-color: #dff0d8\"> \n", + "Réponse\n", + "</summary> \n", + "\n", + "<div style=\"border-left:3px solid #3c763d; border-radius:2pt; color:#3c763d; padding:6px; background-color: #eff0e8\">D) retourne True ou False\n", + "</div>\n", + "</details>\n", + " \n", + "```{caution}\n", + "!! Il ne faut pas confondre l'opérateur d'affectation (`x = 2`) avec l'opérateur de comparaison (`x == 2`) !!\n", + "```\n", + "\n", + "Le résultat d'une comparaison est une valeur booléenne, soit `True` soit `False`.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h3 style=\"color:teal;background-color:azure;\" > <i class=\"fa fa-pencil\" aria-hidden=\"true\"> </i> Exercice 2 </h3>Que se passe-t-il si vous échangez les deux éléments dans `x == 2` ? \n", + "Et si vous échangez les deux éléments dans `x = 2` ?\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = 2 # affectation\n", + "x == 2 # comparaison\n", + "print(x)\n", + "print(x == 2)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Êtes-vous majeur ?\n", + "\n", + "Basé sur votre âge, le programme exécute soit le premier bloc (`if`) soit le deuxième bloc (`else`). Il affiche si vous êtes majeur ou pas.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "age = input('Entrez votre âge: ')\n", + "\n", + "if int(age) < 18:\n", + " print('accès interdit - vous êtes mineur')\n", + "else:\n", + " print('accès OK - vous êtes majeur')\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Le signe d'un nombre\n", + "\n", + "Le mot-clé `elif` est une contraction de **else if** et permet de continuer à tester d'autres conditions.\n", + "Trouvez le signe d'un nombre.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "n = input('Entrez un nombre: ')\n", + "n = int(n)\n", + "\n", + "if n > 0:\n", + " print('positif')\n", + "elif n < 0:\n", + " print('négatif')\n", + "else:\n", + " print('zéro')\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Sans le mot-clé `elif` nous devrions mettre le bloc `if` à l'intérieur du bloc `else` en indentation.\n", + "Avec multiples conditions, les blocs se décalent de plus en plus et rendent le programme illisible.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h3 style=\"color:teal;background-color:azure;\" > <i class=\"fa fa-pencil\" aria-hidden=\"true\"> </i> Exercice 3 </h3>Testez le programme avec -2, 0, 3.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "n = input('Entrez un nombre: ')\n", + "n = int(n)\n", + "\n", + "if n > 0:\n", + " print('positif')\n", + "else:\n", + " if n < 0:\n", + " print('négatif')\n", + " else:\n", + " print('zéro')\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Visualiser la comparaison\n", + "\n", + "Dans l'exemple suivant, nous visualisons le résultat des 6 comparateurs en affichant graphiquement le résultat des 6 comparaisons du type `i < n`. \n", + "\n", + "- La variable `i` va de -9 à 9\n", + "- La variable `n` est marquée en rouge\n", + "- Le résultat `True ` est exprimé avec un grand point, `False` avec un petit\n", + "\n", + "Que fait l'expression `'red' if i == n else 'black'` ?\n", + "\n", + "Elle renvoie `'red'` si `i == n` et `'black'` autrement.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h3 style=\"color:teal;background-color:azure;\" > <i class=\"fa fa-pencil\" aria-hidden=\"true\"> </i> Exercice 4 </h3>Modifiez la variable `n` et exécutez le code de nouveau.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from turtle import *\n", + "d = 20 # dimension de base\n", + "n = 2 # valeur de comparaison\n", + "up()\n", + "\n", + "for j in range(7):\n", + " for i in range(-10, 10):\n", + " goto(i*d, 100-j*d)\n", + " color('red' if i == n else 'black')\n", + " if i == -10:\n", + " c = ('i', '< n', '<= n', '== n', '!= n', '>= n', '> n')[j]\n", + " write(c, font=(None, d//2), align='right')\n", + " elif j == 0:\n", + " write(i, font=(None, d//2), align='center')\n", + " else:\n", + " result = (0, i<n, i<=n, i==n, i!=n, i>=n, i>n)[j]\n", + " dot(d if result else d/4)\n", + "\n", + "done()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Une position aléatoire\n", + "\n", + "Dans ce chapitre nous allons prendre des décisions basées sur la position `(x, y)` d'un point.\n", + "Nous avons donc besoin d'un certain nombre de points, pour ensuite prendre des décisions.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h3 style=\"color:teal;background-color:azure;\" > <i class=\"fa fa-pencil\" aria-hidden=\"true\"> </i> Exercice 5 </h3>Les variables `w, h` (width, height) représentent largeur et hauteur de la plage rectangulaire des valeurs aléatoires. \n", + "Modifiez-les vers `280, 180` et exécutez le code de nouveau.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from turtle import *\n", + "from random import *\n", + "\n", + "w, h = 300, 200\n", + "d, n = 10, 100\n", + "up()\n", + "speed(0)\n", + "\n", + "for i in range(n):\n", + " x, y = randint(-w, w), randint(-h, h)\n", + " goto(x, y)\n", + " dot(d)\n", + "\n", + "done()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Exécution conditionnelle\n", + "\n", + "La structure `if` ci-dessous permet d'exécuter une action seulement si `condition` est `True`.\n", + "\n", + "``` python\n", + "if condition:\n", + " action\n", + "```\n", + "\n", + "Dans notre exemple nous affichons un point rouge seulement si x est positif (`x > 0`)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h3 style=\"color:teal;background-color:azure;\" > <i class=\"fa fa-pencil\" aria-hidden=\"true\"> </i> Exercice 6 </h3>Ajoutez une deuxième condition `if` pour colorier un point en `lime` si `x < -100`.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from turtle import *\n", + "from random import *\n", + "\n", + "w, h = 300, 200\n", + "d, n = 10, 100\n", + "up()\n", + "speed(0)\n", + "\n", + "for i in range(n):\n", + " x, y = randint(-w, w), randint(-h, h)\n", + " goto(x, y)\n", + " if x > 100:\n", + " dot(2*d, 'red')\n", + " dot(d)\n", + "\n", + "done()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## La structure `if else`\n", + "\n", + "La structure `if else` ci-dessous permet d'exécuter une **action_1** seulement si une **condition** est vraie et une **action_2** autrement\n", + "\n", + "``` python\n", + "if condition:\n", + " action_1\n", + "else:\n", + " action_2\n", + "```\n", + "\n", + "Dans l'exemple ci-dessous la condition de test est `y > 0`. \n", + "Si cette condition est vraie, le point est colorié en rouge, autrement en bleu.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from turtle import *\n", + "from random import *\n", + "\n", + "w, h = 300, 200\n", + "d, n = 20, 300\n", + "up()\n", + "speed(0)\n", + "\n", + "for i in range(n):\n", + " x, y = randint(-w, w), randint(-h, h)\n", + " goto(x, y)\n", + " if y > 0:\n", + " dot(d, 'red')\n", + " else:\n", + " dot(d, 'blue')\n", + "\n", + "done()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## L'opération `and`\n", + "\n", + "L'opération logique `and` permet de connecter deux conditions.\n", + "Les deux conditions doivent être vraies pour que l'expression soit vraie.\n", + "\n", + "Pour accélérer le dessin, nous désactivons l'animation avec `tracer(0)`.\n", + "Pour afficher le résultat, nous devons alors appeler la fonction `update()` à la fin.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h3 style=\"color:teal;background-color:azure;\" > <i class=\"fa fa-pencil\" aria-hidden=\"true\"> </i> Exercice 7 </h3>Modifiez le code pour que les points aient une couleur différente dans chaque quadrant.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from turtle import *\n", + "from random import *\n", + "\n", + "w, h = 280, 180\n", + "d, n = 10, 2000\n", + "tracer(0)\n", + "up()\n", + "\n", + "for i in range(n):\n", + " x, y = randint(-w, w), randint(-h, h)\n", + " goto(x, y)\n", + " if x > 0 and y > 0:\n", + " dot(d, 'red')\n", + " else:\n", + " dot(d, 'blue')\n", + "update()\n", + "\n", + "done()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Région en diagonale\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h3 style=\"color:teal;background-color:azure;\" > <i class=\"fa fa-pencil\" aria-hidden=\"true\"> </i> Exercice 8 </h3>Modifiez le code pour que les points aient 4 couleurs, divisées par les 2 diagonales.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from turtle import *\n", + "from random import *\n", + "\n", + "w, h = 280, 180\n", + "d, n = 10, 1000\n", + "tracer(0)\n", + "up()\n", + "\n", + "for i in range(n):\n", + " x, y = randint(-w, w), randint(-h, h)\n", + " goto(x, y)\n", + " if x > y:\n", + " dot(d, 'red')\n", + " else:\n", + " dot(d, 'blue')\n", + "update()\n", + "\n", + "done()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Dans un cercle\n", + "\n", + "Un cercle est défi par une distance donnée d'un point. \n", + "Le cercle autour de l'origine avec un rayon r est donné par la formule\n", + "\n", + "$ x^2 + y^2 = r^2 $\n", + "\n", + "Cette formule nous permet de décider si un point aléatoire est à l'intérieur ou à l'extérieur d'un cercle.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from turtle import *\n", + "from random import *\n", + "\n", + "w, h = 280, 180\n", + "d, n = 10, 2000\n", + "tracer(0)\n", + "up()\n", + "\n", + "for i in range(n):\n", + " x, y = randint(-w, w), randint(-h, h)\n", + " goto(x, y)\n", + " if (x**2 + y**2) > 150**2 :\n", + " dot(d, 'red')\n", + " else:\n", + " dot(d, 'blue')\n", + "update()\n", + "\n", + "done()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "La fonction `in_circle(p, q, r)` vérifie si le point `p` se trouve\n", + "à l'intérieur d'un cercle de rayon `r` qui se trouve à la position `q`.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h3 style=\"color:teal;background-color:azure;\" > <i class=\"fa fa-pencil\" aria-hidden=\"true\"> </i> Exercice 9 </h3>Ajoutez un deuxième cercle avec un rayon r=100, colorié en rouge, qui se trouve à la position (100, -50).\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from turtle import *\n", + "from random import *\n", + "\n", + "w, h = 280, 180\n", + "d, n = 10, 2000\n", + "tracer(0)\n", + "up()\n", + "\n", + "def in_circle(p, q, r):\n", + " d = (p[0]-q[0])**2 + (p[1]-q[1])**2\n", + " return d < r**2\n", + "\n", + "for i in range(n):\n", + " p = randint(-w, w), randint(-h, h)\n", + " goto(p)\n", + " if in_circle(p, (-100, 50), 80):\n", + " dot(d, 'lime')\n", + " else:\n", + " dot(d, 'blue')\n", + "update()\n", + "\n", + "done()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Diagramme de Venne\n", + "\n", + "Avec les 3 opérateurs logiques:\n", + "\n", + "- `and`\n", + "- `or`\n", + "- `not` \n", + "\n", + "nous pouvons trouver des expressions pour trouver les points qui se trouvent dans l'intersection (`and`) ou dans l'union (`or`) de deux cercles.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h3 style=\"color:teal;background-color:azure;\" > <i class=\"fa fa-pencil\" aria-hidden=\"true\"> </i> Exercice 10 </h3>Modifiez le code pour que les points appartenant à l'intersection des deux cercles soient dessinés en jaune.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from turtle import *\n", + "from random import *\n", + "\n", + "w, h = 280, 180\n", + "d, n = 10, 2000\n", + "tracer(0)\n", + "up()\n", + "r, q, q2 = 120, (-60, 0), (60, 0)\n", + "\n", + "def in_circle(p, q, r):\n", + " d = (p[0]-q[0])**2 + (p[1]-q[1])**2\n", + " return d < r**2\n", + "\n", + "for i in range(n):\n", + " p = randint(-w, w), randint(-h, h)\n", + " goto(p)\n", + " if in_circle(p, q, r) and not in_circle(p, q2, r):\n", + " dot(d, 'lime')\n", + " elif in_circle(p, q2, r):\n", + " dot(d, 'red')\n", + " else:\n", + " dot(d, 'blue')\n", + "update()\n", + "\n", + "done()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Dans un rectangle\n", + "\n", + "Dans des programmes interactifs, on doit souvent déterminer si un clic de la souris (x, y) a eu lieu à l'intérieur d'un bouton, qui est normalement une région rectangulaire.\n", + "\n", + "Pour tester si la valeur $x$ se trouve dans l'intervalle $[x_0, x_1]$ nous devons faire deux comparaisons.\n", + "\n", + "Python permet de remplacer `(x0 < x) and (x < x1)` par l'expression plus compacte `x0 < x < x1`.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x0, x1 = 5, 10\n", + "x = 8\n", + "\n", + "if x0 < x < x1:\n", + " print(x, \"est entre\", x0, 'et', x1)\n", + "else:\n", + " print(x, \"n'est entre\", x0, 'et', x1)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "La fonction `in_rect(p, x0, x1, y0, y1)` détermine si la position du point `p` est à l'intérieur du rectangle indiqué par les coordonnées `x0, x1, y0, y1`.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h3 style=\"color:teal;background-color:azure;\" > <i class=\"fa fa-pencil\" aria-hidden=\"true\"> </i> Exercice 11 </h3>Ajoutez un deuxième rectangle ou les points ont une autre couleur.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from turtle import *\n", + "from random import *\n", + "\n", + "w, h = 280, 180\n", + "d, n = 10, 2000\n", + "tracer(0)\n", + "up()\n", + "\n", + "def in_rect(p, x0, x1, y0, y1):\n", + " return x0 < p[0] < x1 and y0 < p[1] < y1\n", + "\n", + "for i in range(n):\n", + " p = randint(-w, w), randint(-h, h)\n", + " goto(p)\n", + " if in_rect(p, 50, 220, -50, 100):\n", + " dot(d, 'lime')\n", + " else:\n", + " dot(d, 'blue')\n", + "\n", + "update()\n", + "\n", + "done()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## À gauche d'une droite\n", + "\n", + "La fonction `is_left(p, q, q2)` est vraie si le point `p` se trouve à gauche de la droite définie par les deux points (q, q2).\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from turtle import *\n", + "from random import *\n", + "\n", + "w, h = 280, 180\n", + "d, n = 10, 2000\n", + "tracer(0)\n", + "up()\n", + "q, q2 = (-160, -100), (60, 0)\n", + "\n", + "def is_left(p, q, q2):\n", + " return (p[0]-q[0])*(q2[1]-q[1]) - (p[1]-q[1])*(q2[0]-q[0]) < 0\n", + "\n", + "for i in range(n):\n", + " p = randint(-w, w), randint(-h, h)\n", + " goto(p)\n", + " if is_left(p, q, q2):\n", + " dot(d, 'lime')\n", + " else:\n", + " dot(d, 'blue')\n", + "\n", + "for p in (q, q2):\n", + " goto(p)\n", + " dot(3*d, 'red')\n", + "\n", + "update()\n", + "\n", + "done()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "La fonction `in_poly(p, poly)` est vraie si le point `p` se trouve à l'intérieur d'un polygone convexe dont les points sont dans l'ordre du sens de l'horloge.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from turtle import *\n", + "from random import *\n", + "\n", + "w, h = 280, 180\n", + "d, n = 10, 2000\n", + "tracer(0)\n", + "up()\n", + "\n", + "poly = ((-160, -100), (100, 100), (60, -100))\n", + "\n", + "def is_left(p, q, q2):\n", + " return (p[0]-q[0])*(q2[1]-q[1]) - (p[1]-q[1])*(q2[0]-q[0]) < 0\n", + "\n", + "def in_poly(p, poly):\n", + " n = len(poly)\n", + " for i in range(n):\n", + " q = poly[i]\n", + " q2 = poly[(i+1)%n]\n", + " if is_left(p, q, q2):\n", + " return False\n", + " return True\n", + "\n", + "for i in range(n):\n", + " p = randint(-w, w), randint(-h, h)\n", + " goto(p)\n", + " if in_poly(p, poly):\n", + " dot(d, 'lime')\n", + " else:\n", + " dot(d, 'blue')\n", + "\n", + "for p in poly:\n", + " goto(p)\n", + " dot(3*d, 'red')\n", + "\n", + "update()\n", + "\n", + "done()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "\n", + "#### Remarque générale\n", + "\n", + "Ce document est une adaptation d'un ressource pédagogique tiré du catalogue modulo https://modulo-info.ch/. Il est sous license Creative Commons [BY-NC-SA](https://creativecommons.org/licenses/?lang=fr)\n", + "\n", + "\n", + " " + ] + } + ], + "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.10.12" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/Notebooks/test.ipynb b/Notebooks/test.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..5b585207d72828a0b2fed4f3b2fd18b20e588764 --- /dev/null +++ b/Notebooks/test.ipynb @@ -0,0 +1 @@ +{"cells":[{"metadata":{},"cell_type":"markdown","source":"<div style=\"padding:20px;background-color:papayawhip;\" > \n<h3 style=\"color:chocolate\"> <i class=\"fa fa-info\" aria-hidden=\"true\"> </i> Remarque introductive <i class=\"fa fa-info\" aria-hidden=\"true\"></h3> \n<p> Ce fichier est fait pour être lu sur le site <a href=\"https://notebook.basthon.fr/\"><img src='https://notebook.basthon.fr/assets/efede5218c9087496f16.png' style=\"border: 0; display:inline; margin: 0 5px; height:30px\" alt=\"Basthon\"/></a>. <br>\n \nSi vous l'avez ouvert avec un autre programme, comme Jupyter notebook, vous riquez de rencontrer quelques bugs. <br>\nVeuillez cliquez sur <a href=\"https://notebook.basthon.fr/\">ce lien</a> et y charger ce fichier à l'aide du bouton \"Ouvrir\" <i class=\"fa fa-folder\" aria-hidden=\"true\"> </i>\n</p> </div> "},{"metadata":{},"cell_type":"markdown","source":"# Décider - `if`\n\nDans ce chapitre, nous allons voir comment un programme peut faire des choix, et comment il peut exécuter du code de façon sélective. Nous allons voir que :\n\n- le mot-clé `if` permet une exécution conditionnelle,\n- le mot-clé `if-else` permet de choisir entre deux alternatives,\n- le mot-clé `elif` (else if) permet d'ajouter différentes conditions.\n\n"},{"metadata":{},"cell_type":"markdown","source":"<h3 style=\"color:chocolate;background-color:papayawhip;\" > <i class=\"fa fa-question\" aria-hidden=\"true\"> </i> Quizz </h3> \n \n```\nEn Python, `if` est suivi\n\nA) d'un bloc\nB) d'une condition\nC) de parenthèses\nD) d'un deux-points\n```"},{"metadata":{},"cell_type":"raw","source":"Ma réponse : "},{"metadata":{},"cell_type":"markdown","source":"<details>\n<summary style=\"border-left:3px solid #3c763d; border-radius:2pt; width:100%; color:#3c763d; padding:6px; background-color: #dff0d8\"> \nRéponse\n</summary> \n\n<div style=\"border-left:3px solid #3c763d; border-radius:2pt; color:#3c763d; padding:6px; background-color: #eff0e8\">B) d'une condition\n</div>\n</details>\n \n"},{"metadata":{},"cell_type":"markdown","source":"## Comparer\n\nUn programme doit parfois comparer deux valeurs.\nPython connait six types de comparaisons :\n\n- plus petit (`<`),\n- plus petit ou égal (`<=`),\n- égal (`==`),\n- différent (`!=`),\n- plus grand (`>`),\n- plus grand ou égal (`>=`).\n\nDans des formules mathématiques nous utilisons les symboles ≤, ≥ et ≠. En Python vous devez utiliser deux symboles: `<=`, `>=` et `!=` à la place.\n\n"},{"metadata":{},"cell_type":"markdown","source":"<h3 style=\"color:teal;background-color:azure;\" > <i class=\"fa fa-pencil\" aria-hidden=\"true\"> </i> Exercice 1 </h3>Ajoutez des exemples avec les autres 5 comparateurs.\n\n"},{"metadata":{"trusted":true},"cell_type":"code","source":"x = 3\nprint('x =', x)\nprint('(x < 2) =', x < 2)\n","execution_count":2,"outputs":[{"output_type":"stream","text":"x = 3\n(x < 2) = False\n","name":"stdout"}]},{"metadata":{},"cell_type":"markdown","source":"<h3 style=\"color:chocolate;background-color:papayawhip;\" > <i class=\"fa fa-question\" aria-hidden=\"true\"> </i> Quizz </h3> \n \n```\nL'expression `x == 2`\n\nA) met la valeur 2 dans la variable x\nB) compare deux valeurs\nC) affecte la variable x avec une valeur\nD) retourne True ou False\n```"},{"metadata":{},"cell_type":"raw","source":"Ma réponse : "},{"metadata":{},"cell_type":"markdown","source":"<details>\n<summary style=\"border-left:3px solid #3c763d; border-radius:2pt; width:100%; color:#3c763d; padding:6px; background-color: #dff0d8\"> \nRéponse\n</summary> \n\n<div style=\"border-left:3px solid #3c763d; border-radius:2pt; color:#3c763d; padding:6px; background-color: #eff0e8\">D) retourne True ou False\n</div>\n</details>\n \n```{caution}\n!! Il ne faut pas confondre l'opérateur d'affectation (`x = 2`) avec l'opérateur de comparaison (`x == 2`) !!\n```\n\nLe résultat d'une comparaison est une valeur booléenne, soit `True` soit `False`.\n\n"},{"metadata":{},"cell_type":"markdown","source":"<h3 style=\"color:teal;background-color:azure;\" > <i class=\"fa fa-pencil\" aria-hidden=\"true\"> </i> Exercice 2 </h3>Que se passe-t-il si vous échangez les deux éléments dans `x == 2` ? \nEt si vous échangez les deux éléments dans `x = 2` ?\n\n"},{"metadata":{"trusted":false},"cell_type":"code","source":"x = 2 # affectation\nx == 2 # comparaison\nprint(x)\nprint(x == 2)\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Êtes-vous majeur ?\n\nBasé sur votre âge, le programme exécute soit le premier bloc (`if`) soit le deuxième bloc (`else`). Il affiche si vous êtes majeur ou pas.\n\n"},{"metadata":{"trusted":false},"cell_type":"code","source":"age = input('Entrez votre âge: ')\n\nif int(age) < 18:\n print('accès interdit - vous êtes mineur')\nelse:\n print('accès OK - vous êtes majeur')\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Le signe d'un nombre\n\nLe mot-clé `elif` est une contraction de **else if** et permet de continuer à tester d'autres conditions.\nTrouvez le signe d'un nombre.\n\n"},{"metadata":{"trusted":false},"cell_type":"code","source":"n = input('Entrez un nombre: ')\nn = int(n)\n\nif n > 0:\n print('positif')\nelif n < 0:\n print('négatif')\nelse:\n print('zéro')\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Sans le mot-clé `elif` nous devrions mettre le bloc `if` à l'intérieur du bloc `else` en indentation.\nAvec multiples conditions, les blocs se décalent de plus en plus et rendent le programme illisible.\n\n"},{"metadata":{},"cell_type":"markdown","source":"<h3 style=\"color:teal;background-color:azure;\" > <i class=\"fa fa-pencil\" aria-hidden=\"true\"> </i> Exercice 3 </h3>Testez le programme avec -2, 0, 3.\n\n"},{"metadata":{"trusted":false},"cell_type":"code","source":"n = input('Entrez un nombre: ')\nn = int(n)\n\nif n > 0:\n print('positif')\nelse:\n if n < 0:\n print('négatif')\n else:\n print('zéro')\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Visualiser la comparaison\n\nDans l'exemple suivant, nous visualisons le résultat des 6 comparateurs en affichant graphiquement le résultat des 6 comparaisons du type `i < n`. \n\n- La variable `i` va de -9 à 9\n- La variable `n` est marquée en rouge\n- Le résultat `True ` est exprimé avec un grand point, `False` avec un petit\n\nQue fait l'expression `'red' if i == n else 'black'` ?\n\nElle renvoie `'red'` si `i == n` et `'black'` autrement.\n\n"},{"metadata":{},"cell_type":"markdown","source":"<h3 style=\"color:teal;background-color:azure;\" > <i class=\"fa fa-pencil\" aria-hidden=\"true\"> </i> Exercice 4 </h3>Modifiez la variable `n` et exécutez le code de nouveau.\n\n"},{"metadata":{"trusted":false},"cell_type":"code","source":"from turtle import *\nd = 20 # dimension de base\nn = 2 # valeur de comparaison\nup()\n\nfor j in range(7):\n for i in range(-10, 10):\n goto(i*d, 100-j*d)\n color('red' if i == n else 'black')\n if i == -10:\n c = ('i', '< n', '<= n', '== n', '!= n', '>= n', '> n')[j]\n write(c, font=(None, d//2), align='right')\n elif j == 0:\n write(i, font=(None, d//2), align='center')\n else:\n result = (0, i<n, i<=n, i==n, i!=n, i>=n, i>n)[j]\n dot(d if result else d/4)\n\ndone()\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Une position aléatoire\n\nDans ce chapitre nous allons prendre des décisions basées sur la position `(x, y)` d'un point.\nNous avons donc besoin d'un certain nombre de points, pour ensuite prendre des décisions.\n\n"},{"metadata":{},"cell_type":"markdown","source":"<h3 style=\"color:teal;background-color:azure;\" > <i class=\"fa fa-pencil\" aria-hidden=\"true\"> </i> Exercice 5 </h3>Les variables `w, h` (width, height) représentent largeur et hauteur de la plage rectangulaire des valeurs aléatoires. \nModifiez-les vers `280, 180` et exécutez le code de nouveau.\n\n"},{"metadata":{"trusted":false},"cell_type":"code","source":"from turtle import *\nfrom random import *\n\nw, h = 300, 200\nd, n = 10, 100\nup()\nspeed(0)\n\nfor i in range(n):\n x, y = randint(-w, w), randint(-h, h)\n goto(x, y)\n dot(d)\n\ndone()\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Exécution conditionnelle\n\nLa structure `if` ci-dessous permet d'exécuter une action seulement si `condition` est `True`.\n\n``` python\nif condition:\n action\n```\n\nDans notre exemple nous affichons un point rouge seulement si x est positif (`x > 0`)\n\n"},{"metadata":{},"cell_type":"markdown","source":"<h3 style=\"color:teal;background-color:azure;\" > <i class=\"fa fa-pencil\" aria-hidden=\"true\"> </i> Exercice 6 </h3>Ajoutez une deuxième condition `if` pour colorier un point en `lime` si `x < -100`.\n\n"},{"metadata":{"trusted":false},"cell_type":"code","source":"from turtle import *\nfrom random import *\n\nw, h = 300, 200\nd, n = 10, 100\nup()\nspeed(0)\n\nfor i in range(n):\n x, y = randint(-w, w), randint(-h, h)\n goto(x, y)\n if x > 100:\n dot(2*d, 'red')\n dot(d)\n\ndone()\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## La structure `if else`\n\nLa structure `if else` ci-dessous permet d'exécuter une **action_1** seulement si une **condition** est vraie et une **action_2** autrement\n\n``` python\nif condition:\n action_1\nelse:\n action_2\n```\n\nDans l'exemple ci-dessous la condition de test est `y > 0`. \nSi cette condition est vraie, le point est colorié en rouge, autrement en bleu.\n\n"},{"metadata":{"trusted":false},"cell_type":"code","source":"from turtle import *\nfrom random import *\n\nw, h = 300, 200\nd, n = 20, 300\nup()\nspeed(0)\n\nfor i in range(n):\n x, y = randint(-w, w), randint(-h, h)\n goto(x, y)\n if y > 0:\n dot(d, 'red')\n else:\n dot(d, 'blue')\n\ndone()\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## L'opération `and`\n\nL'opération logique `and` permet de connecter deux conditions.\nLes deux conditions doivent être vraies pour que l'expression soit vraie.\n\nPour accélérer le dessin, nous désactivons l'animation avec `tracer(0)`.\nPour afficher le résultat, nous devons alors appeler la fonction `update()` à la fin.\n\n"},{"metadata":{},"cell_type":"markdown","source":"<h3 style=\"color:teal;background-color:azure;\" > <i class=\"fa fa-pencil\" aria-hidden=\"true\"> </i> Exercice 7 </h3>Modifiez le code pour que les points aient une couleur différente dans chaque quadrant.\n\n"},{"metadata":{"trusted":false},"cell_type":"code","source":"from turtle import *\nfrom random import *\n\nw, h = 280, 180\nd, n = 10, 2000\ntracer(0)\nup()\n\nfor i in range(n):\n x, y = randint(-w, w), randint(-h, h)\n goto(x, y)\n if x > 0 and y > 0:\n dot(d, 'red')\n else:\n dot(d, 'blue')\nupdate()\n\ndone()\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Région en diagonale\n\n"},{"metadata":{},"cell_type":"markdown","source":"<h3 style=\"color:teal;background-color:azure;\" > <i class=\"fa fa-pencil\" aria-hidden=\"true\"> </i> Exercice 8 </h3>Modifiez le code pour que les points aient 4 couleurs, divisées par les 2 diagonales.\n\n"},{"metadata":{"trusted":false},"cell_type":"code","source":"from turtle import *\nfrom random import *\n\nw, h = 280, 180\nd, n = 10, 1000\ntracer(0)\nup()\n\nfor i in range(n):\n x, y = randint(-w, w), randint(-h, h)\n goto(x, y)\n if x > y:\n dot(d, 'red')\n else:\n dot(d, 'blue')\nupdate()\n\ndone()\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Dans un cercle\n\nUn cercle est défi par une distance donnée d'un point. \nLe cercle autour de l'origine avec un rayon r est donné par la formule\n\n$ x^2 + y^2 = r^2 $\n\nCette formule nous permet de décider si un point aléatoire est à l'intérieur ou à l'extérieur d'un cercle.\n\n"},{"metadata":{"trusted":false},"cell_type":"code","source":"from turtle import *\nfrom random import *\n\nw, h = 280, 180\nd, n = 10, 2000\ntracer(0)\nup()\n\nfor i in range(n):\n x, y = randint(-w, w), randint(-h, h)\n goto(x, y)\n if (x**2 + y**2) > 150**2 :\n dot(d, 'red')\n else:\n dot(d, 'blue')\nupdate()\n\ndone()\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"La fonction `in_circle(p, q, r)` vérifie si le point `p` se trouve\nà l'intérieur d'un cercle de rayon `r` qui se trouve à la position `q`.\n\n"},{"metadata":{},"cell_type":"markdown","source":"<h3 style=\"color:teal;background-color:azure;\" > <i class=\"fa fa-pencil\" aria-hidden=\"true\"> </i> Exercice 9 </h3>Ajoutez un deuxième cercle avec un rayon r=100, colorié en rouge, qui se trouve à la position (100, -50).\n\n"},{"metadata":{"trusted":false},"cell_type":"code","source":"from turtle import *\nfrom random import *\n\nw, h = 280, 180\nd, n = 10, 2000\ntracer(0)\nup()\n\ndef in_circle(p, q, r):\n d = (p[0]-q[0])**2 + (p[1]-q[1])**2\n return d < r**2\n\nfor i in range(n):\n p = randint(-w, w), randint(-h, h)\n goto(p)\n if in_circle(p, (-100, 50), 80):\n dot(d, 'lime')\n else:\n dot(d, 'blue')\nupdate()\n\ndone()\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Diagramme de Venne\n\nAvec les 3 opérateurs logiques:\n\n- `and`\n- `or`\n- `not` \n\nnous pouvons trouver des expressions pour trouver les points qui se trouvent dans l'intersection (`and`) ou dans l'union (`or`) de deux cercles.\n\n"},{"metadata":{},"cell_type":"markdown","source":"<h3 style=\"color:teal;background-color:azure;\" > <i class=\"fa fa-pencil\" aria-hidden=\"true\"> </i> Exercice 10 </h3>Modifiez le code pour que les points appartenant à l'intersection des deux cercles soient dessinés en jaune.\n\n"},{"metadata":{"trusted":false},"cell_type":"code","source":"from turtle import *\nfrom random import *\n\nw, h = 280, 180\nd, n = 10, 2000\ntracer(0)\nup()\nr, q, q2 = 120, (-60, 0), (60, 0)\n\ndef in_circle(p, q, r):\n d = (p[0]-q[0])**2 + (p[1]-q[1])**2\n return d < r**2\n\nfor i in range(n):\n p = randint(-w, w), randint(-h, h)\n goto(p)\n if in_circle(p, q, r) and not in_circle(p, q2, r):\n dot(d, 'lime')\n elif in_circle(p, q2, r):\n dot(d, 'red')\n else:\n dot(d, 'blue')\nupdate()\n\ndone()\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Dans un rectangle\n\nDans des programmes interactifs, on doit souvent déterminer si un clic de la souris (x, y) a eu lieu à l'intérieur d'un bouton, qui est normalement une région rectangulaire.\n\nPour tester si la valeur $x$ se trouve dans l'intervalle $[x_0, x_1]$ nous devons faire deux comparaisons.\n\nPython permet de remplacer `(x0 < x) and (x < x1)` par l'expression plus compacte `x0 < x < x1`.\n\n"},{"metadata":{"trusted":false},"cell_type":"code","source":"x0, x1 = 5, 10\nx = 8\n\nif x0 < x < x1:\n print(x, \"est entre\", x0, 'et', x1)\nelse:\n print(x, \"n'est entre\", x0, 'et', x1)\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"La fonction `in_rect(p, x0, x1, y0, y1)` détermine si la position du point `p` est à l'intérieur du rectangle indiqué par les coordonnées `x0, x1, y0, y1`.\n\n"},{"metadata":{},"cell_type":"markdown","source":"<h3 style=\"color:teal;background-color:azure;\" > <i class=\"fa fa-pencil\" aria-hidden=\"true\"> </i> Exercice 11 </h3>Ajoutez un deuxième rectangle ou les points ont une autre couleur.\n\n"},{"metadata":{"trusted":false},"cell_type":"code","source":"from turtle import *\nfrom random import *\n\nw, h = 280, 180\nd, n = 10, 2000\ntracer(0)\nup()\n\ndef in_rect(p, x0, x1, y0, y1):\n return x0 < p[0] < x1 and y0 < p[1] < y1\n\nfor i in range(n):\n p = randint(-w, w), randint(-h, h)\n goto(p)\n if in_rect(p, 50, 220, -50, 100):\n dot(d, 'lime')\n else:\n dot(d, 'blue')\n\nupdate()\n\ndone()\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## À gauche d'une droite\n\nLa fonction `is_left(p, q, q2)` est vraie si le point `p` se trouve à gauche de la droite définie par les deux points (q, q2).\n\n"},{"metadata":{"trusted":false},"cell_type":"code","source":"from turtle import *\nfrom random import *\n\nw, h = 280, 180\nd, n = 10, 2000\ntracer(0)\nup()\nq, q2 = (-160, -100), (60, 0)\n\ndef is_left(p, q, q2):\n return (p[0]-q[0])*(q2[1]-q[1]) - (p[1]-q[1])*(q2[0]-q[0]) < 0\n\nfor i in range(n):\n p = randint(-w, w), randint(-h, h)\n goto(p)\n if is_left(p, q, q2):\n dot(d, 'lime')\n else:\n dot(d, 'blue')\n\nfor p in (q, q2):\n goto(p)\n dot(3*d, 'red')\n\nupdate()\n\ndone()\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"La fonction `in_poly(p, poly)` est vraie si le point `p` se trouve à l'intérieur d'un polygone convexe dont les points sont dans l'ordre du sens de l'horloge.\n\n"},{"metadata":{"trusted":false},"cell_type":"code","source":"from turtle import *\nfrom random import *\n\nw, h = 280, 180\nd, n = 10, 2000\ntracer(0)\nup()\n\npoly = ((-160, -100), (100, 100), (60, -100))\n\ndef is_left(p, q, q2):\n return (p[0]-q[0])*(q2[1]-q[1]) - (p[1]-q[1])*(q2[0]-q[0]) < 0\n\ndef in_poly(p, poly):\n n = len(poly)\n for i in range(n):\n q = poly[i]\n q2 = poly[(i+1)%n]\n if is_left(p, q, q2):\n return False\n return True\n\nfor i in range(n):\n p = randint(-w, w), randint(-h, h)\n goto(p)\n if in_poly(p, poly):\n dot(d, 'lime')\n else:\n dot(d, 'blue')\n\nfor p in poly:\n goto(p)\n dot(3*d, 'red')\n\nupdate()\n\ndone()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"---\n\n#### Remarque générale\n\nCe document est une adaptation d'un ressource pédagogique tiré du catalogue modulo https://modulo-info.ch/. Il est sous license Creative Commons [BY-NC-SA](https://creativecommons.org/licenses/?lang=fr)\n\n\n "}],"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.10.12"}},"nbformat":4,"nbformat_minor":2} \ No newline at end of file