{ "metadata": { "name": "S1_Bases_Python" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "S\u00e9ance 1 : Introduction au langage Python" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "Formation Python du d\u00e9partement M\u00e9catronique" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "9h15 - 10h45\n", "\n", "Pr\u00e9sentation de l'\u00e9cosyst\u00e8me Python\u00a0: environnement de d\u00e9veloppement, notion de module.\n", "\n", "*Introduction au language Python :*\n", "\n", "1. Arithm\u00e9tique. Instructions et types de donn\u00e9es de bases. Boucles et conditions\n", "2. Manipulation de listes, de cha\u00eenes de caract\u00e8res\n", "3. Manipulation de fichiers (lecture, \u00e9criture)\n", "\n", "Apr\u00e8s cette introduction \u00e0 Python \"g\u00e9n\u00e9raliste\", la s\u00e9ance qui suit (S2) abordera Python \"num\u00e9rique\", c'est \u00e0 dire les modules sp\u00e9cialis\u00e9s pour le calcul scientifique et la visualisation." ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "A) Instructions et types de base" ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "A1) Un peu d'arithm\u00e9tique" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Python la calculette :" ] }, { "cell_type": "code", "collapsed": false, "input": [ "1+3" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 1, "text": [ "4" ] } ], "prompt_number": 1 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Les objets se d\u00e9finissent dynamiquement :" ] }, { "cell_type": "code", "collapsed": false, "input": [ "a = 3 # entier 'int'\n", "a = 3.3 # flottant 'float' \n", "2 * a" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 2, "text": [ "6.6" ] } ], "prompt_number": 2 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Attention \u00e0 la division avec les *nombres entiers*" ] }, { "cell_type": "code", "collapsed": false, "input": [ "print(1/2) # division euclidienne\n", "print(1./2)\n", "print(float(1)/2)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "0\n", "0.5\n", "0.5\n" ] } ], "prompt_number": 3 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Attention, l'exposant (puissance) ne s'\u00e9crit **pas avec '^'** :" ] }, { "cell_type": "code", "collapsed": false, "input": [ "5**2" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 4, "text": [ "25" ] } ], "prompt_number": 4 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Remarque : bien que le type d'une variable ne soit jamais indiqu\u00e9 explicitement, *chaque variable est bien typ\u00e9e*.\n", "\n", "Le type est r\u00e9cup\u00e9rable avec la fonction `type` :" ] }, { "cell_type": "code", "collapsed": false, "input": [ "a = 1.2e3 # notation scientifique 1,2 * 10\u00b3\n", "type(a)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 6, "text": [ "float" ] } ], "prompt_number": 6 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Nombre complexes : \n", "\n", "*\u00e0 vous de chercher sur Internet !* (la meilleure fa\u00e7on d'acc\u00e9der \u00e0 l'information)" ] }, { "cell_type": "code", "collapsed": false, "input": [ "b = 1 + 1j # 1 + i\n", "b**8" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 7, "text": [ "(16+0j)" ] } ], "prompt_number": 7 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "A2) Les listes, une collection ordonn\u00e9e d'objets" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Les listes en Python se notent avec des crochets **[ ]**.\n", "Ces m\u00eames crochets servent \u00e0 acc\u00e9der \u00e0 un \u00e9l\u00e9ment de la collection :" ] }, { "cell_type": "code", "collapsed": false, "input": [ "l = [10, 20, 30, 40, 50]\n", "l" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 8, "text": [ "[10, 20, 30, 40, 50]" ] } ], "prompt_number": 8 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pour acc\u00e9der \u00e0 un \u00e9l\u00e9ment (\"indexing\") on utilise aussi les crochets :" ] }, { "cell_type": "code", "collapsed": false, "input": [ "l[0] # les indices commencent \u00e0 0 (comme en C, javascript) et non \u00e0 1" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 9, "text": [ "10" ] } ], "prompt_number": 9 }, { "cell_type": "markdown", "metadata": {}, "source": [ "On peut indexer \u00e0 partir de la fin :" ] }, { "cell_type": "code", "collapsed": false, "input": [ "l[-1] # le dernier \u00e9l\u00e9ment" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 10, "text": [ "50" ] } ], "prompt_number": 10 }, { "cell_type": "markdown", "metadata": {}, "source": [ "On peut aussi obtenir des morceaux (\"slices\") de liste:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "l[1:3] # syntaxe [start:stop]" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 11, "text": [ "[20, 30]" ] } ], "prompt_number": 11 }, { "cell_type": "code", "collapsed": false, "input": [ "l[0:5:2] # syntaxe [start:stop:step]\n", "# identique \u00e0 l[::2]" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 12, "text": [ "[10, 30, 50]" ] } ], "prompt_number": 12 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Question : utiliser la syntax *start:stop:step* pour obtenir la liste renvers\u00e9e" ] }, { "cell_type": "code", "collapsed": false, "input": [ "# Une solution :\n", "l[::-1]" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 13, "text": [ "[50, 40, 30, 20, 10]" ] } ], "prompt_number": 13 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Les listes sont des objets *modifiables* (\"mutables\")" ] }, { "cell_type": "code", "collapsed": false, "input": [ "l[0] = 9\n", "l" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 14, "text": [ "[9, 20, 30, 40, 50]" ] } ], "prompt_number": 14 }, { "cell_type": "code", "collapsed": false, "input": [ "l.append(60) # append est une *m\u00e9thode* de la list\n", "l" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 15, "text": [ "[9, 20, 30, 40, 50, 60]" ] } ], "prompt_number": 15 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Apart\u00e9 sur les *m\u00e9thodes* et comment les d\u00e9couvrir : taper **l.** puis *TAB* dans IPython" ] }, { "cell_type": "code", "collapsed": false, "input": [ "# Les listes peuvent contenir des objets de types diff\u00e9rents:\n", "l2 = ['a', 'b', 'c', 4, 5, 6]" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 16 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Question : comment obtenir la longeur d'une liste ?" ] }, { "cell_type": "code", "collapsed": false, "input": [ "# Solution : fonction `len`\n", "len(l)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 17, "text": [ "6" ] } ], "prompt_number": 17 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notons enfin le comportement sp\u00e9cifique des op\u00e9rateurs **+** et ***** pour les listes :" ] }, { "cell_type": "code", "collapsed": false, "input": [ "[1,2,3] + [4] # concat\u00e9nation" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 18, "text": [ "[1, 2, 3, 4]" ] } ], "prompt_number": 18 }, { "cell_type": "code", "collapsed": false, "input": [ "[1]*10" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 19, "text": [ "[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]" ] } ], "prompt_number": 19 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "A3) Cha\u00eenes de caract\u00e8res (str)" ] }, { "cell_type": "code", "collapsed": false, "input": [ "nom = 'Fillon' # chaine 'str'\n", "prenom = u'Fran\u00e7ois' # chaine 'unicode', pour caract\u00e8res \"compliqu\u00e9s\"" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 21 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Question : qu'est-ce que l'addition (+) de 2 cha\u00eenes ?" ] }, { "cell_type": "code", "collapsed": false, "input": [ "print(prenom + ' ' + nom)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Fran\u00e7ois Fillon\n" ] } ], "prompt_number": 22 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Remarque importante : le m\u00e9lange des cha\u00eenes `unicode` et `str` est une tr\u00e8s mauvaise pratique.\n", "Python *version 3* r\u00e9sout ce probl\u00e8me : toutes les cha\u00eenes sont Unicode.\n", "\n", "Pour une bonne compr\u00e9hension des concepts tels qu'Unicode et les encodages de caract\u00e8rs, je recommande la vid\u00e9o [Pragmatic Unicode, or How Do I Stop the Pain ?](http://nedbatchelder.com/text/unipain.html). On y trouve aussi des \"bonnes pratiques\" pour r\u00e9soudre et pr\u00e9venir les probl\u00e8mes." ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "A4) Autres conteneurs : tuple, dict, set" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Les tuples** : ils ressemblent beaucoup aux listes..." ] }, { "cell_type": "code", "collapsed": false, "input": [ "a = (1,2,3)\n", "a[0]" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 23, "text": [ "1" ] } ], "prompt_number": 23 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Mais grande diff\u00e9rence, ils sont *\"immutables\"* (essayer `a. + Tab`)" ] }, { "cell_type": "code", "collapsed": false, "input": [ "a[0] = 2" ], "language": "python", "metadata": {}, "outputs": [ { "ename": "TypeError", "evalue": "'tuple' object does not support item assignment", "output_type": "pyerr", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0ma\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mTypeError\u001b[0m: 'tuple' object does not support item assignment" ] } ], "prompt_number": 24 }, { "cell_type": "markdown", "metadata": {}, "source": [ "On passe facilement d'un tuple \u00e0 une liste gr\u00e2ce \u00e0 la fonction constructeur `list` (et vice versa avec `tuple`)" ] }, { "cell_type": "code", "collapsed": false, "input": [ "a_list = list(a) # cr\u00e9\u00e9 une *copie* du tuple\n", "a_list" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 25, "text": [ "[1, 2, 3]" ] } ], "prompt_number": 25 }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Les dictionnaires** sont un mapping *cl\u00e9* -> *valeur*" ] }, { "cell_type": "code", "collapsed": false, "input": [ "annuaire = {u'Fran\u00e7ois' : u'\u00c9lys\u00e9e',\n", " 'Jean-Marc' : 'Matignon',\n", " 'Arnaud' : 'Bercy'}" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 26 }, { "cell_type": "code", "collapsed": false, "input": [ "# Indexation\n", "annuaire['Jean-Marc']\n", "# on peut \u00e9galement r\u00e9assigner une nouvelle valeur..." ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 27, "text": [ "'Matignon'" ] } ], "prompt_number": 27 }, { "cell_type": "code", "collapsed": false, "input": [ "# Ajout dynamique :\n", "annuaire['Manuel'] = 'Place Beauvau'\n", "annuaire" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 28, "text": [ "{'Arnaud': 'Bercy',\n", " u'Fran\\xe7ois': u'\\xc9lys\\xe9e',\n", " 'Jean-Marc': 'Matignon',\n", " 'Manuel': 'Place Beauvau'}" ] } ], "prompt_number": 28 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Autre conteneur : les ensembles `set` contiennent des valeurs uniques, non ordonn\u00e9es. Ils permettent les op\u00e9rations d'union, d'intersection." ] }, { "cell_type": "code", "collapsed": false, "input": [ "mes_films = {'Die Hard 25', 'Iron Man 7', 'Terminator 12'}" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 29 }, { "cell_type": "code", "collapsed": false, "input": [ "tes_films = {'Alien 10', 'Terminator 12', 'Iron Man 7'}\n", "mes_films.union(tes_films)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 30, "text": [ "set(['Iron Man 7', 'Alien 10', 'Terminator 12', 'Die Hard 25'])" ] } ], "prompt_number": 30 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "A5) Boucles et conditions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Les conditions se font avec `if` et `else` (et \u00e9ventuellement `elif` )" ] }, { "cell_type": "code", "collapsed": false, "input": [ "stock_choco = 3\n", "#stock_choco = 0\n", "\n", "if stock_choco > 0:\n", " print(u'Ins\u00e9rez une pi\u00e8ce puis servez vous...')\n", "else:\n", " print(u'D\u00e9sol\u00e9, plus de chocolat !')" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Ins\u00e9rez une pi\u00e8ce puis servez vous...\n" ] } ], "prompt_number": 31 }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Note importante** : en Python il n'y a pas de mot-clef \"end\". C'est simplement **l'indentation** qui marque la s\u00e9paration des blocs logiques." ] }, { "cell_type": "code", "collapsed": false, "input": [ "# Autres tests logiques :\n", "stock_choco == 0 # \"est \u00e9gal \u00e0\"\n", "stock_choco != 0 # \"est diff\u00e9rent de\"\n", "stock_choco >= 0" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 32, "text": [ "True" ] } ], "prompt_number": 32 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Les boucles s'expriment avec `for`" ] }, { "cell_type": "code", "collapsed": false, "input": [ "# it\u00e9ration \"classique\" sur des entiers\n", "for i in range(3):\n", " print(i)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "0\n", "1\n", "2\n" ] } ], "prompt_number": 33 }, { "cell_type": "markdown", "metadata": {}, "source": [ "notons au passage `range` est une fonction renvoyant une liste" ] }, { "cell_type": "code", "collapsed": false, "input": [ "# it\u00e9ration sur les \u00e9l\u00e9ment d'une liste\n", "tensions = [1.8, 3.3, 5, 230] # (volts)\n", "for t in tensions:\n", " print(t)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "1.8\n", "3.3\n", "5\n", "230\n" ] } ], "prompt_number": 34 }, { "cell_type": "markdown", "metadata": {}, "source": [ "(En plus des boucles `for`, il existe aussi boucles `while`)" ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "A6) Les erreurs" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "En Python les erreurs apparaissent *dynamiquement* (\u00e0 part les erreurs de syntaxe)\n", "\n", "Il y en a plusieurs \"types\"" ] }, { "cell_type": "code", "collapsed": false, "input": [ "if 2>1\n", " print(2)" ], "language": "python", "metadata": {}, "outputs": [ { "ename": "SyntaxError", "evalue": "invalid syntax (, line 1)", "output_type": "pyerr", "traceback": [ "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m if 2>1\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" ] } ], "prompt_number": 35 }, { "cell_type": "code", "collapsed": false, "input": [ "1 + '2'" ], "language": "python", "metadata": {}, "outputs": [ { "ename": "TypeError", "evalue": "unsupported operand type(s) for +: 'int' and 'str'", "output_type": "pyerr", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;36m1\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m'2'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mTypeError\u001b[0m: unsupported operand type(s) for +: 'int' and 'str'" ] } ], "prompt_number": 36 }, { "cell_type": "code", "collapsed": false, "input": [ "# transformer une chaine de caract\u00e8re en nombre flottant:\n", "float('1.2') # \u00e7a marche\n", "float('1/2') # \u00e7a non !\n", "float('1,2') # \u00e7a non plus (voir plus bas pour une solution)" ], "language": "python", "metadata": {}, "outputs": [ { "ename": "ValueError", "evalue": "invalid literal for float(): 1/2", "output_type": "pyerr", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m# transformer une chaine de caract\u00e8re en nombre flottant:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0mfloat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'1.2'\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# \u00e7a marche\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mfloat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'1/2'\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# \u00e7a non !\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m \u001b[0mfloat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'1,2'\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# \u00e7a non plus (voir plus bas pour une solution)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mValueError\u001b[0m: invalid literal for float(): 1/2" ] } ], "prompt_number": 37 }, { "cell_type": "code", "collapsed": false, "input": [ "1/0" ], "language": "python", "metadata": {}, "outputs": [ { "ename": "ZeroDivisionError", "evalue": "integer division or modulo by zero", "output_type": "pyerr", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mZeroDivisionError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;36m1\u001b[0m\u001b[0;34m/\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mZeroDivisionError\u001b[0m: integer division or modulo by zero" ] } ], "prompt_number": 38 }, { "cell_type": "markdown", "metadata": {}, "source": [ "*aller plus loin avec les erreurs*\n", "\n", "* utiliser le d\u00e9buggeur Python (le plus simple me semble \u00eatre mode \"d\u00e9buggage automatique\" d'Ipython, activ\u00e9 avec %pdb )\n", "* les \"attraper\" avec `try` et `except`\n", "\n", "G\u00e9rer les erreurs:\n", "\n", " try:\n", " 0/0\n", " except ZeroDivisionError:\n", " print('Houston, on a eu un probleme.')" ] }, { "cell_type": "code", "collapsed": false, "input": [ "%pdb" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Automatic pdb calling has been turned OFF\n" ] } ], "prompt_number": 85 }, { "cell_type": "markdown", "metadata": {}, "source": [ "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "*passage de la console IPython \u00e0 l'environnement de d\u00e9veloppement (IDE) Spyder*\n", "\n", "Instructions pour installer un \u00e9cosyst\u00e8me Python incluant Spyder : http://python-prepa.github.io/intro.html" ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "B) Fonctions, modules" ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "B1) Cr\u00e9er, utiliser des fonctions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Une t\u00e2che routini\u00e8re d'un code peut \u00eatre empaquet\u00e9e dans une fonction.\n", "\n", "Exemple de cahier des charges de fonction :\n", "\n", ">Comment ajouter un titre de Docteur au nom d'une personne ? (concat\u00e9nation de cha\u00eenes de caract\u00e8res)\n", "\n", "*Bonne pratique :* avant d'\u00e9crire une fonction dans un fichier, faire des essais avec des commandes interactives" ] }, { "cell_type": "code", "collapsed": false, "input": [ "nom = 'Georges'\n", "'Dr. ' + nom" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 39, "text": [ "'Dr. Georges'" ] } ], "prompt_number": 39 }, { "cell_type": "markdown", "metadata": {}, "source": [ "En Python, la d\u00e9finition d'une fonction se fait avec le mot-clef **def**,\n", "\n", "* suivi du *nom* de la fonction,\n", "* suivi des *arguments* entre parenth\u00e8ses" ] }, { "cell_type": "code", "collapsed": false, "input": [ "def diplomation(nom):\n", " nom_dipl = 'Dr. ' + nom\n", " return nom_dipl\n", "\n", "diplomation('Georges Dumont')" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 40, "text": [ "'Dr. Georges Dumont'" ] } ], "prompt_number": 40 }, { "cell_type": "markdown", "metadata": {}, "source": [ "On peut (ou on doit ?!?) documenter une fonction gr\u00e2ce \u00e0 une *Docstring* " ] }, { "cell_type": "code", "collapsed": false, "input": [ "def diplomation(nom):\n", " '''cette fonction ajoute un titre de docteur au nom d'une personne\n", " '''\n", " return 'Dr. ' + nom\n", "\n", "diplomation('Georges Dumont')" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 41, "text": [ "'Dr. Georges Dumont'" ] } ], "prompt_number": 41 }, { "cell_type": "code", "collapsed": false, "input": [ "# voir la documentation\n", "diplomation?" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 42 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Remaque : si une fonction de contient pas de `return`, elle ne renvoie pas rien mais l'objet `None`" ] }, { "cell_type": "code", "collapsed": false, "input": [ "def saluer():\n", " print('Bonjour Docteur !')\n", "\n", "a = saluer()\n", "print(a)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Bonjour Docteur !\n", "None\n" ] } ], "prompt_number": 43 }, { "cell_type": "markdown", "metadata": {}, "source": [ "On peut mettre plusieurs arguments (ou bien z\u00e9ro) et ces arguments peuvent \u00eatre optionnels si on leur attribut une *valeur par d\u00e9faut*" ] }, { "cell_type": "code", "collapsed": false, "input": [ "def diplomation(nom, nb=1, titre='Dr.'):\n", " '''cette fonction ajoute un titre de docteur au nom d'une personne\n", " le nombre de doctorat est r\u00e9glable (1) par d\u00e9faut\n", " '''\n", " return (titre+' ')*nb + nom\n", "\n", "print(diplomation('Georges Dumont'))\n", "print(diplomation('Georges Dumont', 2))" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Dr. Georges Dumont\n", "Dr. Dr. Georges Dumont\n" ] } ], "prompt_number": 44 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Les arguments peuvent \u00eatre assign\u00e9s *par leur nom* :" ] }, { "cell_type": "code", "collapsed": false, "input": [ "print(diplomation('Georges Dumont', nb=2))\n", "print(diplomation('Georges Dumont', titre='Dr. Prof.'))" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Dr. Dr. Georges Dumont\n", "Dr. Prof. Georges Dumont\n" ] } ], "prompt_number": 45 }, { "cell_type": "markdown", "metadata": {}, "source": [ "En bonus, une fonction qui peut lever (mot-cl\u00e9 `raise`) une erreur `ValueError`\n", "\n", "(et Python pointe l'endroit exacte de l'erreur, avec tout la pile d'appel des fonctions \"stack trace\")" ] }, { "cell_type": "code", "collapsed": true, "input": [ "def diplomation(nom, nb=1, titre='Dr.'):\n", " '''cette fonction ajoute un titre de docteur au nom d'une personne\n", " le nombre de doctorat est r\u00e9glable (1) par d\u00e9faut\n", " '''\n", " if nb > 3:\n", " raise ValueError(\"Impossible d'avoir plus de 3 doctorats !\")\n", " return (titre+' ')*nb + nom\n", "\n", "print(diplomation('Georges Dumont', nb=2))\n", "print(diplomation('Georges Dumont', nb=4))" ], "language": "python", "metadata": {}, "outputs": [ { "ename": "ValueError", "evalue": "Impossible d'avoir plus de 3 doctorats !", "output_type": "pyerr", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 9\u001b[0m \u001b[0;32mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdiplomation\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Georges Dumont'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnb\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 10\u001b[0;31m \u001b[0;32mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdiplomation\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Georges Dumont'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnb\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m4\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m\u001b[0m in \u001b[0;36mdiplomation\u001b[0;34m(nom, nb, titre)\u001b[0m\n\u001b[1;32m 4\u001b[0m '''\n\u001b[1;32m 5\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mnb\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0;36m3\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Impossible d'avoir plus de 3 doctorats !\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 7\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mtitre\u001b[0m\u001b[0;34m+\u001b[0m\u001b[0;34m' '\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0mnb\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mnom\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mValueError\u001b[0m: Impossible d'avoir plus de 3 doctorats !" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "Dr. Dr. Georges Dumont\n" ] } ], "prompt_number": 46 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "B2) Les \"modules\" pour des fonctionnalit\u00e9s suppl\u00e9mentaires" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "La plupart des fonctions disponibles en Python sont empaquet\u00e9 dans des modules.\n", "\n", "Ces modules permettent par exemple de :\n", "\n", "* t\u00e9l\u00e9charger des fichiers sur Internet,\n", "* manipuler des bases de donn\u00e9es,\n", "* faire des interface graphiques, ...\n", "\n", "Un certain nombre fait partie de la *biblioth\u00e8que standard*, beaucoup d'autres sont \u00e0 installer s\u00e9par\u00e9ment.\n", "\n", "Pour pouvoir les utiliser (une fois install\u00e9), il faut les \"importer\"" ] }, { "cell_type": "code", "collapsed": false, "input": [ "import math # un module \"standard\"" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 48 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Une fois import\u00e9, on peut acc\u00e9der \u00e0 leur contenu : classes, fonctions et parfois variables :" ] }, { "cell_type": "code", "collapsed": false, "input": [ "pi = math.pi\n", "print(pi)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "3.14159265359\n" ] } ], "prompt_number": 49 }, { "cell_type": "code", "collapsed": false, "input": [ "print(math.cos(pi/3))\n", "print(math.sin(pi/3))\n", "print(math.sqrt(3)/2)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "0.5\n", "0.866025403784\n", "0.866025403784\n" ] } ], "prompt_number": 50 }, { "cell_type": "code", "collapsed": false, "input": [ "# Remaquons au passage l'inexactitude in\u00e9vitable des nombres flottants :\n", "print(math.cos(pi/3) == 0.5) # cette comparaison \"semble vraie\"\n", "math.cos(pi/3)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "False\n" ] }, { "output_type": "pyout", "prompt_number": 51, "text": [ "0.5000000000000001" ] } ], "prompt_number": 51 }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Question importante** : Comment savoir ce que contient le module `math` ? Comment m\u00eame savoir qu'il existe ?\n", "\n", "* R\u00e9flexe 1 : taper math. + Tab dans IPython\n", "* R\u00e9flexe 2 : documentation officielle http://docs.python.org\n", "\n", " * choisir la bonne version de Python\n", " * section Library Reference\n", " * puis rechercher \"math\" sur la page (Ctrl+F)\n", " * et on arrive normalement sur http://docs.python.org/2/library/math.html" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "*Aller plus loin* : cr\u00e9er ses propres modules\n", "(Python tutorial http://docs.python.org/2/tutorial/modules.html)\n", "\n", "(empaqueter ses fonctions dans un module que l'on peut r\u00e9utiliser fait partie des \"bonnes pratiques\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---" ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "C) Fichiers et cha\u00eenes de caract\u00e8res : petite application" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "*Contenu :* \n", "\n", "* lecture et \u00e9criture de fichier,\n", "* manipulation simple de cha\u00eenes de caract\u00e8rs,\n", "* dans le but de transcrire un ficher CSV du format \"fran\u00e7ais\" au format usuel." ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "C1) Ouvrir et lire un fichier" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pour lire le contenu d'un fichier, il faut l'ouvrir avec la fonction `open` (pas besoin de module)" ] }, { "cell_type": "code", "collapsed": false, "input": [ "fname = 'S1_Bases_Python/bode_data_FR.csv'\n", "f = open(fname)\n", "# On obtien un objet \"file\" ouvert (~ un \"pointeur\")\n", "f" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 59, "text": [ "" ] } ], "prompt_number": 59 }, { "cell_type": "code", "collapsed": false, "input": [ "# afficher les 3 premi\u00e8res lignes\n", "for i in range(3):\n", " print(f.readline()) ,\n", "#f.close()" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "# Ficher CSV format\u00e9 \"\u00e0 la fran\u00e7aise\"\n", "1,000000e+02;6,155659e+00;-2,409978e+00\n", "1,047616e+02;6,001112e+00;-2,346197e+00\n" ] } ], "prompt_number": 60 }, { "cell_type": "code", "collapsed": false, "input": [ "# On ferme le fichier une fois le travail fini:\n", "f.close()\n", "f\n", "\n", "# \u00c0 essayer: lire le fichier apr\u00e8s qu'il soit ferm\u00e9\n", "#f.readline()" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 55, "text": [ "" ] } ], "prompt_number": 55 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Ce fichier CSV est format\u00e9 \"\u00e0 la fran\u00e7aise\". Peu d'outils interpr\u00e8terons la \",\" comme marque d\u00e9cimale.\n", "\n", "On va donc le convertir avec un script de \"rechercher-remplacer\" ligne par ligne.\n", "\n", "* \",\" transform\u00e9 en \".\"\n", "* \";\" transform\u00e9 en \",\" (\u00e7a c'est plus facultatif)\n", "\n", "Pour cela, on utilise la m\u00e9thode `replace` des cha\u00eenes de caract\u00e8re" ] }, { "cell_type": "code", "collapsed": false, "input": [ "ligne = f.readline()\n", "print(ligne)\n", "ligne = ligne.replace(',', '.')\n", "print(ligne)\n", "ligne = ligne.replace(';', ',')\n", "print(ligne)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "1,097499e+02;5,810821e+00;-2,225484e+00\n", "\n", "1.097499e+02;5.810821e+00;-2.225484e+00\n", "\n", "1.097499e+02,5.810821e+00,-2.225484e+00\n", "\n" ] } ], "prompt_number": 61 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "C2) Manipuler des cha\u00eenes de caract\u00e8res" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Les cha\u00eenes de caract\u00e8res sont des types de listes sp\u00e9cialis\u00e9es pour contenir du texte." ] }, { "cell_type": "code", "collapsed": false, "input": [ "a = 'La SI c\\'est sympa' # notez le caract\u00e8re d'\u00e9chapement \"\\\"\n", "# ou bien\n", "a = \"La SI c'est sympa\" # (identique au pr\u00e9c\u00e9dent)" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 63 }, { "cell_type": "markdown", "metadata": {}, "source": [ "On remarque que les cha\u00eenes de caract\u00e8res disposent de plusieurs m\u00e9thodes pour le manipuler :" ] }, { "cell_type": "code", "collapsed": false, "input": [ "# Taper \"TAB\" pour voir la liste des m\u00e9thodes:\n", "a." ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "les m\u00e9thodes `split`, `replace`, `format`, ... sont particuli\u00e8rement utiles.\n", "\n", "D'autres sont d'utilisation ponctuelles." ] }, { "cell_type": "code", "collapsed": false, "input": [ "# Couper une cha\u00eene \u00e0 l'aide d'un motif :\n", "a.split('SI') # -> renvoie une liste de str !" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 66, "text": [ "['La ', \" c'est sympa\"]" ] } ], "prompt_number": 66 }, { "cell_type": "code", "collapsed": false, "input": [ "a1, a2 = a.split('SI')\n", "print(a1 + u\"M\u00e9ca\" + a2) # notons le u qui pr\u00e9fixe u\"M\u00e9ca\" !" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "La M\u00e9ca c'est sympa\n" ] } ], "prompt_number": 67 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Le formattage de cha\u00eenes, en acc\u00e9l\u00e9r\u00e9 (se r\u00e9f\u00e9rer \u00e0 http://docs.python.org/2/library/string.html#format-string-syntax pour aller plus loin)\n", "\n", "Le but : fabriquer une chaine de caract\u00e8res qui int\u00e8gre la valeur d'une variable" ] }, { "cell_type": "code", "collapsed": false, "input": [ "# Formattage avec des cha\u00eenes\n", "prenom = u'Genevi\u00e8ve'\n", "nom = u'Fioraso'\n", "print(u\"Bonjour Mme {} {}\".format(prenom, nom))\n", "\n", "# Remarque : cce m\u00eame r\u00e9sultat peut \u00eatre obtenu par concat\u00e9nation:\n", "print(u'Bonjour Mme ' + prenom + u' ' + nom)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Bonjour Mme Genevi\u00e8ve Fioraso\n", "Bonjour Mme Genevi\u00e8ve Fioraso\n" ] } ], "prompt_number": 68 }, { "cell_type": "code", "collapsed": false, "input": [ "# Formattage avec des nombres:\n", "n = 5\n", "t = 2.1862\n", "u\"l'algo a converg\u00e9 en {} it\u00e9rations\".format(n)\n", "u\"la simulation a dur\u00e9 {:.2f} secondes\".format(t)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 69, "text": [ "u'la simulation a dur\\xe9 2.19 secondes'" ] } ], "prompt_number": 69 }, { "cell_type": "code", "collapsed": false, "input": [ "# Exemple de m\u00e9thodes d'utilisation ponctuelles (de mon point de vue...)\n", "\n", "# Mettre en minuscule\n", "a.lower()\n", "# Mettre en majuscule\n", "a.upper()" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 70, "text": [ "\"LA SI C'EST SYMPA\"" ] } ], "prompt_number": 70 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "C3) \u00c9criture dans un fichier" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pour transcrire tout le fichier, on ouvre \n", "\n", "* le fichier original en *mode lecture* : **'r'** (mode par d\u00e9faut)\n", "* le fichier transcrit en *mode \u00e9criture* : **'w'**\n", "\n", "L'\u00e9criture se fait avec la m\u00e9thode `write` de l'objet fichier." ] }, { "cell_type": "code", "collapsed": false, "input": [ "fname_in = 'S1_Bases_Python/bode_data_FR.csv'\n", "f_in = open(fname)\n", "\n", "fname_out = 'S1_Bases_Python/bode_data_EN.csv'\n", "# ou bien:\n", "#fname_out = fname_in.split('.')[0] + '_to_EN.csv'\n", "print('transcription dans le fichier \"'+ fname_out + '\"')\n", "f_out = open(fname_out, 'w') # Notez le \"w\"\n", "\n", "# It\u00e9ration sur les lignes:\n", "for ligne in f_in:\n", " ligne = ligne.replace(',', '.')\n", " ligne = ligne.replace(';', ',')\n", " f_out.write(ligne)\n", "\n", "# fermeture des fichiers:\n", "f_in.close()\n", "f_out.close()" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "transcription dans le fichier \"S1_Bases_Python/bode_data_EN.csv\"\n" ] } ], "prompt_number": 71 }, { "cell_type": "code", "collapsed": false, "input": [ "# v\u00e9rification du r\u00e9sultat:\n", "f = open(fname_out)\n", "\n", "for i in range(3):\n", " print(f.readline()) ,\n", " " ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "# Ficher CSV format\u00e9 \"\u00e0 la fran\u00e7aise\"\n", "1.000000e+02,6.155659e+00,-2.409978e+00\n", "1.047616e+02,6.001112e+00,-2.346197e+00\n" ] } ], "prompt_number": 72 }, { "cell_type": "markdown", "metadata": {}, "source": [ "*Aller plus loin* avec les fichiers et les cha\u00eenes de caract\u00e8res :\n", "\n", "1) La m\u00e9thode recommand\u00e9e d'ouvrir un fichier avec le mot-clef `with`\n", " \n", " with open('monfichier.txt') as f:\n", " f.readline()\n", "\n", "2) Pour traiter des cha\u00eenes de caract\u00e8res plus compliqu\u00e9es, il y a un module d'expressions rationnelles (\"regexp\") : `re`\n", "\n", " import re\n", "\n", "-> se reporter \u00e0 sa documentation officielle sur http://docs.python.org/2/library/re.html" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "*fin de la session 1*\n", "\n", "\n", " \"Licence\n", "\n", "\n", "Ce support de formation cr\u00e9\u00e9 par\n", "Pierre Haessig\n", "est mis \u00e0 disposition selon les termes de la\n", "licence Creative Commons Attribution 3.0 France." ] } ], "metadata": {} } ] }