{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "4ae77820",
   "metadata": {},
   "source": [
    "# Séance 1\n",
    "\n",
    ":::{admonition} Objectifs\n",
    "* Utilisation de python en mode \"calculatrice\"\n",
    "* Variables : déclaration, affectation, affichage\n",
    "* Chaînes de caractères\n",
    "* Valeurs et tests logiques\n",
    "* Premières fonctions\n",
    ":::\n",
    "\n",
    "\n",
    "## Présentation rapide de python et jupyter\n",
    "\n",
    "### python\n",
    "\n",
    "**Python** est un langage de programmation sous licence libre permettant une initiation rapide aux concepts de base de programmation et d'algorithmique. Il est apprécié pour la simplicité de sa syntaxe et sa rapidité de déploiement.\n",
    "\n",
    "En pratique, il est beaucoup utilisé dans l'enseignement secondaire et supérieur, mais également dans des contextes de recherche académique (calcul scentifique, big data, machine learning) et dans l'industrie (entre autres, comme langage de script pour des interfaces entre programmes).\n",
    "\n",
    "*Référence :* https://www.python.org/\n",
    "\n",
    "### jupyter\n",
    "\n",
    "**Jupyter** est une application web qui permet, entre autres, d'utiliser différents langages de programmation (notamment python) de manière interactive et visuelle.  Il permet notamment la création de *notebook* (carnet de note, calepin), où peuvent se mêler du texte, des formules mathématiques, des lignes de codes et le résultat de leur exécution.\n",
    "\n",
    "Par exemple, ce livre numérique a été éntièrement créé grâce à jupyter. La page actuelle peut être téléchargée sous la forme d'un notebook (extension *.ipynb*), voir l'icône de téléchargement en haut. Il est ensuite possible de l'exécuter sur votre machine personnelle.\n",
    "\n",
    "*Référence :* https://jupyter.org/\n",
    "\n",
    "\n",
    "## Premières commandes\n",
    "\n",
    "### Calculs élémentaires\n",
    "\n",
    "Avec python, il est possible de calculer le résultat d'expressions mathématiques, comme le ferait une **calculatrice** élémentaire. Pour cela, on entre le calcul à effectuer et on exécute la cellule (avec le bouton d'exécution, ou plus rapidement avec <kbd>Ctrl</kbd>+<kbd>Enter</kbd>).\n",
    "\n",
    "**Exemple.** Pour calculer $1+1$ :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d8129551",
   "metadata": {},
   "outputs": [],
   "source": [
    "1 + 1"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fe9a9a81",
   "metadata": {},
   "source": [
    "L'addition et la soustraction sont représentées par `+` et `-`. La multiplication est notée `*`, l'opération d'exponentation (\"mise à la puissance\") est quant à elle `**`. Python respecte les priorités usuelles sur les opérateurs, mais il est toujours préférable de bien parenthéser ses expressions.\n",
    "\n",
    "**Exemple.** Pour calculer le résultat de l'expression $2^3 + (3 \\times 4 - 1)$, on entre :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3b796b3c",
   "metadata": {},
   "outputs": [],
   "source": [
    "2**3 + (3 * 4 - 1)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9b397f3b",
   "metadata": {},
   "source": [
    "**Remarque.** Python n'est pas sensible aux espaces."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cad4c5ff",
   "metadata": {},
   "outputs": [],
   "source": [
    "2              **3 + (3*4-1)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0878be2a",
   "metadata": {},
   "source": [
    "### Le cas de la division\n",
    "\n",
    "En mathématiques, il existe deux types de divisions : la **division exacte** (éventuellement avec un résultat décimal) et la division euclidienne (avec reste). Voyons comment python implémente ces deux opérations.\n",
    "\n",
    "Calculons le résultat de la division $5/3$ :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fabca3f2",
   "metadata": {},
   "outputs": [],
   "source": [
    "5 / 3"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7c1c2f49",
   "metadata": {},
   "source": [
    "On observe qu'on obtient une valeur décimale approchée : cela signifie que, nativement, python ne sait pas manipuler des valeurs exactes de rationnel.\n",
    "\n",
    "\n",
    "\n",
    "Si l'on souhaite obtenir le quotient de la division euclidienne, il faut utiliser le **double caractère** `//` :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0b925f58",
   "metadata": {},
   "outputs": [],
   "source": [
    "5 // 3"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "25042342",
   "metadata": {},
   "source": [
    "Pour ce qui est du reste de la division euclidienne (le \"modulo\"), l'opérateur est `%`. Par exemple :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "81118bb8",
   "metadata": {},
   "outputs": [],
   "source": [
    "5 % 3"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6a6adb30",
   "metadata": {},
   "source": [
    "**Résumé.** Voici un tableau récapitulatif :\n",
    "\n",
    "| Opération (exemple) | Syntaxe python | Résultat |\n",
    "| :---: | :---: | :---: |\n",
    "| Addition $7 + 3$ | `7 + 3` | $10$ | \n",
    "| Soustration $7 - 3$ | `7 - 3` | $4$ |\n",
    "| Multiplication $7 \\times 3$ | `7 * 3` | $21$ |\n",
    "| Exponentiation $7 ^ 3$ | `7 ** 3` | $343$ |\n",
    "| Division \"exacte\" $7 / 3$ | `7 / 3` | $2.3333333333333335$ |\n",
    "| Division euclidienne de $7$ par $3$ | `7 // 3` | $2$ |\n",
    "| Reste de la division de $7$ par $3$ ($7$ modulo $3$) | `7 % 3` | $1$ |\n",
    "\n",
    "\n",
    "\n",
    "## Variables\n",
    "\n",
    "Python permet de garder en mémoire des valeurs, dans des \"objets mémoire\" représentés par des **variables**. On doit nommer une variable par un texte **sans espace** et essentiellement **sans caractère spécial** (excepté le `_`) , et **commençant par une lettre**.\n",
    "\n",
    "Lorsqu'on place une valeur dans une variable, on dit qu'on lui **affecte** ou **assigne** une valeur. Une affectation se fait par un **signe égal** `=`, en donnant à gauche le nom de la variable, et à droite la valeur à lui affecter. **Attention**, ce n'est pas symétrique !!\n",
    "\n",
    "**Question.** Affecter la valeur $15$ à la variable `a`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "158ab180",
   "metadata": {},
   "outputs": [],
   "source": [
    "a = 15"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "92f23b30",
   "metadata": {},
   "source": [
    "On observe **qu'aucun affichage** n'est donné en sortie. En effet, l'affectation d'une valeur à une variable ne retourne aucun résultat. Si l'on souhaite voir ce qu'il y a dans une variable, on peut l'afficher avec la **fonction** `print`.\n",
    "\n",
    "**Question.** Affecter $8$ à la variable `b` puis l'afficher."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "74183217",
   "metadata": {},
   "outputs": [],
   "source": [
    "b = 8\n",
    "print(b)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1cfb8b91",
   "metadata": {},
   "source": [
    "La fonction `print` prend ici en entrée le **paramètre** `b`. Ce paramètre est passé **entre parenthèses**, après le nom de la fonction.\n",
    "\n",
    "\n",
    "\n",
    "**Remarque importante.** L'environnement jupyter mémorise les différents calculs efféctués dans les cellules. Ainsi, on peut afficher la valeur de la variable ``a`` qui a été définie dans une des cellules précédentes."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a488b21a",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9f8ea09f",
   "metadata": {},
   "source": [
    "Il est possible d'effectuer des calculs sur les variables comme on l'avait précédemment fait directement sur les valeurs.\n",
    "\n",
    "\n",
    "**Question.** Créer une variable `c` et l'affecter avec la somme des valeurs contenues dans `a` et `b`. Puis, afficher `c`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ac839d41",
   "metadata": {},
   "outputs": [],
   "source": [
    "c = a + b\n",
    "print(c)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3cc78be8",
   "metadata": {},
   "source": [
    "La valeur d'une variable peut être mise à jour au cours du temps. On **écrase** alors l'ancienne valeur (elle est perdue).\n",
    "\n",
    "**Question.** Affecter à la variable `a` la valeur $6$, puis incrémenter `a` de $1$, et enfin afficher le résultat."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "01e560f0",
   "metadata": {},
   "outputs": [],
   "source": [
    "a = 6\n",
    "a = a + 1\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ba57f508",
   "metadata": {},
   "source": [
    "Notons que, pour l'incrémentation, la syntaxe plus compacte `+=` sera souvent utilisée :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cc14f6de",
   "metadata": {},
   "outputs": [],
   "source": [
    "a = 6\n",
    "a += 1\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d3a4c897",
   "metadata": {},
   "source": [
    "Cette syntaxe s'étend d'ailleurs à de nombreux opérateurs : \n",
    "+ `x *= 2` pour doubler le contenu de la variable `x`;\n",
    "+ `y -= 3` pour ôter $3$ au contenu de la variable `y`;\n",
    "+ `z %= 10` pour ne garder de `z` que son chiffre des unités; \n",
    "+ etc.\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "## Chaînes de caractères\n",
    "\n",
    "Python permet de manipuler d'autres structures de données que des nombres. Par exemple, les **chaînes de caractères** permettent de stocker du texte. Elles sont définies par des guillemets (simples `'` ou doubles `\"`, c'est équivalent).\n",
    "\n",
    "**Question.** Affecter à la variable `a` la chaîne de caractère \"Hello\"."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "aaed01d4",
   "metadata": {},
   "outputs": [],
   "source": [
    "a = \"Hello\"\n",
    "a"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a023854e",
   "metadata": {},
   "source": [
    "On peut également **concaténer** (= mettre à la suite) deux chaînes de caractères. Pour cela on utilise une nouvelle fois l'opérateur `+`. \n",
    "\n",
    "**Question.** Affecter à la variable `b` la chaîne de caractère \"world\". Puis, afficher la concaténation de `a`, d'un espace, et de la variable `b`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8766b6e5",
   "metadata": {},
   "outputs": [],
   "source": [
    "b = \"world\"\n",
    "print(a + \" \" + b)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "62d43aad",
   "metadata": {},
   "source": [
    "**Remarque.** L'opérateur `+` peut donc s'appliquer à la fois à des nombres, et à des chaînes de caractères. Il n'a pas le même rôle dans ces deux cas : on parle de **surcharge d'opérateur**.\n",
    "\n",
    "\n",
    "On souhaite maintenant répéter plusieurs fois une même chaîne de caractères. Plutôt que d'appliquer l'opérateur `+` un certain nombre de fois, on peut utiliser l'opérateur `*`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5b8ca607",
   "metadata": {},
   "outputs": [],
   "source": [
    "'a' * 12"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cff8cfba",
   "metadata": {},
   "source": [
    "Enfin, on peut accéder à la **longueur** d'une chaîne de caractère (c'est-à-dire, son nombre de caractères), par la **fonction** `len()` :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "82a47d72",
   "metadata": {},
   "outputs": [],
   "source": [
    "len('Hello')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "00171e05",
   "metadata": {},
   "source": [
    "La chaîne de caractère vide `\"\"` existe et a une longueur nulle :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f903cc93",
   "metadata": {},
   "outputs": [],
   "source": [
    "len(\"\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e7415d08",
   "metadata": {},
   "source": [
    "## Valeurs logiques\n",
    "\n",
    "Python permet de manipuler des valeurs logiques booléennes (vrai ou faux). La valeur \"vraie\" est représentée par `True` et la valeur \"fausse\" par `False`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "793a15d0",
   "metadata": {},
   "outputs": [],
   "source": [
    "True"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "df7c3f0c",
   "metadata": {},
   "source": [
    "On peut effectuer des opérations sur les valeurs booléennes. La négation s'écrit `not`, le \"et\" logique `and` et le \"ou inclusif\" logique `or`.\n",
    "\n",
    "\n",
    "**Question.** Afficher la table logique de \"et\"."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ea529642",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(True and True)\n",
    "print(True and False)\n",
    "print(False and True)\n",
    "print(False and False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7265a6c4",
   "metadata": {},
   "source": [
    "## Comparaisons\n",
    "\n",
    "Les valeurs logiques sont souvent issues de comparaisons entre objets (égalité, différence, inégalité, etc.). Voici un tableau des opérations de comparaison possibles pour des nombres :\n",
    "\n",
    "\n",
    "| Comparaison | Syntaxe python (avec deux variables `a` et `b`) |\n",
    "| :---: | :---: |\n",
    "| Égal  | `a == b` | \n",
    "| Différent  | `a != b` | \n",
    "| Strictement inférieur  | `a < b` | \n",
    "| Inférieur ou égal  | `a <= b` | \n",
    "| Strictement supérieur  | `a > b` | \n",
    "| Supérieur ou égal  | `a >= b` | \n",
    "\n",
    "\n",
    "\n",
    "**Question.** Affecter $15$ et $8$ aux variables `a` et `b`. Puis, tester si leur somme est égale à $23$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5f39e3ad",
   "metadata": {},
   "outputs": [],
   "source": [
    "a = 15\n",
    "b = 8\n",
    "a + b == 23"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0405b6e8",
   "metadata": {},
   "source": [
    "**Question.** Tester si $2^{13} < 4000$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7ee7367e",
   "metadata": {},
   "outputs": [],
   "source": [
    "2 ** 13 < 4000"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dcec8e86",
   "metadata": {},
   "source": [
    "**Question.** Tester si $5+7 \\ge 12$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9a878a0a",
   "metadata": {},
   "outputs": [],
   "source": [
    "5 + 7 >= 12 "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "54899968",
   "metadata": {},
   "source": [
    "**Question.** Tester si $a \\ne 1$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9d3c0636",
   "metadata": {},
   "outputs": [],
   "source": [
    "a != 1"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2eff7633",
   "metadata": {},
   "source": [
    "On peut également effectuer des tests sur des chaînes de caractères, notamment l'égalité.\n",
    "\n",
    "**Question.** Vérifier que l'on peut utiliser de manière équivalente les guillemets simples et les guillements doubles pour définir une chaîne de caractères."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d9d74615",
   "metadata": {},
   "outputs": [],
   "source": [
    "\"Hello\" == 'Hello'"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "accdfd75",
   "metadata": {},
   "source": [
    "## Tests et conditions\n",
    "\n",
    "Dans un algorithme, on peut vouloir effectuer des instructions **selon si** une condition est vérifiée (ou non). Par exemple, dans le morceau de code suivant, on teste si le contenu de la variable `x` est strictement positive, et si c'est le cas, on affiche le texte \"Positif\"."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ce23c4ff",
   "metadata": {},
   "outputs": [],
   "source": [
    "x = 1\n",
    "if (x > 0):\n",
    "    print(\"Positif\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5019f427",
   "metadata": {},
   "source": [
    "Le bloc syntaxique doit être **impérativement respecté** : \n",
    "```\n",
    "if (test):\n",
    "    instructions\n",
    "```\n",
    "Notez la présence du mot-clef `if`, suivi d'un test et du caractère `:` en fin de première ligne. Puis, apès un retour à la ligne, les instructions sont **indentées** (il faut utiliser la touche de tabulation &#x21B9;).\n",
    "\n",
    "\n",
    "\n",
    "Pour ajouter le cas où la condition **n'est pas** satisfaite, on utilise le mot-clef `else` :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "11564356",
   "metadata": {},
   "outputs": [],
   "source": [
    "x = -1\n",
    "if (x > 0):\n",
    "    print(\"Positif\")\n",
    "else:\n",
    "    print(\"Négatif\")\t"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e8dd27eb",
   "metadata": {},
   "source": [
    "Enfin, on peut introduire un second test dans le cas où la première condition n'est pas satisfaite, avec le mot-clef `elif` (compression de `else` et `if`)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "592bde90",
   "metadata": {},
   "outputs": [],
   "source": [
    "x = 0\n",
    "if (x > 0):\n",
    "    print(\"Positif\")\n",
    "elif (x == 0):\n",
    "    print(\"Nul\")\n",
    "else:\n",
    "    print(\"Négatif\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f4a53ed7",
   "metadata": {},
   "source": [
    "## Fonctions\n",
    "\n",
    "\n",
    "En programmation, il est d'usage de placer des instructions dans des **fonctions**, destinées à ensuite être réutisées avec divers **arguments** (aussi appelés **paramètres**).\n",
    "\n",
    "\n",
    "La **signature** d'une fonction consiste en son nom et la description de ses arguments. Par exemple, si l'on souhaite nommer une fonction `ma_fonction` et ses arguments sont `arg1` et `arg2` (par exemple), alors sa **signature** sera :\n",
    "```\n",
    "ma_fonction(arg1, arg2)\n",
    "```\n",
    "\n",
    "**Remarque (avancée).** Il n'est pas nécessaire de donner le type des arguments, ni celui de la valeur de sortie de la fonction (mais on peut le faire à titre indicatif).\n",
    "\n",
    "\n",
    "En python, une fonction est **déclarée** avec le mot clef `def`.  Voici un exemple de la déclaration d'une fonction qui permet de calculer l'aire d'un triangle, étant donnée sa base et sa hauteur."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "08ecb9b8",
   "metadata": {},
   "outputs": [],
   "source": [
    "def aire_triangle(base, hauteur):\n",
    "    resultat = (base * hauteur) / 2\n",
    "    return resultat"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "16a156aa",
   "metadata": {},
   "source": [
    "On observe la présence du mot-clef `return` qui permet de **retourner une valeur**. Ce mot-clef n'est pas obligatoire dans la déclaration d'une fonction, mais s'il est absent, alors la fonction ne **retournera rien**.\n",
    "\n",
    "Après l'avoir déclarée, on peut ensuite **appeler** cette fonction avec des arguments quelconques."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8bc60a32",
   "metadata": {},
   "outputs": [],
   "source": [
    "aire_triangle(12, 5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ad7c8868",
   "metadata": {},
   "outputs": [],
   "source": [
    "aire_triangle(2.5, 4)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "385fc3f3",
   "metadata": {},
   "source": [
    "Dans la déclaration d'une fonction, on peut bien sûr appeler d'autres fonctions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "789728b1",
   "metadata": {},
   "outputs": [],
   "source": [
    "def plus_grand_triangle(base1, hauteur1, base2, hauteur2):\n",
    "    aire1 = aire_triangle(base1, hauteur1)\n",
    "    aire2 = aire_triangle(base2, hauteur2)\n",
    "    if aire1 > aire2:\n",
    "        return 1\n",
    "    else:\n",
    "        return 2\n",
    "        \n",
    "plus_grand_triangle(12, 5, 2.5, 4)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "python",
   "language": "python",
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
