Langages de script : l`exemple de python
Transcription
Langages de script : l`exemple de python
Langages de script l'exemple de python P. Poizat Université d'Evry Sources (la bibliographie sera donnée plus loin) ● M. Lutz. Programming Python. O'Reilly. 1996. ● Python.org. Documentation python. http://www.python.org/doc ● L. Pointal. Cours Python. http://www.limsi.fr/Individu/pointal/python.html ● L. Pierron. GUI programmation en Tcl, Perl et Python. http://www.loria.fr/~pierron/GUI/ Plan ● les langages de script ● le choix de python ● bases de python ● python et les entrées-sorties ● python et IHM ● python et programmation scientifique 3 Les langages de script 4 Script ? ● ● un programme habituellement court utilisé principalement comme glu entre composants existants (IHM, filtre, ...) ● écrit dans un langage de haut niveau ● interprété et portable [interprète] ● ● de plus en plus populaires (open source community) exemples: shells Unix, TCL, perl, PHP, python, ruby, Rexx, ... 5 Programmes courts ? ● soit un fichier f.data à lire et à sommer : 1.1 9 5.2 1.762543E02 0 0.1 0.001 0.0001 9 3 7 ● en python : fichier = open('f.data','r') nombres = fichier.read().split() somme = reduce(lambda x,y:x+float(y), nombres, 0) print somme ● en C/C++/Java : plus complexe ! 6 Programmes courts ? ● soit une IHM permettant la conversion entre F et € : 7 Programmes courts ? from Tkinter import * tk = Tk() tk.title('convertisseur F <> EUR') valeur, resultat = DoubleVar(), DoubleVar() def EUR2F(): resultat.set(valeur.get()*6.55957) def F2EUR(): resultat.set(valeur.get()/6.55957) Label(tk, text='Conversion Euros <> Francs\n').pack Entry(tk, textvariable=valeur).pack() Button(tk, text='EUR', command=F2EUR).pack() Button(tk, text='F', command=EUR2F).pack() Label(tk, textvariable=resultat).pack() tk.mainloop() 8 Avantages ● ● ● le scripting induit des programmes plus courts un programme plus court signifie moins de bogues cycle développement/débogage plus rapide (edit & test, pas de compilation) J. K. Ousterhout. Scripting: Higher Level Programming for the 21st Century. IEEE Computer. Mars 1998. www.tcl.tk/doc/scripting.html 9 Avantages / Inconvénients ● ● ● ● ● ● connexion de composants interface/IHM au dessus d'un module existant analyse de texte intensive ● ● ● nécessité du typage statique données ou algorithmes complexes gros volumes de données LoL (lots of lists) communication avec le Web prototypage 10 Plan ● les langages de script ● le choix de python ● bases de python ● python et les entrées-sorties ● python et IHM ● python et programmation scientifique 11 Le choix de python 12 Pourquoi ? http://www.pythonology.com/ ● productivité x2-x10 par rapport à C, C++, Java, Perl, VB, ... ● flexibilité langage indépendant, langage de colle ● intérêt grandissant parmi les langages de programmation open source ● robuste mais plus simple, plus propre indentation obligatoire, structures données haut niveau réussites : google, NASA, CERN, Civilization IV, Zope, ... 13 Shells (Unix) vs. python python est un vrai langage de programmation avec : ● types de données de haut niveau ● orientation-objet ● gestion d'exceptions ● nombreux modules disponibles ● mécanismes de colle du shell (> >> < |) imitables en python (os.system, os.exec*, os.popen, ...) ● idem pour opérations sur fichiers (cp, mv, rm, ls, chmod, tests sur fichiers, ...) 14 Perl vs. python @list = ([1,2,3],["a","b","c"]); for $i ( 0 .. $#list ) { for $j ( 0 .. $#{$list[$i]} ) { printf "list[%d][%d]:%s\n",$i,$j,$list[$i][$j]; list = [[1,2,3],["a","b","c"]] for i in range(len(list)): for j in range(len(list[i])): print "list[%d][%d]:%s" % (i,j,list[i][j]) 15 Vitesse ? Les scripts sont réputés plus lents (que le code compilé) mais : ● ● ● ● génération de bytecode (.py / .pyc) existence de modules externes spécifiques (en C compilé) extension : utilisation possible de code efficace en interne ou en externe (C, Fortran) incorporation : utilisation de python dans du code C 16 Lancement de python ● session interactive machine> python Python 2.4.1 (#1, May 16 2005, 15:19:29) [GCC 4.0.0 20050512 (Red Hat 4.0.05)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> (Control-D / EOF pour sortir) ● interprétation machine> python prog.py machine> ./prog.py (#!/usr/bin/python ligne 1) 17 Editeurs python (emacs) 18 Editeurs python (idle) 19 Aide en ligne ● fonction help >>> help() (interactif, quit pour quitter) >>> help(module) ... exemple : help(str) help(math) ... >>> help(fonction) ... exemple : help(math.cos) help(cos) (q pour quitter) ● important : importer le module (+ loin) 20 Récupérer et installer python ● python 2.4, www.python.org ● disponible sous Unix, Mac, Windows (et de nombreux autres) ● ● installeur sous Mac et Windows archive ou paquetage sous Unix VPython, www.vpython.org python + idle + Tk + numarray + numeric plus simple sous window (un .msi, un .exe) 21 Plan ● les langages de script ● le choix de python ● bases de python ● python et les entrées-sorties ● python et IHM ● python et programmation scientifique 22 Bases de python 23 Plan de cette partie ● règles de base ● types de base ● typage dynamique ● opérateurs ● types collections ● structures de contrôle ● fonctions ● exceptions ● modules 24 Règles de base ● commentaires : # explication – ● à utiliser intensivement ! identificateurs : nb _x2 – la casse compte (rang ≠ Rang) – attention aux mot-clés réservés ! – nommez intelligemment ! ● oui : temperature plafondMax ... ● à éviter (sauf contexte clair) : t x y z ... ● non : lorie steevy pq ... 25 Règles de base (suite) ● ● indentation obligatoire (plus clair) if (4<temp<4): if (modeAvertir): print "risque de verglas" à comparer à : if(t>4&&t<4) if(ma) printf("verglas !\n"); 26 Règles de base (suite) ● continuation de lignes explicite if 1900<an<2100 and 1<=mois<=12 \ and 1<=jour<=31 and 0<=heure<24 \ and 0<=minute<60 and 0<=seconde<60: return True ● continuation de lignes implicite mois = ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre'] 27 Règles de base (suite) ● ● affectation : variable = valeur x,y,z = 0,1,2 x_0=y_0=z_0=0 instruction nulle (mais utile) : pass if (modeAvertir): pass # je le ferai plus tard ... else: pass # ca aussi ! 28 Règles de base (fin) ● tout est objet ● mutable vs immutable ● variables, fonctions, modules, ... référencent des objets >>> a=b=0 >>> a=3 >>> a 3 >>> b 0 29 Règles de base (fin) ● tout est objet ● mutable vs immutable ● variables, fonctions, modules, ... référencent des objets >>> a=0 >>> b=a >>> a=3 >>> a 3 >>> b 0 30 Règles de base (fin) ● tout est objet ● mutable vs immutable ● variables, fonctions, modules, ... référencent des objets >>> a=[2,3] >>> b=a >>> a[0]=99 >>> a [99,3] >>> b [99,3] 31 Codage binaire ● rappel ? ● dans une machine, deux valeurs : 0 et 1 ● traduction des types, variables, ... ● type atomique : le bit ● mot machine : octet (byte) = 8 bits 72 = 64 + 8 donne 01001000 0x2^7+1x2^6+0x2^5+0x2^4+1x2^3+0x2^2+0x2^1+0x2^0 32 Types de base ● ● entiers : 15 15L int(15) long(15) – int : 32 bits, de -2147483648 à 2146483647, si débordement overflow error – long : illimité (en fait limite mémoire) "réels" : 3.02 3.0 float(3) 314159.26E5 – ● float : 64 bits, flottants double précision (machine), si débordement Inf complexes : 2j+3 complex(2) – complex : paire de flottants (.real, .imag) 33 Types de base (suite) ● booléens : True False bool(0) bool(4) – ● bool : mots-clés ou valeur sous contexte bool. chaînes : 'c' 'chaine' "chaine d'exemple" str(4) – str : un type de séquence particulier – chaînes multi-lignes : ''' ou """ >>> '''toto est ... content''' >>> 'toto\nest content' >>> "toto (SyntaxError) 34 Formatage des chaînes ● ● échappement : opérateur \ \ : \' \" \\ \0 \n \t ... remplacement : opérateur % chaine % tuple de valeurs la chaîne contient des codes %XXc c : s c d i u o x X e E f g G % ... XX : '%2d'%(1) '%02d'%(1) '%.4f'%(math.pi) exemple : 'Hello %s\n' % ('World') 'Hello World\n' 35 Typage dynamique ● python n'est pas typé statiquement >>> a=3 >>> type(a) <type 'int'> >>> a="toto" >>> type(a) <type 'str'> ● mais python est fortement typé ● + de flexibilité, + de généricité 36 Typage dynamique ● ● python n'est pas typé statiquement mais python est fortement typé >>> a=3 >>> b="toto" >>> a+b Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: unsupported operand type(s) for +: 'int' and 'str' ● + de flexibilité, + de généricité, tout en assurant un niveau correct de sécurité 37 Opérateurs ● ● ● numériques – unaires: + – binaires : + * ** / & << >> % booléens – unaires : not – binaires : or and ^ bit à bit – unaires : | – binaires : ~ 38 Opérateurs (suite) ● ● comparaisons – (in)égalité : == != <> – inférieur/supérieur : < > <= >= possibilité : x op y op z exemple : 3 < temperature < 3 39 Surcharge ● même nom d'opérateur ou de fonction ● type différent ● sûreté : typage fort (statique ou dynamique) >>> 10*10 100 >>> (10+1j)*(10+1j) (99+20j) #(a,b)(c,d)=(acbd,ad+bc) >>> 'a'*10 'aaaaaaaaaa' 40 Types collections ● ● ● L'une des forces de python : ses types de haut niveau pour les collections Haut niveau : – prédéfinis et donc plus efficaces (encodage en C) – support de nombreuses fonctions et notations directement au niveau du langage Ces types peuvent être mutables ou immutables (efficacité vs. flexibilité) 41 Types séquences (immutables) ● ● ● chaînes (str) : 'bonjour' "bonjour" nous l'avons vu plus tôt encodage ASCII unicode (unicode) : U'bonjour' encodage UNICODE tuples (tuple) : () ('origine',0+0j) attention : type(4) = type((4)) = int type((4,)) = type((4,5,6)) = tuple 42 Types séquences (mutables) ● listes : [] ['pomme','poire','banane'] >>> v = ['Nantes','Rennes',Vannes'] >>> del(v[1]) >>> v ['Nantes','Vannes'] 43 Constructeurs de séquences ● construire des séquences d'entiers : construit range(debut,fin,pas) ou au fur et à mesure xrange(debut,fin,pas) >>> range(4) [0, 1, 2, 3] >>> range(4,6) [4, 5] >>> range(4,10,2) [4, 6, 8] >>> range(8,4) [] >>> range(8,4,1) [8, 7, 6, 5] # pas de début : 0 # pas de pas : 1 # range vide # avec le bon pas 44 Opérateurs séquences ● ● ● ● test de présence e in seq e not in seq nombre d'éléments len(seq) valeurs min et max min(seq) max(seq) concaténation seq1+seq2 répétition seq*n n*seq 45 Opérateurs séquences (suite) ● ● attention au problème de la copie >>> a=[2,3] >>> b=a >>> a[0]=99 >>> a [99,3] >>> b [99,3] copie (un niveau) copie = original[:] 46 Opérateurs séquences (slices) ● ● seq[i:j] sélectionne les i≤k<j si indice négatif, additionne len(seq) l = "hippopotame" 01234567890 l[1] # hippopotame l[3:7] # hippopotame l[3] (8) l[4:2] (7:9) 47 Opérateurs séquences (mut.) ● modification seq[indice]=val seq[2:4]=['a','b','c'] >>> l = [1,2,3,4,5] >>> l[2:4] = [99,98,97] >>> l [1, 2, 99, 98, 97, 5] 48 Opérateurs séquences (mut.) ● ajout / insertion seq.append(val) seq.extend([v1,...,vn]) seq.insert(indice,val) >>> l = [1,2,3,4,5] >>> l.extend([99,98,97]) >>> l [1, 2, 3, 4, 5, 99, 98, 97] 49 Opérateurs séquences (mut.) ● suppression del(seq[indice]) del(seq[i:j]) >>> l = [1,2,3,4,5] >>> del(l[2:4]) >>> l [1, 2, 97, 5] 50 Opérateurs séquences (mut.) ● recherche seq.count(val) seq.index(val) >>> l = [1,4,3,4,5] >>> l.count(4) 2 >>> l.index(4) 1 51 Opérateurs séquences (mut.) ● tris (sur place !) seq.sort() seq.reverse() >>> l = [1,3,7,2,1] >>> l2 = l[:] >>> l2.sort() >>> l2 [1, 1, 2, 3, 7] >>> l [1, 3, 7, 2, 1] 52 Fonctions séquences ● ● ● ● filtrage filter(fonction,seq) application map(fonction,seq,...) réduction reduce(fonction,seq,init) "zipage" zip(seq1,seq2,...) 53 Interlude ● ● une fonction anonyme est une lambda fonction (vous verrez peut être un jour le -calcul) syntaxe : lambda arguments : corps >>> plus1 = lambda x : x+1 >>> addition = lambda x,y : x+y >>> addition <function <lambda> at 0xb7f51f44> >>> addition(2,3) 5 54 Fonctions séquences (suite) >>> filter(lambda x:x>2, [1,2,4,8]) [4, 8] >>> map(lambda x,y:x+y, [1,2], [3,4]) [4, 6] >>> reduce(lambda x,y:x+y, [1,2,4,8], 0) 15 >>> reduce(lambda x,y:x+y, [1,2,4,8], 10) 25 >>> zip([1,2],[3,4]) [(1, 3), (2, 4)] 55 Types mappings (mutables) ● ● ● dictionnaires (dict) : {} {'L':3, 'M':2, 'D':3} >>> durees = {} >>> durees['L'] = 3 >>> durees {'L':3} durees['L']=4 del(durees['L']) ... table de hachage, correspondance clé/valeur, unicité de la clé aucun ordre sur les clés ! 56 Opérateurs mappings (mut.) ● ● ● ● ● positionnement / modification d[clé] = valeur suppression del d[clé] nombre de couples clés / valeurs len(d) test clé d.has_key(clé) liste clés d.keys() liste valeurs d.values() 57 Ensembles ● type set : collection non ordonnée sans doublons >>> fruits=set(['pomme','poire','banane']) >>> 'pomme' in fruits True >>> fruits=fruitsset(['pomme']) set(['banane', 'poire']) >>> 'pomme' in fruits False 58 Ensembles (opérations) ● ● ● ● différence ensembliste (surcharge -) S S' union (surcharge |) S | S' intersection (surcharge &) S & S' union exclusive : (S|S') - (S&S') S ^ S' 59 Structures de contrôle ● ● nombre restreint : – test : if else elif – boucles : for in while break continue mais très bonne intégration avec collections de haut niveau : – cas typique : itération sur les listes for element in liste: traitement(element) for cle in dictionnaire.keys(): traitement(dictionnaire[cle]) 60 Structures de contrôle (if) ● ● condition : interprétation booléenne (booléen ou non zéro ou non vide) if (si) else (sinon) else if ou elif >>> temp, modeAvertir = 2, True >>> if (4 < temp < 4) : ... if modeAvertir : ... print ('Verglas') ... Verglas >>> 61 Structures de contrôle (if) ● ● condition : interprétation booléenne (booléen ou non zéro ou non vide) if (si) else (sinon) else if ou elif >>> arguments={'v':'oui';'a':'non'} >>> if arguments['v'] == 'oui' : ... modeVerbeux = True ... elif arguments['v'] == 'non' : ... modeVerbeux = False ... else: ... print('Mauvaise valeur\n') 62 ... Structures de contrôle (for) ● ● ● itère sur les éléments d'une séquence valable pour tout objet fournissant un itérateur for element in sequence : >>> somme = 0 >>> for val in [1,2,3,4]: ... somme = somme + val ... >>> print somme 10 >>> 63 Structures de contrôle (while) ● ● condition : interprétation booléenne (booléen ou non zéro ou non vide) while (condition) : # (tant que) >>> i, MAX, l = 0, 10, [] >>> while i<MAX: ... l.append(i) ... i = i+1 ... >>> print l [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> 64 Structures de contrôle (while) ● ● attention aux boucles infinies ! résultats possibles : non terminaison, manque de mémoire, pile d'appel pleine >>> i, MAX = 0, 10 >>> while i<MAX: ... print i ... (boucle sans fin) 65 Structures de contrôle (for/while) ● boucle avec sortie implicite (while) >>> i, MAX, DIV, l = 1, 10, 5, [] >>> fini = False >>> while i<MAX and not fini : ... if i%DIV : ... l.append(i) ... i = i+1 ... else: fini = True ... >>> print l [0, 1, 2, 3, 4] 66 Structures de contrôle (for/while) ● boucle avec sortie explicite (for/while) >>> i, MAX, DIV, l = 1, 10, 5, [] >>> while i<MAX : ... if i%DIV : ... l.append(i) ... i = i+1 ... else: break ... >>> print l [0, 1, 2, 3, 4] 67 Structures de contrôle (for/while) ● ● instruction de terminaison de boucle valable en cas de terminaison correcte (pas de break) >>> liste, ERREUR = [1,2,99,4], 99 >>> for element in liste: ... if element==ERREUR: break ... else: print 'liste correcte' ... >>> 68 Structures de contrôle (for/while) ● ● instruction de terminaison de boucle valable en cas de terminaison correcte (pas de break) >>> liste, ERREUR = [1,2,3,4], 99 >>> for element in liste: ... if element==ERREUR: break ... else: print 'liste correcte' ... liste correcte 69 Structures de contrôle (for/while) ● instruction de reprise de boucle ● attention à conserver des boucles finies ! >>> somme, liste = 0, [1,2,3,4] >>> for element in liste: ... if element%2 : continue ... somme = somme + element ... >>> print somme 70 Construction de listes ● ● ● il est possible de construire des listes en extension vs. en compréhension nous avons déjà vu la première possibilité >>> l = [1,2,3,4] en compréhension : { expr e tel que e ∈ seq ∧ cond e } [expr(e) for e in seq] [expr(e) for e in seq if cond(e)] >>> [2**exp for exp in l] [2, 4, 8, 16] >>> [val for val in l if val%2] 71 [1, 3] Fonctions ● ● définition avec def + indentation pas de typage explicite (ni retour, ni arguments) ● arguments passés par référence ● résultat avec return (None par défaut) >>> def addition(nb1, nb2): ... return nb1+nb2 ... >>> 72 Fonctions ● ● définition avec def + indentation pas de typage explicite (ni retour, ni arguments) ● arguments passés par référence ● résultat avec return (None par défaut) >>> addition(1,2) 3 >>> addition('Hello',' World!') 'Hello World!' 73 Fonctions ● valeurs par défaut (à droite) def add(nombre, ajout=0): return nombre+ajout appel : add(1) add(1,1) ● nombre variable d'arguments – anonymes (liste) – nommés (dictionnaire) 74 Fonctions ● valeurs par défaut (à droite) ● nombre variable d'arguments – anonymes (liste) def add(x, *reste): rtr = x for nombre in reste: rtr = rtr + nombre return rtr appel : add(1) add(1,2) add(1,2,3,4) – nommés (dictionnaire) 75 Fonctions ● valeurs par défaut (à droite) ● nombre variable d'arguments – anonymes (liste) – nommés (dictionnaire) def add(x, **param): rtr = x for cle in param.keys(): if cle in 'abc': rtr = rtr + param[cle] return rtr appel : add(1) add(1,a=1,t=2,c=3) add(x=1,a=2) 76 Fonctions ● il est important de documenter vos fonctions def divise(x,y): """division entière de deux entiers """ return x/y ● ● ● utilisé par help(divise) python documentation Special Interest Group : www.python.org/sigs/docsig docutils.sourceforge.net (HTML, LaTeX) 77 Fonctions (interlude) ● ● il est parfois utile d'avoir des fonctions anonymes (IHM, fonctions en argument, ...) vu plus tôt avec filter, map, ... lambda fonctions 78 Gestion des exceptions ● les erreurs existent et ne sont pas toutes évitables def divise(x,y=1): return x/y ● # erreur si divise(_,0) que faire en cas d'erreur ? – rien – afficher un message – autre chose ... 79 Gestion des exceptions ● ● les erreurs existent et ne sont pas toutes évitables que faire en cas d'erreur ? – rien >>> divise(1,0) Traceback (most recent call last): File "<stdin>", line 1, in ? File "<stdin>", line 4, in divise ZeroDivisionError: integer division or modulo by zero – afficher un message – autre chose ... 80 Gestion des exceptions ● ● les erreurs existent et ne sont pas toutes évitables que faire en cas d'erreur ? – rien – afficher un message (ou rien !) def divise(x,y=1): if y==0 : print 'Erreur' # return None else: return x/y – autre chose ... 81 Gestion des exceptions ● ● ● récupérer les erreurs (exceptions) sans tester chaque instruction (if) réagir de différentes façon, y compris de façon uniforme avec le langage cette réaction pouvant dépendre du type d'erreur le traitement d'exceptions 82 Gestion des exceptions ● bloc contrôlé : try ● bloc(s) de réaction : except def grosCalcul(x,y,z): ... try: somme = x*y/z # erreur possible except: pass # traitement choisi ... 83 Gestion des exceptions ● traitement selon l'exception ... except ZeroDivisionError: print "division par zéro" except EOFError: print "fin de fichier atteinte" except Exception: print "autre chose" ... 84 Gestion des exceptions ● traitement particulier : lever une exception ... try: ... except ZeroDivisionError: print 'division par zéro' raise ... 85 Gestion des exceptions ● traitement particulier : lever une exception ... try: ... except ZeroDivisionError: raise Exception, 'division par zéro' ... 86 Gestion des exceptions ● ● cas terminal (si tout va bien) ... try: ... except: ... else: print "tout va bien !" ... cas terminal (même si tout va mal) 87 Gestion des exceptions ● ● cas terminal (si tout va bien) cas terminal (même si tout va mal) ... try: ... except: ... finally: pass # un peu de nettoyage ... 88 De l'usage des modules ● un module regroupe des fonctionnalités et données connexes (même objet d'application, même thème, interdépendance forte, ...) ● modularité/décomposition + réutilisation ● un module = un fichier ● – modules système (/usr/lib/pythonX.Y) – modules utilisateur (répertoires + .) sys.path / PYTHONPATH 89 Modules #!/usr/bin/python # maths.py pi = 3.1415926535897931 e = 2.7182818284590451 def addition(x,y): return x+y def multiplication(x,y): return x*y ... 90 Modules ● import global from maths import * print addition(pi,e) ● import module (à privilégier) import maths print maths.addition(maths.pi, maths.e) ● intermédiaire from maths import e, pi, addition print addition(pi,e) 91 Modules ● important : documenter ! #!/usr/bin/python # maths.py """ module contenant des définitions de fonctions annexes de maths. version 0.1, jj/mm/aaaa """ def addition(x,y): """additionne deux nombres. """ ... 92 Modules ● __main__ : défaut ou tests minimaux (il y aussi unittest) ... if __name__ == '__main__': ... ● différencie >>> import module et machine> python module.py 93 De l'usage des paquetages ● un paquetage est un regroupement de modules connexes ● un paquetage = un répertoire ● sous-paquetages = sous-répertoires ● module __init__.py ● – peut être vide – initialisations – __all__ : liste modules (from paq import *) sys.env / PYTHONPATH 94 Paquetages ● Sound – __init__.py – Formats – ● __init__.py ● wavread.py ● wavwrite.py ● ... Effects ● __init__.py ● echo.py ● ... import Sound.Effects.echo Sound.Effects.echo.bell(10) from Sound.Effects import echo echo.bell(10) from Sound.Effects.echo import bell bell(10) from Sound.Effects import * 95 Plan ● les langages de script ● le choix de python ● bases de python ● python et les entrées-sorties ● python et IHM ● python et programmation scientifique 96 Python et les entrées-sorties 97 Plan de cette partie ● entrée-sorties standard, arguments sys, stdin, stdout, stderr, argv ● gestion des fichiers ouverture/fermeture, lecture, écriture ● lien avec le S.E., gestion des processus os, commandes externes, communication ● quelques modules utiles getopt, string, re 98 Flots ● tout processus est associé à trois flots : – entrée standard : stdin – sortie standard : stdout – sortie erreurs : stderr ● flots = fichiers, ouverts au départ ● module sys (importer) ● pour écrire : print (par défaut sur stdout) voir les chaînes pour formatage ● ● pour lire : lu = stdin.readline() 99 pour les erreurs : raise, stderr.write() Le module sys ● objets liés à l'interprète et interaction avec lui (ex: sys.path) ● flots (stdin, stdout, stderr) ● sortie : sys.exit() sys.exit(valeur) 0 : ok, autre : erreur (1,2,autres) ● arguments en ligne de commande : argv machine> ./somme.py 1 2 3 4 4 arguments sommés, somme = 10 machine> 100 Le module sys #!/usr/bin/python import sys somme = 0 for argument in sys.argv[1:]: somme = somme + int(argument) print "%d arguments sommés, somme = %d" \ % (len(sys.argv),somme) 101 Fichiers ● un fichier est une suite d'informations, potentiellement hétérogènes, terminé par une fin de fichier (Control-D, EOF) ● type file ● fichier = open(nom, mode) mode : {r (read), w (write), a (append)} ● fermer les fichiers ouverts est plus propre fichier.close() 102 Fichiers ● lecture dans un fichier f = open('pierrot.txt', 'r') au clair de la lune mon ami Pierrot – une chaîne : read, f.read() renvoit : 'au clair de la lune\nmon ami Pierrot' '' après EOF – une ligne : readline, f.realine() renvoit : 'au clair de la lune\n' 'mon ami Pierrot' '' après EOF – (1er appel) (2ème appel) une liste : readlines, f.readlines() renvoit : ['au clair de la lune\n', 'mon ami Pierrot']103 [] après EOF Fichiers ● itération en lecture f = open('pierrot.txt', 'r') for ligne in f: print ligne ● écriture dans un fichier f = open('corbeau.txt', 'w') – une chaîne : write, f.write('le corbeau') – une liste : writelines, f.writelines(lignes) possible avec un itérateur – éventuellement f.flush() ou f.close() (buffering) 104 Fichiers ● lecture/écriture facile pour des chaînes (direct) ou des nombres (int, float, ...) ● plus complexe pour les collections ● solution : module pickle [persistance] f = open('sauveListe.data','w') pickle.dump(liste,f) f.close() f = open('sauveListe.data','r') liste = pickle.load(f) 105 Processus 106 Le module getopt ● analyseur pour options en ligne de cde machine> ./prog.py m 4 o f.data brut.data ... machine> ./prog.py help prog.py [options] fichier_données options : m : taille des blocs analysés o : nom du fichier de sortie (stdout défaut) v, verbeux : afficher l'avancement h, help : afficher l'aide (ce document) machine> ● getopt(args, options [,options longues]) 107 Le module getopt >>> args = 'a b4 c foo a b'.split() >>> args ['a', 'b4', 'c', 'foo', 'a', 'b'] >>> options, args = getopt(args,'ab:c:') >>> args ['a', 'b'] >>> options [('a', ''), ('b', '4'), ('c', 'foo')] >>> 108 Le module getopt >>> args = 'a b4 c foo a b'.split() >>> args ['a', 'b4', 'c', 'foo', 'a', 'b'] >>> options, args = getopt(args,'ab:c') >>> args ['foo', 'a', 'b'] >>> options [('a', ''), ('b', '4'), ('c', '')] >>> 109 Le module getopt >>> args = 'a b4 c foo a b'.split() >>> args ['a', 'b4', 'c', 'foo', 'a', 'b'] >>> options, args = getopt(args,'abc:') (lignes d'information) getopt.GetoptError: option 4 not recognized ● en effet, a b et ab sont interchangeables dans certain cas 110 Le module getopt >>> args = 'out=a.data help b'.split() >>> options, args = getopt(args, \ ... '', ['out=', 'help']) >>> args ['b'] >>> options [('out', 'a.data'), ('help', '')] >>> 111 Le module getopt ● utilisation typique avec sys.argv[1:] try: options, args = getopt(argv[1:], ...) except GetoptError: usage() sys.exit(2) for option, valeur in options: if option in ('h', 'help'): usage() sys.exit() elif ... 112 Le module string ● ● module dédié aux chaînes – constantes – templates – fonctions module complémentaire : re 113 Le module string ● les constantes : – ascii_letters, ascii_lowercase, ascii_uppercase – letters, lowercase, uppercase – digits, hexdigits – whitespace 114 Le module string ● les templates : substitutions simples de chaînes – chaînes de template $$, $nom, ${nom} >>> hello = 'Bonjour $prenom ${nom}!' – constructeur de template Template(chaîne) >>> t = Template(hello) – substitution : substitute, safe_substitute >>> t.safe_substitute(nom='Foo') 'Bonjour $prenom Foo!' 115 Le module string ● les fonctions : – la plupart sont maintenant des fonctions de chaînes – c'est-à-dire que string.capitalize('foo') et 'foo'.capitalize() sont équivalents (la seconde forme est celle qui va rester) – pour l'aide, préférer help(''.fonction) à help(string.fonction) 116 Les fonctions de chaînes ● count, find, index, rfind, rindex ● join, split, rsplit, splitlines ● isalnum, isalpha, isdigit, islower, isspace, isupper ● capizalize, lower, upper, swapcase ● lstrip, rstrip, strip ● replace 117 Le module re ● expressions régulières (regex) ● définition (syntaxe) ● utilisation (rechercher, remplacer, ...) ● – force de langages comme perl – on les retrouve en shell script ou encore avec la commande grep nous allons ici voir les bases plus d'infos : www.python.org/ 118 Syntaxe des regex ● utilisation la plus simple : recherche ● correspondance regex / (sous-)chaîne ● ● la plupart des caractères se correspondent (a correspond à a) méta caractères . ^ $ * + ? { } [ ] \ | ( ) 119 Syntaxe des regex ● [ ... ] : classe de caractères [abc] ● [az] [azAZ] échappements : \ \[ \\ \s (espaces) \d ([09]) \w ([azAZ09_]) ● [az$] [^09] \S (tout sauf espace) \D (tout sauf ...) \W (tout sauf ...) . : tout sauf newline au clair de la lune mon ami Pierrot l[aeiou] m. 120 Syntaxe des regex ● | : alternative pigeon | merle | colibri pigeon, oiseau des villes tu es vraiment le plus agile ... ● ^ : début de ligne ^le $ : fin de ligne le plus agile, à mon regard tu te dérobes ... ● \b : limite de mot (opposé : \B) \brobe\b oiseau à la belle robe, à mon regard tu te dérobes ... 121 Syntaxe des regex ● ● répétitions – * : 0 ou plus – ? : 0 ou 1 – + : 1 ou plus – {m,n} : entre m et n ab*c ac abc abbc ● ● ab+c abc abbc ab?c ac abc mot-clé, mot clé, mot-clef, mot-clef mot[- ]cl[ée]f? (mot-cléf !) a/b a//b a/{1,3}b a///b 122 Utilisation des regex ● construction de la regex >>> import re >>> regex = re.compile('ab*c') ● fonctions : – match() : correspondance au début – search() : recherche partout Ces deux fonctions retournent None ou un "match object" utiliser : group(), start(), end(), span() – findall() : liste de toutes les sous-chaînes ok – finditer() : idem mais itérateur 123 Utilisation des regex ● attention aux \ passés à compile() ● il faut les préfixer \brobe\b devient par exemple \\brobe\\b et \section i.e. \\section devient \\\\section ! ● ou alors utiliser les "raw strings" r'\brobe\b' r'\\section' 124 Utilisation des regex >>> import re >>> regex = re.compile('robe') >>> texte = """Pigeon, ... Oiseau à la grise robe, dans l'enfer des villes ... A mon regard tu te dérobes, tu es vraiment le plus agile""" >>> regex.findall(texte) ['robe', 'robe'] >>> regex.search(texte) <_sre.SRE_Match object at 0xb7f1afa8> >>> regex.search(texte).span() (26, 30) 125 Utilisation des regex >>> import re >>> regex = re.compile(r'[\w]*robe[\w]*') >>> texte = """Pigeon, ... Oiseau à la grise robe, dans l'enfer des villes ... A mon regard tu te derobes, tu es vraiment le plus agile""" >>> regex.findall(texte) ['robe', 'derobe'] 126 Regex : groupements ● récupération de groupes de caractères ● patrons [email protected] [email protected] [\w]+\.[\w]+@[\w.]+\.univ-[\w]+\.fr 127 Regex : regroupements >>> import re >>> regex = compile(r'[\w]+\.[\w]+@[\w]+\.univ[\w]+.fr') >>> adresses = ''' [email protected]evry.fr [email protected] [email protected]lille.fr ''' >>> regex.findall(adresses) ['[email protected]evry.fr', '[email protected]lille.fr'] 128 Regex : regroupements ● utilisation de groupe parenthesés >>> import re >>> regex = compile(r'([\w]+)\.([\w]+)@[\w]+\.univ([\w]+).fr') >>> adresses = ''' [email protected]evry.fr [email protected] [email protected]lille.fr ''' 129 Regex : regroupements ● utilisation de groupe parenthesés >>> regex.findall(adresses) [('Pascal', 'Poizat', 'evry'), ('Gregoire', 'Petit', 'lille')] >>> ● parfois pas très pratique ... ● solution : utiliser finditer() et group() 130 Regex : regroupements ● utilisation de groupe parenthesés >>> for occ in regex.finditer(adresses): ... print "%s %s travaille à %s" % (occ.group(1), ... occ.group(2), ... occ.group(3)) ... Pascal Poizat travaille à evry Gregoire Petit travaille à lille >>> 131 Regex : regroupements ● parenthèses non regroupantes (?:...) [\w]+\.[\w]+@(?:[\w]+\.)?univ[\w]+\.fr permet de filtrer : Pascal.Poizat@univevry.fr ● groupes nommés (?P<id>...) déclaration dans la regex (?P<prenom>[\w]+)\.(?P<nom>[\w]+)@ ... utilisation groupe indexé (entier tjs possible) .group('prenom') (?P<prenom>[\w]+)\.(?P<nom>[\w]+)@(?:[\w]+\.)?univ(?P<ville>[\w]+)\.fr 132 Regex : découpage ● découpage de chaîne : split plus général que '...'.split(chaîne) >>> histoire1 = 'le pigeon mange une graine' >>> histoire2 = 'le pigeon avale une graine' >>> histoire1.split('mange') ['le pigeon', 'une graine'] >>> histoire2.split('mange') ['le pigeon avale une graine'] >>> verbes = re.compile('mange|avale') >>> verbes.split(histoire1) ['le pigeon', 'une graine'] >>> verbes.split(histoire2) ['le pigeon', 'une graine'] 133 Regex : découpage >>> verbes = 'mange|avale|joue avec' >>> complements = 'dans|derrière|devant' >>> histoire = 'Le joli pigeon joue avec sa balle devant la maison' >>> separateurs = verbes+'|'+complements >>> re_sep = re.compile(separateurs) >>> re_sep.split(histoire) ['le joli pigeon', 'sa balle', 'la maison'] 134 Regex : remplacement ● remplacement de chaîne : sub plus général que '...'.replace(chaîne) >>> histoire1 = 'le pigeon vole' >>> histoire2 = 'le pigeon marche' >>> histoire1.replace('vole', 'mange') 'le pigeon mange' >>> histoire2.replace('vole', 'mange') 'le pigeon marche' >>> mvt = re.compile('mange|marche| court') >>> mvt.sub('mange', histoire1) 'le pigeon mange' >>> mvt.sub('mange', histoire2) 'le pigeon mange' 135 Regex : remplacement >>> histoire = 'Il était une fois un lutin bleu qui avait des chaussettes vertes, des lunettes jaunes et un chapeau rouge' >>> couleurs = 'rouge[s]?|jaune[s]? |vert[e]?[s]?|bleu[e]?[s]?' >>> re_coul = re.compile(couleurs) >>> re_coul.sub('de couleur', histoire) 'Il était une fois un lutin de couleur qui avait des chaussettes de couleur, des lunettes de couleur et un chapeau de couleur' 136 Regex : remplacement ● le premier argument peut être une fonction (plus de flexibilité) def coloration(correspondance): suffixe, orig = '', correspondance.group(0) if orig[1]=='s': # pluriels orig, suffixe = orig[:1], 's' if orig[1]=='e': # féminin ? if orig[:1] in ['bleu','vert']: # feminin ! suffixe = 'e'+suffixe return 'coloré'+suffixe 137 Regex : remplacement ● le premier argument peut être une fonction (plus de flexibilité) >>> histoire = 'Il était une fois un lutin bleu qui avait des chaussettes vertes, des lunettes jaunes et un chapeau rouge' >>> couleurs = 'rouge[s]?|jaune[s]? |vert[e]?[s]?|bleu[e]?[s]?' >>> re_coul = re.compile(couleurs) >>> re_coul.sub(coloration, histoire) 'Il était une fois un lutin coloré qui avait des 138 chaussettes colorées, des lunettes colorés et un chapeau coloré' Plan ● les langages de script ● le choix de python ● bases de python ● python et les entrées-sorties ● python et IHM ● python et programmation scientifique 139 Python et IHM 140 Plan de cette partie ● (à voir en fonction du temps) 141 Plan ● les langages de script ● le choix de python ● bases de python ● python et les entrées-sorties ● python et IHM ● python et programmation scientifique 142 Python et programmation scientifique 143 Plan de cette partie ● modules numarray et numeric ● opérations de bases sur les matrices ● sorties graphiques 144