{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "253baee0",
   "metadata": {},
   "source": [
    "# ICS - Série 2\n",
    "\n",
    "17.09.25\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ed03616a",
   "metadata": {},
   "source": [
    "## Exercice 1 : qu'affiche ce code?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b2b541a2",
   "metadata": {},
   "outputs": [],
   "source": [
    "def f():\n",
    "    x = \"une variable locale\"\n",
    "    print(\"je suis dans f, x = \", x)\n",
    "\n",
    "x = 2\n",
    "print(\"je suis dehors, x = \", x)\n",
    "f()\n",
    "print(\"je suis dehors, x = \", x)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "017430b4",
   "metadata": {},
   "outputs": [],
   "source": [
    "def vol_cube(x1, x2, x3 = 1):\n",
    "    return x1 * x2 * x3\n",
    "\n",
    "print(vol_cube(2, 3, 4))\n",
    "print(vol_cube(2, 3))\n",
    "print(vol_cube(2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "906e6241",
   "metadata": {},
   "outputs": [],
   "source": [
    "def f(x, y = 1, z = \"blah\"):\n",
    "    print(x, y, z)\n",
    "    \n",
    "f(1, 2, 3)\n",
    "f(1, 2)\n",
    "f(1, \"blih\")\n",
    "f(1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9d0c5665",
   "metadata": {},
   "outputs": [],
   "source": [
    "x = 3\n",
    "y = 4\n",
    "print(x % 2 == 0, y % 2 == 0)\n",
    "print(x > 3 and y > 3)\n",
    "print(x > 3 or y > 3)\n",
    "print(not x > 3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b713ea88",
   "metadata": {},
   "outputs": [],
   "source": [
    "if (\"baobab\" > \"banane\") and (\"Banane\" < \"ane\"):\n",
    "    print(\"Le monde est ordonné lexicographiquement\")\n",
    "else:\n",
    "    print(\"Le monde ne fait pas sens\")\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "32381b69",
   "metadata": {},
   "outputs": [],
   "source": [
    "x = 1\n",
    "y = 2\n",
    "z = 3\n",
    "\n",
    "print((x < y) or (x < z) and (y > z))\n",
    "\n",
    "print(((x < y) or (x < z)) and (y > z))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7e85f0f3",
   "metadata": {},
   "outputs": [],
   "source": [
    "x = 3\n",
    "if x == 3:\n",
    "    print(\"x est égal à 3\")\n",
    "    \n",
    "if x == 4:\n",
    "    print('x est égal à 4')\n",
    "    print(x == 4)\n",
    "else:\n",
    "    print('x pas égal à 4')\n",
    "    print(x != 4)\n",
    "    "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ba906bdc",
   "metadata": {},
   "source": [
    "## Exercice 2 : valeur absolue\n",
    "\n",
    "La fonction `abs` de Python prend un nombre en entrée et retourne sa valeur absolue. Ecrivez une fonction `val_abs` qui implémente la même fonctionnalité (sans utiliser `abs`).\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "498ab4b0",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "4e3daffb",
   "metadata": {},
   "source": [
    "## Exercice 3: bonjour\n",
    "\n",
    "Ecrivez une fonction `bonjour` qui prend en entrée\n",
    "- deux paramètres obligatoires `nom` et `prenom`\n",
    "- un paramètre optionnel `reverse` de valeur par défaut `0`\n",
    "\n",
    "et \n",
    "- si `reverse` vaut `0`, affiche `Bonjour, prenom nom !`\n",
    "- sinon, affiche `Bonjour, nom prenom !` .\n",
    "\n",
    "Par exemple, l'appel `bonjour('Anastasia', 'Khukhro')` doit afficher `Bonjour, Anastasia Khukhro !` et l'appel\n",
    "`bonjour('Samuel', 'Dubuis', 42)` doit afficher `Bonjour, Dubuis Samuel !` "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "32d76495",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "08609269",
   "metadata": {},
   "source": [
    "## Exercice 4: arguments nommés\n",
    "\n",
    "\n",
    "On a vu en cours que lors de l'appel d'une fonction, les valeurs des arguments de l'appel sont liées aux paramètres de la fonction dans l'ordre où les paramètres sont définis. On dit que dans cet appel, les arguments sont **positionnels**.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2db0f407",
   "metadata": {},
   "outputs": [],
   "source": [
    "import math\n",
    "\n",
    "def vol_cylindre(h, r):\n",
    "    print(\"je calcule le volume d'un cylindre de rayon\", r, \"et hauteur\", h)\n",
    "    return math.pi * r**2 * h\n",
    "\n",
    "print(vol_cylindre(3, 5))\n",
    "print(vol_cylindre(5, 3))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2ce3e447",
   "metadata": {},
   "source": [
    "Cependant, on peut, dans l'appel de la fonction, lier explicitement un argument à un paramètre, et ceci dans n'importe quel ordre. On parle d'arguments **nommés**."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "66bcb13b",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(vol_cylindre(r = 3, h = 5))\n",
    "print(\"\\n**************\\n\")\n",
    "print(vol_cylindre(h = 3, r = 5))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cf43aeba",
   "metadata": {},
   "source": [
    "Cela rend le code plus lisible: lorsqu'on lit la portion de code où se fait l'appel à `vol_cylindre`, on sait tout de suite quelles valeurs correspondent respectivement au rayon et à la hauteur, sans devoir aller vérifier la définition de la fonction.\n",
    "\n",
    "\n",
    "On peut aussi, dans l'appel de la fonction, nommer explicitement certains arguments mais pas tous (toujours pour des raisons de lisibilité). Mais dans ce cas, les arguments nommés doivent apparaître **après** tous les arguments positionnels."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4765fde8",
   "metadata": {},
   "outputs": [],
   "source": [
    "from math import sqrt\n",
    "\n",
    "def moyenne(x, y, alg):\n",
    "    '''\n",
    "    Entrée: x et y nombres positifs, alg booléen\n",
    "    calcule la moyenne algébrique de x et y si alg = True\n",
    "    sinon calcule la moyenne géométrique\n",
    "    '''\n",
    "    \n",
    "    if alg:\n",
    "        return (x + y)/2\n",
    "    \n",
    "    else:\n",
    "        return sqrt(x * y)\n",
    "    \n",
    "print(moyenne(2, 1, True))\n",
    "print(moyenne(2, 1, False))  \n",
    "\n",
    "print(\"\\n********************\\n\")\n",
    "\n",
    "print(moyenne(2, 1, alg = True))\n",
    "print(moyenne(2, 1, alg = False))\n",
    "\n",
    "print(\"\\n********************\\n\")\n",
    "\n",
    "\n",
    "print(moyenne(x = 2, y = 1, alg = True))\n",
    "print(moyenne(2, y = 1, alg = False))\n",
    "\n",
    "# que se passe-t-il si un argument nommé apparaît avant un argument positionnel?\n",
    "# pour le savoir, décommentez cette ligne\n",
    "\n",
    "#print(moyenne(x = 2, 1, alg = True))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8933fad6",
   "metadata": {},
   "source": [
    "Avoir deux genre de paramètres, obligatoire ou par défaut, et avoir deux genres d'arguments, positionnels ou nommés, sont deux choses différentes, qui ne sont pas mutuellement exclusives."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d9b4aa17",
   "metadata": {},
   "outputs": [],
   "source": [
    "from math import sqrt\n",
    "\n",
    "def moyenne(x, y, alg = True):\n",
    "    if alg:\n",
    "        return (x + y)/2\n",
    "    \n",
    "    else:\n",
    "        return sqrt(x * y)\n",
    "    \n",
    "print(moyenne(2, 1, alg = True))\n",
    "print(moyenne(2, 1, False))\n",
    "print(moyenne(2, 1))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5440fb47",
   "metadata": {},
   "source": [
    "Lesquelles des instructions suivantes génèrent des erreurs?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "00f37b06",
   "metadata": {},
   "outputs": [],
   "source": [
    "import math\n",
    "\n",
    "def vol_cylindre(h, r = 1):\n",
    "    return math.pi * r**2 * h\n",
    "\n",
    "print(vol_cylindre(3, 2))\n",
    "print(vol_cylindre(r = 2, h = 3))\n",
    "print(vol_cylindre(3))\n",
    "print(vol_cylindre(h = 3))\n",
    "print(vol_cylindre(r = 3))\n",
    "print(vol_cylindre(2, r = 3))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6f29b12a",
   "metadata": {},
   "source": [
    "## Exercice 5: maximum \n",
    "\n",
    "La fonction `max` de Python prend en entrée deux objets ou plus comparables entre eux, et retourne le maximum de ces objets (on verra plus tard qu'elle peut aussi prendre un _itérable_). Ecrivez une fonction `max_trois` qui implémente une version à fonctionnalité limitée de la fonction `max`: votre fonction doit prendre trois nombres en entrée et retourner le plus grand.\n",
    "\n",
    "Vous ne pouvez pas utiliser la fonction built-in `max`.\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "37342392",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "ff3cf40f",
   "metadata": {},
   "source": [
    "## Exercice 6: classification d'un nombre aléatoire\n",
    "\n",
    "**(a)** Ecrivez une fonction `classif_nombre` qui prend un nombre positif `x` en entrée, et selon la valeur de `x`, produit\n",
    "un des affichages suivants:\n",
    "\n",
    "`0 <= x < 50`\n",
    "\n",
    "`50 <= x < 100`\n",
    "\n",
    "`100 <= x`\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "22a6d793",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "745bf902",
   "metadata": {},
   "source": [
    "**(b)** que se passe-t-il si on appelle `classif_nombre` avec un objet qui n'est pas de type numérique?\n",
    "\n",
    "Pour éviter ce problème, modifiez votre fonction de telle sorte à ce qu'elle vérifie que `x` est bien de type numérique, et sinon elle n'effectue pas de comparaisons qui mènent à une erreur."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0d3e4d14",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "8e1a8988",
   "metadata": {},
   "source": [
    "**(b)** Ecrivez une fonction `classif_nombre_aleatoire`, qui\n",
    "- ne prend aucune entrée\n",
    "- génère, à l'aide de la fonction randint du module random, un entier aléatoire entre 0 et 200 inclus\n",
    "- appelle la fonction `classif_nombre` pour afficher l'intervalle du nombre aléatoire généré.\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9a96a426",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "3322d98e",
   "metadata": {},
   "source": [
    "## Exercice 7: équation quadratique\n",
    "\n",
    "\n",
    "**Rappel** : Pour résoudre une **équation quadratique** $ax^2 + bx + c = 0$, où $a \\neq 0$, $b$ et $c$ sont des coefficients réels, on commence par calculer son **discriminant** $\\Delta = b^2 - 4 ac$. L'ensemble de solutions de l'équation dépendra du signe de $\\Delta = b^2 - 4 ac$ :\n",
    "\n",
    "- Si $\\Delta > 0$, l'équation admet deux solutions distinctes réelles $x_1 = \\frac{-b + \\sqrt{\\Delta}}{2a}$ et $x_2 = \\frac{-b - \\sqrt{\\Delta}}{2a}$\n",
    "- Si $\\Delta = 0$, l'équation admet une solution réelle double $x_0 = \\frac{-b + \\sqrt{\\Delta}}{2a} = \\frac{-b - \\sqrt{\\Delta}}{2a} = \\frac{-b}{2a}$\n",
    "- Si $\\Delta < 0$, l'équation n'admet aucune solution réelle. \n",
    "\n",
    "**a)** Ecrivez une fonction `racine_polynome_quadratique` qui\n",
    "- prend en entrée trois coefficients réels `a`, `b`, `c` et suppose que `a` est non nul\n",
    "- si l'équation admet deux solutions distinctes, retourne ces deux solutions\n",
    "- si l'équation admet une solution double $x_0$, retourne la paire de valeurs $x_0$ et `None`\n",
    "- si l'équation n'admet pas de solution réelle, retourne deux fois la valeur `None` .\n",
    "\n",
    "\n",
    "Par exemple, l'instruction `print(racine_polynome_quadratique(2, 3, 1))` doit afficher \n",
    "\n",
    "`-0.5 -1.0` ,\n",
    "\n",
    "`print(racine_polynome_quadratique(1, -2, 1))` doit afficher\n",
    "\n",
    "`1.0 None`  ,\n",
    "\n",
    "et `print(racine_polynome_quadratique(1, 0, 1))` doit afficher\n",
    "\n",
    "`None None` .\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8ec0ca60",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "410bf3a1",
   "metadata": {},
   "source": [
    "**b)** Ecrivez une fonction `poly_quadratique_affichage` qui\n",
    "- prend en entrée trois coefficients réels `a`, `b`, `c` tels que `a` est non nul\n",
    "- appelle la fonction `racine_polynome_quadratique` avec ces trois valeurs\n",
    "- distingue par un affichage approprié les trois cas de figure (deux racines, une racine, pas de racines réelles).\n",
    "\n",
    "Donc \n",
    "- l'instruction `poly_quadratique_affichage(2, 3, 1)` doit afficher:\n",
    "\n",
    "`2x^2 + 3x + 1 = 2(x - -0.5)(x - -1.0)`\n",
    "\n",
    "\n",
    "- l'instruction `poly_quadratique_affichage(1, 2, 1)` doit afficher:\n",
    "\n",
    "`1x^2 + 2x + 1 = 1(x - -1.0)^2`\n",
    "\n",
    "- l'instruction `poly_quadratique_affichage(1, 1, 1)` doit afficher:\n",
    "\n",
    "`l'équation 1x^2 + 1x + 1 = 0 n'admet pas de solutions réelles.`\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "88e1012c",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "ddb8276d",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "**c) BONUS** La fonction `poly_quadratique_affichage` fait son travail correctement mais ses affichages sont plutôt laids. Ecrivez une fonction `poly_quadratique_affichage_joli` qui affiche les signes de manière plus lisible. Par exemple l'instruction `poly_quadratique_affichage_joli(2, 3, 1)` doit afficher\n",
    "\n",
    "`2x^2 + 3x + 1 = 2(x + 0.5)(x + 1.0)` ,\n",
    "\n",
    "\n",
    "et l'instruction `poly_quadratique_affichage_joli(1, -2, 1)` doit afficher\n",
    "\n",
    "`1x^2 - 2x + 1 = 1(x + 1)^2`.\n",
    "\n",
    "**Remarque.** Si vous avez envie, vous pouvez encore améliorer l'affichage pour gérer les coefficients qui valent 1 ou 0, et pour représenter les racines entières sans floating point, mais on va s'arrêter ici."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2c90f2bf",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "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.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
