Introduction au Python pour le calcul scientifique en mécanique¶
Ces notes de cours s'adressent à des étudiants ayant déjà des notions de programmation. Les concepts de typage des variables (entiers, réels, complexes, logiques...), d'affectation de variable, de tableaux, de boucles, de tests sont supposés connus. Il en est de même sur la manipulation d'algorithmes élémentaires. Nous ne revenons donc pas sur ces notions mais décrirons la manière de les implémenter en Python.
Dans cette UE, nous avons choisi d'utiliser Python 3. Il faut juste savoir que la version 2 de Python existe toujours. Nous mentionnons son existence car de nombreux exemples de codes se trouvent sur le web en Python 2. Il faut alors adapter la syntaxe qui diffère parfois.
Si vous souhaitez installer python chez vous, privilegiez la distribution anaconda qui est très simple d'installation. https://www.anaconda.com/products/individual Vous pouvez retrouver plus d'explications pour l'installation sur la page moodle du cours. Si vous avez peu de place sur votre disque dur prenez miniconda.
Il y a deux modes principaux d'utilisation de python :
- Un mode
interactif
- Un mode
script
Nous allons utiliser spyder
. Spyder est IDE (Integrated Development Environment). C'est une sorte d'éditeur amélioré pour développer du code. On écrit un ensemble d'instructions dans des fichiers (appelés scripts) que l'on peut sauvegarder sur son disque dur. L'extension du fichier est .py
Pour accéder au mode interactif, on se place dans une console ipython
. Cela ressemble à une calculatrice sophistiquée. La console est une fenètre intégrée dans spyder
. On peut ainsi tester rapidement et simplement l'effet d'une commande ou faire de petits calculs.
Il existe aussi un environement très populaire appelé jupyter notebook
. Les notebooks permettent de mélanger dans un même document du code, des textes, des figures, des vidéos, des liens vers des sites internet etc. Cela peut être très pratique pour la rédaction de document et pour communiquer des résultats scientifiques. L'extension du fichier est alors .ipynb. Par exemple, ce cours a été rédigé à l'aide d'un jupyter notebook
puis exporté au format html. Vous n'utiliserez pas les notebooks dans cette UE.
Le typage des données et les variables:¶
En python, le typage des données est dynamique et se fait au moment de l'affectation de la donnée dans une variable. Par exemple, chacune des instructions ci-dessous
a = 5.3
compteur = 5
Nom_UE = "Outils informatiques pour la mécanique"
z = 1 + 5j
MonLogique = (3 < 5)
fait les opérations suivantes.
- réserve de l'espace en mémoire
- décide du type de la donnée
- affecte la valeur de la donnée à droite du signe "=" à la variable à gauche de ce signe.
On peut le vérifier à l'aide de l'intruction print
et type
.
print(a)
type(a)
a est donc un float c-à-d un réel qui vaut 5.3.
Dans spyder
, on peut regarder les variables dans la fenêtre "explorateur de variables". C'est ce qu'il y a de plus pratique.
Alternativement, dans la console ipython, la commande whos
permet d'afficher l'ensemble des variables utilisées en mémoire et leur type.
whos
Les principaux types de données et les noms de variable :¶
Les principaux types sont les booléens, chaines de caractères str
, les réels float
, les entiers int
et les complexes complex
. Le nom des variables est assez libre mais comme dans tous les langages, il faut choisir des noms pertinents pour faciliter la lecture du code. Contrairement à certains langage comme le fortran, Python est sensible à la casse, il distingue donc les majuscules des minuscules. Il ne faut pas utiliser les mots clés de python comme nom de variable. La liste des mots-clés peut être connue en enchainant les deux commandes suivantes : import keyword
et print(keyword.kwlist)
. Vous pouvez constater qu'il y en a très peu.
Les principaux opérateurs et l'ordre de priorité.¶
Priorité des opérateurs ( de la plus élevée à la plus basse) | Description : |
---|---|
$**$ | Elever à la puissance |
$* \quad / \quad \% \quad \textrm{//} $ | Multiplier, diviser, modulo et division entière |
$+ \quad -$ | Addition et soustraction |
$ \textrm{ and not or } $ | Opérateurs logiques |
$<= \quad < \quad > \quad >= $ | Opérateurs de comparaison |
== != |
Opérateurs d'égalité |
$= \quad -= \quad += \quad *= $ | Opérateurs d'affectation |
Il y a beaucoup d'erreurs liées à une méconnaissance des priorités des opérateurs ! En cas de doute, il faut mettre des parenthèses.
Les commentaires¶
Le symbole # sert à commenter une ligne.
Un bloc de lignes peut être commenté en commençant et en finissant par une ligne avec " " " (trois guillemets).
# Cette ligne a été commentée
"""
Ces deux lignes
sont commentées
"""
f = lambda x : x**2 + 1 # version avec une variable
g = lambda x,y : x**2 + y # version avec deux variables
print(f(3))
print(g(3,2))
Version classique et plus générale avec le mot clé def
¶
def EnergieCin(m,v):
Ec = 1./2.*m*v**2
print('Energie cinétique = ', Ec, 'J')
# Notez l'indentation qui est significative en Python. En général on prend 4 espaces.
return # pas obligatoire si on ne renvoie rien. Ce n'est pas le return qui ferme la définition de la fonction.
EnergieCin(80,5) # Ici j'appelle la fonction EnergieCin avec les deux paramètres 80 et 5.
#print(Ec) # Produit une erreur car Ec n'est pas connu. C'est une variable interne à la fonction.
Il faut bien noter la syntaxe de la fonction :
- Le mot clé
def
puis le nom de la fonction, suivi d'arguments entre parenthèse et séparés par des virgules et la présence des ":" au bout de la première ligne - un bloc d'instructions INDENTÉ (ici 4 espaces)
Il faut impérativement respecter cette syntaxe. L'indention est très importante. Contrairement à beaucoup de langage, l'indentation n'est pas utilisée par souci de lisibilité, elle est significative et fait parti du langage. La définition de la fonction est terminé quand on arrète d'indenter. Dans cette première fonction, le return
n'est pas obligatoire ici car la fonction ne renvoie rien mais c'est mieux de le mettre.
Remarque : La variable interne Ec n'est pas connue en dehors de la fonction
Version avec renvoi de résultat et notion d'argument facultatif.¶
En général, on souhaite que la fonction renvoie le résultat du calcul pour s'en servir ailleurs.
def EnergieCin_new(m,v):
Ec = 1./2.*m*v**2
return Ec
# Cette fois EnergieCin-new renvoie la valeur Ec
masse = 80
vitesse = 4
EcHomme = EnergieCin_new(masse,vitesse) # EcHomme prend la valeur qui a été renvoyée par la fonction
print('Energie cinétique Homme = ', EcHomme, 'J')
def Energies(m,v,h,g=9.81): # g est un argument facultatif avec une valeur par défaut.
Ec = 1./2.*m*v**2
Ep = m*g*h
return Ec,Ep # La fonction peut renvoyer plusieurs valeurs.
hauteur = 10
EcHomme, EpHomme = Energies(masse,vitesse,hauteur) # sans préciser g, la fonction prend la valeur par défaut
print('Energie potentielle Homme = ', EpHomme, 'J')
Sur la Lune, le résultat est différent pour l'énergie potentielle
gravite_Lune = 1.62
EcHomme, EpHomme = Energies(masse,vitesse,hauteur,gravite_Lune)
print('Energie cinétique Homme = ', EcHomme, 'J')
print('Energie potentielle Homme = ', EpHomme, 'J')
# Affectation de plusieurs variables sur une ligne. C'est pratique mais trop limité si on a un grand nombre d'éléments.
a , b, c = 1.5, "chien", 4<5
print(a,b,c)
Les conteneurs (objets itérables)¶
Le conteneur est une généralisation du tableau que vous connaissez déjà probablement. Le principal intéret des conteneurs est de pouvoir mélanger dans un même "tableau" des éléments avec différents types. Il y a trois conteneurs principaux dans le python de base :
- les listes
- les tuples
- les dictionnaires.
Nous introduisons briévement ici uniquement les deux premiers: les listes et les tuples. Dans ce cours, nous les utiliserons peu.
Les listes et les tuples sont des collections ordonnées de variables pouvant être hétérogènes (mélange des types).
Les listes sont modifiables. Les tuples sont non modifiables.
Liste et tuple sont des objets itérables (appelés parfois séquences), c-à-d que l'on peut faire des boucles pour les parcourir.
Ces notions vont être plus claires à travers quelques exemples.
Liste : création et accès aux éléments¶
Les listes sont délimités par des crochets [ ]
et les éléments séparés par une virgule,
.
mescouleurs = ["rouge","vert","bleu"] # ici la liste est homogène
autreliste = ["rouge", 18, "vert", 22 ,"bleue", 43.5, 3<5 , True, 28.3] # La liste est hétérogène
print(autreliste[1]) #
print(autreliste[0]) # J'affiche le premier élément de la liste
autreliste[3] = "cyan" # Je remplace un entier par une chaine de caractère
print(autreliste) # Affiche toute la liste
print(autreliste[-1]) # Affiche le dernier élément de la liste.
unelistevide = []
Maliste2liste = [mescouleurs,autreliste]
print(Maliste2liste)
On note ici que les éléments des listes (ou tuples) sont repérés par des entiers qui commencent à 0 comme en langage C et non à 1 comme en matlab ou fortran. Le dernier élément est repéré par -1. L'avant dernier par -2 etc..
Manipulation de liste : Insertion et suppression d'éléments¶
autreliste = ["rouge", 18, "vert", 22 ,"bleue", 43.5, 3<5 , True, 28.3]
del(autreliste[3]) # je supprime le quatrième élément de la liste.
autreliste.insert(2,"noir") # j'ajoute un élément "noir" avec l'indice 2 dans la liste
autreliste.append(66.4) # j'ajoute à la fin de la liste 66.4
print(autreliste)
# Une combinaison souvent utilisée
liste_1 = [] # On commence par une liste vide
liste_1.append(4) # On ajoute des éléments avec .append
liste_1.append('oiseau')
print(liste_1)
Tuple : création et accès aux éléments¶
Les listes sont délimités par des parenthèses ( )
et les éléments séparés par une virgule,
.
# Je crée un tuple : Bien noter les ( ) au lieu des [ ]
couleursdrapeau = ("bleu","blanc","rouge")
# Je peux connaître le nombre d'éléments d'une liste ou tuple avec la fonction len
len(couleursdrapeau)
# Comme pour une liste ou un tuple on accède au dernier élément avec l'indice -1, l'avant dernier avec -2 etc
couleursdrapeau[-2]
L'accès aux éléments se fait aussi avec des crochets [ ]
comme pour les listes
>>> couleursdrapeau[1] = "noir"
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-5-7fa94d11d4d6> in <module>
----> 1 couleursdrapeau[1] = "noir"
TypeError: 'tuple' object does not support item assignment
Cette commande engendre une erreur car le tuple n'est pas modifiable. De même, l'instruction del(couleursdrapeau[1])
aurait provoqué une erreur.
Les instructions de contrôle¶
En général, on utilise les intructions de contrôle dans des scripts. Il faut utiliser un éditeur ou un IDE comme spyder
pour les écrire. Les scripts sont sauvegardés avec l'extension .py
. Une fois que la succession de commandes sont dans le script monscript.py
, il est possible de l'exécuter en tapant python monscript.py
dans un terminal ou en cliquant sur le triangle vert dans spyder. Un script exécute les instructions en séquence de haut en bas. Les instructions peuvent être répétées (boucles) ou éxecutées sous conditions (les tests).
La syntaxe pour ces instructions composées est particulière au python car l'indentation des lignes est significative (comme pour la définition des fonctions avec def
).
Il y a :
- une ligne d'introduction avec un mot-clé terminée par le caractère deux points :
- un bloc d'instructions indenté par rapport à la ligne d'introduction. Il est d'usage de mettre 4 espaces pour faire cette indentation.
Les instructions de contrôle : Les tests¶
Les tests se font avec les mots clés if
, elif
et else
.
- Les comparateurs sont classiques
>
,<
,>=
(supérieur ou égal),<=
(inferieur ou égal),==
(égalité) et!=
(différent). - Les opérateurs booléens sont
and
,not
,or
.
Voici un exemple d'utilisation de if
: bien observer les indentations !
x = 7
if x < 0 :
print("x est strictement négatif")
elif x%2 !=0 :
print("x est positif et impair")
else:
print("x n'est pas négatif et est pair")
if x>= 5 and x<8: # combinaison de conditions
print("x est tel que : 5 <= x < 8")
Les instructions de contrôle : Les boucles for¶
Les boucles for
parcourent des itérables
. C'est donc un peu plus général que les boucles parcourant simplement des indices. On peut ainsi parcourir directement une liste (ou un tuple) sans passer par les indices de la liste. Exemple :
for couleurs in mescouleurs:
print(couleurs)
print("Toutes les couleurs sont imprimées")
Une chaine de caractères (str) est aussi un itérable car la variable est considérée comme une liste non modifiable de caractères.
Prenom = "Joséphine"
for lettre in Prenom:
print(lettre)
La notion d'itérateur : range¶
Pour parcourir des indices comme avec des langages de plus bas niveau, on a recours à un "itérateur" appelé range. Il y a trois syntaxes possibles:
- range(stop) génère des entiers allant de 0 à stop-1
- range(start,stop) génére des entiers allant de start à stop-1
- range(start,stop,step) génère des entiers allant de start à stop-1 avec un pas step.
Note : Il est aussi possible de créer des listes à partir de range
et list
:
maliste = list(range(2,9,2))
print(maliste)
Exemples de boucles avec range :
for i in range(5):
print(i)
print("Démarre à 0 et finit à 4 !")
Boucle interrompue par l'instruction break:
for i in range(2,17,3):
if i>11:
break
print(i, end=" ") # Le end=" " remplace le retour à la ligne du print() par un espace.
print(" La boucle est interrompue pour i stritement supérieur à 11")
print(i)
Boucle utilisant l'instruction continue:
for i in range(2,20,3):
if i==8:
continue
print(i, end=" ") # Le end=" " remplace le retour à la ligne du print() par un espace.
print(" La boucle a sauté la valeur 8 ")
print("En sortie de boucle la valeur de i vaut :",i)
Les instructions de contrôle : Les boucles while¶
Les boucles while
répetent des instructions tant qu'une condition est vérifiée. Exemple :
x = 0
while (x<10):
print(x)
x +=1
Ajout de fonctions supplémentaires avec import¶
Python est assez rudimentaire et très peu de fonctions sont connues. On peut ajouter des modules (ou bibliothèques) avec la fonction import.
Pour avoir accéder aux fonctions mathématiques classiques, on importe la bibliothèque math
import math
puis on précéde le nom de la fonction du nom de la bibliothèque séparé par un point
par exemple
math.log(4.5)
math.pi
Pour manipuler les complexes on importerait cmath
import math
import cmath # Importe les fonctions math pour manipuler les complexes
math.log(4.5)
print(math.pi)
print(cmath.sqrt(-1))
# print(math.sqrt(-1)) provoque une erreur
# dir(math) pour voir les fon
A propos des listes:¶
Les listes ne sont pas forcément très performantes et pratiques quand il s'agit de faire du calcul scientifique. Pour remédier à cela, des modules ont été crées. Les principaux modules pour le calcul scientifique sont numpy et scipy. Pour générer des graphiques, la bibliothèque standard est matplotlib