{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Les fonctions (en Python 3)\n", "___\n", "\n", "Références de cette section :\n", " - [Le cours Moodle sur les fonctions](https://moodle.insa-toulouse.fr/course/view.php?id=1090#section-3)\n", " - [The Python Language Reference -- Function definitions](https://docs.python.org/3/reference/compound_stmts.html#function-definitions)\n", " - [The Python Tutorial -- Functions](https://docs.python.org/3/tutorial/controlflow.html#defining-functions)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Propagande : pourquoi les fonctions sont importantes\n", "\n", "Un point essentiel en informatique (en fait, dans toute discipline scientifique) est la possibilité de raisonner par **abstraction**.\n", "\n", "Dans un langage de programmation, l'abstraction se traduit en premier lieu par la possibilité de définir des **fonctions** qui permettent de répéter plusieurs fois un même algorithme, ou simplement de cacher (on dit \"abstraire\") les détails d'un algorithme.\n", "\n", "Python permet de définir très simplement des fonctions. Mieux : les fonctions sont des objets standards en Python (on dit que ce sont des valeurs de première classe) -- nous en reparlons en cours de programmation fonctionnelle, en 4ème année info.\n", "\n", "D'autres abstractions sont nécessaires pour le développement de logiciels conséquents : la\n", "*généricité*, la *modularité*, l'encapsulation (la possibilité de définir des **types abstraits**), etc. . Pour l'instant (en 2018), Python n'est pas encore à la hauteur sur tous ces points, en particulier l'encapsulation et la définition de types abstraits. Il ne devrait donc pas être utilisé pour du développement logiciel de qualité \"industrielle\". Il est probable toutefois que le langage évolue à l'avenir.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Définition de fonction, la base\n", "\n", "Un exemple suffit:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%reset -f\n", "\n", "## Carré signé\n", "def carre_signe(x):\n", " \"\"\"\n", " carre_signe(x) renvoie la valeur x^2, mais en préservant le signe de x.\n", " (Je ne garantis pas que cette fonction soit réellement utile.)\n", " \n", " Invariants : | carre_signe(x) | = x^2 \n", " et carre_signe(x) >= 0 <=> x >= 0\n", " \"\"\"\n", " if x >= 0:\n", " return x*x\n", " else:\n", " return -(x*x)\n", " \n", " \n", "print(carre_signe(4))\n", "print(carre_signe(-3))\n", "\n", "## CTRL+ENTER ... ESC+o" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " - **def** est le mot clef pour définir une fonction\n", " - La chaîne de caractères entre trois guillemets \"\"\" s'appelle une [documentation string](https://docs.python.org/3/tutorial/controlflow.html#documentation-strings). Bien qu'optionnelle, c'est une excellente idée d'introduire la documentation au sein même de la définition de la fonction.\n", " \n", " Pour accéder à la documentation d'une fonction :" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "## À exécuter juste après avoir exécuté le bloc ci-dessus, qui définit carre_signe.\n", "help(carre_signe)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Exercice rapide\n", "\n", " - Facile : obtenez l'aide pour la fonction print() (dans le cadre de code ci-dessous)\n", "\n", " - Moins facile : rappelez-vous de la méthode pop() invoquée sur une liste dans la leçon sur le WHILE. Trouvez comment obtenir l'aide pour cette méthode.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%reset -f\n", "\n", "## Obtenez l'aide pour la fonction print.\n", "print(\"The cake is a lie.\")\n", "\n", "## Obtenez l'aide pour la méthode pop des listes :\n", "sequence = [1,2,3]\n", "sequence.pop()\n", "\n", "## Si vous obtenez l'aide pour la classe int (les entiers), c'est que vous avez raté quelque chose.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Fonction qui renvoie None (procédure)\n", "\n", "Une fonction qui ne renvoie rien (comme une procédure en Ada), est en réalité une fonction qui renvoie ```None```.\n", "\n", "Prévoyez ce qu'affiche le code ci-dessous (attention, il faut bien réfléchir). Si vous parvenez à prévoir TOUT ce qui est affiché, vous pouvez vous déclarer Guerrier Dragon du None (et non l'inverse). " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "## Ces deux fonctions sont équivalentes, à la prononciation près.\n", "\n", "def say_hello():\n", " print(\"Hi.\")\n", " \n", "def say_bonjour():\n", " print(\"Aïl.\")\n", " return None ## Il n'y a en général aucune raison d'écrire return None\n", "\n", "res1 = say_hello()\n", "res2 = say_bonjour()\n", "\n", "print(\"=========\")\n", "\n", "## Ces print devraient vous paraître bizarre.\n", "## Ils servent à afficher la valeur renvoyée par les fonctions.\n", "print(res1)\n", "print(\"--------\")\n", "print(res2)\n", "\n", "print(\"=========\")\n", "\n", "## À votre avis, que renvoie ce test ?\n", "\n", "if say_hello() == say_bonjour():\n", " print(\"Même valeur\")\n", "else:\n", " print(\"Différents.\")\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "