{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Université d’Orléans - Licence 1 semestre 1 - 2026-27  <br>  Programmation et Algorithmique 1      \n",
    "<h3 align=\"center\">TP optionnel</h3>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h4>Présentation générale</h4>\n",
    "\n",
    "<ul>\n",
    "    <li>Dans ce TP nous travaillerons essentiellement sur les chaînes de caractères et sur les listes. </li>\n",
    "    <li>Nous appliquerons des méthodes spécifiques des <i>str</i> et des <i>list</i> et nous définirons des fonctions que nous appliquerons à ces objets.</li>\n",
    "   </ul>\n",
    "\n",
    "<h5>Le thème du TP</h5> \n",
    "Nous travaillerons sur les expressions algébriques données sous formes de chaînes de caractères, comme par exemple \"31 + 2 * 7 - 51 / 3 + 15 - 8 * 17\", ou encore \"3 * 41 - 2 * 7\". Nous les appellerons des \"chaînes algébriques\".\n",
    "\n",
    "Cette première version traitera les expressions <b>sans parenthèses</b>.\n",
    "\n",
    "<h5>L'objectif du TP</h5>\n",
    "Nous allons créer des fonctions et un programme principal où sont effectués divers traitements sur ces chaînes algébriques, avec une évaluation numérique finale de l'expression. Le cours sur les méthodes appliquées aux <i>str</i> et aux <i>list</i> sera d'une aide importante.\n",
    "\n",
    "<h5>Les tests</h5>\n",
    "Les questions posées sont pour la plupart accompagnées de <b>tests déjà écrits</b> qu'il faut valider avant de continuer."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "## Exercice 1 - simplification d'une chaîne algébrique\n",
    "\n",
    "\n",
    "Une chaîne algébrique peut parfois, de façon plus ou moins régulière selon l'auteur, comporter des espaces inutiles. Par exemple \"3 + 4 * 2\" contient 4 espaces inutiles et peut se résumer à l'expression simplifiée \"3+4*2\".\n",
    "\n",
    "Complétez le code de la fonction suivante qui retourne une chaîne algébrique où les espaces ont tous été supprimés.\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def simplifier(expr) :\n",
    "    # retourne une chaîne algébrique égale à expr, sans ses espaces.\n",
    "    pass\n",
    "\n",
    "# tests de la fonction\n",
    "expr1 = \"-3 + 4 * 2 - 8/ 9\"\n",
    "expr2 = \" 25+  12  - 6 *17\"\n",
    "expr3 = \"5 + 121 * 18  -3 \"\n",
    "\n",
    "exprsimp1 = simplifier(expr1)\n",
    "exprsimp2 = simplifier(expr2)\n",
    "exprsimp3 = simplifier(expr3)\n",
    "\n",
    "print(expr1, \"  =>  \", exprsimp1, \", ... simplification ok ?  \", exprsimp1 == \"-3+4*2-8/9\")\n",
    "print(expr2, \"  =>  \", exprsimp2, \", ... simplification ok ?  \", exprsimp2 == \"25+12-6*17\")\n",
    "print(expr3, \"  =>  \", exprsimp3, \", ... simplification ok ?  \", exprsimp3 == \"5+121*18-3\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "## Exercice 2 - validation d'une chaîne algébrique\n",
    "\n",
    "Pour pouvoir être évaluée numériquement, une chaîne algébrique doit être valide, et donc respecter certaines conditions. Sa chaîne simplifiée doit :\n",
    "\n",
    "<ul>\n",
    "    <li> contenir exclusivement des caractères de \"0123456789+-*/\" ;</li> \n",
    "    <li> commencer par un chiffre ou par le caractère \"-\", suivi d'un chiffre ;</li>\n",
    "    <li> finir par un chiffre ;</li>\n",
    "    <li> ne jamais avoir deux opérateurs à la suite (un opérateur est un caractère de \"+-*/\"). Cette condition est plus difficile !</li>\n",
    "</ul>\n",
    "    \n",
    "\n",
    "Complétez le code des fonctions c1, c2, c3, c4 correspondant aux 4 conditions ci-dessus. Ces fonctions prennent un argument qui sera une chaîne algébrique pas forcément simplifiée, et retournent un booléen disant si oui ou non la condition est validée.\n",
    "\n",
    "Enfin, complétez le code de la fonction est_valide qui dit si oui ou non la chaîne algébrique passée en paramètre respecte simultanément les 4 conditions.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def c1(expr) :\n",
    "    # dit si oui ou non la simplification de expr ne contient \n",
    "    # que des caractères de \"0123456789+-*/\"\n",
    "    pass\n",
    "\n",
    "def c2(expr) :\n",
    "    # dit si oui ou non la simplification de expr commence par un chiffre, \n",
    "    # ou bien par un \"-\" suivi d'un chiffre\n",
    "    pass\n",
    "\n",
    "def c3(expr) :\n",
    "    # dit si oui ou non la simplification de expr finit par un chiffre, \n",
    "    pass\n",
    "\n",
    "def c4(expr) :\n",
    "    # dit si oui ou non la simplification de expr ne contient jamais  \n",
    "    # deux opérateurs consécutifs\n",
    "    pass\n",
    "\n",
    "def est_valide(expr) :\n",
    "    # dit si oui ou non la chaîne algébrique valide les 4 conditions précédentes\n",
    "    pass\n",
    "\n",
    "# tests des fonctions\n",
    "expr4 = \"6 - 2 + 7 + 3 +  \"\n",
    "expr5 = \"6 -2+6 * * 5 ++ 4\"\n",
    "expr6 = \"31 - 878 +- 719 +\"\n",
    "\n",
    "print(expr1, \" ... expression valide ?  \", est_valide(expr1), \"(attendu = True)\")\n",
    "print(expr2, \" ... expression valide ?  \", est_valide(expr2), \"(attendu = True)\")\n",
    "print(expr3, \" ... expression valide ?  \", est_valide(expr3), \"(attendu = True)\")\n",
    "print(expr4, \" ... expression valide ?  \", est_valide(expr4), \"(attendu = False)\")\n",
    "print(expr5, \" ... expression valide ?  \", est_valide(expr5), \"(attendu = False)\")\n",
    "print(expr6, \" ... expression valide ?  \", est_valide(expr6), \"(attendu = False)\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Exercice 3\n",
    "\n",
    "On va maintenant extraire deux listes d'une chaîne algébrique : celle des opérateurs, et celle des opérandes.\n",
    "\n",
    "Par exemple, pour la chaîne \"5 + 121 - 18 * 3\", on extraiera : \n",
    "\n",
    "<ul>\n",
    "    <li> la liste [5, 121, 18, 3] des opérandes ;</li>\n",
    "    <li> la liste ['+', '-', '*'] des opérateurs ;</li>\n",
    "</ul>\n",
    "\n",
    "Par contre, pour la chaîne \"-5 + 121 - 18 * 3\", on extraiera : \n",
    "\n",
    "<ul>\n",
    "    <li> la liste [-5, 121, 18, 3] des opérandes ;</li>\n",
    "    <li> la liste ['+', '-', '*'] des opérateurs ;</li>\n",
    "</ul>\n",
    "\n",
    "En effet, dans ce cas seulement, le signe \"-\" est incorporé à l'entier.\n",
    "\n",
    "<ol>\n",
    "    <li> Pour la liste des opérandes :\n",
    "        <ul>\n",
    "            <li> commencer par récupérer, dans une variable, la chaîne algébrique simplifiée ;</li>\n",
    "            <li> remplacer ensuite dans cette variable tous les opérateurs (sauf l'éventuel signe \"-\" initial) par \"%\" ;</li>\n",
    "            <li> récupérer, grâce à une certaine méthode des chaînes, la liste obtenue par découpage au moyen du séparateur \"%\" ;</li>\n",
    "            <li> retourner ensuite une liste obtenue par conversion de chaque élément de la précédente en int.</li>\n",
    "        </ul>\n",
    "    </li>\n",
    "    <br>\n",
    "    <li> Pour la liste des opérateurs :\n",
    "        <ul>\n",
    "            <li> commencer par récupérer, dans une variable, la chaîne algébrique simplifiée ;</li>\n",
    "            <li> récupérer ensuite la liste des opérandes ; </li>\n",
    "            <li> dans la chaîne algébrique simplifiée, remplacer chaque opérande (sa conversion en str) par \"%\". Ainsi, il ne restera que les opérateurs (même pas un \"-\" initial) ;</li>\n",
    "            <li> retourner de cette liste la sous-liste excluant les éléments qui ne sont pas des opérateurs. </li>\n",
    "        </ul>\n",
    "    </li>\n",
    "</ol>\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def operandes(expr) :\n",
    "    pass\n",
    "\n",
    "def operateurs(expr) :\n",
    "    pass\n",
    "    \n",
    "\n",
    "\n",
    "# tests de la fonction\n",
    "print(expr1, \" ... opérandes  = \", operandes(expr1), \"       (attendu = [-3, 4, 2, 8, 9])\")\n",
    "print(expr1, \" ... opérateurs = \", operateurs(expr1), \"   (attendu = ['+', '*', '-', '/'])\")\n",
    "print(expr2, \" ... opérandes  = \", operandes(expr2), \"        (attendu = [25, 12, 6, 17])\")\n",
    "print(expr2, \" ... opérateurs = \", operateurs(expr2), \"        (attendu = ['+', '-', '*'])\")\n",
    "print(expr3, \" ... opérandes  = \", operandes(expr3), \"        (attendu = [5, 121, 18, 3])\")\n",
    "print(expr3, \" ... opérateurs = \", operateurs(expr3), \"        (attendu = ['+', '-', '*'])\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Exercice 4\n",
    "\n",
    "Nous allons ici définir deux nouvelles fonctions essentielles :\n",
    "\n",
    "<ul>\n",
    "    <li> une fonction qui prendra en charge 3 paramètres : 2 opérandes et un opérateur. Elle retournera le résultat de l'opération entre le premier et le deuxième opérande, selon l'opérateur ;</li>\n",
    "    <li> une fonction qui retourne la priorité d'un opérateur passé en paramètre : ce sera 1 pour '+' et '-', et 2 pour '*' et '/'.</li>\n",
    "</ul>\n",
    "\n",
    "Codez ces deux fonctions.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def operation(a, op, b) :\n",
    "    pass\n",
    "\n",
    "def priorite(op) :\n",
    "    pass\n",
    "\n",
    "# tests de la fonction\n",
    "print(\"21 + 7 ...\", operation(21, \"+\", 7))\n",
    "print(\"21 * 7 ...\", operation(21, \"*\", 7))\n",
    "print(\"21 - 7 ...\", operation(21, \"-\", 7))\n",
    "print(\"21 / 7 ...\", operation(21, \"/\", 7))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Exercice 5\n",
    "\n",
    "Nous allons coder une fonction **evaluer(expr)** qui va donner le résultat de l'évaluation de la chaîne algébrique passée en paramètre.\n",
    "\n",
    "Pour cela, nous aurons besoin des opérandes et des opérateurs. \n",
    "Voici ce qui va se passer, sur trois exemples.\n",
    "\n",
    "#### exemple 1 :\n",
    "\n",
    "<ul>\n",
    "    <li>on part de expression = \"-3 + 4\"</li>\n",
    "    <li>l'expression simplifiée sera \"-3+4\"</li>\n",
    "    <li>les opérandes : [-3, 4]</li>\n",
    "    <li>les opérateurs : ['+']</li>\n",
    "    <li>comme il n'y a qu'un seul opérateur, il suffit d'extraire les 2 opérandes et l'opérateur, de calculer l'opération et d'afficher le résultat.</li>\n",
    "</ul>\n",
    "\n",
    "#### exemple 2 :\n",
    "\n",
    "<ul>\n",
    "    <li>on part de expression = \"-3 + 4 * 7\"</li>\n",
    "    <li>l'expression simplifiée sera \"-3+4*7\"</li>\n",
    "    <li>les opérandes : [-3, 4, 7]</li>\n",
    "    <li>les opérateurs : ['+', '*']</li>\n",
    "    <li>si on procéde comme au premier exemple, on ne respectera pas la priorité du '*' sur le '+'. on va donc :\n",
    "        <ul>\n",
    "            <li>extraire le deuxième et le troisième opérande, ainsi que le deuxième opérateur.</li>\n",
    "            <li>effectuer l'opération, puis réinsèrer le résultat à sa bonne place.</li>\n",
    "            <li>on arrive à : [-3, 28] et ['+'], et on retombe dans le premier cas (seulement 2 opérandes)</li>\n",
    "        </ul>\n",
    "    </li>\n",
    "</ul>\n",
    "\n",
    "\n",
    "#### exemple 3 :\n",
    "\n",
    "<ul>\n",
    "    <li>on part de expression = \"-3 + 4 - 7\"</li>\n",
    "    <li>l'expression simplifiée sera \"-3+4-7\"</li>\n",
    "    <li>les opérandes : [-3, 4, 7]</li>\n",
    "    <li>les opérateurs : ['+', '-']</li>\n",
    "    <li>ici les deux premiers opérateurs ont la même priorité, on fait donc le calcul entre les deux premiers opérandes :\n",
    "        <ul>\n",
    "            <li>on extraite le premier opérande, le deuxième et le premier opérateur.</li>\n",
    "            <li>on effectue le caalcul, et on réinsère le résultat à sa bonne place parmi les opérandes.</li>\n",
    "            <li>on arrive à : [-3, 28] et ['+'], et on retombe dans le premier cas (seulement 2 opérandes)</li>\n",
    "        </ul>\n",
    "    </li>\n",
    "</ul>\n",
    "\n",
    "<br>\n",
    "En vous inspirant de ces trois exemples, codez la fonction <b>evaluer(expr)</b>\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def evaluer(expr) :\n",
    "    pass\n",
    "       \n",
    "\n",
    "# tests de la fonction\n",
    "expression3 = \"-3 + 4 * 5 + 6 / 3 - 7\"\n",
    "print(expression3)\n",
    "print(simplifier(expression3))\n",
    "print(\"expression 3 valide ?\", est_valide(expression3))\n",
    "print(\"opérandes de expression 3  :\", operandes(expression3))\n",
    "print(\"opérateurs de expression 3 :\", operateurs(expression3))\n",
    "print(\"---\")\n",
    "evaluer(expression3)"
   ]
  }
 ],
 "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.12.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
