{ "cells": [ { "cell_type": "markdown", "id": "9d80ce9d", "metadata": {}, "source": [ "# Huitième exercice en Python (Niveau Lycée)" ] }, { "cell_type": "markdown", "id": "a9f6c8c6", "metadata": {}, "source": [ "" ] }, { "cell_type": "markdown", "id": "ecbdb248", "metadata": {}, "source": [ "Quelques explications sur la **notation polonaise inverse** (**RPN**), utilisée par exemple sur les calculatrices de la marque HP (vidéo sur ma chaine Youtube pour en savoir plus) :" ] }, { "attachments": {}, "cell_type": "markdown", "id": "bb2c5af0", "metadata": {}, "source": [ "" ] }, { "cell_type": "markdown", "id": "75ae8941", "metadata": {}, "source": [ "Utilisez ce simulateur pour faire les calculs ci-dessous :\n", "\n", "
2 ENTER 3 +\n",
    "Affichage : 5\n",
    "\n",
    "3 ENTER 4 ENTER 5 * +\n",
    "Affichage : 23
" ] }, { "cell_type": "markdown", "id": "4dbba5ba", "metadata": {}, "source": [ "Ces calculatrices utilisent une **pile** (**stack**) pour placer (**empiler**) les valeurs (**opérandes**) et les calculs sont effectués dès que l'on appuie sur un **opérateur** (+, -, *, sin, etc.). Pour cela la machine dépile 1 ou plusieurs éléments sur le principe du \"dernier arrivé, premier sorti\" (LIFO = Last In First Out). Pour des opérateurs **dyadiques** comme l'**addition** ou la **multiplication**, il faut dépiler **2 éléments**. Pour un opérateur **monadique**, comme **sinus**, on ne dépile qu'**une seule valeur**." ] }, { "cell_type": "markdown", "id": "9e1c6706", "metadata": {}, "source": [ "Reprenons les étapes de l'exemple proposé dans l'énoncé : `5 1 2 + 4 * + 3 -`\n", "\n", "
5 ENTER 1 ENTER 2  // Pile = 5 | 1 | 2     (3 éléments empilés)\n",
    "+                  // Pile = 5 | 3         (calcul 1 + 2 = 3)\n",
    "4                  // Pile = 5 | 3 | 4     (4 empilé)\n",
    "*                  // Pile = 5 | 12        (calcul 3 * 4 = 12)\n",
    "+                  // Pile = 17            (calcul 5 + 12 = 17) \n",
    "3                  // Pile = 17 | 3        (3 empilé)\n",
    "-                  // Pile = 14            (calcul 17 - 3 = 14) 
\n", "\n", "Un des intérêts du RPN est qu'il n'y a pas **besoin de parenthèses**, d'ailleurs vous n'en trouverez pas sur les anciennes calculatrices HP." ] }, { "cell_type": "markdown", "id": "71e7e345", "metadata": {}, "source": [ "Les **piles** sont simplement des **listes** où l'on va pouvoir **empiler** et/ou **dépiler** des éléments :" ] }, { "cell_type": "code", "execution_count": 1, "id": "75f3e4e1", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[2, 9]" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pile = [ ] # pile vide\n", "pile.append(2) # on empile la valeur 2\n", "pile.append(9) # et la valeur 9\n", "pile" ] }, { "cell_type": "code", "execution_count": 2, "id": "4a9d5794", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[2]" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pile.pop() # On dépile suivant \"Last In First Out\"\n", "pile" ] }, { "cell_type": "markdown", "id": "86b4f9cf", "metadata": {}, "source": [ "## Evaluer une expression en python et javascript" ] }, { "cell_type": "markdown", "id": "b050d504", "metadata": {}, "source": [ "Une première solution est d'utiliser `eval` :" ] }, { "cell_type": "code", "execution_count": 3, "id": "e419a222", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "5" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "eval('2 + 3')" ] }, { "cell_type": "markdown", "id": "36fabfbb", "metadata": {}, "source": [ "Une autre idée est de voir **2 + 3** comme **l'opérateur** `+` appliqué aux **opérandes** `2` et `3`, c'est-à-dire `+(2,3)`. C'est tout simplement la notation `f(x,y)` utilisée en mathématique." ] }, { "cell_type": "code", "execution_count": 4, "id": "d1c3cf40", "metadata": {}, "outputs": [], "source": [ "OPS = { \\\n", " '+': lambda x, y: x + y, '-': lambda x, y: x - y, \\\n", " '*': lambda x, y: x * y, '/': lambda x, y: x / y \\\n", " }" ] }, { "cell_type": "code", "execution_count": 5, "id": "9e066011", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "5" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "OPS['+'](2,3)" ] }, { "cell_type": "markdown", "id": "59916de4", "metadata": {}, "source": [ "## Idée du programme" ] }, { "cell_type": "markdown", "id": "4a541e34", "metadata": {}, "source": [ "Gardons l'exemple : `5 1 2 + 4 * + 3 -`" ] }, { "cell_type": "markdown", "id": "d411b272", "metadata": {}, "source": [ "On va **séparer** (`split`) les différents éléments de la chaine puis, en partant de la gauche, **empiler si** c'est un **nombre**, sinon **si** c'est un **opérateur**, **dépiler** les **2 derniers** éléments (les 4 opérateurs `+-/*` étant tous dyadiques), effectuer le **calcul** et **empiler** le résultat." ] }, { "cell_type": "markdown", "id": "882ef3cb", "metadata": {}, "source": [ "
On empile 5 puis 1 puis 2\n",
    "'+' étant un opérateur dyadique, on dépile 1 et 2\n",
    "On effectue le calcul +(1,2) qui donne 3\n",
    "On empile cette valeur, etc.
" ] }, { "cell_type": "code", "execution_count": 6, "id": "0af84e9e", "metadata": {}, "outputs": [], "source": [ "def calc(s):\n", " OPS = { \\\n", " '+': lambda x, y: x + y, '-': lambda x, y: x - y, \\\n", " '*': lambda x, y: x * y, '/': lambda x, y: x / y \\\n", " }\n", " pile = [ ] # Pile vide\n", " for v in s.split(): # On parcourt les éléments\n", " if v in OPS: # Est-ce un opérateur ?\n", " b, a = pile.pop(), pile.pop() # on dépile 2 éléments\n", " pile.append(OPS[v](a, b)) # calcul + empiler le résultat\n", " else: # sinon\n", " pile.append(float(v)) # on empile la valeur\n", " return pile.pop() # Contenu de la pile" ] }, { "cell_type": "code", "execution_count": 7, "id": "acd9363c", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "14.0" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "calc('5 1 2 + 4 * + 3 -')" ] }, { "cell_type": "code", "execution_count": 8, "id": "d7d8d068", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "6.0" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "calc('3.5 2.5 +')" ] } ], "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.6" } }, "nbformat": 4, "nbformat_minor": 5 }