Python

Python présente plusieurs avantage à l'origine de son choix pour ce cours:

  • C'est un langage généraliste présent dans de nombreuses domaines: calcul scientifique, web, bases de données, jeu vidéo, graphisme, etc. C'est un outil polyvalent qu'un ingénieur peut utiliser pour toutes les tâches numériques dont il a besoin.
  • Il est présent sur la majorité des plateformes: Windows, Mac OS, Linux, Unix, Android
  • C'est un langage libre et gratuit avec un grande communauté d'utilisateurs. Tous vos programmes sont donc échangeables sans contraintes. Vos questions trouveront toujours des réponses sur internet. Enfin, très peu de bugs sont présents dans Python.

Installation

Sous Windows, nous vous conseillons la distribution Anaconda qui permet d'installer tous les outils nécessaires aux exemples traités ici.

Introduction

 Premiers pas

Vous pouvez voir Python comme une grosse calculatrice, vous pouvez y taper des commandes et voir le résultat instantanément:


In [1]:
print 'Hello World !'
a = 5.
b = 7.
a + b


Hello World !
Out[1]:
12.0

Nombres


In [2]:
a = 3.      # On définit un flottant (64 bits par défaut) 
b = 7       # On définit un entier (32 bits par défaut)
type(a), type(b)  # On demande le type de a et b


Out[2]:
(float, int)

In [3]:
a + b       # On additionne a et b, on remarque que le résultat est un flottant.
c = a + b   # On assigne à c la valeur a + b

 Chaînes de caractères


In [4]:
mon_texte = 'salade verte' # Une chaîne de caractères
mon_texte[0] # Premier caractère


Out[4]:
's'

In [5]:
mon_texte[1] # Second caractère


Out[5]:
'a'

In [6]:
mon_texte[-1] # Dernier caractère


Out[6]:
'e'

In [7]:
motif = 'Les {0} sont {1}' # Une comportant des balises de formatage
motif.format('lapins', 'rouges') # Formatage de la chaine


Out[7]:
'Les lapins sont rouges'

In [8]:
motif.format('tortues', 5)


Out[8]:
'Les tortues sont 5'

 Listes et dictionnaires


In [9]:
ma_liste = [] # On crée une liste vide 
ma_liste.append(45) # On ajoute 45 à la fin de la liste.
mon_texte = 'Les lapins ont des grandes oreilles' # On définit une chaine de caractères nommé mon_texte
ma_liste.append(mon_texte) # On ajoute mon_texte à la fin de ma_liste.
ma_liste    # On demande à voir le contenu de ma_liste


Out[9]:
[45, 'Les lapins ont des grandes oreilles']

In [10]:
ma_liste[0] # On demande le premier élément de la liste (Python compte à partir de 0)


Out[10]:
45

In [11]:
ma_liste[1]


Out[11]:
'Les lapins ont des grandes oreilles'

In [12]:
ma_liste[0] = a + b # On écrase le premier élément de ma_liste avec a + b
ma_liste


Out[12]:
[10.0, 'Les lapins ont des grandes oreilles']

In [13]:
mon_dict = {} # On définit un dictionnaire
mon_dict['lapin'] = 'rabbit' # On associe à la clé 'lapin' la valeur 'rabbit'
mon_dict[1] = 'one' # On associe à la clé 1 la valeur 'one'
mon_dict


Out[13]:
{1: 'one', 'lapin': 'rabbit'}

In [14]:
mon_dict[1]


Out[14]:
'one'

In [15]:
mon_dict.keys() # Liste des clés


Out[15]:
[1, 'lapin']

In [16]:
mon_dict.values() # Liste des valeurs


Out[16]:
['one', 'rabbit']

Structures de contrôle (ou boucles)


In [17]:
# Boucles en Python

# Boucle FOR
print 'Boucle FOR'
ma_liste = ['rouge', 'vert', 'noir', 56]

for truc in ma_liste:
  print truc # Bien remarquer le decalage de cette ligne (ou indentation) qui delimite le bloc de code qui appartient a la boucle. Dans Python, les blocs sont toujours definis par une indentation.
 
# Boucle IF
print 'Boucle IF'
nombre = raw_input(' 2 + 2 = ')
if nombre == 4:
  print 'Bon'
else:
  print 'Pas bon'
  
# Boucle WHILE
print 'boucle WHILE'
nombre = 3.
while nombre < 4.:
  nombre = raw_input('Donnez un nombre plus petit que 4: ')


Boucle FOR
rouge
vert
noir
56
Boucle IF
 2 + 2 = 4
Pas bon
boucle WHILE
Donnez un nombre plus petit que 4: 4

 Fonctions

On crée un fichier :download:fonctions.py <Python/Example_code/fonctions.py>:


In [18]:
# Definition d'une fonction
def ma_fonction(x, k = 1.): # On declare la fonction et ses arguments
  '''
  Renvoie k*x**2 avec k ayant une valeur par defaut de 1.
  '''
  out = k * x**2 # On fait les calculs necessaires
  return out # La commande return permet de renvoyer un resultat
  
  
ma_fonction(3)


Out[18]:
9.0

In [19]:
ma_fonction(5.)


Out[19]:
25.0

In [20]:
ma_fonction(5., k = 5)


Out[20]:
125.0

In [21]:
help(ma_fonction)


Help on function ma_fonction in module __main__:

ma_fonction(x, k=1.0)
    Renvoie k*x**2 avec k ayant une valeur par defaut de 1.

Classes


In [22]:
# Creation d'une classe de vecteurs

class vecteur:
  '''
  Classe vecteur: decrit le comportement d'un vecteur a 3 dimensions.
  '''
  def __init__(self, x = 0., y = 0., z = 0.): # Constructeur: c'est la fonction (ou methode) qui est lancee lors de la creation d'un exemplaire de la classe.
    self.x = float(x)
    self.y = float(y)
    self.z = float(z)
    
  def norme(self): # Une methode qui renvoie la norme
    x, y, z = self.x, self.y, self.z
    return (x**2 + y**2 + z**2)**.5
  
  def __repr__(self): # On definit comment la classe apparait dans le terminal
    x, y, z = self.x, self.y, self.z
    return '<vecteur: ({0}, {1}, {2})>'.format(x, y, z)
  
  # Addition
  def __add__(self, other): # On definit le comportement de la classe vis-a-vis de l'addition
    x, y, z = self.x, self.y, self.z
    if type(other) in [float, int]: # Avec un nombre
      return vecteur(x + other, y + other, z + other)
    if isinstance(other, vecteur): # Avec un vecteur
      return vecteur(x + other.x, y + other.y, z + other.z)
  __radd__ = __add__ # On definit l'addition a gauche pour garantir la commutativite
  
  # Multiplication: 
  def __mul__(self, other): # On definit le comportement de la classe vis-a-vis de la multiplication
    x, y, z = self.x, self.y, self.z
    if type(other) in [float, int]: # Avec un nombre
      return vecteur(x * other, y * other, z * other)
    if isinstance(other, vecteur): # Avec un vecteur: produit vectoriel
      x2, y2, z2 = other.x, other.y, other.z
      xo = y * z2 - y2 * z
      yo = z * x2 - z2 * x
      zo = x * y2 - x2 * y 
      return vecteur(xo, yo, zo)
  __rmul__ = __mul__ # On definit le produit vectoriel a gauche
  
  def scalaire(self, other):
    '''
    Effectue le produit scalaire entre 2 vecteurs.
    ''' 
    x, y, z = self.x, self.y, self.z
    x2, y2, z2 = other.x, other.y, other.z
    return x * x2 + y * y2 + z * z2
  
  def normaliser(self):
    '''
    Normalise le vecteur.
    '''
    x, y, z = self.x, self.y, self.z
    n = self.norme()
    self.x, self.y, self.z = x / n, y / n , z / n

In [23]:
v = vecteur(1, 0, 0)
v + 4


Out[23]:
<vecteur: (5.0, 4.0, 4.0)>

In [24]:
w = vecteur(0, 1, 0)
v + w


Out[24]:
<vecteur: (1.0, 1.0, 0.0)>

In [25]:
v * w


Out[25]:
<vecteur: (0.0, 0.0, 1.0)>

In [26]:
v.scalaire(w)


Out[26]:
0.0

In [27]:
q = v + w
q


Out[27]:
<vecteur: (1.0, 1.0, 0.0)>

In [28]:
q.norme()


Out[28]:
1.4142135623730951

In [29]:
k = vecteur(2, 5, 6)
k.normaliser()
k


Out[29]:
<vecteur: (0.248069469178, 0.620173672946, 0.744208407535)>

In [30]:
k.norme()


Out[30]:
1.0

Fichiers


In [31]:
f = open("fichier.txt", "wb") # On ouvre un fichier en ecriture
f.write("Very important data") # On ecrit
f.close() # On ferme de fichier

In [32]:
f = open("fichier.txt", "r") # On ouvre le fichier en lecture
data = f.read()
data


Out[32]:
'Very important data'

Modules

Les outils présents dans Python ont vocation à être très généralistes. De très nombreux outils orientés vers des applications particulières existes mais ils ne font pas directement partie du Python, ils sont alors disponibles sous forme de modules ou de packages. A titre d'exemple, si on cherche à utiliser des fonctions mathématiques de base dans Python, on remarque qu'elles n'existent pas:


In [33]:
sin(0)


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-33-b5f5b12908fe> in <module>()
----> 1 sin(0)

NameError: name 'sin' is not defined

Cependant, elles sont disponibles dans plusieurs libraires (modules ou packages dans Python). Il en existe beaucoup ce qui permet de faire à peu près tout. Ici, nous nous focalisons sur les plus indispensables:

Numpy: l'indispensable outil du calcul numérique


In [34]:
ma_liste = [1., 3., 5., 10. ] # Une liste
ma_liste + ma_liste # Somme de liste = concaténation


Out[34]:
[1.0, 3.0, 5.0, 10.0, 1.0, 3.0, 5.0, 10.0]

In [35]:
ma_liste*2 # Produit = concaténation aussi....


Out[35]:
[1.0, 3.0, 5.0, 10.0, 1.0, 3.0, 5.0, 10.0]

In [36]:
import numpy as np # On import numpy et on le renomme np par commodité.
mon_array = np.array(ma_liste) # On crée un array à partir de la liste.
mon_array


Out[36]:
array([  1.,   3.,   5.,  10.])

In [37]:
mon_array * 2 # array * entier = produit terme à terme


Out[37]:
array([  2.,   6.,  10.,  20.])

In [38]:
mon_array +5 # array + array = somme terme à terme


Out[38]:
array([  6.,   8.,  10.,  15.])

In [39]:
mon_array.sum() # Somme du array


Out[39]:
19.0

In [40]:
mon_array.mean() # Valeur moyenne


Out[40]:
4.75

In [41]:
mon_array.std() # Ecart type


Out[41]:
3.344772040064913

In [42]:
np.where(mon_array  > 3., 1., 0.) # Seuillage avec le très puissant where


Out[42]:
array([ 0.,  0.,  1.,  1.])

Scipy

Scipy ou scientific Python est une bibliothèque qui contient la majorité des agorithmes classiques en méthodes numériques.

Matplotlib

Matplotlib est un module de graphisme qui produit des figures de grande qualité dans tous les formats utiles. Voici quelques exemples:

  • Tracé d'une courbe $y = \dfrac{\sin( 2 \pi x)}{x}$:

In [44]:
# PACKAGES
import numpy as np
from matplotlib import pyplot as plt # On import pyplot (un sous module de Matplotlib) et on le renomme plt
%matplotlib nbagg

# FONCTIONS
def ma_fonction(x):
  '''
  Une fonction a tracer.
  '''
  return np.sin(2 * np.pi * x ) / x
  

# DEFINITIONS DIVERSES  
x = np.linspace(1., 10., 500) # On demande un array contenant 100 points equirepartis entre 0 et 5.
y = ma_fonction(x) # Grace a numpy, on applique la fonction a tous les points x d'un coup

# TRACE DE LA COURBE
fig = plt.figure() # On cree une figure
plt.clf()          # On purge la figure
plt.plot(x, y, 'b-', linewidth = 2.)     # On trace y en fonction de x
plt.xlabel('$x$')    # On definit le label de l'axe x
plt.ylabel('$y$')
plt.grid()         # On demande d'avoir une grille
plt.title(r'$y = \sin (2 \pi x) / x$') # On definit le titre et on utilise la syntaxe de LaTeX pour y introduire des maths.
plt.show()


  • Tracé d'un champ $z = \sin (2 \pi x) \sin (2 \pi y) / \sqrt{x^2 + y^2}$:

In [45]:
# FONCTIONS
def ma_fonction(x,y):
  '''
  Une fonction a tracer.
  '''
  return np.sin(np.pi * 2 *x) * np.sin(np.pi * 2 *y) / (x**2 + y**2)**.5
  

# DEFINITIONS DIVERSES  
x = np.linspace(1., 5., 100) # On demande un array contenant 100 points equirepartis entre 0 et 5.
y = np.linspace(1., 5., 100) 
X, Y = np.meshgrid(x,y) # On cree des grilles X, Y qui couvrent toutes les combinaisons de x et de y
Z = ma_fonction(X, Y) # Grace a numpy, on applique la fonction a tous les points x d'un coup

# TRACE DE LA COURBE
niveaux = 20 
fig = plt.figure() # On cree une figure
plt.clf()          # On purge la figure
plt.contourf(X, Y, Z, niveaux)
cbar = plt.colorbar()
plt.contour(X, Y, Z, niveaux, colors = 'black')

cbar.set_label('Z')
plt.xlabel('$X$')    # On definit le label de l'axe x
plt.ylabel('$Y$')
plt.grid()         # On demande d'avoir une grille
plt.title(r'$z = \sin (2 \pi x) \sin (2 \pi y) / \sqrt{x^2 + y^2}$') # On definit le titre et on utilise la syntaxe de LaTeX pour y introduire des maths.
plt.show()