Installation d'un distribution Python

Il existe plusieurs distributions de Python à destination des scientifiques :

Chacune de ces distributions est disponible pour un grand nombre d'architectures 32 et 64 bits (Linux, Windows, Mac OS...).
Courant 2014, Anaconda semble être l'offre la plus simple d'accès et qui offre la meilleure compatibilité multi-plateformes. Il s'agit de la distribution installée par défaut sur les machines de la salle de TP.

Installation de packages supplémentaires :

Chacune de ces distributions comprend un ensemble de packages scientifiques (numpy, scipy, pandas...) et d'outils de développement (Spyder, Ipython). Python étant un langage ouvert, il est possible d'installer d'autres packages issus de la communauté ou de collègues.

Plusieurs outils de gestion des paquets existent. Par exemple, pour installer seaborn :

pip install seaborn
ou 
conda install seaborn (uniquement pour la distribution Anaconda)

Ces outils se connectent à des dépots en ligne et gèrent intégralement le téléchargement des sources et leur installation.

Si un paquet n'est pas disponible dans les dépôts officiels, il existe plusieurs alternatives :

  • Télécharger les sources et les installer manuellement avec la commande
python setup.py install

Prise en main de Spyder

Spyder est un environnement graphique de développement inspiré de l'interface Matlab.

Ses fonctionnalités comprennent :

  • Edition et éxecution de fichiers sources
  • Exploration de fichiers et de variables
  • Profiling du code
  • Affichage de l'aide
  • Gestion des variables d'environnement
  • ...

Création de fichier :

  • Créez un nouveau fichier en cliquant sur l'icône en haut à gauche ou avec le raccourci CTRL+N
  • Tapez
    print "hello world"
    
  • Exécutez-le en tapant F5...
  • ... ou n'exécutez que la ligne en cours de sélection avec F9
  • Le résultat de l'exécution s'affiche dans la console

TP 1 : Types, variables et opérations de contrôle :

Ouvrez le fichier data_type.py contenu dans l'archive avec Spyder

Print


In [23]:
print "Hello world"


Hello world

In [24]:
print '1', # la virgule empèche le saut de ligne après le print
print '2'


1 2

Scalaires

  • Les types numériques int et float

In [25]:
a = 1  # int
b = 1. # float
print a
print b


1
1.0

In [26]:
# Les variables sont sensibles à la casse
print A


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-26-6cc3eabd3eb1> in <module>()
      1 # Les variables sont sensibles à la casse
----> 2 print A

NameError: name 'A' is not defined

In [27]:
print(1+1.)
print 1+1
print 1/2
print 1./2


2.0
2
0
0.5

Nombres complexes


In [28]:
c = 1+2j

In [29]:
print c.real        # real et un attribut de l'objet c
print c.imag        # imag et un attribut de l'objet c
print c.conjugate() # Pourquoi des parenthèses ici? conjugate est une méthode de c
print c*c
print a+c


1.0
2.0
(1-2j)
(-3+4j)
(2+2j)

Question :

  • calculer le module de c

Booléens

Les booléens sont un sous ensemble des entiers


In [30]:
print True + True  #True vaut 1, False vaut 0 
print True & False
print (1 | False)
print not False
print a == b 
print a is b


2
False
1
True
True
False

Pourquoi

a == b

retourne vrai alors que

a is b

retourne faux?

Test "If"


In [31]:
if a == 1 : 
    print "a == 1" # Notez les 4 espaces après le retour à la ligne.
                   # Un groupe d'instruction est marqué par un même niveau d'indentation
else : 
    print "a <> 1"


a == 1

In [32]:
if a == 1 : 
    if type(a) == type(1.0) : 
        print "a is a float"
        
    elif type(a) == type(1):        
        print 'a is an integer'
        
else : 
    print "a <> 1"


a is an integer

Boucle "For"


In [33]:
for i in [0,1,2,'a','test'] : 
    print i


0
1
2
a
test

In [50]:
range(3)


Out[50]:
[0, 1, 2]

Boucle "While"


In [34]:
i = 0
while i < 5: 
    i += 1 # identique à i = i + 1
    print i


1
2
3
4
5

Exercice :

  • Ecrire les multiples de 7 et de 3 de 0 à 500 (utiliser l'opérateur // pour le modulo)

Caractères et chaînes de caractères


In [35]:
print "a"
print 'b' # on peut aussi bien utiliser ' que "
print "aujourd'hui"


a
b
aujourd'hui

Le concaténation des caractères se fait avec le signe +


In [52]:
print 'a'+'b'
print 'a'*5+'b'*4


ab
aaaaabbbb

Les caractères disposent de méthodes de manipulation, remplacement et de recherche :


In [37]:
print 'banana'.split('a')
print 'banana'.replace('n','l')
print 'banana'.capitalize()
print 'banana'.upper()
print '--'.join(['1','2','3','4'])
print 'banana'.count('na')
print "Python".find('on')


['b', 'n', 'n', '']
balala
Banana
BANANA
1--2--3--4
2
4

Les chaînes de caractères sont en fait des listes de caractères :


In [55]:
e = 'anticonstitutionnellement'
print len(e)
print e[0] # Comme en C, les listes commencent à 0
print e[-1] # l'élément -1 est le dernier élément, le -2 l'avant dernier...
print e[15:] # imprime tous les éléments après le 15ème

for i,char in enumerate(e) :  # enumerate liste les éléments d'une liste et leur position
    print i,char


25
a
t
nnellement
0 a
1 n
2 t
3 i
4 c
5 o
6 n
7 s
8 t
9 i
10 t
11 u
12 t
13 i
14 o
15 n
16 n
17 e
18 l
19 l
20 e
21 m
22 e
23 n
24 t

In [56]:
e[0] = 'A' # les chaînes de charactères sont immutables


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-56-2c9bea4d62f9> in <module>()
----> 1 e[0] = 'A' # les chaînes de charactères sont immutables

TypeError: 'str' object does not support item assignment

In [40]:
### Lecture d'un fichier ligne par ligne : 
f = open('zen.txt','r')
print 'Ligne 0: '+ f.readline()
print 'Ligne 1: '+ f.readline() 
print 'Ligne 2: '+ f.readline() 
print 'Ligne 3: '+ f.readline() 
f.close() # fermeture du fichier
# Si le fichier reste ouvert, il sera indisponible pour les autres programmes de l'OS


Ligne 0: Gur Mra bs Clguba, ol Gvz Crgref

Ligne 1: 

Ligne 2: Ornhgvshy vf orggre guna htyl.

Ligne 3: Rkcyvpvg vf orggre guna vzcyvpvg.

Une version plus efficace de la lecture de fichier est d'utiliser le mot clef with. Celui-ci crée un sous bloc de code qui, quoi qu'il arrive, exécute une action avant la sortie de code. Utilisé en conjonction avec open, with fermera toujours le fichier en fin de code.


In [255]:
with open('zen.txt','r') as f : 
    s =  f.read()
    print s
    # à la fin execute f.__exit__() qui ferme le fichier


Gur Mra bs Clguba, ol Gvz Crgref

Ornhgvshy vf orggre guna htyl.
Rkcyvpvg vf orggre guna vzcyvpvg.
Fvzcyr vf orggre guna pbzcyrk.
Pbzcyrk vf orggre guna pbzcyvpngrq.
Syng vf orggre guna arfgrq.
Fcnefr vf orggre guna qrafr.
Ernqnovyvgl pbhagf.
Fcrpvny pnfrf nera'g fcrpvny rabhtu gb oernx gur ehyrf.
Nygubhtu cenpgvpnyvgl orngf chevgl.
Reebef fubhyq arire cnff fvyragyl.
Hayrff rkcyvpvgyl fvyraprq.
Va gur snpr bs nzovthvgl, ershfr gur grzcgngvba gb thrff.
Gurer fubhyq or bar-- naq cersrenoyl bayl bar --boivbhf jnl gb qb vg.
Nygubhtu gung jnl znl abg or boivbhf ng svefg hayrff lbh'er Qhgpu.
Abj vf orggre guna arire.
Nygubhtu arire vf bsgra orggre guna *evtug* abj.
Vs gur vzcyrzragngvba vf uneq gb rkcynva, vg'f n onq vqrn.
Vs gur vzcyrzragngvba vf rnfl gb rkcynva, vg znl or n tbbq vqrn.
Anzrfcnprf ner bar ubaxvat terng vqrn -- yrg'f qb zber bs gubfr!

In [243]:
f.read()


---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-243-bacd0e0f09a3> in <module>()
----> 1 f.read()

ValueError: I/O operation on closed file

Conversion de nombres en textes


In [145]:
print "%d"%42
print "La variable %s vaut %2.3f à l'itération %d"%('toto',3.14159,12.) # arguments positionnels


42
La variable toto vaut 3.142 à l'itération 12

Il existe une autre syntaxe qui permet des expressions plus complexes :


In [148]:
print '{0}, {1}, {2}'.format('a', 'b', 'c')
print 'Coordinates: {latitude}N, {longitude}W {text}'.format(latitude=37.24, longitude=-115.81,text='Zen')


a, b, c
Coordinates: 37.24N, -115.81W Zen

Pour aller plus loin avec les chaînes de caractères :

  • Expressions régulières avec le module re (import re)

Les listes

  • Ce sont des containers, c'est à dire que les listes contiennent d'autres objets, peu importe leur type.
  • Les listes sont des objets mutables, c'est à dire qu'elles sont modifiables après leur création

In [68]:
g = [1,2,3] 
print g
print g[0] # Comme en C, les listes commencent par 0
g[1]='deux'  # les listes sont modifiables ("mutable")
print g
print g[1][0] # accède au premier élément de l'élément 2 de la liste
print g[-1]


[1, 2, 3]
1
[1, 'deux', 3]
d
3

La liste est mutable, il est possible de lui ajouter des éléments


In [69]:
g.append(4)
print g
g.extend([5,6,7])
print g


[1, 'deux', 3, 4]
[1, 'deux', 3, 4, 5, 6, 7]

Attention les variables en Python sont des pointeurs, c'est à dire une adresse qui pointe vers un objet dans la mémoire.


In [70]:
print g 
g2 = g
g2[0] = 'un'
print g2
print g # La modification de la liste g2 entraine la modification de la liste g ... g et g2 pointent toutes les deux vers la même variable


[1, 'deux', 3, 4, 5, 6, 7]
['un', 'deux', 3, 4, 5, 6, 7]
['un', 'deux', 3, 4, 5, 6, 7]

Pour être sûr de créer un nouvel objet, il faut utiliser le module copy


In [71]:
from copy import copy 

g2 = copy(g)

print g
g2[-1] = 'sept'
print g2
print g


['un', 'deux', 3, 4, 5, 6, 7]
['un', 'deux', 3, 4, 5, 6, 'sept']
['un', 'deux', 3, 4, 5, 6, 7]

La liste n'est qu'un container, elle ne réalise peu ou pas d'opérations numériques.

La liste n'est pas l'équivalent du vecteur (on verra plus tard le vecteur dans numpy)


In [73]:
print g+g
print g*3
# La liste se comporte comme la chaine de caractère. + est une opération de concaténation


['un', 'deux', 3, 4, 5, 6, 7, 'un', 'deux', 3, 4, 5, 6, 7]
['un', 'deux', 3, 4, 5, 6, 7, 'un', 'deux', 3, 4, 5, 6, 7, 'un', 'deux', 3, 4, 5, 6, 7]

Il existe des fonctions de création de liste comme range


In [77]:
h = range(1,4)
print h


[1, 2, 3]

Les listes possèdent également des méthodes de tri et de recherche d'éléments


In [78]:
h.append(0)
print h 

h.sort()
print h 

h.reverse()
print h 
# Exercice : fabriquer une liste d'entier allant de 42 à 99 par pas de 4


[1, 2, 3, 0]
[0, 1, 2, 3]
[3, 2, 1, 0]

Listes en compréhension

(comprehensive list)

Il s'agit d'une syntaxe spécifique pour créer des listes :


In [231]:
cl = [ i**2 for i in range(5) ]
print cl


[0, 1, 4, 9, 16]

Les tuples

Les tuples sont des listes immutables


In [245]:
# Les tuples
g = (1,2,3) # on utilise des parenthèses à la place des crochets pour la création
print g 
print g[0]        # mais on indice des la même manière


(1, 2, 3)
1

In [244]:
g[1]='test'  # les tuples ne sont pas modifiables ("immutable")


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-244-0f8cdda09c6b> in <module>()
----> 1 g[1]='test'  # les tuples ne sont pas modifiables ("immutable")

TypeError: 'tuple' object does not support item assignment

In [248]:
print g+g
print g*3
print g == [1,2,3]
print g == (1,2,3)


(1, 2, 3, 1, 2, 3)
(1, 2, 3, 1, 2, 3, 1, 2, 3)
False
True

In [247]:
g.sort()


---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-247-ba39f7e6986f> in <module>()
----> 1 g.sort()

AttributeError: 'tuple' object has no attribute 'sort'

Les dictionnaires :

Les dictionnaires sont des containers qui relient une clef à une valeur. Les dictionnaires reposent sur des tables de hachage et ont une complexité en temps de l'ordre de $\mathcal{O}(1)$, c'est à dire que quelle que soit la taille d'un dictionnaire, le temps pour retrouver un élément est constant.

Cette performance vient avec une limitation : les clefs d'un dictionnaire sont nécessairement immutables (pour être précis, elles doivent être hashable). On ne peut donc pas utiliser de listes comme clef. On peut cependant utiliser un tuple. Il n'y a pas de limitation sur les valeurs. Tout les objets peuvent être stockés dans un dictionnaire.


In [249]:
k = {} # dictionnaire vide
k['A'] = [0,1,2,'trois',['toto']]
k["text"] = 'zen'
k[(0,1)] = 'tuple' 
print k


{'A': [0, 1, 2, 'trois', ['toto']], 'text': 'zen', (0, 1): 'tuple'}

In [250]:
k[[0,1]] = 'list' # renvoie une erreur


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-250-c7e573206a44> in <module>()
----> 1 k[[0,1]] = 'list' # renvoie une erreur

TypeError: unhashable type: 'list'

In [160]:
print k['A']  # retrouve la valeur associée à la clef 'A'


[0, 1, 2, 'trois', ['toto']]

In [161]:
k.keys() # retourne la liste des clefs


Out[161]:
['A', 'text', (0, 1)]

In [162]:
k.values() # retourne la liste des valeurs


Out[162]:
[[0, 1, 2, 'trois', ['toto']], 'zen', 'tuple']

In [163]:
k.items() #retourne la liste des paires clefs values sous la forme d'une liste de tuples


Out[163]:
[('A', [0, 1, 2, 'trois', ['toto']]), ('text', 'zen'), ((0, 1), 'tuple')]

On peut créer un dictionnaire directement :


In [166]:
k2 = {1:'A',
      2:'B',
      3:'C'}
print k2


{1: 'A', 2: 'B', 3: 'C'}

Ou bien à partir d'une liste de (clefs, valeurs)


In [234]:
k3 = dict( [('T','Température'),
            ('P','Puissance'),
            ('H','humidité')])
print k3

print 'T' in k3 # T est une clefs de k3
print 't' in k3


{'P': 'Puissance', 'T': 'Temp\xc3\xa9rature', 'H': 'humidit\xc3\xa9'}
True
False

Exercice :

  • En utilisant la fonction enumerate, créez un dictionnaire qui associe à chaque chiffre de 0 à 25 la lettre de l'alphabet correspondante

In [173]:
import string
print string.ascii_lowercase


abcdefghijklmnopqrstuvwxyz

Exercice :

  • Décryptez le texte stocké dans le fichier zen.txt à l'aide du dictionnaire d

In [256]:
from this import d
print d


{'A': 'N', 'C': 'P', 'B': 'O', 'E': 'R', 'D': 'Q', 'G': 'T', 'F': 'S', 'I': 'V', 'H': 'U', 'K': 'X', 'J': 'W', 'M': 'Z', 'L': 'Y', 'O': 'B', 'N': 'A', 'Q': 'D', 'P': 'C', 'S': 'F', 'R': 'E', 'U': 'H', 'T': 'G', 'W': 'J', 'V': 'I', 'Y': 'L', 'X': 'K', 'Z': 'M', 'a': 'n', 'c': 'p', 'b': 'o', 'e': 'r', 'd': 'q', 'g': 't', 'f': 's', 'i': 'v', 'h': 'u', 'k': 'x', 'j': 'w', 'm': 'z', 'l': 'y', 'o': 'b', 'n': 'a', 'q': 'd', 'p': 'c', 's': 'f', 'r': 'e', 'u': 'h', 't': 'g', 'w': 'j', 'v': 'i', 'y': 'l', 'x': 'k', 'z': 'm'}

Les dictionnaires en compréhension

(comprehensive dictionnary)


In [181]:
k4 = {k: k**2 for k in range(10)}
print k4


{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}

Header Header Header Header
Cell Cell Cell Cell
Cell Cell Cell Cell
Cell Cell Cell Cell
Cell Cell Cell Cell

Les variables et les objets

  • Une variable Python est un pointeur, c'est à dire une adresse vers un objet dans la mémoire vive de votre OS.
  • En Python, tout est objet (une liste est un objet, un module est un objet, une classe est un objet...).
  • Une variable peut être de plusieurs types : modifiable (mutable) ou non modifiable (immutable).

In [84]:
a = 1
b = 2
print a
print b
a,b = b,a # permutation de variables
print a,b


1
2
2 1

In [80]:
a+b


Out[80]:
3

Un objet Python possède :

  • des attributs : càd des informations qui le définissent
  • des méthodes : càd des fonctions permettant de le manipuler

In [81]:
a.__doc__ # La documentation d'un objet est disponible dans son attribut __doc__


Out[81]:
"int(x=0) -> int or long\nint(x, base=10) -> int or long\n\nConvert a number or string to an integer, or return 0 if no arguments\nare given.  If x is floating point, the conversion truncates towards zero.\nIf x is outside the integer range, the function returns a long instead.\n\nIf x is not a number or if base is given, then x must be a string or\nUnicode object representing an integer literal in the given base.  The\nliteral can be preceded by '+' or '-' and be surrounded by whitespace.\nThe base defaults to 10.  Valid bases are 0 and 2-36.  Base 0 means to\ninterpret the base from the string as an integer literal.\n>>> int('0b100', base=0)\n4"

In [82]:
print a.__add__ # la méthode __add__ permet d'additionner des variables entre elles. 
print a.__add__(b)


<method-wrapper '__add__' of int object at 0x0000000001DE7970>
3

Les méthodes et les attributs commençant et finissant par "__" sont des méthodes spéciales.

Par exemple, Python interprete toujours la méthode __add__ comme la méthode permettant d'additioner un objet avec un autre. La méthode __doc__ est appelée sur un objet lorsque que l'on invoque la commande help(objet)

Pour acceder à la liste des méthodes et des attributs d'un objet, vous pouvez taper dir(objet). En mode interactif dans Ipython, il suffit de taper un point à la suite du nom d'un objet et de faire tab.

Les importations de packages

Python est modulaire, il repose sur un écosystème de packages permettant d'enrichir ses fonctionnalités (ie : toolbox matlab gratuite)

Exemple : Le package datetime permet la manipulation des dates et du temps


In [112]:
import datetime

start = datetime.datetime(2015,3,4,8,30)
end = datetime.datetime(2015,3,4,18,30)
t = end-start
print start, end
print t


2015-03-04 08:30:00 2015-03-04 18:30:00
10:00:00

In [113]:
print start.isoweekday()
print start.strftime('%A %B %Y %H::%m::%S')
print t.seconds


3
Wednesday March 2015 08::03::00
36000

Pour alléger les notations, il est possible de faire de imports relatifs :


In [122]:
from datetime import datetime, timedelta

dt = timedelta(hours=2,minutes=7,seconds=18)
print datetime.utcnow()
print datetime.utcnow()+dt


2015-03-03 10:38:53.282000
2015-03-03 12:46:11.282000

Exercice :

  • En utilisant les sous-modules datetime et timedelta, calculer le nombre de secondes entre le 1er juin 2012 et le début de cette formation.
  • Combien de jours cela fait-il?

Les fonctions


In [238]:
def fun2(a,b): 
    
    return a*b

print fun2('fun',5) 
print fun2(12,5)      # appel de fonction avec argument positionnel
print fun2(b=5,a=12)  # appel de fonction avec argument par mot clef
print a                # la valeur de la variable a n'a pas changé


funfunfunfunfun
60
60
2

In [ ]:
print a

def fun1():
    print a
    pass
print fun1()

Notez que a n'était pas passé en argument... Les variables à l'extérieur des fonctions sont accessible dans la fonction... mais pas l'inverse fun1 ne reroune aucune valeur, son résultat est

None

In [192]:
def fun3(a=0):
    return a

print fun3() # Argument par défault
print fun3(4)


0
4

In [253]:
def fun4(param0, param1 = 1, param2 = 3.14 ): 
    """
    Documentation ici
    
    """
    return param0*param1*param2, param0*param1

res1,res2 = fun4(1)
print res1, res2
print fun4(param0 = 1)
print fun4(param0=1, param1 = 1, param2 = 3.14 )
# Toutes les lignes sont strictement équivalentes
help(fun4)


3.14 1
(3.14, 1)
(3.14, 1)
Help on function fun4 in module __main__:

fun4(param0, param1=1, param2=3.14)
    Documentation ici

On peut aussi définir des fonctions avec une liste d'arguments variable


In [230]:
def fun5(req0,req1,opt0=0.0, opt1='c',opt2={},**kwargs):
    print req0
    print req1
    print opt0
    print opt1
    print opt2   
    print kwargs # key worded arguments
    
    return None
 
print fun5(req0='a',req1='b',opt0=1,opt1=2,opt2=3,**{'toto':7,'tata':8})


a
b
1
2
3
{'toto': 7, 'tata': 8}
None

Documentation de fonction avec le docstring (les triples quotes au début de la définition de la fonction)


In [202]:
def empty_documented_function(required_int,optional_float=0.0, optional_string='CSTB', *kargs ,**kwargs):
    u"""
Mettre ici la description de ce que la fonction fait.

Des équations en ligne ici  :math:`T_{ext}(t)\\geq0^{\\circ}C`

Des équations centrées ici : 

.. math:: e_{sat}(t) = 610.5e^{\\frac{17.269.T_{ext}(t)}{273.3+T_{ext}(t)}}   
   
Parameters
----------
required_int: int
    required_int how great is the CSTB [1]_
optional_float : float
    optional_float is an optional float. Default value is 0.0.
optional_string : string
    optional_string is an optional string of character. Its default value is 
*kargs : a list 
    Output shape.  If the given shape is, e.g., ``(m, n, k)``, then
    ``m * n * k`` samples are drawn.

See Also
--------
myModule.myOtherFunctionDoingSimilarThing : also great.



References
----------
.. [1] CSTB, "Web site",
       http://www.cstb.fr/

Examples
--------

>>> s = empty_function(2)

>>> len(s)


    """
    s = ' '.join(['CSTB is']+['great']*required_int+['!'])
    
    print s
    return s

if __name__ == "__main__" : 
    print(u'Le module est executé en tant que script')

else : 
    print(u'Le module est importé')


Le module est executé en tant que script

regarder l'aide de empty_documented_function

Mise en page des équations : http://martinkeefe.com/math/mathjax1

Packages par thèmes :


In [5]:
%%javascript
console.log("Hello World!")



In [ ]: