2013 Vincent.Favre-Nicolin@cea.fr Objectifs de cette UE : - (matriser un nouveau language) - connatre les modules scientifiques - et les appliquer un micro-projet de recherche
Sances prvues
1.5 sance d'introduction Python 1.5 sance d'introduction aux modules scientifiques en Python 2 sances consacres la ralisation d'un micro-projet personnel
Assembleur
_start "Bonjour\n" $4 , %eax $1 , %ebx $BONJ , %ecx $8 , %edx $0x80 $1 $0 $0x80 , %eax , %ebx ; ; ; ; ; ; ; D'aprs wikipedia.fr Definition en mmoire de la chane afficher. \n correspond au saut de ligne Mettre 4 dans le registre eax (appel systme ''Write'') Mettre 1 dans le registre ebx (descripteur de fichier ''STDOUT'') Mettre l'adresse mmoire de notre chane de caractre dans le registre ecx Mettre la taille de la chane dans edx Interruption 0x80, xcutant un appel systme sous Linux)
.global BONJ: .ascii _start: mov mov mov mov int mov mov int
; Mettre 1 dans eax (appel systme ''Exit'') ; Mettre 0 dans ebx (valeur de retour du programme) ; Interruption 0x80, xcutant un appel systme sous Linux)
Pas de gestion explicite de la mmoire Auto-dclaration des objets Prsence (en gnral) d'un interprteur de commande
print Bonjour
Le programme doit tre compil avant d'tre xcut Le programme est lu au fur et mesure de l'xcution Le programme est automatiquement compil l'xcution
Interprt
Compil au vol
Sous linux :
Python est en gnral install par dfaut, et est livr avec de nombreuses librairies
(Debian lenny comprend 1520 paquets avec le mot python )
[vincent@d420 ~]$ python Python 2.5.2 (r252:60911, Aug 5 2008, 15:33:24) [GCC 4.2.3 (4.2.3-6mnb1)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>>
[vincent@d420 ~]$ ipython Python 2.5.2 (r252:60911, Aug 5 2008, 15:33:24) Type "copyright", "credits" or "license" for more information. IPython 0.8.4 -- An enhanced Interactive Python. ? -> Introduction and overview of IPython's features. %quickref -> Quick reference. help -> Python's own help system. object? -> Details about 'object'. ?object also works, ?? prints more. In [1]: print 2+3 5 In [2]:
Crer un fichier texte (avec kwrite ou kate) qui s'appelle prog.py , qui contient :
print 2+3 print nous sommes mardi
-bash-3.2$ cd /home/NFS/HOME/v/vfavreni/python/prog.py -bash-3.2$ ipython prog.py 5 nous sommes mardi Python 2.5.2 (r252:60911, Aug 5 2008, 16:17:06) Type "copyright", "credits" or "license" for more information. IPython 0.8.1 -- An enhanced Interactive Python. [...] In [1]:
Variables
Le type de chaque variable est automatiquement fix >>> type(a) <type 'int'> # entier >>> type(1.2) <type 'float'> # nombre rel virgule flottante
=> typage fort , dynamique Une variable peut changer de type par simple affectation >>> a= Vive la Physique et la Chimie ! >>> print a Vive la Physique et la Chimie ! >>> type(a) <type 'str'> # string: chane de caractres
0,1, -1,100000000000 1.0, 2.5, 3.14159, 1.4e10 1+1j, 2.5+3.75j Oprations mathmatiques
abc ou abc \n abc+def 3*abc ab cd e.split() 1,2,3.split(,) ,.join([1,2]) a b c .strip() text.find(ex) Abc.upper() Abc.lower() -> abcdef -> abcabcabc -> [ab,cd,e] -> [1, 2, 3] -> 1,2 -> a b c -> 1 -> ABC -> abc # ajoute , entre les lments # enlve les espaces de fin et dbut #recherche # retour la ligne
Conversion vers des nombres: int(2), float(2.1) Conversion vers du texte : str(3), str([1, 2, 3])
Dans ipython, mettre le nom de la variable suivi de '?' donne accs l'aide
Boolen : True et False Un nombre nul <-> False, non nul <-> True
>>> if True: print toto ... toto >>> if 0: ... print toto # indentation ! ... else: ... print tata ... print et voila ... tata et voila L'indentation (espaces en dbut de ligne) remplace les accolades en python. Pour sortir d'une boucle, d'une condition, il suffit de revenir l'indentation prcdente
Boucles for
for <variable> in <liste> : code code >>> for i in [1,2,'a'] : ... print i ... 1 2 'a' >>> for i in range(4) : ... print i ... 0 1 2 3 # NB: mieux vaut utiliser xrange
Boucles while
while <condition> : code code >>> i=0 >>> while i<5: ... print i ... i=i+1 ... 0 1 2 3 4
# comparateurs: <
>
<=
>=
==
Utile lorsqu'on doit rpter une mme srie d'instructions plusieurs fois
Utile lorsqu'on doit traiter des donnes complexes, avec de multiples usages
Rappelle de l'historique avec (mme sessions prcdentes) Documentation d'objets avec nom? Code d'un objet ou d'une fonction avec nom?? Compltion: commencer taper un nom de variable + tabulation Code et coloration syntaxique (en cas d'erreur) Gestion des librairies graphiques en parallle...
Modules
Python est un langage modulaire Toutes les fonctions & types d'objets complexes sont rangs dans des
modules : >>> import math >>> print math.sin(1.2) 0.93203908596722629 >>> help(math) >>> from math import * >>> print sin(1.2) 0.93203908596722629 # aide sur le module # from + nom du module + import * # import + nom du module # NomDuModule.NomDelaFonction(arguments)
Scientifique Web (google, certains wiki, zope,...) Accs aux base de donnes Nombreux programmes crits en python
... Car la plupart des libraries (scientifiques ou autres) sont interfaces avec le => pas de besoin de rinventer la roue ! Tout code existant en c/c++/fortran est utilisable en python
langage Python :
Liens utiles
Le site officiel de python prog./libr. scientifiques Scientific python Recettes en scipy Graphisme scientifique Livre gratuit (*) Python reference card (anglais)
http://wiki.python.org/moin/NumericAndScientific
python physics -> 2.8 M liens... python molecule quantum -> 42000 rsultats ...
Affinements etc...
Rsolution d'quations
Calculs mathmatiques
Python inclus les modules 'math' et 'cmath' (math pour complexes) :
In [3]: import math In [4]: print math.sin(math.pi/4) 0.707106781187 In [5]: import cmath In [6]: print cmath.sin(2+1j) (1.40311925062-0.489056259041j)
Mais :
ces modules sont limits des calculs simples (une valeur la fois) Il faut utiliser un module diffrent pour les nombres complexes
Modules scientifiques
scipy :
calculs scientifiques avancs (affinement, transformes, rsolution, intgration,...)
numpy :
oprations lmentaires sur des tableaux
graphisme 1D/2D
Matplotlib (pylab) :
Python
tableaux
Les donnes pour des calculs sont ranger dans des vecteurs (numpy)
In In In [1 [1]: import numpy [2]: a=numpy.array([1,2,3]) [3]: print a 2 3] # cration directe
Cration de tableaux
...Autres crations de tableaux :
In [17]: print numpy.ones((2,2)) [[ 1. 1.] [ 1. 1.]] In [18]: print numpy.zeros((2,2),dtype=int) [[0 0] [0 0]] # tableau 2x2 remplis de 1
Types de base des tableaux: bool, int, uint, float complex Types Types Types Types avancs avancs avancs avancs (entiers signs): int8, int16, int32, int64 (entiers non signs): uint8, uint16, uint32, uint64 (rels flottants): float32, float64, float128 (complexes): complex64, complex128, complex128
Dans un tableau, le type des donnes est identique pour tous les lments (contrairement une liste).
Tableaux alatoires
In [[ [ [ [ [16]: print 1.58095991 1.00491457 0.17771713 0.89480039 numpy.random.uniform(0,2,size=(4,4)) 0.15385365 0.82891886 0.0390148 ] 0.35195621 1.76908828 1.40046406] 1.59835664 0.82339367 1.94511778] 1.31375333 1.26548763 0.83465617]] # Distribution uniforme # entre 0 et 2 # tableau 4x4
In [17]: print numpy.random.normal(0,2,size=(4,4)) [[-4.20057151 -3.74078452 -2.68678707 1.31524717] [ 0.94090408 0.54095026 1.12982079 -0.36770016] [ 1.54574406 0.33812108 2.20872166 0.74243889] [-1.03764455 2.97095545 0.10432429 -0.31398585]]
Astuce : si on veut un vecteur de 100 lments, avec 30% de 1 et 70% de zros : In [4]: (numpy.random.uniform(0,1,(100))>0.7).astype(numpy.float) Out[4]: array([ 0., 1., 0., 1., 1., 1., 0., 0., 0., 0., 0., 0., 1., 0., 1., 1., 0., 0., 1., 0., 0., 0., 1., 0., 0., 1., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 1., 1., 0., 1., 1., 0., 1., 1., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 1., 0., 1., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 1., 0., 0., 0., 0., 1., 1., 0., 1., 0., 0., 0., 1., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 1., 0., 0., 0., 0., 1., 0.])
Pas de boucle pour c=a+b 456.287 Mflops (Q6600 2.4GHz) Vitesse * 220 !
... et en C++ ? Code beaucoup plus long Risque d'erreurs avec des pointeurs 476.19 Mflops (Q6600 2.4GHz, -03)
Les calculs se font toujours lment par lment pour des tableaux (array) Pour une multiplication matricielle :
In [28]: print numpy.dot(a,b) [[ 45 48 51] [162 174 186] [279 300 321]]
In [7]: print eig(A) # vecteurs et valeurs propres (array([ 10.57624887+0.j , -0.28812444+0.1074048j, -0.28812444-0.1074048j]), array([[-0.14056873+0.j -0.58724949-0.17776272j, -0.58724949+0.17776272j], [-0.48042175+0.j , 0.0035321 +0.16590709j, 0.0035321 -0.16590709j], [-0.86569936+0.j , 0.77201089+0.j , 0.j ]]))
0.77201089-
des
Matplotlib : librairie graphique en python, clone les fonctionnalits de Matlab. http://matplotlib.sourceforge.net Nombreux exemples @ http://matplotlib.sourceforge.net/screenshots.html Pour l'utiliser : lancer ipython avec l'option -pylab :
[vincent@d420 doc]$ ipython -pylab Python 2.5.2 (r252:60911, Aug 5 2008, 15:33:24) Type "copyright", "credits" or "license" for more information.
IPython 0.8.4 -- An enhanced Interactive Python. ? -> Introduction and overview of IPython's features. %quickref -> Quick reference. help -> Python's own help system. object? -> Details about 'object'. ?object also works, ?? prints more. Welcome to pylab, a matplotlib-based Python environment. For more information, type 'help(pylab)'. In [1]: x=linspace(0,10,1000) # de 0 10, 1000 points
In [2]: plot(x,sin(x)) # trac de la courbe Out[2]: [<matplotlib.lines.Line2D instance at 0x8f675ac>] In [3]: savefig("sinus.png")
# Thanks to Charles Twardy for this example # #See http://matplotlib.sf.net/examples/legend_demo2.py for an example #controlling which lines the legend uses and the order from pylab import * a = arange(0,3,.02) b = arange(0,3,.02) c = exp(a) Tracer plusieurs courbes avec d = c.tolist() d.reverse() des styles diffrents, d = array(d)
ax = subplot(111) plot(a,c,'k--',a,d,'k:',a,c+d,'k') legend(('Model length', 'Data length', 'Total message length'), 'upper center', shadow=True) ax.set_ylim([-1,20]) ax.grid(0) xlabel('Model complexity --->') ylabel('Message length --->') title('Minimum Message Length') ax.set_xticklabels([]) # Pas de coordonnes ax.set_yticklabels([])
# Thanks to Charles Twardy for this example # #See http://matplotlib.sf.net/examples/legend_demo2.py for an example #controlling which lines the legend uses and the order from pylab import * a = arange(0,3,.02) b = arange(0,3,.02) c = exp(a) Tracer plusieurs courbes avec d = c.tolist() d.reverse() des styles diffrents, d = array(d)
ax = subplot(111) plot(a,c,'k--',a,d,'k:',a,c+d,'k') legend(('Model length', 'Data length', 'Total message length'), 'upper center', shadow=True) ax.set_ylim([-1,20]) ax.grid(0) xlabel('Model complexity --->') ylabel('Message length --->') title('Minimum Message Length') ax.set_xticklabels([]) # Pas de coordonnes ax.set_yticklabels([])
title(r"$\sqrt[3]{\frac{X_2}{Y}}=5$")
In [2]: y=linspace(-5,5,101)[:,newaxis] In [3]: z=exp(-(x**2+y**2)/5) In [4]: pcolor(x+y**2,y,z) # On donne x,y,z pour chaque point Out[4]: <matplotlib.collections.PolyCollection instance at 0x965e60c>
Pour changer de couleur In [15]: autumn() In [16]: colorbar() # Aussi jet() bone() grey() copper() hot() hsv() ...
http://code.enthought.com/projects/mayavi/docs/development/html/mayavi/ Simple scripting with mlab Lancer ipython avec ipython -wthread from numpy import * from enthought.mayavi import mlab # Create the data. dphi, dtheta = pi/250.0, pi/250.0 [phi,theta] = mgrid[0:pi+dphi*1.5:dphi,0:2*pi+dtheta*1.5:dtheta] m0 = 4; m1 = 3; m2 = 2; m3 = 3; m4 = 6; m5 = 2; m6 = 6; m7 = 4; r = sin(m0*phi)**m1 + cos(m2*phi)**m3 + sin(m4*theta)**m5 + cos(m6*theta)**m7 x = r*sin(phi)*cos(theta) y = r*cos(phi) z = r*sin(phi)*sin(theta) # View it. s = mlab.mesh(x, y, z) mlab.show()
0 x 2 dx = 1 3
1
Methods for Integrating Functions given fixed samples. trapz cumtrapz simps romb ----Use trapezoidal rule to compute integral from samples. Use trapezoidal rule to cumulatively compute integral. Use Simpson's rule to compute integral from samples. Use Romberg Integration to compute integral from (2**k + 1) evenly-spaced samples.
See the special module's orthogonal polynomials (special) for Gaussian quadrature roots and weights for other weighting factors and regions. Interface to numerical integrators of ODE systems. odeint ode -- General integration of ordinary differential equations. -- Integrate ODE using vode routine.
y = y sin t t
NB: l'intgration se fait avec un pas adaptatif (plus petit l o les drives sont grandes), indpendamment des abscisses demandes
2 y 0.2 y 2 = 10 y 2 t t
{ }
y 0= y y y 1= t
y =10 y 2 0 0.2 y 1 t
y0 = y1 t
def f(y,t): # Drive de y0(t) et y1(t) return [y[1],-10*y[0]-0.2*y[1]] t=linspace(0,20,201) # Valeurs de t souhaites y=integrate.odeint(f,[2,0],t) # Calcul en partant de y=2, y'=0 plot(t,y[:,0]) # Affichage de y(t)
Liens
Partie III
Lecture/criture de fichiers
fonctions membres (appeles mthodes) Exemple: class MaClasse: x=12 a=MaClasse() print a.x a.x=25 b=MaClasse() print b.x 12 # deuxime objet de type MaClasse # Accs la donne x de l'objet b # Cration d'un objet de type MaClasse # Accs la donne x de l'objet a
Classes et donnes
class MaClasse:
# Cration d'un objet de type MaClasse # Accs la donne x de l'objet a # Ajout d'une variable membre y # Ajout d'une variable membre 'nom'
Note : pour la clart du code, il est nanmoins conseill d'ajouter et de documenter toutes les variables membres au dbut de la classe Note 2: Attention, une variable ajoute n'est disponible que dans l'instance o elle a t ajoute !!
class MaClasse:
Les mthodes sont des fonctions dclares dans le corps de la classe. Elles
doivent avoir comme premire variable le mot-clef 'self' qui reprsente l'instance de la classe pour laquelle on appelle la fonction
class MaClasse: """ Ceci est une classe exemple """ x=12 def fonction1(self): print "Valeur de l'objet: ",self.x def valeurx(self): return self.x def ajoute(self,y=1): self.x += y a=Maclasse() a.fonction1() a.ajoute(20) # rponse: "Valeur de l'objet: 12" # ajoute 20 a.x # Renvoie une valeur # Ajoute une valeur (par dfaut : 1)
Il existe des mthodes spciales avec des noms prdfinis (utilisant deux '_' __init__ : constructeur de la classe cette fonction est appele lorsqu'on cre
avant et aprs):
une instance de la classe cela permet de passer des paramtres lors de la construction d'un objet :
class MaClasse: def __init__(self, x, x2=5): # constructeur une valeur par dfaut self.x=x self.y=x2
a=Maclasse(1,2)
class MaClasse: x=12 def __str__(self): return "MaClasse, valeur=%d"%(self.x) def __add__(self,b): a=Maclasse() a.x=self.x+b.x return a def __eq__(self,b): return self.x==b.x a=MaClasse() b=MaClasse() print str(a) print a+b print a==b # quivalent a.__str__() # quivalent a.__add__(b) # quivalent a.__eq__(b)
Pour stocker des donnes avec des fonctions qui permettent d'interprter ou de traiter
ces donnes : a=Molecule() a.Energie() a.NombreAtome() a.FormuleBrute() len(a) a[0].x a.SpectreRMN() # Nombre d'atomes # Coordonne x du premier atome # Renvoie le spectre RMN # Enregistrement dans un fichier mol
a.save("nom.mol",format='mol')
Pour bien "ordonner" son code : une fonction est toujours associe
l'objet laquelle elle se rapporte. Si la manire dont sont stockes les donnes changent, les fonctions
qui sont codes avec sont galement modifies MAIS les fonctions doivent toujours prendre la mme forme (mme arguments, mmes rsultat) => les fonctions sont une couche d'abstraction qui cachent la manire dont sont stockes et traites les donnes Il n'est pas ncessaire de connatre le dtail d'une fonction /
d'une classe pour l'utiliser. Il suffit de connatre sa documentation (arguments, valeurs renvoyes)
Une classe peut hriter d'une autre : elle possde alors toutes les
Note: l'hritage ne doit tre utilis que si les deux classes ont rellement des proprits en commun. Par exemple une classe "Proteine" peut hriter de "Molecule", mais pas de "Atome" . Par contre Molecule va contenir des objets Atome.
Polymorphisme : lorsqu'une classe hrite d'une autre, elle peut rcrire une
fonction de la classe parente: class Rectangle: def __init__(self, a=5,b=2): self.x=a self.y=b def Surface(self): return self.x*self.y def Circonference(self): return 2*(self.x+self.y) class Carre(Rectangle): def __init__(self, a=5): self.x=a def Surface(self): return self.x*self.x def Circonference(self): return 4*self.x L'intrt du polymorphisme est qu'on peut appeler une mthode sans savoir si l'objet est de type Carre ou Rectangle
Lecture/criture de donnes
Fonctions de base :
# Ouverture d'un fichier pour lecture # Lit toutes les lignes d'un fichier # Imprime toutes les lignes # Fermeture du fichier # Ouverture d'un fichier # Lit une ligne sous forme d'une chane de car. # A la fin du fichier la chane est vide # On spare les champs (fichier avec 2 colonnes)
f=open("data.txt",'r') ll=f.readlines() for l in ll: print l f.close() f=open("data.txt",'r') l=f.readline() vx,vy=[],[] While len(l)>0: s=l.split() vx.append(float(s[0])) vy.append(float(s[1])) l=f.readline() f.close()
# relecture
Note: le module cPickle est similaire pickle, mais crit en C et plus efficiace ! Note 2: il vaut mieux utiliser cPickle.dump((a,b),f, protocol=-1) qui permet d'tre
encore plus efficace (compression)... Note 3: lec fichiers enregistrs ne sont pas portables ! Il ne peuvent a priori tre relus que sur le mme ordinateur (version de python,systme, architecture)...
Partie IV
Acquisition de donnes
WxPython : bas sur la librairie wxWidgets (http://www.wxpython.org) PyQt : bas sur la librairie Qt la librairie sur laquelle est construit l'environnement KDE sous Linux (http://www.riverbankcomputing.co.uk/software/pyqt/intro). Cette librairies a t dveloppe par TrollTech, socit appartenant maintenant Nokia Python-tkinter : bas sur Tcl/Tk a t trs populaire mais d'une conception un peu ancienne. (http://wiki.python.org/moin/TkInter) PyGTK : bas sur la librairie GTK, utilise pour l'interface Gnome sous Linux ( http://www.pygtk.org/)
Signalons aussi l'interface python permettant d'utiliser la librairie ROOT du CERN : http://wlav.web.cern.ch/wlav/pyroot/ etc...
Acquisition de donnes
Il existe des librairies spcialises pour l'acquisition de donnes Avec l'USB, en utilisant des cartes d'acquisition :
PyUL (python-Universal Library) avec un botier de "measurement computing" http://www.scipy.org/Cookbook/Data_Acquisition_with_PyUL
Avec les ports srie & parallle : http://pyserial.wiki.sourceforge.net/ Pour tous les ports(usb, srie, gpib) : http://pyvisa.sourceforge.net/
1) crire un fichier avec les dclarations de variables, fonctions et classes 2) sauvergarder comme ModuleExemple.py 3) Importation avec : Import ModuleExemple L'importation fonctionne tant que le fichier se trouve dans le chemin recherch par python, que l'on peut consulter via : import sys print sys.path Pour qu'un module soit disponible sur un ordinateur, il faut le mettre dans le rpertoire 'dist-packages', soit pour python 2.7 sous Linux : '/usr/lib/python2.7/dist-packages''
cProfile
Comment dterminer combien de temps prend chaque partie d'un programme python ? => http://docs.python.org/2/library/profile.html Pour 'profiler' une fonction 'maFonction()', simplement utiliser : import cProfile cProfile.run('maFonction()') Il est aussi possible d'obtenir une reprsentation graphique des temps d'xcution : http://code.google.com/p/jrfonseca/wiki/Gprof2Dot
Partie V
Exceptions
Le module 'sys'
=> contient les fonctions & paramtres spcifiques au systme : import sys sys.path # Chemin de recherche des modules python sys.argv # Arguments de la ligne de commande python sys.modules # Listes des modules imports sys.version # Version de python sys.version_info #Version de python, plus facile interprter
Le module 'os'
=> fonctions & paramtres spcifiques au systme d'exploitation: import os os.cwd() os.chdir(dirname) os.environ os.listdir(dirname) os.mkdir(dirname) os.system('ls -la') # 'Current Working Directory' # Change le rpertoire dirname # Variables d'environnement (dictionnaire) # Liste des fichiers&rpertoires dans dirname # Cration du rpertoire dirname # Excute la commande 'ls -la' dans l'OS
Exceptions
=> En cas de problme, python renvoie des erreurs : >>> print 10/0 Traceback (most recent call last): File "<stdin>", line 1, in <module> ZeroDivisionError: division by zero Chaque erreur correspond une exception spcifique, qu'il est possible de dtecter l'aide des instructions try/except: try: print 10/0 except: print "Oups!" Plus d'informations : http://docs.python.org/2/tutorial/errors.html
Exceptions
Il est possible de ne dtecter qu'un type d'erreur: try: print 10/0 except ZeroDivisionError: print "Oups!" On peut enchaner les tests d'exceptions : try: print 10+"toto" except ZeroDivisionError: print "Oups ! Division par zro" except: print "Exception !!"
Exceptions
Il est possible de rcuprer l'objet correspondant l'exception : try print 10/0 except ZeroDivisionError as err: print "Oups ! Division par zro" print err Les exceptions forment une hirarchie de classes : >>> help(ZeroDivisionError) Help on class ZeroDivisionError in module exceptions: class ZeroDivisionError(ArithmeticError) | Second argument to a division or modulo operation was zero. | | Method resolution order: | ZeroDivisionError | ArithmeticError | StandardError | Exception | BaseException | __builtin__.object
Une copie par rfrence permet d'viter d'utiliser trop de mmoire. Toute modification d'une copie par rfrence modifie aussi l'original !