0% ont trouvé ce document utile (0 vote)
1 vues60 pages

Tutoriel Python 2026

Transféré par

micky.oubro
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
1 vues60 pages

Tutoriel Python 2026

Transféré par

micky.oubro
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

Tutoriel Python

PROJ0001-1 : Introduction aux méthodes numériques et projet


Bachelier en Sciences de l’Ingénieur (Bloc 1)
Année académique 2025-2026

Table des matières


1 Installation d’Anaconda, de Python et de l’IDE Spyder 3
1.1 IDE Spyder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

2 Types de variables 6
2.1 Type int (nombre entier) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.2 Type float (nombre à virgule flottante) . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.3 Type complex (complexe) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.4 Type str (chaîne de caractères) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.5 Type bool (booléen) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

3 Aide 8

4 Terminologie 10
4.1 Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
4.2 Fonctions/functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
4.3 Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
4.4 Paquets/packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
4.5 Librairies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
4.6 Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

5 Edition de scripts 14
5.1 Indentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

6 Librairies, fonctions, variables locales et globales 18


6.1 Liste de librairies utiles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
6.1.1 matplotlib . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
6.1.2 numpy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
6.1.3 scipy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

7 D’autres types d’objets : list, tuple et array 23


7.1 Liste et tuple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
7.2 Tableau à 1 dimension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
7.2.1 Opérations sur un tableau à 1 dimension . . . . . . . . . . . . . . . . . . . . . 27
7.3 Tableaux à 2 dimensions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

8 Les sorties de fonction et les différents types de tableaux possibles 30

1
9 Résolution de systèmes d’équations linéaires 32

10 Structures de contrôle : for, if/elif/else, while, break, continue 32


10.1 La boucle for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
10.2 if/elif/else . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
10.3 La boucle while/break/continue . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

11 Les polynômes 36

12 Graphiques 37
12.1 Les bases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
12.2 Afficher plusieurs courbes dans un graphique, créer une nouvelle figure . . . . . . . . 39

13 Interpolation par splines 41

14 Entrées et sorties 42

15 Résolution d’équations différentielles 43


15.1 Ajouter des paramètres aux équations différentielles . . . . . . . . . . . . . . . . . . . 47
15.2 Valeurs particulières de l’EDO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

16 Le codage en dur (“hardcode”) 49

17 Débogage 52

18 Analyse des performances 56

19 Fin du tutoriel 59

2
1 Installation d’Anaconda, de Python et de l’IDE Spyder
Python est un langage de programmation open source orienté objet de haut niveau largement utilisé
dans le monde industriel et scientifique. Ce langage permet non seulement d’effectuer du calcul
scientifique et de la visualisation graphique, mais également de créer des sites web. Afin de pouvoir
en bénéficier, nous utiliserons la plateforme de distribution Anaconda permettant d’installer Python
et l’environnement de programmation Spyder. Pour débuter, téléchargez et installez la distribution
d’Anaconda de votre système d’exploitation (Windows, Mac OS ou Linux) :
https ://[Link]/products/individual
En installant Anaconda, vous installerez Python, Jupyter Notebook et Spyder. Une fois Anaconda
installé, vous pourrez lancer l’environnement de programmation Spyder et faire tourner les Note-
books (ce tutoriel par exemple).
Une fois que vous avez installé Anaconda, démarrez l’application. A partir de l’écran d’accueil, vous
pourrez démarrer soit Spyder soit Jupyter Notebook en double cliquant sur l’icône correspondante.

1.1 IDE Spyder


Spyder est un environnement de développement scientifique pour Python (Scientific PYthon De-
velopment EnviRonment) : un puissant environnement de développement interactif (IDE) pour le
langage Python avec des fonctions avancées d’édition, de test interactif, de débogage et d’analyse
de performance (profiler).
https ://[Link]/.

— Dans Spyder, la console IPython est l’interpréteur Python par défaut.


— Le code dans l’éditeur peut être exécuté entièrement ou partiellement dans cette console.
— L’éditeur prend en charge la vérification automatique des erreurs Python .
— Le débogueur Ipython peut être activé.
— Un profiler est fourni pour analyser l’efficacité du code.

3
— Un explorateur d’objets montre la documentation des fonctions, des méthodes, . . .
— L’explorateur de variables affiche les noms, la taille et les valeurs des variables numériques.
— L’explorateur de fichier permet de naviguer dans votre arborescence de fichiers.

Une fois Spyder lancé, vous verrez une interface organisée en trois grandes fenêtres : l’éditeur utilisé
pour écrire et sauvegarder vos commandes et vos programmes, l’explorateur de fichiers, de figures
ainsi que l’aide, et la console qui exécute les commandes écrites en Python ainsi que l’historique des
commandes entrées. Cette dernière option est très utile pour remonter dans le temps et permet de
voir quelles commandes ont été exécutées, dans quel ordre et à quel moment.

La console IPython permet d’entrer des commandes après l’invite de commande “In [ ] :”

[1]: a = 2

L’exemple ci-dessus montre que l’on a affecté la valeur 2 à la variable a à l’aide de l’opérateur =.
Une variable est un conteneur d’information sous la forme d’un scalaire, d’un tableau, d’une suite
de caractères ou, plus généralement, d’un objet. Nous pouvons affecter plusieurs variables à la fois.
La définition est silencieuse par défaut, càd que la valeur de a ne s’affichera pas à l’exécution de la
commande a=2. Si nous voulons afficher la valeur de a, nous pouvons utiliser la fonction print( )
ou utiliser l’explorateur de variables. Nous pouvons voir dans l’exemple ci-dessous que nous avons
créé une variable appelée a, qui est un entier de dimension 1 et de valeur “2”.
L’explorateur des variables constitue donc notre espace de travail. Il fournit à l’utilisateur des
informations sur les variables définies à l’instant présent. Il offre des fonctionnalités pour la gestion
des variables (création, édition, suppression, etc.). Ces informations sont également accessibles par
le biais des commandes who et whos ou la commande type().

[2]: a1 = a2 = a3 = 3
print(a1 * a2 * a3)

27

4
[3]: print(a)

[4]: who

a a1 a2 a3

[5]: whos

Variable Type Data/Info


----------------------------
a int 2
a1 int 3
a2 int 3
a3 int 3

[6]: type(a)

[6]: int

Si nous voulons effacer des variables, nous pouvons utiliser la commande %reset (qui demander
une confirmation) pour effacer toutes les variables ou del pour effacer une variable spécifique. La
commande clear ne fait elle que de nettoyer la console tout en gardant les variables en mémoire.

[7]: del a

[8]: %reset

On peut également utiliser les opérateurs d’addition +, de soustraction - de multiplication *, de


division /, de modulo % et de puissance ** ou les combiner. Par exemple += incrémente la variable
affectée d’une valeur à spécifier.

5
[9]: a = 2 + 3
print(a)

[10]: print(2**3)

[11]: a += 1
print(a)

[12]: a -= 1
print(a)

5
Python définit plusieurs types d’opérations de base par défaut (affectation, arithmétique, puissance,
valeur absolue, comparaisons, logique) :

[1]: 2 == 2

[1]: True

[2]: 2 < 4

[2]: True

[3]: 2 > 4

[3]: False

[13]: 1 != 2

[13]: True

[14]: True & False

[14]: False

[15]: True & True

[15]: True

2 Types de variables
Dans Python, il n’est pas nécessaire de déclarer les variables avant de pouvoir les utiliser (typage
dynamique). La valeur que l’on affecte à la variable définit son type. Les principaux types sont :

6
2.1 Type int (nombre entier)
[16]: a = 300
type(a)

[16]: int

2.2 Type float (nombre à virgule flottante)


[17]: a = 1.25e3
type(a)

[17]: float

2.3 Type complex (complexe)


[18]: a = 1 + 3j
type(a)

[18]: complex

2.4 Type str (chaîne de caractères)


[19]: a = "bonjour"
print(a ,"\n")
type(a)

bonjour

[19]: str

\n est le caractère de saut de ligne.

[20]: a = 'aurevoir'
print(a)
type(a)

aurevoir

[20]: str

2.5 Type bool (booléen)


[21]: a = True
type(a)

[21]: bool

7
[22]: b = not(a)
print(b)

False
Nous avons utilisé l’opérateur not() pour renvoyer l’opposé de la valeur booléenne transmise.
Il n’est pas nécessaire de préciser le type de variables dans Python (typage dit dynamique), mais il
faut néanmoins bien les connaître car il n’est pas toujours possible de réaliser des opérations entre
variables non compatibles (source fréquente de bug). Les exemples ci-dessous illustrent d’une
part une addition entre une variable de type int et une variable de type float et d’autre part
l’addition entre deux variables non compatibles de type int et de type str :

[4]: a = 1
print('a est de type', type(a))

b = 2.3
print('b est de type', type(b))

print(a + b)

a est de type <class 'int'>


b est de type <class 'float'>
3.3

[5]: c = '2.3'
print('c est de type', type(c))

c est de type <class 'str'>

[6]: a + c

---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[6], line 1
----> 1 a + c

TypeError: unsupported operand type(s) for +: 'int' and 'str'

Exercice : Créez deux variables de type str et additionnez les. Quel est le résultat ?

[ ]:

3 Aide
Il existe énormément de ressources pour Python sur internet (https ://[Link]/search/,
https ://[Link]/3/[Link], https ://[Link]/3/tutorial/) mais l’utilisateur
peut d’abord trouver de l’aide localement en appuyant sur Cmd+I ou Ctrl+I devant n’importe quel
objet. Vous pouvez également utiliser l’aide interactive fournie dans l’environnement Spyder dans

8
l’aide ou à travers la console en entrant par exemple help(print). Finalement, une aide se montrera
automatiquement après avoir écrit une parenthèse de gauche à côté d’un objet.

[23]: help(print)

Help on built-in function print in module builtins:

print(*args, sep=' ', end='\n', file=None, flush=False)


Prints the values to a stream, or to [Link] by default.

sep
string inserted between values, default a space.
end
string appended after the last value, default a newline.
file
a file-like object (stream); defaults to the current [Link].
flush
whether to forcibly flush the stream.

9
Plus simplement, si nous souhaitons obtenir de l’aide au niveau de l’utilisation de la console, nous
pouvons utiliser ?

[ ]: ?

Exercice : Rechercher de l’aide sur la fonction abs() et utiliser cette fonction sur un nombre de
votre choix défini dans une variable a.

[ ]:

Exercice : Affecter à une variable votre prénom et votre nom séparé par un . et calculer la longueur
de la chaîne de caractères ainsi crée.

[ ]:

4 Terminologie
Python utilise un certain nombre de concept propre au langage qu’il est impor-
tant de définir. Vous trouverez de plus amples informations au sein du glossaire
(https ://[Link]/fr/3/[Link]#glossary).

4.1 Scripts
Un script est simplement un fichier .py où est enregistré un ensemble d’instructions destinées à être
exécutées. L’exécution du script créera de nouvelles variables ou des graphiques dans l’espace de
travail.

4.2 Fonctions/functions
Une fonction est un ensemble de lignes d’instructions organisé selon une syntaxe bien définie (utili-
sant le mot-clé def) et réutilisable, qui est employé pour effectuer une action unique correspondante
à la fonction. La syntaxe correspondante est donnée dans l’exemple suivant qui effectue simplement
la somme de deux variables a et b et qui affecte le résultat dans une variable c retournée à l’aide
du mot-clé return comme sortie de la fonction :

[7]: %reset
def somme_a_b(a,b):
#Cette fonction effectue la somme de 'a' et de 'b'
c = a + b
return c

[8]: somme_a_b(1.2,3)

[8]: 4.2

La fonction définie ci-dessus ne précise pas le type de variable renvoyé par la fonction. Pour en
faciliter l’annotation, on peut utiliser la syntaxe -> type pour indiquer (mais pas pour imposer) le
type de variable attendue en sortie, ce qui permet de mieux comprendre l’incompatibilité éventuelle
entre variables en permettant de vérifier le typeattendu via la commande help. Dans l’exemple

10
ci-dessous, nous essayons d’additionner une variable de type float and une variable de type str
(une chaîne de caractères) ce qui retourne une erreur que l’on peut interpréter pour corriger le code.

[9]: def somme_a_b(a, b)->float:


#Cette fonction effectue la somme de a et de b
c = a + b
return c
help(somme_a_b)
d = '3'
d + somme_a_b(1, 2)

Help on function somme_a_b in module __main__:

somme_a_b(a, b) -> float

---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[9], line 7
5 help(somme_a_b)
6 d = '3'
----> 7 d + somme_a_b(1, 2)

TypeError: can only concatenate str (not "int") to str

L’erreur ci-dessus indique clairement (en anglais : TypeError : can only concatenate str (not “int”)
to str ) que l’on ne peut pas concaténer une variable de type int (un entier) avec une variable de
type str(une chaîne de caractères).
Lors de la définition d’une fonction, il est possible de spécifier des valeurs par défaut pour certains
paramètres. Les paramètres ayant une valeur par défaut doivent être placés à la fin de la liste des
paramètres dans la définition de la fonction.

[31]: def somme(a,b = 1):


#Cette fonction effectue la somme de 'a' et de 'b' s'il y a deux paramètres␣
,→et incrémente 'a' de 1 s'il n'y a qu'un paramètre

c = a + b
return c

[32]: somme(5)

[32]: 6

Une définition de fonction associe un nom de fonction à un objet fonction dans l’espace de noms
actuel que l’on peut voir ci-dessous à travers la commande whos.

[33]: whos

Variable Type Data/Info

11
---------------------------------
somme function <function somme at 0x0000028BA7DDBB00>
somme_a_b function <function somme_a_b at 0x0000028BA4F163E0>
Exercice : Soit la fonction suivante :

f (x) = ax2 + bx

Créez une fonction qui reçoit en argument x et qui retourne f (x) si a = 3 et b = 2.4.

[ ]:

4.3 Modules
Un module est un fichier Python (.py) destiné à être importé dans des scripts, dans la console
ou d’autres modules. Il définit des classes, des fonctions et des variables destinées à être utilisées
une fois importé. On peut ainsi réutiliser des fonctions écrites pour un programme dans un autre
sans avoir à les copier. La commande import permet d’importer le module en entier ou des parties
de celui-ci. On peut ensuite accéder à celle-ci en utilisant nom_du_module.nom_de_l_objet. Dans
l’exemple ci-dessous, le module dummy_module.py contient les instructions suivantes :

[34]: #Contenu du fichier dummy_module.py


course_code = 'PROJ0001-1'

students_number = 300

def number_group(n):
print(n/3)

[35]: %reset
import dummy_module

[36]: whos

Variable Type Data/Info


----------------------------------
dummy_module module <module 'dummy_module' fr<...>1_2025\\dummy_module.py'>

[37]: print(dummy_module.course_code)
n = dummy_module.students_number
dummy_module.number_group(n)

PROJ0001-1
100.0
Notons que si nous exécutons le contenu du fichier dummy_module.py directement dans la console,
nous créerons une fonction number_group(), ainsi que deux variables : la chaîne de caractères
course_code et le nombre entier students_number. L’importation du même ne créera que le module
dummy_module dans l’espace de travail.

12
4.4 Paquets/packages
Un paquet est un certain type de module Python qui peut contenir des sous-modules ou des sous-
paquets. Techniquement, un paquet est un module qui possède un attribut __path__. Les paquets
sont un moyen de structurer les différents modules en utilisant une notation « pointée ». Par exemple,
le nom de module A.B désigne le sous-module B du paquet A. Vous pouvez vous représenter les
paquets comme des répertoires dans le système de fichiers et les modules comme des fichiers dans
ces répertoires. Les paquets sont un moyen de distribuer du code Python via PyPi ou Anaconda
par exemple.

4.5 Librairies
Une librairie peut contenir des dizaines, voire des centaines de modules individuels qui peuvent
fournir un large éventail de fonctionnalités. Matplotlib est une bibliothèque permettant de créer
des graphiques pour visualiser des données (https ://[Link]). La librairie standard de Python
(https ://[Link]/3/library/) contient des centaines de modules permettant d’effectuer des
tâches courantes, comme par exemple la fonction help() qui permet d’invoquer le système d’aide.

4.6 Classes
Une classe peut être vue comme étant un modèle contenant des attributs (ou variables) et des
méthodes (ou fonctions) permettant des créer des instances de cette classe. Les classes permettent
de définir de nouveaux types de variables propres à la personne qui programme. L’instanciation
d’une classe permet de créer un objet de cette classe. Les méthodes associées à une classe ont un
accès privilégié aux données de la classe et les attributs se comportent comme des variables globales
pour les méthodes de la classe. Une classe se définit par le mot-clé class. Nous pouvons par exemple
décider de créer une classe student où des attributs tels que l’âge ou le prénom seront définis et
une méthode permettant de calculer sa probabilité de réussir son année. Ensuite, nous utiliserons
cette classe pour créer différentes instances d’étudiant.e.s et examiner leurs chances de réussite.

[38]: class student:


def __init__(self, age, prenom, nom, ects_obtenu, bloc1, cycle):
[Link] = age
[Link] = prenom
[Link] = prenom + '.' + nom + '@[Link]'
[Link] = nom
self.ects_obtenu = ects_obtenu
self.bloc1 = bloc1
[Link] = cycle

def proba_reussite(self):
pr = ([Link]/self.ects_obtenu)
return pr

s932810 = student(20, 'John', 'Smith', 30, True, 'bachelier')


s493304 = student(22, 'Jane', 'Doe', 30, False, 'Master')

13
[39]: print([Link])
print([Link])

[Link]@[Link]
[Link]@[Link]

[40]: print(s932810.proba_reussite())

0.6666666666666666

[41]: print(s493304.proba_reussite())

0.7333333333333333
Le mot clé self désigne l’instance de la classe sur laquelle va s’appliquer la méthode et __init__
est le constructeur de la classe qui permet d’initialiser les attributs de la classe.
Exercice : Créez votre propre classe de Professeur avec ses attributes et ses méthodes et trouvez-en
une utilité.

[ ]:

5 Edition de scripts
Le répertoire courant est le répertoire où l’utilisateur travaille. Le contenu de ce répertoire est
affiché dans Spyder et des fonctionnalités pour la gestion de son contenu sont fournies. L’affichage
du contenu du répertoire courant peut également être obtenu dans la fenêtre de commande à l’aide
de la commande “ls”.

[43]: ls

14
Volume in drive C is Windows-SSD
Volume Serial Number is E688-648B

Directory of c:\Users\Benjamin\Desktop\Unif\Assistant\methodes_numeriques_et_pr
ojet\creation_tuto_Python\projet_bac1_2025

13/12/2024 10:33 <DIR> .


12/12/2024 11:41 <DIR> ..
12/12/2024 18:24 <DIR> __pycache__
13/12/2024 10:33 <DIR> autres
19/08/2023 10:58 458 [Link]
20/08/2023 13:14 56 [Link]
11/12/2024 17:23 130 dummy_module.py
11/12/2024 17:35 72 [Link]
12/12/2024 18:18 362 normalised_data.txt
20/08/2023 14:39 490 [Link]
17/08/2023 11:14 103 [Link]
17/08/2023 11:13 62 [Link]
21/08/2023 10:02 458 [Link]
13/12/2024 09:53 451.787 tuto_python_2025.ipynb
13/12/2024 10:16 81.523 tuto_python_2025.log
13/12/2024 10:16 169.168 tuto_python_2025.tex
12 File(s) 704.669 bytes
4 Dir(s) [Link] bytes free
Comme défini ci-dessus, un script est simplement un fichier où est enregistré un ensemble de com-
mandes qui seront exécutées dans la console exactement comme si on y entrait les commandes
directement. Les fichiers de script s’enregistrent dans le répertoire courant avec l’extension “.py” et
peuvent être lancé à partir de l’éditeur dans Spyder en cliquant sur run ou en exécutant la com-
mande %run suivi du nom du fichier du script. Tout ce qui suit le caractère # est considéré comme
un commentaire et ne sera donc pas exécuté. On peut faire intervenir dans un script des instructions
simples, des importations de modules et des appels à des fonctions pour autant que celles-ci soient
définies dans l’espace de travail.

[47]: %run [Link]

Hello 2021 bachelor students !


Welcome to PROJ0001

15
Un script est donc simplement un fichier où est enregistré un ensemble de commandes qui seront
exécutées dans la console exactement comme si on y entrait les commandes directement comme
illustré ci-dessous :

[48]: print("Hello 2021 bachelor students !") #Ceci est un commentaire


print("Welcome to PROJ0001")

Hello 2021 bachelor students !


Welcome to PROJ0001
Quand on exécute un script, tout le script s’exécute, et aucune fonction n’est appelée automatique,
à l’inverse d’autres langages comme le C où la fonction main() est la première fonction exécutée.
Ceci peut être problématique quand on importe un script plutôt que de le lancer directement. Afin
d’éviter cela, il suffit d’ajouter dans le corps du script if __name__=='__main__': afin de spécifier
que le code qui suit la condition ne sera exécuté que si le script est appelé directement et pas
importé. Nous l’illustrons en dessous avec les scripts [Link] et [Link].

[54]: %reset

[55]: #Script de [Link]


def ping():
print("pong")
ping()

pong

[56]: #Script de [Link]

def ping():

16
print("pong")

if __name__ == '__main__':
ping()

pong

[57]: import pingpong

[58]: import ping

[59]: whos

Variable Type Data/Info


------------------------------
ping module <module 'ping' from 'c:\\<...>ojet_bac1_2025\\[Link]'>
pingpong module <module 'pingpong' from '<...>_bac1_2025\\[Link]'>
Exercice : Créez un script Python dans lequel est définit une fonction greet(nom) qui imprime
Hello ‘nom’, et utilisez cette fonction pour faire apparaître Hello ‘notre nom’ dans la console.

[ ]:

5.1 Indentation
La plupart des langages informatiques ont une forme de structure début-fin, ou des accolades d’ou-
verture et de fermeture, ou quelque chose du genre pour délimiter clairement le morceau de code
qui se trouve dans une boucle, ou dans différentes parties d’une structure. En général, les program-
meurs aguerris indentent également leur code afin qu’il soit plus facile pour un lecteur de voir ce qui
se trouve à l’intérieur d’une boucle, en particulier s’il y a plusieurs boucles imbriquées. Mais dans
la plupart des langues, l’indentation n’est qu’une question de style et la structure début-fin de la
langue détermine comment elle est réellement interprétée par l’ordinateur.
En Python, l’indentation est tout ce qu’il y a de plus important. Il n’y a pas de début et de fin,
seulement de l’indentation. Tout ce qui est censé se trouver à un niveau d’une boucle doit être indenté
à ce niveau. Une fois que la boucle est terminée, l’indentation doit revenir au niveau précédent.
Le nombre d’espaces à indenter à chaque niveau est une question de style, mais vous devez être
cohérent dans un seul code. La norme est souvent de 4 espaces. Ceci permet de rendre le code
lisible. N’hésitez pas non plus à ajouter des commentaires afin d’augmenter la lisibilité de votre code
avec l’utilisation du caractère # ou des caractères """ """ permettant d’insérer des commentaires
sur plusieurs lignes. Il est également possible de commenter plusieurs lignes dans spyder avec le
raccourci clavier Ctrl + 1 ou Cmd + 1.

[60]: """
Created on Wed Jan 20 11:19:08 2021

Ce programme calcule le cosinus de i pour i allant de 0 à 3 avec un pas de 1


et affiche la dernière valeur obtenue. Il ne nécessite aucun paramètre d'entrée
et ne fournit aucune sortie

17
@author : proj0001
"""

# Import de librairies nécessaires à ce script


import numpy

# Corps principal du script


for i in [0, 1, 2, 3]:
x = [Link](i)

# Affichage de la valeur de x
print('x vaut', x)

x vaut -0.9899924966004454

6 Librairies, fonctions, variables locales et globales


Au démarrage de Python, un certain nombre de fonctions de base sont disponibles, par exemple
la fonction print() qui permet d’afficher des variables ou des chaînes de caractères, ainsi que la
syntaxe générale du langage. Cependant, la plupart des fonctions nécessaires à des fins spécifiques
comme simplement calculer le cosinus d’un angle se trouvent dans des librairies qui ne se chargent
pas par défaut afin de ne pas consommer trop de temps pour démarrer Python. Par exemple, si on
essaye le lancer la fonction cos() on fait face à un message d’erreur :

[61]: cos(0)

---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[61], line 1
----> 1 cos(0)

NameError: name 'cos' is not defined

La fonction cosinus est disponible dans la librairie NumPy. Les librairies sont importées dans l’espace
de travail avec la commande d’importation import. Chaque librairie contient de nombreuses fonc-
tions. Pour utiliser la fonction cos() de la librairie NumPy, il nous faut le spécifier. Pour ce faire, la
syntaxe est la suivante : [Link]().

[62]: import numpy


[Link](0)

[62]: 1.0

[63]: type(numpy)

18
[63]: module

[64]: type([Link])

[64]: [Link]

Nous pouvons également choisir d’importer uniquement la fonction cos() du module NumPy et de
la renommer, ici cosinus.

[65]: from numpy import cos as cosinus


cosinus(0)

[65]: 1.0

Pour définir une fonction, il suffit d’utiliser la syntaxe def. Les commandes ci-dessous entrées dans
la console définissent une fonction “PolarToCartesian” qui prend en paramètres d’entrée le rayon
“rho” et l’angle “theta” défini en degrés. Ces paramètres suivent le nom de la fonction et sont définis
au sein des parenthèses. Cette fonction produit en sortie les coordonnées cartésiennes “x” et “y”
correspondantes grâce à la commande return :

[66]: %reset

[67]: # Importation de librairies ou de fonctions externes


import numpy

# Définition de la fonction
def PolarToCartesian(rho,theta):
"""
Parameters
----------
rho : float
Rayon.
theta : float
Angle en dégrés.

Returns
-------
x, y : float
Coordonnées cartésiennces d'un point défini à
partir de ses coordonnées polaires.

"""

theta = theta * [Link]/180


x = rho * [Link](theta)
y = rho * [Link](theta)
return x,y

19
[68]: whos

Variable Type Data/Info


----------------------------------------
PolarToCartesian function <function PolarToCartesian at 0x0000028BA8A6F560>
numpy module <module 'numpy' from
'c:\<...>ges\\numpy\\__init__.py'>
Pour appeler une fonction dans la console une fois qu’elle y est définie, il faut taper son nom et lui
faire suivre des parenthèses en y entrant les arguments de la fonction (si celle-ci en nécessite) :

[69]: PolarToCartesian(1,0)

[69]: (1.0, 0.0)

On peut voir ci-dessus que la fonction PolarToCartesian() nécessite l’utilisation de la librairie NumPy
pour calculer les cosinus et les sinus de l’angle donné. Il est important de noter qu’une fonction est un
ensemble de commandes exécutées dans un sous-environnement qui n’existe que pendant l’exécution
de la fonction. Si nous essayons d’appeler la variable “x” en dehors de la fonction PolarToCartesian(),
la console nous retournera un message d’erreur. Un appel à who permet de vérifier que la fonction
existe mais pas les variables définies au sein de cette fonction. Les variables définies au sein d’une
fonction ont donc une portée locale.

[70]: x

---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[70], line 1
----> 1 x

NameError: name 'x' is not defined

[71]: who

PolarToCartesian numpy
Une variable peut avoir une portée globale si elle est déclarée en dehors d’une fonction.

[72]: global_x = 'variable globale'

def dummy_function():
print('Je suis une ' + global_x)

dummy_function()

Je suis une variable globale


Si l’on souhaite pouvoir modifier une variable globale au sein d’une fonction, il faut la déclarer
comme global

20
[73]: global_x = 'variable globale'

def dummy_function():
global global_x
global_x = 'Je suis une ' + global_x

dummy_function()
print(global_x)

Je suis une variable globale


Finalement, Python offre la possibilité de déclarer une variable comme étant non-locale avec le
mot-clé nonlocal. C’est utilisé lorsque des fonctions imbriquées sont implémentées dans un script.
Ainsi, la fonction imbriquée a accès aux variables des fonctions englobantes. Supposons que l’on
veuille calculer l’aire d’un disque et la circonférence d’un trou centré sur ce disque et dont le rayon
est deux fois plus petit que le rayon du disque.

[74]: import numpy

def cercle(rayon):
pi = [Link]
aire_disque = pi * (rayon) ** 2
def circonference():
nonlocal rayon
rayon = rayon/2
circonference = 2 * pi * rayon
return circonference
print(circonference())
return aire_disque
print(cercle(3))

9.42477796076938
28.274333882308138
La portée d’une variable en Python est donc la partie du code où elle est visible. Elle peut être
locale, non-locale, globale et “built-in”.
Sauf pour des fonctions très simples, vous ne voulez pas écrire les fonctions directement dans la
console. Normalement, vous devrez créer un fichier .py contenant votre fonction et importer le
module résultant dans votre session interactive ou dans votre script. Dans l’exemple suivant, nous
avons copié l’ensemble des commandes de la fonction PolarToCartesian ci-dessus dans un fichier
“[Link]”. Nous importons le module “chgtcoord” que nous renommons “coord” et nous utilisons
la fonction “PolarToCartesian” définie au sein du module.

[6]: %reset

[7]: import chgtcoord as coord

[8]: whos

21
Variable Type Data/Info
------------------------------
coord module <module 'chgtcoord' from <...>bac1_2025\\[Link]'>

[9]: [Link](1,0)

[9]: (1.0, 0.0)

6.1 Liste de librairies utiles


Nous listons ci-dessous une série de librairies et de fonctions utiles au déroulement du cours. N’hésitez
pas à lire l’aide correspondante aux différentes fonctions proposées et à les tester par vous-même.

6.1.1 matplotlib
Exemples de fonctions utiles : Dans le sous-module [Link]
plot() legend() xlabel() ylabel() show() xlim() grid()

[ ]: # Exemple

import [Link] as plt

[Link]()

6.1.2 numpy
Exemples de fonctions utiles : abs() sum() zeros() asarray() arange() min() max()
where() linspace() shape() loadtxt() floor() ceil() log() cos() sqrt()

[ ]: # Exemple

import numpy as np

[Link]()

6.1.3 scipy
Exemples de fonctions utiles : integrate.solve_ivp() [Link]()
[Link]()
Exercice : Soit l’équation quadratique :

ax2 + bx + c = 0

Créer une fonction qui reçoit en argument les coefficients a, b, c et qui fournit en sortie les deux
racines.

[ ]:

22
7 D’autres types d’objets : list, tuple et array
Nous utiliserons la librairie numpy pour effectuer des opérations mathématiques sur des tableaux
(appelés arrays). A côté de ces tableaux, Python possède d’autres types de données pouvant enre-
gistrer des séquences d’éléments : les listes et les tuples. Ces derniers ne sont cependant pas utilisés
pour effectuer des opérations mathématiques.

7.1 Liste et tuple


Une liste se définit par des [ ] tandis qu’un tuple se définit par des ( ). On peut modifier les
valeurs entrées dans une liste mais pas dans un tuple.

[1]: une_liste=[2, 4, 6, 8, 10]


print(une_liste)
type(une_liste)

[2, 4, 6, 8, 10]

[1]: list

[2]: un_tuple=(2, 4, 6, 8, 10)


print(un_tuple)
type(un_tuple)

(2, 4, 6, 8, 10)

[2]: tuple

Si nous nous essayons à effectuer une opération sur ces deux objets, nous voyons que ce qui pour-
rait être compris comme une opération mathématique crée en fait une nouvelle liste qui contient
une_liste deux fois tandis qu’il n’est pas possible de modifier un_tuple.

[3]: une_liste * 2

[3]: [2, 4, 6, 8, 10, 2, 4, 6, 8, 10]

[4]: un_tuple + 2

---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[4], line 1
----> 1 un_tuple + 2

TypeError: can only concatenate tuple (not "int") to tuple

Les listes et les tuples peuvent contenir des séquences de plusieurs types, et pas uniquement des
nombres. Dans l’exemple ci-dessous, nous créons une liste contenant une chaîne de caractères, des
nombres, ainsi qu’une fonction.

23
[5]: une_liste_variee = ['liste', 1, 20.45, print]
print(une_liste_variee)

['liste', 1, 20.45, <built-in function print>]

7.2 Tableau à 1 dimension


Pour effectuer des opérations mathématiques sur des objets contenant des séquences de valeurs,
nous utiliserons des tableaux. Pour ceci, nous aurons besoin des librairies NumPy et matplotlib

[12]: %matplotlib inline


import numpy as np
import [Link] as plt

Ensuite, nous pouvons utiliser différentes fonctions pour créer un tableau à 1 dimension allant par
exemple de 1 à 5 :

[13]: x = [Link]([1, 2, 3, 4, 5]) # Nous avons insérer manuellement les éléments␣


,→individuels

# du tableau en utilisant une liste


print('x:', x, type(x))

y = [Link](1,6,1) #Démarre de 1, s'arrête avant 6 avec un pas de 1


print('y:', y, type(y))

z = [Link](1,5,5) #Démarre de 1 jusque 5 avec 5 points espacés uniformément


print('z:', z, type(z))

x: [1 2 3 4 5] <class '[Link]'>
y: [1 2 3 4 5] <class '[Link]'>
z: [1. 2. 3. 4. 5.] <class '[Link]'>
En utilisant les fonctions len (built-in), shape (utile pour les tableaux à plus de 1 dimensions) et
ndim (méthodes de ndarray), nous pouvons calculer les formes, les dimensions des tableaux et leurs
longueurs :

[14]: print(len(x))

[15]: [Link]

[15]: 1

[16]: [Link]

[16]: (5,)

Pour accéder aux éléments des tableaux, nous utilisons leurs indices linéaires en commençant par
le 0. Le premier élément d’un tableau à 1 dimension a donc l’indice 0. Le dernier élément d’un

24
tableau à 1 dimension peut être accédé à l’aide de l’indice -1. Les indices sont spécifiés en utilisant
des crochets [indice]. Les valeurs des éléments peuvent ainsi être modifiées.

[17]: print('La valeur du premier élément de x est', x[0])

x[0]=10

print('Le premier élément de x vaut maintenant', x[0])

La valeur du premier élément de x est 1


Le premier élément de x vaut maintenant 10

[18]: x[-1]

[18]: 5

On peut également accéder à plusieurs éléments en utilisant : et en spécifiant le début, la fin et le


pas.

[19]: x[0:4:2] #x[début:avant_fin:pas]

[19]: array([10, 3])

[20]: x[:]

[20]: array([10, 2, 3, 4, 5])

Il est également possible de parcourir les tableaux à l’envers

[21]: x[len(x)::-1]

[21]: array([ 5, 4, 3, 2, 10])

On peut également rechercher certains éléments spécifiques d’un array avec la fonction where
comme illustré ci-dessous :

[22]: a = [Link]([-1, 0, 1.3, 4, -10, 0.4, 3, 9, 1])


ind_a_neg = [Link](a < 0)
print('les indices correspondants à des valeurs négatives sont:', ind_a_neg)
print('les valeurs négatives de a sont:', a[ind_a_neg])

les indices correspondants à des valeurs négatives sont: (array([0, 4],


dtype=int64),)
les valeurs négatives de a sont: [ -1. -10.]
Des vecteurs boolean (True/False) peuvent aussi être utiliser pour accéder directement aux valeurs
qui satisfaillent la condition. Pour de grand vecteurs, ils sont généralement plus rapide qu’un vecteur
d’indice.

[23]: ie = a < 0 # boolean array


print('les valeurs négatives de a sont:', a[ie])

25
les valeurs négatives de a sont: [ -1. -10.]
Les slices en Python permettent de découper des objets contenant des séquences de valeurs d’un
objet a (nparrary, list, tuple, chaîne de caractères) en ne sélectionnant qu’une partie de ceux-ci. La
syntaxe des slices est a[i:j] ou s[i:j:k], les indices i (début), j (fin) et k (incrément) peuvent
être omis :

[21]: a = 'abcdefghijklmnopqrstuvwxyz'
type(a)

[21]: str

[22]: a[0:2]

[22]: 'ab'

[23]: a[0:]

[23]: 'abcdefghijklmnopqrstuvwxyz'

[24]: a[0:26:2]

[24]: 'acegikmoqsuwy'

[25]: a[:12]

[25]: 'abcdefghijkl'

[26]: a[:]

[26]: 'abcdefghijklmnopqrstuvwxyz'

[27]: a[-1]

[27]: 'z'

[28]: a_tuple = (1, 2, 3, 'quatre')

[29]: a_tuple[2:4]

[29]: (3, 'quatre')

[30]: a_liste = [1, 3, 4, 4]


a_liste[0:3]

[30]: [1, 3, 4]

[31]: a_array = [Link](a_liste)


a_array[0:3]

26
[31]: array([1, 3, 4])

7.2.1 Opérations sur un tableau à 1 dimension


Lorsque l’on effectue des opérations sur des arrays NumPy, la vitesse d’exécution peut être gran-
dement améliorée en évitant l’utilisation de boucles pour parcourir les tableaux et en utilisant les
différentes fonctions de NumPy qui peuvent s’appliquer directement aux tableaux.

[32]: x = [Link](1,6,1)
y = [Link]([Link]) #initialisation de y de même taille que x
for i in range(len(x)):
y[i] = [Link](x[i])
print(y)

[ 0.84147098 0.90929743 0.14112001 -0.7568025 -0.95892427]


Ceci peut être simplement écrit :

[33]: y = [Link](x)
print(y)

[ 0.84147098 0.90929743 0.14112001 -0.7568025 -0.95892427]


Les opérations dites vectorielles peuvent s’appliquer aux tableaux à 1 dimension de type array en
utilisant les fonctions appropriées de NumPy tandis que les opérations de base s’appliquent élément
par élément. Par exemple la multiplication de x par y à l’aide de l’opérateur * donne :

[34]: x = [Link](1,6,1)
y = [Link](0,5,1)
print('x:', x)
print('y:', y)
x * y

x: [1 2 3 4 5]
y: [0 1 2 3 4]

[34]: array([ 0, 2, 6, 12, 20])

Pour effectuer le produit scalaire des vecteurs x et y, on peut utiliser la fonction dot de NumPy

[35]: [Link](x,y)

[35]: 40

Exercice : Créer un tableau à une dimension (vecteur ligne) x de 5 nombres successifs entre 2 et
3 et séparés par des intervalles égaux.

[ ]:

Exercice : Ajouter 1 au deuxième élément de x.

[ ]:

27
Exercice : Créer un deuxième tableau ligne y de la même dimension que x mais dont les éléments
sont les nombres pairs successifs en commençant à 4.

[ ]:

7.3 Tableaux à 2 dimensions


Les tableaux peuvent être de dimensions arbitraires, mais nous utiliserons dans ce cours fréquemment
les tableaux à 2 dimensions pour lesquels des opérations matricielles peuvent être définies. Pour créer
ces tableaux, nous pouvons réutiliser la fonction array de NumPy

[36]: A = [Link]([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15]])
print(A)
print('Le nombre de dimensions de A est : ', [Link](A))

[[ 1 2 3 4 5]
[ 6 7 8 9 10]
[11 12 13 14 15]]
Le nombre de dimensions de A est : 2

[37]: print('La taille de A est: ',[Link])

La taille de A est: (3, 5)


Les fonctions flatten et reshape de NumPy permettent de modifier les dimensions des tableaux.
flatten permet de transformer un tableau à plusieurs dimensions en un tableau en une dimension
tandis que reshape permet de préciser les dimensions du tableau que l’on souhaite obtenir. flatten
ne demande pas de paramètres d’entrées, tandis que reshape demande que les dimensions des deux
tableaux soient compatibles.

[38]: B = [Link]()
print([Link]())
print('Le nombre de dimensions de [Link]() est : ', [Link](B))

[ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]
Le nombre de dimensions de [Link]() est : 1

[39]: [Link](3,5)

[39]: array([[ 1, 2, 3, 4, 5],


[ 6, 7, 8, 9, 10],
[11, 12, 13, 14, 15]])

[40]: [Link](3,6)

---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[40], line 1
----> 1 [Link](3,6)

28
ValueError: cannot reshape array of size 15 into shape (3,6)

L’indice d’un tableau à 2 dimensions est spécifié par deux valeurs, la première correspond aux
lignes, la seconde aux colonnes du tableau et sont données à l’aide d’un tuple (donc défini entre
parenthèses). Dans l’exemple ci-dessous, nous créons un tableau à 2 dimensions rempli de 0 et nous
le modifions en changeant 1 élément, puis une partie de ligne et enfin le dernier élément.

[ ]: B = [Link]((3,5))
print('Initialisation de B:')
print(B)
print('Modification de B:')
B[0,0] = 5
B[1,2:] = 10
B[-1,-1] = 500
print(B)

Initialisation de B:
[[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]]
Modification de B:
[[ 5. 0. 0. 0. 0.]
[ 0. 0. 10. 10. 10.]
[ 0. 0. 0. 0. 500.]]
Comme précédemment, les opérations de base s’effectuent élément par élément :

[ ]: print(A * B)

[[5.0e+00 0.0e+00 0.0e+00 0.0e+00 0.0e+00]


[0.0e+00 0.0e+00 8.0e+01 9.0e+01 1.0e+02]
[0.0e+00 0.0e+00 0.0e+00 0.0e+00 7.5e+03]]
L’objet array de NumPy, ici A, possède certaines méthodes définies automatiquement comme la
transposée de A qui se note A.T. Les opérations matricielles peuvent être effectuées en utilisant les
fonction de NumPy :

[ ]: print([Link](A.T,B))

[[5.00e+00 0.00e+00 6.00e+01 6.00e+01 5.56e+03]


[1.00e+01 0.00e+00 7.00e+01 7.00e+01 6.07e+03]
[1.50e+01 0.00e+00 8.00e+01 8.00e+01 6.58e+03]
[2.00e+01 0.00e+00 9.00e+01 9.00e+01 7.09e+03]
[2.50e+01 0.00e+00 1.00e+02 1.00e+02 7.60e+03]]
Exercice : Créer un tableau de type ndarray à 2 dimensions A dont la première ligne est égale
à x, la deuxième ligne est remplie de 1 et la troisième ligne est égale à y. x et y sont définis dans
l’exercice précédent.

29
[ ]:

Exercice : Soit deux matrices :

   
√4 −5 2 3+i
A= , B=
3 π/4 −72/3 0.2

où i est le nombre imaginaire. Calculer les éléments suivants :

A + B, AB, A2 , AT , B −1 , B T AT , A2 + B 2 − AB

[ ]:

8 Les sorties de fonction et les différents types de tableaux possibles


Une des difficultés associées au typage dynamique et à la multitude d’objets possibles dans Py-
thon pour représenter des tableaux réside dans l’incompatibilité potentielle entre les objets de type
list, tuple et ndarray, que l’on interprète globalement comme des tableaux mais qui ne sont pas
nécessairement compatibles, ce qui peut être une source fréquente de bug.

[24]: import numpy as np


A = [1, 2, 3, 4]
B = (1, 2, 3, 4)
C = [Link](A)

print('A is',type(A), 'of length', len(A), A)


print('B is ',type(B),'of length', len(B), B)
print('C is ',type(C),'of length', len(C), C)

A is <class 'list'> of length 4 [1, 2, 3, 4]


B is <class 'tuple'> of length 4 (1, 2, 3, 4)
C is <class '[Link]'> of length 4 [1 2 3 4]

[25]: A[0]+B[0]+C[0]

[25]: 3

[26]: A+B+C

---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[26], line 1
----> 1 A+B+C

TypeError: can only concatenate list (not "tuple") to list

30
La fonction asarray de la librairie numpy nous permet de transformer les objets de type list et
tuple en ndarray et ainsi de pouvoir réaliser des opérations avec les tableaux de même type.

[27]: A_asarray = [Link](A)


print(A_asarray)

[1 2 3 4]

[28]: B_asarray = [Link](B)


print(B_asarray)

[1 2 3 4]

[29]: A_asarray + B_asarray + C

[29]: array([ 3, 6, 9, 12])

Il sera d’autant plus difficile de suivre ceci si l’on intègre l’utilisation de fonctions fournissant des
tableaux en sortie. De manière générale, il faudra veiller à bien noter le type de sortie attendue si
l’on souhaite pouvoir éviter des erreurs d’incompatibilité entre variables, en particulier lorsque l’on
utilise des fonctions des librairies existantes. Noter ci-dessous les différentes possibilités de syntaxe
après return induisant un type de variable différent, source fréquente de bug :

[30]: def test_return_1(a, b):


return a + b, a - b

def test_return_2(a, b):


return [a + b, a - b]

[31]: b1 = test_return_1(1, 2)
b2 = test_return_2(1, 2)

print(type(b1), type(b2))

<class 'tuple'> <class 'list'>

[32]: a = [1, 2]
a + b1

---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[32], line 2
1 a = [1, 2]
----> 2 a + b1

TypeError: can only concatenate list (not "tuple") to list

31
9 Résolution de systèmes d’équations linéaires
Pour résoudre un système linéaire Ax = b, par exemple :

    
5 6 10 x1 4
 −3 0 14   x2  =  10  ,
0 −7 21 x3 0

nous pouvons utiliser la méthode solve, qui fait partie de la sous-librairie linalg de NumPy. La
méthode de résolution prend en entrée un tableau bidimensionnel (la matrice A) et un tableau
unidimensionnel (le côté droit) et renvoie la solution.

[44]: A = [Link]([[5, 6, 10],[-3, 0, 14], [0, -7, 21]])


b = [Link]([4, 10, 0])
solution = [Link](A, b)
print(solution)

[-1.45454545 1.20779221 0.4025974 ]


On peut simplement vérifier que la solution fournie est la bonne en multipliant la matrice A par la
solution

[45]: [Link](A,solution)

[45]: array([ 4., 10., 0.])

Exercice : Résoudre le système d’équations linéaires suivant :

5.4x + 2y = 0
−x + 4y − 25z = 3
3x + 7z = 2

[ ]:

10 Structures de contrôle : for, if/elif/else, while, break, continue


Par défaut, python intègre des structures de contrôle. Elles permettent notamment d’effectuer des
boucles et de vérifier si certaines conditions sont remplies avant d’exécuter certaines lignes de codes.
Pour cette partie du tutoriel, nous aurons ici besoin de numpy et de matplotlib nous commençons
donc par les importer.

10.1 La boucle for


La syntaxe est la suivante et permet d’exécuter un bloc de commandes de manière répétée :

[46]: for i in [0, 1, 2, 3, 4]: # La ligne se termine par :


print('La valeur de i est :', i) # Le bloc de commandes est indenté
print('Nous sommes sortis de la boucle')

32
La valeur de i est : 0
La valeur de i est : 1
La valeur de i est : 2
La valeur de i est : 3
La valeur de i est : 4
Nous sommes sortis de la boucle
Il faut remarquer ici qu’à la fin du for il est nécessaire d’introduire : et d’indenter le bloc de
commandes à exécuter au sein de la boucle. La fin de l’indentation met fin à la boucle.
Nous pouvons utiliser les boucles for pour affecter des valeurs à des éléments d’un tableau

[47]: x = [Link](0, 2*[Link], 200)


y = np.zeros_like(x)
for i in range(len(x)):
y[i] = [Link](x[i])
[Link](x,y);

Notons que nous aurions dû tirer parti de la vectorisation offerte par NumPy et éviter d’écrire une
boucle for :

[48]: [Link](x,[Link](x));

33
10.2 if/elif/else
La condition if permet d’exécuter un bloc de commandes pour autant que le résultat de l’évaluation
de if soit True.

[49]: a = 2
if a == 2:
print('a est bien égale à', a)

a est bien égale à 2


La condition if peut être suivie d’un else qui sera évaluée si l’évaluation du if est False.

[50]: a = 3
if a == 2:
print('a est bien égale à', a)
else:
print('a est différent de 2')

a est différent de 2
Finalement, nous pouvons utiliser la commande elif pour rajouter des conditions avant l’utilisation
du else

[51]: a = 3
if a == 2:
print('a est bien égale à', a)
elif a==3:
print('a est bien égale à', a)
else:
print('a est différent de 2 et de 3')

a est bien égale à 3

34
10.3 La boucle while/break/continue
La boucle while permet d’exécuter un bloc de commandes jusqu’à ce qu’une condition soit rencon-
trée ou lorsqu’une commande break est rencontrée. La syntaxe est la suivante :

[52]: a = 0
while a < 6:
a += 1
print(a)

1
2
3
4
5
6
Il est important d’être vigilant à ne pas créer de boucle infinie et d’utiliser la commande break
après un certain nombre de passage dans la boucle.

[53]: a = 0
while a < 60000:
a += 1
print(a)
if a > 15:
print('Sortie anticipée de boucle')
break
print('Nous sommes sortis de la boucle')

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Sortie anticipée de boucle
Nous sommes sortis de la boucle
L’instruction continue permet de passer directement à l’itération suivante d’une boucle en sautant
le reste du code prévu pour l’itération en cours.

35
[54]: a = 0
while a < 5:
a += 1
if a == 3:
continue
print(a)

1
2
4
5
Exercice : La fonction exponentielle admet le développement en série :

X xi
exp(x) =
i!
i=0

Ecrire une fonction Python qui prend en entrée la variable n et qui calcule cette série limitée aux
n+1 premiers termes.

[ ]:

11 Les polynômes
Les polynômes peuvent être conçus et manipulés à travers la classe [Link] qui contient
différentes possibilités (puissance, Chebyshev, Legendre. . .). Par exemple le polynôme :

x4 − 12x3 + 5x

peut être représenté par ses coefficients repris dans la liste coef ci-dessous.

[14]: coef = [0, 5, 0, -12, 1]

[15]: from [Link] import Polynomial as poly


p = poly(coef)
p
[15]:
x 7→ 0.0 + 5.0 x+0.0 x2 − 12.0 x3 + 1.0 x4

[57]: type(p)

[57]: [Link]

[58]: print(p)

0.0 + 5.0 x + 0.0 x**2 - 12.0 x**3 + 1.0 x**4


Nous pouvons ensuite effectuer un nombre important d’opérations comme calculer la dérivée du
polynôme, l’évaluer en un point, par exemple en x = 5, ou encore déterminer ses racines :

36
[59]: [Link](1)
[59]:
x 7→ 5.0+0.0 x − 36.0 x2 + 4.0 x3

[60]: p(5)

[60]: -850.0

[61]: [Link]()

[61]: array([-0.62921183, 0. , 0.66413705, 11.96507478])

Si un ensemble de points nous est donné mais que nous ne connaissons pas le polynôme associé,
nous pouvons ajuster au sens des moindres carrés un polynôme d’un certain degré à ces points en
utiliser la fonction polyfit.

[62]: from [Link] import polyfit


coef2 = polyfit([0, 1, 4, 5], [-1, 2, 1, 4], 3)

[63]: p2 = poly(coef2)
print(p2)

-1.0 + 5.16666667 x - 2.5 x**2 + 0.33333333 x**3

12 Graphiques
12.1 Les bases
Pour effectuer des graphiques dans Python, nous utiliserons la librairie matplotlib et la sous-
librairie pyplot. La commande %matplotlib inline est ici utilisée pour ne pas faire apparaître les
graphiques sur une page à part. L’ensemble des graphiques disponibles est décrit ici : https ://mat-
[Link]/[Link]

[16]: %matplotlib inline


import [Link] as plt

Nous pouvons maintenant faire appel aux fonctions graphiques en utilisant la commande
[Link], par exemple la fonction plot(x, y, chaîne de caractères) où la chaîne de ca-
ractères définit le type de marqueur ou de trait utilisé.

[19]: [Link](1, 0, 'or'); # or signifie qu'on veut un gros point "o", rouge (red) "r"

37
Nous pouvons ainsi visualiser le polynôme généré ci-dessus à l’aide des tableaux x et y.

[21]: x = [Link](-1, 12, 200)


y = np.zeros_like(x)
[Link](x,p(x),'g--');

La fonction plot peut prendre un grand nombre d’arguments optionnels à travers des mots-clés.
La syntaxe est fonction(mot-clé1=valeur1, mot-clé2=valeur2). Par exemple, pour tracer le
polynôme en tirets bleu et avec une épaisseur de trait de 4 on écrit :

[22]: [Link](x,p(x),'b--',linewidth = 4);

38
12.2 Afficher plusieurs courbes dans un graphique, créer une nouvelle figure
Pour créer une nouvelle figure, il faut utiliser la fonction figure de [Link]. On peut
alors spécifier la taille de la figure. Les commandes suivantes utilisant la fonction plot utilisera cette
figure, afin par exemple de superposer des courbes. On peut y ajouter une légende, un titre ainsi
que labéliser les axes. Il est possible d’augmenter la taille des polices des légendes, des axes, du titre
et des graduations en ajoutant le paramètre fontsize.

[28]: [Link](figsize=(15, 10)) # Crée une nouvelle figure


[Link](x,p(x),'r');
[Link](x,np.zeros_like(x),'b');
[Link]([Link](),np.zeros_like([Link]()),'og')
[Link](['polynome','droite', 'racines'],loc='best', fontsize = 16) #Ajout␣
,→d'une légende

[Link]('Polynôme de degré 4', fontsize = 18) #Ajout d'un titre


[Link]('Axe des Y', fontsize = 16) # Labélisation de l'axe des ordonnées
[Link]('Axe des X', fontsize = 16) # Labélisation de l'axe des abscisses
[Link](fontsize=14) # Taille des graduations de l'axe X
[Link](fontsize=14) # Taille des graduations de l'axe Y

[Link]() # Crée une nouvelle figure


[Link](x,p(x),'r');

39
Exercice : Tracer le graphique de la fonction

y(x) = e−0.8x sinωx

pour ω = 10 rad/s et x ∈ [0 10] s.

[ ]:

40
Exercice : Soit la fonction
y(x) = 10 + 5e−x cos(ωx + 0.5)
Ecrire un script qui trace le graphique pour ω = 1, 3, 10 rad/s et x ∈ [0 5] s. Les trois courbes
doivent apparaître en vert, avec une ligne continue pour ω = 1 rad/s, une ligne en traits discontinus
pour ω = 3 rad/s et une ligne en pointillés pour ω = 10 rad/s.

[ ]:

13 Interpolation par splines


Python offre la possibilité de réaliser des interpolations par splines à travers la librairie SciPy et la
sous-librairie interpolate. Nous utiliserons par exemple la fonction CubicSpline.

[74]: import numpy as np


import matplotlib
from [Link] import CubicSpline
%matplotlib inline
import [Link] as plt

Considérons tout d’abord un ensemble de points x et y entre lesquels nous souhaitons interpoler.

[75]: x = [Link](0,100,10)
y = [Link](10)
[Link](x,y,'o');

[76]: x_cs = [Link](0,100,500)


cs = CubicSpline(x,y,bc_type='clamped') #le paramètre bc_type permet d'imposer␣
,→certaines conditions aux limites

[Link](x_cs,cs(x_cs),label='Spline')
[Link](x,y,'ro', label='Data')
[Link](loc='best')

41
[76]: <[Link] at 0x29b0bf39b90>

14 Entrées et sorties
Plutôt que de créer des points aléatoirement comme dans l’exemple de la spline cubique, nous
pourrions avoir besoin d’en importer de l’extérieur, par exemple ces points pourraient être contenu
dans une fichier txt [Link].

[ ]: 0. -1.
1. 2.
3. 0.1
4. -0.1
5. -2.
6. -8.
7. -9.

La fonction loadtxt de NumPy nous permet d’ouvrir ce fichier, de lire son contenu et de le mettre
dans une nouvelle variable.

[77]: import numpy as np


a = [Link]('[Link]')
print(a)
type(a)

[[ 0. -1. ]
[ 1. 2. ]
[ 3. 0.1]
[ 4. -0.1]
[ 5. -2. ]
[ 6. -8. ]
[ 7. -9. ]]

42
[77]: [Link]

Nous pouvons maintenant effectuer des opérations mathématiques sur le tableau créé (ici nous
normalisons la seconde colonne) et ensuite le sauver sous format .txt à l’aide de la fonction savetxt
de NumPy.

[78]: a[:,1]=a[:,1]/[Link](a[:,1])
[Link]('normalised_data.txt',a)
print(a)

[[ 0. -0.5 ]
[ 1. 1. ]
[ 3. 0.05]
[ 4. -0.05]
[ 5. -1. ]
[ 6. -4. ]
[ 7. -4.5 ]]
D’autres possibilités existent à travers des fonctions telles que les fonctions de base open utilisée
pour lire, écrire et modifier un fichier ou input() qui permet une saisie au clavier. De nombreux
modules existent également pour lire différents types de fichier comme xlrd utilisé pour lire les
fichiers du logiciel Microsoft Excel (.xlx, .xls).

[82]: prenom = input('Quel est votre prénom ? : ')

[83]: print(prenom)

Albert

[84]: with open('[Link]') as f_data:


print(f_data.read())

0. -1.
1. 2.
3. 0.1
4. -0.1
5. -2.
6. -8.
7. -9.

Exercice : Tracer le graphique de l’interpolation par spline cubique et de l’interpolation linéaire


des points de données du fichier ‘normalised_data.txt’ ci-dessus.

[ ]:

15 Résolution d’équations différentielles


Considérons l’équation différentielle de l’oscillateur de Van der Pol :

43
dx1
= x2 (1)
dt
dx2
= ϵω(1 − x21 )x2 − ω 2 x1 (2)
dt

Avec les constantes ϵ et ω égales à 0.1 et 1 respectivement.


Dans Python, cette équation différentielle peut être représentée par une fonction définie comme
suit :

[1]: # fichier [Link]

import numpy as np

def odefunction(t, y):


"""Système d'équations différentielles ordinaires.

Parameters
----------
t : array_like
Le temps.
y : array_like
Les variables du système.

Returns
-------
dy: array_like
La fonction retourne dy, un array contenant les dérivées.
"""

#Partie principale

#Definitions locale de constantes


epsilon = 0.1
omega = 1

dy = [Link](2)
dy[0] = y[1]
dy[1] = epsilon * omega * (1-y[0]**2)*y[1] - (omega**2)*y[0]

return dy

Ces lignes de codes sont enregistrées dans un fichier portant le nom [Link]. La résolution
numérique nécessite la librairie SciPy et la fonction solve_ivp de la sous-libraire [Link].
Ici la sortie d’odefunction fournit une solution de type list mais nous pourrions également sortir
un type [Link].

44
[1]: from [Link] import solve_ivp as ode45 # Defining the solver (ode45)
from matplotlib import pyplot
import OdeFun

[2]: whos

Variable Type Data/Info


--------------------------------
OdeFun module <module 'OdeFun' from 'c:<...>_tuto_python\\[Link]'>
ode45 function <function solve_ivp at 0x000002CA24F09620>
pyplot module <module '[Link]<...>\\matplotlib\\[Link]'>
La fonction [Link].sole_ivp et ici renommée ode45 utilise par défaut une méthode de
Runge-Kutta explicite pour la résolution de l’équation et les paramètres d’intégration peuvent être
ajustés avec des options. Le code suivant résout l’équation différentielle entre 0 et 100 (tspan) avec
comme conditions initiales 0 et 1 (y0) et trace le résultat à l’écran pour la première variable :

[3]: tspan = [0, 100]


y0 = [0, 1]

solution = ode45([Link], tspan, y0)

La fonction [Link].sole_ivp (renomée ode45), fournit en sortie un objet de type


[Link]._ivp.[Link] dans la variable appelée solution qui contient plusieurs
champs dont le champ t et le champ y qui contiennent respectivement des tableaux de type ndarray
avec la variable indépendante (le temps ici) et les solutions du système d’équations différentielles
ordinaires dont la dimension dépend du nombre d’inconnues. Pour y accèder, il suffit d’utiliser la
syntaxe solution.t et solution.y :

[4]: print('La variable solution contient les champs suivants : \n', solution)
print('Le tableau comprenant les temps est de taille :', [Link])
print('Le tableau comprenant les solutions est de taille :',[Link])
print('Les types des champs t et y de la solution sont :', type(solution.t),␣
,→type(solution.y))

La variable solution contient les champs suivants :


message: The solver successfully reached the end of the integration interval.
success: True
status: 0
t: [ 0.000e+00 9.990e-04 ... 9.905e+01 1.000e+02]
y: [[ 0.000e+00 9.991e-04 ... -1.986e+00 -9.774e-01]
[ 1.000e+00 1.000e+00 ... 2.887e-01 1.679e+00]]
sol: None
t_events: None
y_events: None
nfev: 842
njev: 0
nlu: 0
Le tableau comprenant les temps est de taille : (110,)

45
Le tableau comprenant les solutions est de taille : (2, 110)
Les types des champs t et y de la solution sont : <class '[Link]'> <class
'[Link]'>
La première dimension de solution.y correspond au nombre d’inconnues (ici deux), tandis que
la seconde dimension correspond au temps. Cette dernière est donc cohérente avec la longueur du
tableau solution.t, ce qui permet de tracer les graphiques des deux solutions en fonction du temps
ou d’aller rechercher une valeur pour une position donnée.

[5]: [Link](solution.t, solution.y[0,:], label='x1')


[Link](solution.t, solution.y[1,:], label='x2')
[Link]('Résolution de l\'oscillateur de Van der Pol ') #Ajout d'un titre
[Link]('x_1 et x_2') # Labélisation de l'axe des ordonnées
[Link]('Temps') # Labélisation de l'axe des abscisses
[Link]()

print('La valeur x1 au temps t =', solution.t[5], 'est de', solution.y[0,5])

La valeur x1 au temps t = 1.675339048653088 est de 1.0561398057071318

Le solveur [Link].sole_ivp offre un nombre important d’options. Ces dernières per-


mettent par exemple de définir les valeurs de tolérance relative et absolue.

[6]: solution = ode45([Link], [0,100], [0, 1], rtol=1e-8)


[Link](solution.t,solution.y[0,:]);
[Link]('Résolution de l\'oscillateur de Van der Pol '); #Ajout d'un titre
[Link]('x_1'); # Labélisation de l'axe des ordonnées
[Link]('Temps'); # Labélisation de l'axe des abscisses

46
15.1 Ajouter des paramètres aux équations différentielles
Le premier paramètre du solveur [Link].solve_ivp est une fonction qui doit accepter
exactement deux arguments : t et y. Dans l’exemple ci-dessus, les paramètres de l’équation diffé-
rentielle ont été définis localement dans la fonction odefunction. Modifions cet exemple afin que
odefunction prenne en charge un vecteur de paramètres supplémentaire nommé const :

[ ]: # fichier [Link]

import numpy as np

def odefunction(t, y, const):


"""Système d'équations différentielles ordinaires.

Parameters
----------
t : array_like
Le temps.
y : array_like
Les variables du système.

Returns
-------
dy: array_like
La fonction retourne dy, un array contenant les dérivées.
"""

#Partie principale
#Definitions de constantes

47
epsilon = const[0]
omega = const[1]

dy = [Link](2)
dy[0] = y[1]
dy[1] = epsilon * omega * (1-y[0]**2)*y[1] - (omega**2)*y[0]

return dy

Afin d’utiliser cette fonction avec solve_ivp, nous pouvons utiliser une fonction lambda. Une fonc-
tion lambda est une fonction anonyme, c’est-à-dire une fonction sans nom, dont la syntaxe est la
suivante : lambda arguments: expression.

[7]: import OdeFun2

const = [0.1, 1]
tspan = [0, 100]
y0 = [0, 1]

solution = ode45(lambda t, y: [Link](t, y, const), tspan, y0)

Dans l’exemple ci-dessus, la fonction lambda prend deux arguments t et y, qui sont ceux requis par
solve_ivp, et appelle [Link] avec les arguments (t, y, const).

15.2 Valeurs particulières de l’EDO


Il est souvent utile de déterminer quand la solution du système d’équations différentielles atteint une
valeur particulière (comme 0 par exemple). Ceci peut se faire grâce à la définition d’options. Ceci
demande de créer une fonction définissant le type d’événement à déterminer puis nous recalculons
la solution. Les événements sont enregistrés dans solution.t_events et solution.y_events.
Pour plus d’informations, n’hésitez pas à consulter l’aide de la fonction [Link].sole_ivp.

[6]: def event(t,y):


return y[0]

[7]: solution = ode45(lambda t, y: [Link](t,y,const),[0,100],[0, 1],␣


,→events=event)

[Link](solution.t,solution.y[0,:]);
[Link](solution.t_events[0],solution.y_events[0][0:,0],'rx');
[Link]('Résolution de l\'oscillateur de Van der Pol '); #Ajout d'un titre
[Link]('x_1'); # Labélisation de l'axe des ordonnées
[Link]('Temps'); # Labélisation de l'axe des abscisses

48
Exercice : Pour l’oscillateur de Van der Pol ci-dessus, trouver tous les points pour lesquels la
valeur de x1 vaut 1 et tracer en un graphique les illustrant.

[ ]:

Exercice : Résolvez l’équation différentielle suivante :


dy1
= cos(y2 ) · y3
dt
dy2 y1
=−
dt y3
dy3
= −0.8 y1 y2
dt
avec les conditions initiales y1 (0) = 0, y2 (0) = 1 et y3 (0) = 1 pour un temps allant de 0 à 100 et
tracer l’évolution des trois variables dans une même graphique. Trouvez les zéros de la variable y2
s’il y en a.

[ ]:

16 Le codage en dur (“hardcode”)


Le codage en dur consiste à coder directement dans le programme des données susceptibles de
pouvoir varier. Ceci est à éviter car il ne permet pas un usage flexible du code et nécessite de
modifier ces données dans beaucoup de lignes différentes. Par exemple, pour l’oscillateur de Van der
Pol ci-dessous, nous avons remplacé les constantes par des valeurs données : ici nous avons remplacé
ϵ par 0.1 et ω par 2. Nous pouvons constater dans les lignes de code ci-dessous, que le codage en
dur induit plusieurs difficultés :

— Pour modifier ϵ et ω, il faut pouvoir les identifer, et donc ici connaître les équations, en
espérant qu’il n’y ait pas eu de permutations.
— Pour les modifier, il faut répéter plusieurs fois la même opération, ce qui est une perte de
temps.

49
[7]: import numpy as np

def odefunction_hardcoded(t,y):
"""Système d'équations différentielles ordinaires.

Parameters
----------
t : array_like
Le temps.
y : array_like
Les variables du système.

Returns
-------
dy: array_like
La fonction retourne dy, un array contenant les dérivées.
"""

#Partie principale
#Definitions de constantes

dy = [Link](len(y))
dy[0] = y[1]
dy[1] = 0.1 * 2 * (1-y[0]**2)*y[1] - (2**2)*y[0]

return dy

De même lors de la résolution du système d’équations différentielles ci-dessous, on a remplacé les


variables tspan et y0, ce qui conduit en un code qui fonctionne, mais qui demande de connaître
la position et les variables de mémoire contrairement à la seconde écriture qui permet d’identifier
très rapidement les variables et surtour de les réutiliser. La troisième version permet d’identifier
directement les variables et par exemple de les placer dans un fichier séparé ou de résoudre le
système d’équations plusieurs fois de suite avec des conditions initiales différentes par exemple.

[ ]: #1
solution = ode45(lambda t, y: [Link](t, y, [0.1, 1]), [0,100], [0,␣
,→1])

#2
c = [0.1, 1]
tspan = [0,100]
y0 = [0, 1]

solution = ode45(lambda t, y: [Link](t, y, c), tspan, y0)

#3

50
epsilon = 0.1
omega = 1
t0 = 0
tf = 100
x1_0 = 0
x2_0 = 1

solution = ode45(lambda t, y: [Link](t, y, [epsilon, omega]),␣


,→[t0,tf], [x1_0, x2_0])

Exercice : La méthode d’Euler permet de résoudre des équations différentielles ordinaires, càd
trouver la fonction y(t) en connaissant sa dérivée y ′ (t) = f (y(t), t) et des conditions intiales y(t0 ) =
y0 à travers
yi+1 = yi + h · f (yi , ti )
où h := ti+1 − ti .
La méthode d’Euler demande de définir des paramètres génériques à la méthode, comme le pas
d’intégration h, ce qui avec le temps d’intégration d’un temps initial t0 à un temps final tf définit
la taille du tableau qui va accueillir les solutions de l’équation différentielle. Un code est proposé
ci-dessous, pourriez-vous repérer ce qui est codé en dur et l’améliorer ?

[8]: %reset
# Définition des constantes
c = [0.1, 1]

import numpy as np
import [Link] as plt
import OdeFun

t = [Link](0, 100, 1001)


y = [Link]((2, 1001))
y[:, 0] = [0, 1]

fun = lambda t, y: [Link](t, y, c)

for i in range(1, 1001):


y[:, i] = y[:, i-1] + 0.1 * fun(t[i-1], y[:, i-1]) # Méthode d'Euler

[Link](t, y[0, :], label="x1")


[Link]('x_1'); # Labélisation de l'axe des ordonnées
[Link]('Temps (sec)'); # Labélisation de l'axe des abscisses

51
17 Débogage
Spyder comprend un debbuger intégré à l’éditeur : https ://[Link]-
[Link]/5/en/panes/[Link]
Tout d’abord, lorsque l’on édite un fichier .py, l’éditeur détectera automatique des erreurs de syn-
taxte par exemple et affichera un cercle rouge avec une croix dedans pour signaler l’erreur. Ce type
d’erreur critique ne permettra pas au script de s’exécuter. L’éditeur peut également afficher une
icône avertissement pour indiquer par exemple la non-utilisation de la librairie NumPy. Il ne s’agit
pas d’une erreur critique et le programme pourra s’exécuter.

52
En plus de cette vérification en temps réel, Spyder propose un outil qui permet d’arrêter un pro-

53
gramme en cours d’exécution pour examiner la valeur des différentes variables et détecter d’éven-
tuelles erreurs. A cet effet, des points d’arrêt doivent être créés au préalable dans le(s) fichier(s)
.py. Pour créer un point d’arrêt (breakpoint), il suffit de cliquer à droite du numéro de la ligne
correspondante et un point rouge apparaît à gauche de la ligne de courante.
L’exécution du programme est alors réalisée via le bouton Debug file. Le programme s’arrête au
point d’arrêt indiqué par une flèche. Vous pouvez examiner le contenu des variables du Workspace,
avancer d’une ligne, continuer l’exécution jusqu’au prochain point arrêt ou arrêter le programme.
Lorsqu’une ligne fait appel à une fonction, il est possible de rentrer à l’intérieur de cette fonction
ou de sauter directement à la ligne suivante.

54
Des fonctionnalités de débogage sont également accessibles lorsqu’un programme produit une erreur.
Dans la console, le message d’erreur en rouge indique alors la ligne à laquelle l’erreur s’est produite.
On peut y accéder directement en cliquant sur le numéro de la ligne.

55
Exercice : Déboguer le code suivant :

[ ]: %reset
a == 2
b == 3

def somme(a,b)
c = a + b
return c

somme(12 14)

if a=2;
print(a est égale à deux)
else
print(a, "est différent de deux)"

18 Analyse des performances


Des outils de performance avancés existent pour analyser l’efficacité des programmes sur Python :
https ://[Link]/3/library/[Link]

56
Le module cProfile qui permet de regarder combien de temps le programme exécuté passe dans
chaque fonction et le nombre d’appels des fonctions :

— ncalls : le nombre d’appels à une fonction.


— tottime : temps total passé dans une fonction sans compter le temps passé dans les appels
aux sous-fonctions.
— percall : temps passé pour les appels.
— cumtime : temps cumulé passé dans la fonction et dans les sous-fonctions.
— percall : cumtime divisé par les appels.
— filename:lineno(function) : données des fonctions.

L’IDE Spyder nous offre une interface graphique lisible nous permettant de rapidement analyser
le temps pris nos scripts Python. Pour y accéder, il faut tout d’abord s’assurer d’avoir activé le
Profiler à travers le menu View > Panes > Profiler.

Considérons maintenant le script test_profile.py ci-dessous qui comprend deux boucles, une
fonction propre fun et qui utilisent des fonctions de la librairie NumPy pour réaliser une interpolation
d’une fonction définie en quelques points.

[ ]: import numpy as np
from [Link] import polyfit
from [Link] import Polynomial as poly

def fun(x):
return x**2+[Link](x)-1

x = [Link](100,100)

57
y = np.zeros_like(x)
IT1 = range([Link][0])
IT2 = range([Link][1])
slow = False
if slow == True:
for i in IT1:
for j in IT2:
coef = polyfit([0, 1, 4, 5],[-1, 2, 1, 4],3)
p=poly(coef)
y[i,j]=fun(x[i,j])/2 + p(x[i,j])
else:
coef = polyfit([0, 1, 4, 5],[-1, 2, 1, 4],3)
p=poly(coef)
for i in IT1:
for j in IT2:
y[i,j]=fun(x[i,j])/2 + p(x[i,j])

Nous allons la tester avec l’aide du Profiler et classer les résultats par temps cumulé afin de voir
quelle partie du code prend le plus de temps à tourner. Tout d’abord nous faisons tourner une
version “lente” du code avec la variable slow = True et nous obtenons le résultat suivant :

On peut voir qu’à l’exécution du script avec slow = True, nous calculons les coefficients d’un
polynôme à l’aide de polyfit à chaque fois dans les deux boucles alors que ces coefficients sont
indépendants des boucles. Le temps passé à appeler 10000 la fonction polyfit est de 1.11 secondes.
Afin d’améliorer l’efficacité de cette fonction, nous pouvons sortir le calcul des coefficients des boucles
et ne le calculer qu’une seule fois (slow = False). On peut alors vérifier que polyfit n’est appelée
qu’une seule fois et que le temps mis pour exécuter le script est beaucoup plus faible.

58
Il existe également des fonctions permettant de chronométrer l’exécution de Python dans Spyder
comme %time ou %timeit.
Exercice : Créez un script de votre choix pour comparer l’utilisation de la fonction sum() de NumPy
avec votre propre fonction qui devra utiliser une boucle for pour calculer la somme des éléments
d’un tableau à 1 dimension de type ndarray. Analysez la performance de votre fonction par rapport
à la fonction de NumPy.

[ ]:

19 Fin du tutoriel
Nous voici au bout de ce tutoriel. Quelques conseils avant de débuter le projet. Lancez-vous, avant
toute chose, à pieds joints dans le langage Python, essayez les différentes fonctionnalités présentées
ici et n’hésitez pas à vous renseigner ailleurs et de partager entre vous vos bonnes pratiques.
Complétez ce tutoriel avant de démarrer le projet, et soyez certain.e.s de le maîtriser avant de passer
l’examen oral ;)

[8]: %reset

59
Print dependencies
[1]: %load_ext watermark

[2]: %watermark -v -m -p numpy,scipy,matplotlib,time,watermark


print(" ")
%watermark -u -n -t -z

Python implementation: CPython


Python version : 3.11.5
IPython version : 8.15.0

numpy : 1.24.3
scipy : 1.11.1
matplotlib: 3.7.2
time : unknown
watermark : 2.5.0

Compiler : MSC v.1916 64 bit (AMD64)


OS : Windows
Release : 10
Machine : AMD64
Processor : AMD64 Family 23 Model 104 Stepping 1, AuthenticAMD
CPU cores : 16
Architecture: 64bit

Last updated: Fri Jan 03 2025 09:59:07SA Pacific Standard Time

60

Vous aimerez peut-être aussi