0% ont trouvé ce document utile (0 vote)
101 vues99 pages

Révision Python pour Classes Préparatoires

Ce document présente les bases essentielles du langage Python, avec un focus sur sa syntaxe simple et intuitive. Il couvre : Introduction au langage Python et ses caractéristiques. La structure d’un programme Python. Les règles de syntaxe de base (indentation, variables, opérateurs). Les types de données fondamentaux (entiers, flottants, chaînes, booléens). Les premières instructions (affichage, entrées, conditions).

Transféré par

Sweety Princess
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)
101 vues99 pages

Révision Python pour Classes Préparatoires

Ce document présente les bases essentielles du langage Python, avec un focus sur sa syntaxe simple et intuitive. Il couvre : Introduction au langage Python et ses caractéristiques. La structure d’un programme Python. Les règles de syntaxe de base (indentation, variables, opérateurs). Les types de données fondamentaux (entiers, flottants, chaînes, booléens). Les premières instructions (affichage, entrées, conditions).

Transféré par

Sweety Princess
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

Faculté des Sciences de Monastir

Département des Sciences de l’Informatique

Enseignant: Jaafar CHAAOURI

Informatique des Classes


Préparatoires:
MP2/PC2

A.U 2022-2023

Révision : Notions de base


Opérations : (d'entrée sortie, arithmétiques, relationnelles et logiques)
Types simples
Structures de contrôle
Les itérables
Fonctions utiles pour les itérables :
Les sous programmes
La récursivité
Gestion des exceptions
M
Gestion des fichiers textes
Notions de complexité
FS
1ère Partie: Programation orientée objet en Python
Introduction
Classes et objets
Méthodes
Attributs :
Dérivation / Héritage :
Ploymorphisme et surcharge
Exercices :
Application : Pile(Stack) & File(Queue)

2ème Partie : Simulation numérique avec Python


NumPy
1. Démarrer avec Numpy
2. Les fonctions fabriques d' ndarray
3. Avantages des ndarrays par rapport aux itérables natifs :
4. Les propriétés "interessantes" d'un ndarray :
5. Méthodes prédéfinies sur les ndarray:
6. Algèbre linéaire avec numpy
SciPy (calcul scientifique avec python)

1. Fonctions d'intégration numérique [Link]


2. Résolution d'équations différentielles ordinaires : [Link]
3. Recherche de racine et optimisation: [Link]
4. Initiation au traitement des images numériques [Link]
5. Problèmes d’interpolations (Interpolation de Lagrange) [Link]

3ème Partie : Les bases de données avec Python


1. Concepts fondamentaux
2. LDD : Langage de description des données
3. Algèbre relationnelle
4. LMD : Langage de manipulation de données
5. Accès aux données : module SQlite3 de Python
6. Exemples et Exercices d'application

M
FS
Faculté des Sciences de Monastir

Département des Sciences de l’Informatique

Informatique des Classes Préparatoires: MP2/PC2

Enseignant: Jaafar CHAAOURI

Révision : Notions de base :

Opérations : (d’entrée sortie, arithmétiques, relationnelles, logiques)


Types simples
Structures de contrôle
Les itérables
M
Fonctions utiles pour les itérables :
Les sous programmes
La récursivité
Gestion des exceptions
Gestion des fichiers textes
Notions de complexité
FS
Opérations d’entrée sortie

In [ ]: # Sortie
print("Welcome to Python:")
# Entrée
nom_var = input()
nom_var = input(" message ")
nom = input('donner votre nom : ')
n = int(input(' n = '))
x = float(input(' x = '))
# Affectation
nom = expression
x = 5 #simple
x = y= z = t = 5 #simultanée
x, y, z = 1, 2, 5 #multiple

Opérations arithmétiques
In [ ]: # Parenthèses ()
x+2**3
(x+2)**3
# Puissance **
1j**2 # -1+0j
# division flottante
4/2 #2.0 (float)
# division entière
4//2 #2 (int)
# modulo
4%2 # 0

1
Opérations relationnelles

In [ ]: # Comparaison d’identité is et is not


l = [1,2,3]
l1 = l
l2 = [Link]()
l is l1 #True id(l) == id(l1)
l is l2 #False id(l) != id(l2)
# Comparaison de contenu == et !=
l == l2 #True
# Comparaison riche
<
>
<=
>=

Opérations logiques
In [ ]: # Produisent un booléen (instance de la classe bool)
# Syntaxe :
and
or
not

In [ ]: True or False

Out[ ]: True
M
Classes simples

Une classe (type) décrit les attributs (les données) et les opérations (méthodes) de ses instances.

In [2]: x = 1
# ou
x =int(1)
FS
x

Out[2]: 1

In [5]: x='python'
# ou
x =str('python')
x

Out[5]: 'python'

2
In [ ]: '''Classe de l’objet spécial None : cette classe possède une seule instance elle est utilisée
par Python pour indiquer l’absence de valeur de retour pour certaines fonctions.'''

type(None) #NoneType
x = print("Hello")
x is None # True

'''Booléens bool : cette classe possède deux instances True & False qui représentent
les valeurs de vérités. '''

type(True) ##bool

'''Entiers relatifs (Z) '''


x = int('52')
x = 53 # décimal
x = 0b1101 # binaire
x = 0xabf5 # hexadécimal
x = 0o733 # octal

int(22.5) #22

# Nombres flottants :
x = float('22.2')

x = 0.001 # notation fractionnaire


x = 1e-3 # notation exponentielle

'''Nombres complexes : l'ensemble C, chaque instance est composée de deux


attributs de type float : real qui décrit la partie réelle et imag qui décrit la partie
imaginaire.'''

z = 1+2j
z2 = complex(3, 2)
M [Link] #1.0 (float)
[Link] #2.0 (float)
[Link]() #3-2j (complex)
z = 1+j #NameError j (identificateur)
z = 1+ 1j # correct : 1j unité imaginaire.

Structures de contrôle
FS
Un bloc de code est un groupe d’instructions Python précédé par le caractère « : » où chaque instruction du bloc est indentée. Les
structures de contrôle permettent de changer le flot d’exécution d’un programme.

In [ ]: # Structure conditionnelle : permet de conditionner un ou plusieurs blocs d’instructions


# obligatoire
if cond :
bloc1
if cond 2 :

# (optionnelle) autant de fois que nécessaire


elif cond2 :
bloc2
...
# (optionnelle) une seule fois à la fin
else :
blocd

In [ ]: #maximum de 3 entiers x, y, z
if x > y and x > z :
print(x)
elif y > z:
print(y)
else :
print(z)

Boucle Conditionnelle Tantque : permet d’exécuter un bloc tant que la condition de la boucle est vraie, la condition est toujours testée
avant l’exécution du bloc de la boucle.

Exemple 1 : pgcd

3
In [ ]: # ∀ x,y ∈ Z pgcd(x, y) =pgcd(y, x mod y)
x=145
y=75
while y != 0 :
x, y = y, x % y

print(x)
print(y)

5
0

In [ ]: x=145
y=75
---------------
x=75
y= 145%75= 70
--------------
x= 70
y= 75%70 = 5
------------
x= 5
y= 70%5 = 0
--------

Exemple : 2

u1 = 1

un = u2n−1 + u n−1 trouver le premier terme uk tel que uk > 10

M In [ ]: u = 1
while u <= 10 :
u = u**2+u
# u= 1+1 =2
# u=4+2 = 6
# u= 36+6 = 42 u>10

Boucle conditionnelle Répéter . . . jusqu’à cond : permet d’exécuter un bloc jusqu’à ce que la condition d’arrêt devienne False.

La condition d’arrêt est toujours testée après l’exécution du bloc de la boucle.


FS
In [ ]: while True :
if cond :
break

In [ ]: #saisie d’un réel entre 0 et 1


while True :
p = float(input(' p= '))
if 0 <= p <= 1:
break

Boucle Pour : Permet d’exécuter le bloc pour chaque élément de l’itérable source.

La classe range permet de générer un itérable formé par une succession d’entiers int.

In [ ]: range(n) # {0 . . . n − 1}
range(start,stop) # {start . . . stop − 1}
range(start, stop, step) # {start, start+step, . . . v}

In [ ]: for i in range(1,11,3):
print(i)

1
4
7
10

In [ ]: for v in itérable:
bloc # calcul de la factorielle de n

4
In [ ]: # calcul de la factorielle de n
f = 1
for v in range(2,n+1):
f *= v

Les itérables

Les Séquences :

La classe str :

Une chaine est une séquence non modifiable et ordonnée de caractères. Le tableau suivant résume les principales opérations
applicables sur les chaines.

In [ ]: # Création d’une chaine de caractères #chaine simple


ch = "Welcome"
ch = 'Welcome' #idem
#chaine multilignes
ch = """
une chaine qui s'étale
sur
plusieurs
lignes
"""
M print(ch)

une chaine qui s'étale


sur
plusieurs
lignes

In [ ]: ch='fG15Z'
# Retourne une copie de ch en lettres minuscules [Link]() ch='fG15Z'
[Link]() # 'fg15z'
# Retourne une copie de ch à ch en lettres majuscule [Link]() ch="fG15Z"
FS
[Link]() # "FG15Z"
'''Retourne une liste des sous-chaines obtenues en découpant ch autour du motif
séparateur sep. Par défaut, les lettres transparentes (espace, retour à la ligne, retour
charriot, tabulation etc.) sont considérées comme séparateur.'''
# [Link](sep)

In [ ]: s='python1&python2&python3&python4&python5'
sep ='&'
L=[Link](sep)
L

Out[ ]: ['python1', 'python2', 'python3', 'python4', 'python5']

In [ ]: '/'.join(L)

Out[ ]: 'python1/python2/python3/python4/python5'

In [ ]: ch='MP1 & PC1 & MP2 & PC2'


sep='&'
[Link](sep)

Out[ ]: ['MP1 ', ' PC1 ', ' MP2 ', ' PC2']

In [ ]: [Link](paramètres)
'''Retourne une chaine de caractères en remplacent chaque paire d’accolades "{}"
par l’argument correspondant (dans le même ordre) de la méthode (objets de classe
quelconque).'''

ch = 'A.U {}/{} FSM'.format(21,22)


ch

Out[ ]: 'A.U 21/22 FSM'

5
In [ ]: ch=f'A.U {21}/{22} FSM'
ch

Out[ ]: 'A.U 21/22 FSM'

In [ ]: '''Retourne une chaine de caractères résultante de la concaténation des chaines de


l’itérable src intercalées par le motif sep. (déclenche TypeError si l’itérable contient
un objet non instance de la classe str).'''
[Link](src)
# Exemple :
l=['a','b','c']
'/'.join(l) #'a/b/c'
'@'.join(l) #'a@b@c'

'''Retourne le code (int) du caractère passé en paramètre selon le standard UNICODE'''


ord('A') # 65
ord('Z') # 90
ord('a') # 97
'''Retourne le caractère qui correspond au code (int) UNICODE passée en paramètre'''
chr(65) # 'A'
chr(65+25) #'Z'
chr(10) #'\n'

In [ ]: chr(ord('A')+5)

Out[ ]: 'F'

In [9]: s= 'python'
for i in range(len(s)) :
print(s[i])

M p
y
t
h
o
n

In [ ]: s= 'python'
for i ,c in enumerate(s) :
print("indice:",i,"carctère :",c)

indice: 0 carctère : p
FS
indice: 1 carctère : y
indice: 2 carctère : t
indice: 3 carctère : h
indice: 4 carctère : o
indice: 5 carctère : n

In [ ]: s='python'
for c in s :
print(c)

p
y
t
h
o
n

La classe list :

Une liste est une séquence d’éléments séparés par une virgule et délimitée par une paire de crochets. (Ordonnée, Mutable (modifiable),
Indexée et Hétérogène)

In [ ]: #liste vide
l=[]
l=list()
#liste d'éléments
l = [obj1, ... , objk]
l = list(src) # ou src une instance d'une classe itérable

6
In [ ]: # str ==> list
list('ABCA') # ['A','B','C','A']
# set ==> list
list({3,'A',4}) # [3,4,'A']
# tuple ==> list
list((2,2,(1,2)))# [2,2,(1,2)]
# dict ==> list
list({2 :45,'x' :[1,2]} #[2,'x']
# TypeError
list(145)

In [ ]: # Ajouter un objet à la fin de la liste l


[Link](objet)
# Ajouter l’objet x dans la liste l à l’indice i.
[Link](i ,x)
# Ajouter les éléments de l’itérable t à la fin de la liste l
[Link](t)
# Retourner et supprimer le dernier élément de la liste l.
[Link]()
# Retourner et supprimer l’élément d’indice i de la liste l.
[Link](i)
# Supprimer le premier objet x trouvé dans la liste l. ValueError si x not in l.
x=[Link](x)
# Retourner le nombre d’occurrence de l’objet x dans la liste l
[Link](x)

In [ ]: L=[1,2,3,4]
x = [Link]()
x

Out[ ]: 4

M In [ ]: L=[10,9,5,15,1,2,3,45]
x=[Link](1)
x

Out[ ]: 9

In [ ]: L=[1,2,3]
L1=[4,5,6]
[Link](L1)
L
FS
Out[ ]: [1, 2, 3, [4, 5, 6]]

In [ ]: L1=[1,2,3]
L2=[4,5,6]
[Link](0,L2)
L1

Out[ ]: [[4, 5, 6], 1, 2, 3]

In [ ]: l = [11,[15,99],11]
[Link](11) # 2
[Link](99) # 0
[Link]([15,99]) # 1

In [ ]: # Retourner l’indice de la première occurrence de elt dans l. ValueError si elt not in l. [Link]
ex(elt)
[Link](elt)

In [ ]: # Parcourir un itérable à travers les indices


for i in range (len(l)) :
# traitement sur l[i]
# parcourir les éléments d'une liste
for e in l:
#traitement sur e
# parcourir les indices et les éléments
for idx, elt in enumerate(l):
traitement

La classe tuple :

7
Un tuple est une séquence d’éléments séparés par une virgule (Ordonné, Immuable (non modifiable), Indexé et hétérogène).

In [ ]: #tuple vide
t=()
t=tuple()
#singleton
t = obj,
# tuple d'éléments
l = (obj1, ... , objk)
t = tuple(src)
# ou src une instance d'une classe itérable

In [ ]: t=('lundi', 'mardi')
t1 =t[0] ,'jeudi'
t1

Out[ ]: ('lundi', 'jeudi')

In [ ]: t=255, #(255,)
t=[12,5], #([12,5],)
tuple('ABCA') #('A','B','C','A')
tuple({3,'A',4}) #(3,'A',4)
tuple({2 :45,'x' :[1,2]} #(2,'x')
tuple(145)# TypeError

In [ ]: # Retourner le nombre d’occurrences de l’objet x dans le tuple t


[Link](x)
# Retourner l’indice de la première occurrence de l’objet x dans t. ValueError si x not in t
[Link](x)

M In [ ]: # Test d’appartenance d’un élément x à un itérable t


x in t
x not in t

In [ ]: # Exemple :
5 in (1,5,[1,3]) # True
3 in (1,5,[1,3]) # False

Slicing and Indexing


FS
In [ ]: #str, list, tuple
s = [1,2,3,4]
s = ('a','b', 'c')
s = 'python'

In [ ]: # Indexage simple (uniquement pour les séquences).


s[i] avec 0 ≤ i ≤ len(s)-1 # pour un indexage à partir de la gauche
-len(s) ≤ i ≤ −1 # pour un indexage à partir de la droite

s[i] = obj # Valide uniquement pour les séquences mutables

s = "python" ; s[-1] #"n"


s[0], s[len(s)-1] #"p","n"
s[len(s)] #IndexError

In [ ]: s[0] # premier elt de la séquance


s[len(s)-1] # dernier elt de la séquence
s[-1] # dernier elt de la séquence
s[-len(s)] # premier elt de la séquance

In [ ]: # Morceler une séquence (slicing) s[dep:fin]


s[dep:fin:pas]
s[dep :]; s[ :fin]; s[::pas]
s = "python"
s[::-1] # "nohtyp"
s[:2] #"py"
s[2:] #"thon"

8
In [ ]: #str, list, tuple
for idx, value in enumerate(seq) :
print(idx, value)

0 p
1 y
2 t
3 h
4 o
5 n

In [ ]: # silicing
seq=[1,2,3,4,5,6,7,8,9,10]
seq[::2]

Out[ ]: [1, 3, 5, 7, 9]

In [ ]: str , tuple , list


s='python'
len(s)
[Link]('n')
[Link]('n')

Out[ ]: 5

In [ ]: s = "python"
s1 = s[:2]+'x'+s[3:]
s1

La classe set :
M
Représente la notion mathématique d’ensemble (valeurs uniques non ordonnées). Doit impérativement comporter des éléments non
modifiables (créer un ensemble comportant des listes, des dictionnaires ou des ensembles déclenche l’exception TypeError)

In [ ]: # Création d’un ensemble


s= set()
s= {} # créé une nouvelle instance de la classe dict
s= {obj1, ..., objk}
s= set(src) #où src est un objet itérable
s = {v for v in it}
FS
In [ ]: # Copie d'un esemble
[Link]()
# Ajout d'un objet
[Link](obj)
# Exemple :
s=set()
[Link](5) # s={5}
[Link]('x') # s={5,'x'}
[Link]([1,2,3]) #typeError

In [ ]: #supprimer un objet
[Link](x)
[Link](x) # déclenche KeyError si x not in s

In [ ]: s={1,2}
[Link](5) # KeyError
[Link](1)
s # {2}

In [ ]: s={1,2,'x', (2.5,40.5)}
[Link](3)
[Link]('x')
# [Link](elt)
s

Out[ ]: {(2.5, 40.5), 1, 2, 3}

9
In [ ]: # Les opérations ensemblistes
s = {1,2} | {2,3}
s #{1,2,3}
s = {1,2} & {2,3}
s #{2}
# s1 - s2
s = {1,2} - {2,3}
s #{1}
# s1 ^ s2
s = {1,2}^{2,3}
s #{1,3}
# s1 ⊂ s2
{1,2} < {1,2,5} #True
{1,2} < {1,2} #False
# s1 ⊆ s2
{1,2} <= {1,2,5} #True
{1,2} <= {1,2} #True

In [ ]: E= {1,2,3,5,'x',('2.5','test')}
for elt in E :
print(elt)

1
2
3
5
('2.5', 'test')
x

In [ ]: txt = 'Python'
s = set(txt) # {'P', 'h', 'n', 'o', 't', 'y'}
s = set(3.25) # TypeError
M s[i]

L2=[3,4,5]
E1=set(L1)
E2=set(L2)
E1 ^ E2
# déclenche l’exception TypeError
# Attention : Il est interdit d’indexer un ensemble

In [ ]: L1=[1,2,3]

Out[ ]: {1, 2, 4, 5}
FS
La classe dict :

Permet de construire une table associative (clé → valeur).

Les clés sont impérativement des objet non modifiables (utiliser des listes, des dictionnaires ou des sets comme clé déclenche
TypeError).
Les valeurs sont des objets de type quelconque.

In [ ]: # Création d’un dictonnaire


d = dict()
d = {} #dict vide
d = {clé1 : obj1, ... , clék, objk}
d= dict(src) # où src itérable
d= {k:v for k,v in it} # par compréhension
# Exemple 1:
t = [(5,2), "ab", [1,2] ]
dict(t) #{1: 2, 5: 2, 'a': 'b'}
# Exemple 2:
clés = [1,2,3]
vals = 'abc'
dict(zip(clés, vals)) # {1: 'a', 2: 'b', 3: 'c'}

10
In [ ]: # Accès à une entrée du dictionnaire
d[k] #KeyError si k not in d
[Link](k) #None si k not in d
[Link](k, vdef)# vdef si k not in d
# Exemple :
d = {'a':3, 'b':5, 4j:33}
d['a'] #3
d['c'] #KeyError
[Link]('c') #None
[Link]('c', 0) #0
[Link]('a', []) #3

In [ ]: # Mettre à jour / insérer une entrée dans le dictionnaire


d[k] = val
# mise à jour si k in d
# insertion si k not in d
[Link]({k1 :val1, k2:val2})

In [ ]: # Exemple :
d = {}
d["a"] = 33 #insertion
d #{"a" :33}
d["a"] = 22 #mise à jour
d # {"a" :22}
[Link]({'b':11})
d

Out[ ]: {'a': 22, 'b': 11}

In [ ]: # Supprimer une entrée à partir de sa clé


[Link](k)
M #KeyError si k not in d
#renvoie la valeur associée à la clé k
del d[k] # instruction ne renvoie rien

In [ ]: # Parcourir les clés d’un dictionnaire


for k in d:
traitements
# Parcourir les valeurs d’un dictionnaire
for v in [Link]():
traitements
# Parcourir les couples clé, valeur d’un dictionnaire
FS
for k, v in [Link]():
traitement

# Exemple :
d = {1:2, "a":10}
for k in d:
print(k)
for k, v in [Link]():
print(k,v)

In [ ]: d= {1: 2, 5: 2, 'a': 'b'}

In [ ]: for i in range(len(d)):
d[i] # KeyError

In [ ]: L=[(1,'a'),(2,'b')]
d=dict(L)
d

Out[ ]: {1: 'a', 2: 'b'}

Fonctions utiles pour les itérables :


In [ ]: # Taille d’un itérable : str, tuple, list, set, dict
len(it)

In [ ]: L=[9,1,5,3,4] # des élts comparables


min(L), max(L), sum(L)

Out[ ]: (1, 9, 22)

11
In [ ]: # Valeur maximale d’un itérable, TypeError pour un itérable comportant des objets non comparabl
es.
max(it)
max(it, key = fct_critère)
max(v1, v2, ... , vn)
# Exemple :
l = (1+3j, 2+5j, 11j)
max(l) #TypeError
#max(l, key = abs) #11j

In [ ]: l = (1+3j, 2+5j, 11j)


#max(l) #TypeError
max(l, key= abs) #11j

Out[ ]: 11j

In [ ]: def f(z) :
return [Link]
# ou bien
f = lambda z:[Link]

In [ ]: l = (1+3j, 2+5j, 11j)


f= lambda z:[Link]
max(l,key=f)

Out[ ]: (2+5j)

In [ ]: # Valeur minimale d’un itérable. TypeError pour un itérable comportant des objets non comparabl
es.
min(it)
min(it, key = fct_critère)

M min(v1, v2, ... ,vn)


# Exemple :
min(l, key= lambda z : [Link]) #1+3j

In [ ]: # Concaténation (uniquement pour les séquences (str, tuple, list))


seq1 + seq2
# Exemple :
(1,2) + (3,) # (1,2,3)
"med" + " " + "ali" #'med ali'

In [ ]: # Répétition (uniquement pour les séquences)


FS
n * seq # ou bien
seq * n
# Exemple :
[0] * 3 # [0,0,0]
-6 * [1,2] # []
"ab" * 3 #"ababab"

In [ ]: L=[1,2,3]
L*3

Out[ ]: [1, 2, 3, 1, 2, 3, 1, 2, 3]

In [ ]: # Sort the list by the length of the values:


cars = ['Ford', 'Mitsubishi', 'BMW', 'VW']
# A function that returns the length of the value:
f= lambda e : len(e)
[Link]( key = f)
cars

Out[ ]: ['VW', 'BMW', 'Ford', 'Mitsubishi']

12
In [ ]: def f(e):
return e['year']

cars = [
{'car': 'Ford', 'year': 2005},
{'car': 'Mitsubishi', 'year': 2000},
{'car': 'BMW', 'year': 2019},
{'car': 'VW', 'year': 2011}
]

[Link](key=f) # , reverse=True)
cars

Out[ ]: [{'car': 'Mitsubishi', 'year': 2000},


{'car': 'Ford', 'year': 2005},
{'car': 'VW', 'year': 2011},
{'car': 'BMW', 'year': 2019}]

In [ ]: # Trier un itérable d’objets comparables


# (TypeError si l’itérable source comporte des objets non comparables).
# Renvoie une list contenant les éléments dans l’ordre.
sorted(it)
sorted(it, key = fct_critère)
sorted(it, reverse = True)
sorted(it, reverse = True, key = fct_critère)
# Exemple :
d = {'med':10, 'ali':20, 'lilia':5}
sorted(d) # ['ali', 'lilia', 'med']
sorted(d, reverse = True) #['med', 'lilia', 'ali']
sorted(d, key = lambda k : d[k] ) #['lilia','med','ali']

In [ ]: # Zipper plusieurs itérables (premier avec premier, deuxième avec deuxième etc.)
M zip(it1, it2)
zip(it1, ..., itn)
# Exemple :
ch = "abc"; l = [1,2,3]
list(zip(ch,l))

Les sous programmes


#[("a",1), ("b",2), ("c",3)]

Une fonction est un bloc d’instructions (corps de la fonction) destiné à réaliser une opération. Elle peut recevoir des arguments et
FS
renvoie un objet.
L’appel d’une fonction Python retourne toujours un objet, par défaut None. Dans le corps de la fonction ce retour est spécifié à l’aide
de l’instruction return expression.

In [ ]: # Définition d’une fonction


def nom_f(paramètres):
corps de la fonction

In [ ]: # Exemple :
def f(x,y) :
import math
z = x**2 + [Link](y)
return z
result = f(2,3)
result

Out[ ]: 4.141120008059867

In [ ]: # Appel d’une fonction nom_f(arguments)


print(f(3,2)) #arguments positionnels
r = f(y = 2, x = 3) #arguments par mot-clé

Retour d’une fonction L’instruction return permet de transmettre un résultat à l’appelant de la fonction en cours.
Cette instruction engendre la sortie immédiate du code de la fonction et le retour vers le code appelant.

In [ ]: x= None
type(x)

Out[ ]: NoneType

13
In [ ]: def f(x) :
if x > 0 :
return x**0.5
print(f(4)) #2.0
print(f(-4)) #None

In [ ]: #fonction sans paramètes


def f() :
for i in range(10**10) :
#print(i)
return i
print(f()) #0

Paramètres optionnels : les paramètres optionnels sont associés à une valeur par défaut (évaluée une seule fois au moment de la
définition de la fonction). Si l’argument associé au paramètre n’est pas indiqué lors de l’appel, Python utilise la valeur par défaut pour
substituer le paramètre optionnel.

In [ ]: def f(x, y = 6) :
return x + y
print(f(1,3)) #4
print(f(3)) #9
print(f(y = 2, x = 1))#3

Fonctions lambda : permet de créer une expression de type fonction. Utilisée généralement pour les fonctions d’ordre supérieur :
fonctions qui prennent des paramètres de type fonction exemple (sorted, [Link], min, max etc.)

In [ ]: # lambda paramètres : résultat

M In [ ]: g= lambda i,j=5 : i+j


g(3)

Out[ ]: 8

La récursivité

Un traitement récursif nécessite de déterminer :


FS
le cas trivial ou encore le cas d’arrêt
le traitement récurrent et de s’assurer que ce dernier atteindra le cas d’arrêt (terminaison).

In [ ]: # Calcul de la factorielle de n.
# Cas trivial 0! = 1
# Cas récursif n! = n × (n − 1)!
def fact(n):
if n<=1: #cas trivial
return 1
else:
return n*fact(n-1)

In [ ]: f(5) = 5 *f(4)
--------------
f(4)= 4*f(3)
--------------
f(2)= 2*f(1)

Exemple : Recherche dichotomique d’un élément x dans une liste lst triée en ordre croissant.

Cas trivial :
si liste vide alors résultat = False,
sinon si l’élément du milieu m contient x alors résultat = True.
Cas récursif :
si lst[m] > x alors effectuer la recherche dans la moitié gauche de la liste 0 . . . m − 1.
Si lst[m] < x alors effectuer la recherche dans la moitié droite de la liste m + 1 . . . len(lst).

14
In [ ]: def dicho_search(x,l):
if len(l) == 0:
return False
else:
m = len(l)//2
if l[m] == x:
return True
elif l[m] > x:
return dicho_search(x,l[:m])
else :
return dicho_search(x,l[m+1:])

Gestion des exceptions

Les exceptions sont des objets spéciaux permettant de représenter une erreur d’exécution dans un script Python.

Il existe plusieurs types d’erreurs : TypeError, ValueError, IndexError.

Ces derniers sont des classes Python héritant toutes de la classe de base Exception permettant de représenter une Erreur quelconque.

In [ ]: # Déclencher une exception


raise Exception("message")
# ou bien
raise Exception()
# Exemple :
raise TypeError(" entier attendu ! ")

M In [ ]: # Prévoir une exception


if cond_erreur :
raise Exception("message")
# ou bien
assert not cond_erreur, " message "

In [ ]: # Intercepter une exception


try :
bloc_ risqué
except :
bloc_cas_erreur
else :
FS
bloc_cas_pas_erreur

In [ ]: # Exemple :
# saisie d’un entier positif (avec gestion d’erreur)
def f() :
while True:
try:
x = int(input("x = "))
except:
print('erreur !' )
else :
if x > 0 :
return x

In [ ]: f()

x = a
erreur !
x = 1

Out[ ]: 1

Gestion des fichiers textes

Un fichier est une collection d’informations stockées dans une mémoire de masse.
Un fichier texte contient une succession de caractères séquentiels.
Lors de l’ouverture d’un fichier texte, un encodeur assure la conversion des octets lus/écris en lettres UNICODE.

15
Ouverture d’un fichier.

In [ ]: '''Mode Lecture seule (mode = 'r') : Le fichier doit exister et seule la lecture
est autorisée. L’ouverture d’un fichier inexistant génère une erreur.'''
# Ouverture du fichier [Link] en mode lecture
f = open("[Link]", "r")

In [ ]: # Ouverture de fichier [Link] en mode écriture


# f = open(file_path, mode)
f = open("[Link]", "w")
'''Mode Écriture (mode = 'w') : Si le fichier n’existe pas, il est créé, sinon il
est écrasé.'''

In [ ]: # Ouverture en mode mise à jour


f = open("[Link]", "a")
'''Mode mise à jour (mode = 'a') : identique au mode ’w’, sauf que si le fichier
existe, il n’est pas écrasé et l’ajout se fait en fin du fichier.'''

Lecture à partir d’un fichier texte.

In [ ]: s = [Link]() # lecture intégral


linge= [Link]()
lignes = [Link]()

Lecture intégrale :
M [Link]()
renvoie un str contenant le contenu intégral du fichier.
Lecture Ligne par ligne :
[Link]()
Fournit la ligne courante sous forme d’un str et place le curseur sur la ligne suivante.
Elle renvoie la chaîne vide si fin du fichier.
Lecture intégrale ligne par ligne :
[Link]()
Fournit la totalité du contenu du fichier sous forme d’une liste de str.
Le caractère de saut de ligne '\n ' présent à la fin de chaque chaîne indique la fin de chaque ligne.
FS
Itérer sur un fichier ligne par ligne :

In [ ]: for line in [Link]():


# traitement sur une ligne de f

Écriture dans un fichier Texte

In [ ]: # Écriture d’un str :


[Link](ch)
# Écriture d’une liste de str :
lst=['ligne0','ligne1','ligne2']
[Link](lst)

Fermeture d’un fichier.


Cette instruction permet de fermer la connexion établie par open et de libérer les ressources réservées.

In [ ]: [Link]()

Notions de complexité

16
Le calcul de coût d’une fonction renseigne sur le temps nécessaire à son exécution, mais il suffit de changer de machine que la
valeur obtenue change avec des données identiques. Il sera utile de construire une fonction qui décrit le comportement de
l’algorithme quand la taille des données s'accroît : on parle de comportement asymptotique des algorithmes;
Mesurer la complexité d’un algorithme revient alors à trouver une fonction qui informe sur la nature de ce comportement
asymptotique dans le pire des cas. On parle de fonctions d’ordre de grandeurs notées généralement O, dans l'obejectif est de borner
la fonction de coût. :

Classification des Problèmes

Classes de complexité: O(1)


Désignations : Complexité constante: le temps d’exécution n’augmente pas avec l’accroissement de la taille des données
Exemple de problèmes : - Affectation, - Calcul arithmétique, - Comparaison, - Accès au premier élément d’un ensemble de données

Classes de complexité : O(log(n))


Désignations : Complexité logarithmique : Augmentation très faible du temps d’exécution quand la taille des données s'accroît
Exemple de problèmes : - Recherche dichotomique, - Couper un ensemble de données en deux sous-ensembles

M
Classes de complexité : O(n)
Désignations : Complexité linéaire : le temps d’exécution s'accroît d’une manière linéaire avec la taille des données
Exemple de problèmes : - Parcours d’une liste, - Recherche linéaire dans une liste

Classes de complexité : O(nlog(n))


Désignations : Complexité quasi—linéaire : le temps d’exécution s'accroît d’une manière quasi linéaire avec la taille des données
Exemple de problèmes : Couper un ensemble de données en deux sous-ensembles d’une manière répétitive et combiner les sous-
FS
ensembles pour obtenir la solution finale (les problèmes diviser pour régner …)

Classes de complexité: O(n2 )


Désignations : Complexité quadratique : le temps d’exécution est le carré de la taille des données -Exemple de problèmes: Double
boucle for imbriquées

Analyse de la complexité :

Exemple :1

In [ ]: def tri_par_selection(L): # T(n)


n=len(L) # 1+1
for i in range(n-1) : # n-2 boucles
indice_min = i # 1
for j in range( i+1,n) : # (n-i-1) boucles
if L[j]<L[indice_min] : # 1
indice_min = j # 1
L[i],L[indice_min]= L[indice_min], L[i] # 1

17
→ le nombre de comparaison est donné par (n − i − 1) pour l’élément à la position i d’où :
n−2
T (n) = (n − 1) + (n − 2) + … + 2 + 1 = ∑ (n − i − 1)
i=0

T (n) peut être vu comme la somme de n − 1 termes d’une suite arithmétique de premier terme 1 et de raison 1 :
(n−1)(n) 2
n
n
T (n) = = −
2 2 2

→ O(T (n)) = O(n )


2
: l’algorithme du tri est quadratique.

Exemple :2

In [ ]: i=10**9
while(i>=1): # nombe d'itération
print(i)
i=i//2

1000000000
500000000
250000000
125000000
62500000
31250000
15625000
7812500
3906250
1953125
976562

M 488281
244140
122070
61035
30517
15258
7629
3814
1907
953
476
238
FS
119
59
29
14
7
3
1

In [ ]: import math
math.log2(10**9)

Out[ ]: 29.897352853986263

La complexité est logarithmique : O(log2(n))

Augmentation très faible du temps d’exécution quand la taille des données s'accroît

18
Faculté des Sciences de Monastir

Département des Sciences de l’Informatique

Informatique des Classes Préparatoires: MP2/PC2

Enseignant: Jaafar CHAAOURI

1ère Partie :
Programation orientée objet en
Python

Plan

Introduction
Classes et objets
Méthodes
Attributs :
Dérivation / Héritage :
Ploymorphisme et surcharge
Exercices :
Application : Pile(Stack) & File(Queue)
M
Programation orientée objet en Python
FS
Introduction

Le Concept Objet

Un objet est une entité du monde réel : une personne, une voiture, une forme géométrique, une image, une feuille, etc.
Les classes sont un moyen de réunir des données et des fonctionnalités.

Objet = [ attributs + méthodes ]


Créer une nouvelle classe ⇒ crée un nouveau type d'objet et ainsi de nouvelles instances de ce type peuvent être
construites.

L’héritage et le polymorphisme forment avec le principe d’encapsulation les trois piliers de la programmation orientée
objet.

Les classes :

Les classes sont les principaux outils de la programmation orientée objet ou POO (Object Oriented Programming ou
OOP en anglais).
Ce type de programmation permet de structurer les logiciels complexes en les organisant comme des ensembles
d'objets qui interagissent, entre eux et avec le monde extérieur.
Les bénéfices de cette approche :
Les différents objets utilisés peuvent être construits indépendamment les uns des autres (par exemple par des
programmeurs différents).
La possibilité de construire de nouveaux objets à partir d'objets préexistants. Cela est rendu possible grâce aux
concepts de dérivation(héritage) et de polymorphisme.

19
Héritage et polymorphisme

La dérivation : (Héritage)

C'est le mécanisme qui permet de construire une classe « enfant » au départ d'une classe « parente ». La classe
enfant ainsi obtenu hérite toutes les propriétés et toute les fonctionnalités.
Toutefois, il est possible de modifier une méthode dans une classe enfant héritée de la classe mère.
Le polymorphisme :

permet d'attribuer des comportements différents à des objets dérivant les uns des autres, ou au même objet.
Le mot polymorphisme signifie avoir plusieurs formes.
En programmation, polymorphisme signifie que le même nom de fonction (mais des signatures différentes) est
utilisé pour différents types.
En Python, Polymorphisme nous permet de définir des méthodes dans la classe enfant portant le même nom que
les méthodes de la classe mère.

Classes et objets
Définition d’une classe élémentaire

Pour créer une nouvelle classe d'objets Python, donc un nouveau type de donnée, on utilise l'instruction "class".

Par exemple, nous allons créer un nouveau type : le type "Point". Ce type correspondra au concept de point en
mathématiques. Dans un espace à trois dimensions, un point est caractérisé par trois nombres (ses coordonnées x,y et
z).
M
Nous voudrions cependant combiner ces trois valeurs dans une seule entité, ou un seul objet. Pour y arriver, nous allons
définir une classe Point() :

In [ ]: class Point:
"Définition d'un point mathématique"
FS
Nous pouvons dès à présent nous servir de cette classe pour créer des objets de ce type, par instanciation.

Créons par exemple un nouvel objet p9.

In [ ]: p9 = Point()
# Point est une classe donc un nouveau type ou encore un nouveau modèle
# p9 est un objet, une instance ou encore un expemlaire de type Point

Après cette instruction, la variable p9 contient la référence d'un nouvel objet de type Point. Nous pouvons dire également
que p9 est une nouvelle instance de la classe Point().

Méthodes & Attributs

Une méthode s'écrit comme une fonction dans le coprs de la classe avec un premier paramètre self obligatoire (le nom
self est une convention qui désigne l'objet ou l'instance sur le quel la méthode sera appliquée).

Exemple 1:
Définir une classe Point avec un constructeur, un point est définit soit par deux coordonnées x et y, s’il s’agit d’une
représentation d’un point au plan ou par trois coordonnées x, y et z, s’il s’agit d’une représentation d’un point dans
l'espace.
Les trois coordonnées x,y et z sont trois attributs d'instance de la classe Point

La classe Point doit contenir une méthode str qui affiche le point.

Une méthode Distance qui retourne la distance qui sépare le point en cours et un deuxième point passé comme
paramètre.

20
In [ ]: class Point:
def __init__(self,a,b,c=None):
#par défault on donne la valeur None à l'attribut z
# attributs d'instance (spécifique à l'instance)
self.x=a
self.y=b
self.z=c
def __str__(self):
# L'affichage du point
if self.z==None:# si z n'est pas défini
return "P({},{})".format(self.x,self.y)
else: # si z est défini
return "P({} ,{} , {})".format(self.x,self.y,self.z)
def Distance(self,P):
""" Méthode qui retourne la distance entre le point en cours
et le point P"""
from math import sqrt
if self.z==None:# si z n'est pas défini
return sqrt((self.x-P.x)**2+(self.y-P.y )**2)
else :
return sqrt((self.x-P.x)**2+(self.y-P.y )**2 + (self.z-P.z )**2 )

In [ ]: # Instanciation de l'objet P1
P1=Point(2,3)
print(P1)

P(2,3)

In [ ]: # Instanciation des objets P2 et P3


P2=Point(1,-5,6)
P3=Point(-1,5,3)
P3.__str__() # ou print(P3)

'P(-1 ,5 , 3)'
Out[ ]:

In [ ]: # récupération de la distance entre P2 et P3


[Link](P3) # ou [Link](P2)
M
10.63014581273465
Out[ ]:

Exemple 2 : La classe CompteBancaire


FS
définir une classe CompteBancaire(),
instancier des objets tels que compte1, compte2, etc.
Le constructeur de cette classe initialisera les deux attributs d’instance nom et solde, avec les valeurs par défaut
’NomPersonne’ et 0.0.

Trois autres méthodes à définir :

depot(somme) permettra d’ajouter une certaine somme au solde ;


retrait(somme) permettra de retirer une certaine somme du solde ;
affiche() permettra d’afficher le nom du titulaire et le solde de son compte.

In [ ]: class CompteBancaire:

def __init__(self,nom='NomPersonne',solde=0.0):
""" création du constructeur de la classe avec les valeurs
par defaut 'NomPersonne' et 0.0 """

[Link]=nom
[Link]=solde

def depot(self,somme):
""" ajout d'une somme à l'attribut solde """

[Link]+=somme

def retrait(self,somme):
""" retrait d'une somme à l'attribut solde """

[Link]-=somme

def affiche(self):

21
""" L'affichage des informations d'un compte"""
print("Le solde du compte bancaire de {} est de {} dinars.".format([Link],[Link]))

In [ ]: compte1 = CompteBancaire('Personne1', 800)


[Link](350)
[Link](200)
[Link]()

Le solde du compte bancaire de Personne1 est de 950.000 dinars.

In [ ]: compte2 = CompteBancaire()
[Link]()

Le solde du compte bancaire de NomPersonne est de 0.000 dinars.

Méthodes spéciales :
Les méthodes spéciales sont des méthodes d'instance que Python reconnait et sait utiliser, dans certains contextes. Elles
peuvent servir à indiquer à python ce qui'il doit faire quand il se retrouve devant une expression comme objet1+ objet2 voir
meme objet[indice], elles controllent encore la façcon dont un objet est créé ainsi que l'accès à ses attributs.

Construteur : init

Lors de l'instanciation d'un objet, la structure de base de l'objet est créée en mémoire, et la méthode init est
automatiquement appelée pour initialiser l'objet. C'est typiquement dans cette méthode spéciale que sont créés les attributs
d'instance avec leur valeur initiale.

Destructeur : del

Lors de la supression d'un objet, la méthode del est automatiquement appelée pour le détruire de la mémoire. Souvent on
peut personnaliser le comportement de cette méthode spéciale.

Surcharge des opératuers :


M
La surcharge d’opérateurs permet la redéfinition et l’utilisation des opérateurs en fonction de la classe. Par exemple,
l’utilisation de l’opérateur + pour additionner deux objets de même type.
Python associe à chaque opérateur une méthode spéciale qu’on peut surcharger, on cite dans la suite quelques
FS
exemples :

Exemples des méthodes spéciales permettant la surcharge des opérateurs arithmétiques :

+ : __add__(self,other)
* : __mul__(self, other)
- : __sub__(self,other)

Exemples des méthodes spéciales permettant la surcharge des opérateurs d’indexation :

objet[i]: __getitem__(self,indice)
objet[i]= v : __setitem__(self,indice,valeur)

Exemple 2:

In [ ]: x1 = 3 ; x2 = 5.1 ; x2 + x1

8.1
Out[ ]:

In [ ]: float.__add__(x2, x1)

8.1
Out[ ]:

In [ ]: z1 = 3+4j; z2 = 2-3j; z2 + z1

(5+1j)
Out[ ]:

In [ ]: complex.__add__(z2,z1)

22
(5+1j)
Out[ ]:

In [ ]: s1 = "ali" ; s2 = "med" ; s2 + s1

'medali'
Out[ ]:

In [ ]: s1.__add__(s2)

'alimed'
Out[ ]:

In [ ]: str.__add__(s2, s1)

'medali'
Out[ ]:

In [ ]: t1 = (5,2); t2 = (3,); t2 +t1

(3, 5, 2)
Out[ ]:

In [ ]: tuple.__add__(t2, t1)

(3, 5, 2)
Out[ ]:

La surcharge permet à un opérateur de pooséder un sens différent suivant le type de ses opérandes. Par exemple l'pérateur
'+' permet :

In [ ]: 5+8 # additionner deux entiers

13
Out[ ]:

In [ ]: # surcharge de l'opérateur d'addition pour concaténer deux chaines de caractères

Out[ ]:
"bon"+"jour"

'bonjour'
M
In [ ]: "bon".__add__("jour")

'bonjour'
Out[ ]:
FS
Exercice :

Pour comprendre le fonctionnement des méthodes spéciales on va créer une classe appelée Complexe qui représente un
nombre complexe qui est caractérisé par sa partie Réelle et sa partie imaginaire.

Dans cette classe on définit les méthodes suivantes:

add: qui permet d’additionner deux nombres complexes en utilisant le symbole ‘+’

sub: qui permet de soustraire deux nombres complexes en utilisant le symbole ‘-‘

mul: qui permet de multiplier deux nombres complexes en utilisant le symbole ‘*’

str: pour afficher un nombre complexe en utilisant la fonction str

repr: pour afficher un nombre complexe par son nom

In [ ]: class Complexe:
def __init__(self,reelle ,imaginaire):
# C'est le constructeur de la classe Complexe
[Link]=reelle
[Link]=imaginaire

def __add__(self,c): # c est un antre combre complexe


""" Cette méthode permet d'ajouter deux nombre complexe en utilisant
directement le symbole '+' """

R= [Link] + [Link]
I=[Link] + [Link]
return Complexe(R,I)

def __sub__(self,c):
""" Cette méthode permet de soustraire deux nombre complexe en utilisant
23
directement le symbole '-' """

R=[Link] - [Link]
I=[Link] - [Link]
return Complexe(R,I)

def __mul__(self,c):
""" Cette méthode permet de multiplier deux nombre complexe en utilisant
directement le symbole '*' """

R=[Link] * [Link] - [Link] * [Link]


I=[Link] * [Link] + [Link]+[Link]
return Complexe(R,I)

def __str__(self):

"""Cette méthode permet d''afficher notre objet (nombre complexe)


en utilisant la méthode str(objet) """

Img=[Link]
R=[Link]
I='i'
S='+'

#on traite tous les cas pour avoir un affichage plus joli

if abs([Link])==1:Img='' # 1+0i
if [Link]==0:Img=S=I=''
if [Link]==0:R=S=''
if [Link]<0:
S='-'
if ([Link]!=-1): Img=abs([Link])

return '{} {} {}{}'.format(R,S,I,Img) # 1 - 2j

def __repr__(self):
"""
M
Cette méthode permet d''afficher notre objet (nombre complexe) en utilisant juste le nom de l'
"""
Img=[Link]
R=[Link]
I='i'
FS
S='+'

#on traite tous les cas pour avoir un affichage plus joli

if abs([Link])==1:Img=''
if [Link]==0:Img=S=I=''
if [Link]==0:R=S=''
if [Link]<0:
S='-'
if ([Link]!=-1):Img=abs([Link])

return '{} {} {}{}'.format(R,S,I,Img)

Exemples d'exécution:

In [ ]: C1=Complexe(2,3) # 2+3i
C2=Complexe(1,-4) # 1-4i
C3=C1 + C2
print(C3) # __str__

3 - i

In [ ]: c3 = C1.__add__(C2)
C3

3 - i
Out[ ]:

In [ ]: C3.__repr__()

'3 - i'
Out[ ]:

In [ ]: C3

3 - i
Out[ ]:

24
In [ ]: print(C1-C2)

1 + i7

In [ ]: C4=Complexe(-5,2)

In [ ]: print(C4)

-5 + i2

In [ ]: C4

-5 + i2
Out[ ]:

Attributs de classe :
Il existe deux types attributs :

les attributs d'instance (spécifique à l'instance)


les attributs de classe (partagé par toutes les instances).

In [ ]: class Personne:
objets_crees=0 # Le compteur vaut 0 au départ
#attributs de classe (partagé par toutes les instances).
def __init__(self,nom):
[Link] = nom
Personne.objets_crees+=1 # à chaque création d'un objet on incrémente le comptuer

L'attribut "nom" est dit attribut d'instance. Si on crée plusieurs instances l'attribut nom ne sera pas identique d'une
instance à une autre.
M
Lattribut "obejts_crees" est dit attribut de classe. Il est définit directement dans le corps de la classe. Quand on veut
l'appeler, on préfixe le nom de l'attribut par le nom de la classe.

In [ ]: Personne.objets_crees

0
Out[ ]:
FS
In [ ]: a1= Personne("Youssef")
a2= Personne("Karim")
Personne.objets_crees

2
Out[ ]:

Dérivation /Héritage :

Si une classe B hérite de la classe A : les objets créer dans la classe B auront accès aux méthodes et attributs de la
classe A

La classe B va pourvoir en définir d'autres méthodes et d'autres attributs qui lui sont propores, en plus des méthodes et
attributs de la classe A. elle va pouvoir également reféfinir les méthodes de la classe mère.

In [ ]: class A :
# instruction 1
# instruction 2

class B(A) :
# classe B hérite de la classe A

In [ ]: b= B()

Exemples :
1. Qu'affiche ce code ?

In [ ]: class A:
25
def __init__(self) :
print("Création d'un objet A")
class B(A):
def __init__(self) :
A.__init__(self)
print("Création d'un objet B")

b =B()

Création d'un objet B


Création d'un objet A
Création d'un objet A, Création d'un objet B
Création d'un objet B, Création d'un objet A

2. Qu'affiche ce code ?

In [ ]: class A:
def __init__(self, xInit=1) :
self.x=xInit
class B(A):
def __init__(self, xInit=0,yInit=0):
A.__init__(self,xInit)
self.y=yInit
v1=B()
v2=B(5,4)
print(v1.x,v1.y,v2.x,v2.y)

0054
1000
Une erreur
5454

3. Qu'affiche ce code ?
M
In [ ]: class A:
def __init__(self, x) :
self.x=x
FS
class B(A):
def __init__(self, x):
A.__init__(self)
b=B(5)
print(b.x)

x
0
une erreur
5

4. Qu'affiche ce code ?

In [ ]: class A:
def __init__(self, xInit=0.0) :
self.x=xInit

a=A()
print(a.x)

5.0
__ x
Une erreur
0.0

Ploymorphisme et surcharge

Exemple :
26
Une classe Rectangle avec un constructeur donnant des valeurs (longueur et largeur) par défaut et un attribut nom =
“rectangle”, il faut ensuite définir les méthodes:

perimetre qui retourne le périmètre du rectangle.


surface qui retourne la surface du rectangle.
afficher qui affiche le périmètre et la surface d’un rectangle ainsi leurs dimensions en longueur et largeur.

Définir une classe Carre héritant de Rectangle et qui permet de redéfinir l’attribut d’instance : nom = “carré”.

In [ ]: class Rectangle:#definition
"Classe de rectangles"
def __init__(self, longueur =0, largeur =0):
self.L = longueur
self.l = largeur
[Link] ="rectangle"
def perimetre(self):
return "(%d + %d) * 2 = %d" % (self.L, self.l,(self.L + self.l)*2)
#return f"({} + {}) * 2 = {}" (self.L, self.l,(self.L + self.l)*2)
def surface(self):
return "%d * %d = %d" % (self.L, self.l, self.L*self.l)

def afficher(self):
print("Un %s de %d sur %d" % ([Link], self.L, self.l))
print("a une surface de %s" % ([Link](),))
print("et un périmètre de %s\n" % ([Link](),))

In [ ]: R=Rectangle(5,7)
[Link]()

Un rectangle de 5 sur 7
a une surface de 5 * 7 = 35
et un périmètre de (5 + 7) * 2 = 24
M
In [ ]: """ la classe Carre hérite de la classe mère "Rectangle", donc la classe fille
"Carre" hérite tous les attributs et toutes les méthode de la classe mère Rectangle"""
class Carre(Rectangle):
"Classe de carrés"

def __init__(self, cote):#redéfinir le constructeur "Polymorphisme d'héritage"


FS
"""Instanciation de la classe mère (appeler le constructeur de la classe
mère dans le constructeur de la classe fille)"""
Rectangle.__init__(self, cote, cote)
[Link] ="carré" #redéfinir la valeur de l'attribut nom au sein de la classe fille.

In [ ]: C=Carre(6)
[Link]()
C.

Un carré de 6 sur 6
a une surface de 6 * 6 = 36
et un périmètre de (6 + 6) * 2 = 24

Et donc à cause de l'héritage, il peut y avoir, comme nous l'avons vu, plusieurs méthodes avec le meme nom définies dans
plusieurs classe. Laquelle appelée ? Python choisit, si'il trouve, celle définit directement dans la classe, et sinon parcourt la
hiérarchie de l'héritage jusqu'à tomber sur la méthode.

Le polymorphisme est le concept qui permet d’avoir différentes formes d’une méthode. Entre autres, il permet de
redéfinir des méthodes avec des fonctionnalités similaires.

Exemple : Héritage (Personne, employé et chef)


Définir les classes suivantes:

1. Une classe DateNaissance avec trois attributs, jour, mois, année et une méthode ToString qui convertit la date de
naissance en chaine de caractères

In [ ]: class DateNaissance:
"Classe DateNaissance"
def __init__(self,jour,mois,annee):

27
[Link]=jour
[Link]=mois
[Link]=annee

def ToString(self):
"""Méthode qui convertit la date de naissance en chaine de caractère"""
return f"{[Link]},{[Link]},{[Link]}"

1. Une classe Personne avec trois attributs, nom, prénom et date de naissance et une méthode polymorphe Afficher pour
afficher les données de chaque personne.

In [ ]: class personne:#la classe mère


def __init__(self,nom,prenom,date_naissance):
[Link]=nom
[Link]=prenom
self.date_naissance=date_naissance

def afficher(self):
print("Nom:%s \nPrénom: %s \nDate de naissance: %s"%([Link],[Link],self.date_naissance.

1. Une classe Employé qui dérive de la classe Personne, avec en plus un attribut Salaire et la redéfinition de la méthode
Afficher.

In [ ]: class employe(personne):#employe est une classe fille qui hérite de la classe mère personne

#redéfinir le constructeur "Polymorphisme d'héritage"


def __init__(self,nom,prenom,date_naissance,salaire):
"""Instanciation de la classe mère (appeler le constructeur de la classe
mère dans le constructeur de la classe fille)"""
personne.__init__(self,nom,prenom,date_naissance)
[Link]=salaire

[Link](self)
print("Salaire: %.02f"%[Link])
M
def afficher(self):#redéfinir la méthode polymorphe Afficher

1. Une classe Chef qui dérive de la classe Employé, avec en plus un attribut Service et la redéfinition de la méthode
Afficher.
FS
In [ ]: """chef est une classe fille de la classe mère employe qui est une classe fille
de la classe personne"""
class chef(employe):
def __init__(self,nom,prenom,date_naissance,salaire,service):
employe.__init__(self,nom,prenom,date_naissance,salaire)
[Link]=service
def afficher(self):
[Link](self)
print("Service: %s"%[Link])

In [ ]: P=personne("Ilyass","tounsi",DateNaissance(1,7,1982))
[Link]()

Nom:Ilyass
Prénom: tounsi
Date de naissance: 01 / 07 / 1982

In [ ]: E=employe("youssef","tounsi",DateNaissance(1,7,1985),1500.000)
[Link]()

Nom:youssef
Prénom: tounsi
Date de naissance: 01 / 07 / 1985
Salaire: 1500.00

In [ ]: Ch=chef("Chahine","tounsi",DateNaissance(3,5,1978),3500.000,"Ressource humaine")
[Link]()

Nom:Chahine
Prénom: tounsi
Date de naissance: 03 / 05 / 1978
Salaire: 3500.00
Service: Ressource humaine

Application : Pile(Stack) & File(Queue)


28
1. Une Pile(Stack)

Une Pile(Stack) est une structure de données qui permet de représenter une collection d’éléments.
L’ajout/retrait des éléments dans cette collection doit suivre l’ordre : Premier Entré Dernier Sorti (First In Last Out).

La pile est une structure de données qui ne permet que deux opérations :
empiler un élément, qui consiste à ajouter un élément en haut de la pile;
dépiler un élément, qui consiste à retirer le dernier élément empilé et à lire son contenu.
Pour représenter l'état de la pile, on la considère comme une liste. Le sommet de la pile est le dernier élément ajouté.

La notion d'indice n'intervient pas dans l'utilisation d'une pile car on ne fait pas d'accès aléatoire aux éléments.
M
Implémentation de la classe Pile
Les insertions retraits doivent avoir lieu dans la même extrémité de la liste. Nous choisissions, la queue de la liste, ainsi
nous empilons un nouvel élément en appelant la méthode [Link] et nous dépilons via la méthode prédéfinie
FS
[Link]().

In [ ]: class Pile:
def __init__(self):

self.L =[]
def sommet(self):
if self.est_vide():
raise Exception("Pile vide")
else:
return self.L[-1]

def est_vide(self):

return len(self.L)==0
# return self.L== []

def __len__(self):

return len(self.L)

def empiler(self, item):

[Link](item)

def depiler(self):

if self.est_vide() :
raise Exception("Erreur ")
else :
[Link](len(self.L)-1)
#[Link](-1)
#[Link]()

def __str__(self):

29
return str(self.L)

In [ ]: p= Pile()
[Link](1)
[Link](2)
[Link](3)
[Link]()

[Link]()
len(p)

2
Out[ ]:

In [ ]: L=[1,2,3]
str(L)

'[1, 2, 3]'
Out[ ]:

In [ ]: print(p)

[1, 2, 3]

In [ ]: L=[1,2,3]
print(L)

[1, 2, 3]

Applications des piles

Exercice 1 : Expression bien parenthésée.

Nous supposons qu’une expression mathématique est donnée sous forme d’un texte (une instance de la classe str) qui
comporte 3 types de parenthèses :
M
• les parenthèses : ouvrante ( et fermante )
• les crochets : ouvrant [ et fermant ]
• les accolades : ouvrante { et fermante }
FS
Nous nous intéressons à vérifier la parenthétisation d’une expression, pour ce faire il faut examiner l’ordre d’apparition des
parenthèses ouvrantes ([ { et fermantes )]}. Pour chaque occurrence d’une paire fermante, il faut aller vers la dernière paire
ouvrante non encore vérifiée, 3 cas se présentent ainsi :

1. aucune paire ouvrante n’est disponible ⇒ expression mal parenthésée


2. une paire ouvrante est disponible, mais cette paire est non compatible avec la paire fermante rencontrée ⇒ l’expression
est mal parenthésée
3. une paire ouvrante compatible avec la paire fermante est rencontrée ⇒ continuer la vérification des autres paires

4. Aussi à la fin de la vérification il faut examiner s’il existe des paires ouvrantes pour lesquels aucune paire fermante n’a
été rencontrée.

En utilisant une instance de la classe Pile, écrire une fonction permettant de vérifier la parenthétisation d’une expression
passée en entrée sous forme de str.

In [ ]: correspondantes = {")":"(","}":"{","]":"["}
ouvrantes= {"{", "(", "["}
fermantes= {"}", ")", "]"}

def prenthesage(expr):

p=pile()
for c in expr :
if c in ouvrantes :
[Link](c)

elif c in fermantes:
f=c
try :
s=[Link]()
except:
return False

30
if correspondantes[f]==s :
[Link]()
else :
return False
if p.est_vide() :
return True
else :
return False

In [ ]: expr= '({([{}])'
prenthesage(expr)

False
Out[ ]:

2. Une File(Queue)

Une File(Queue) est est une structure de données qui permet de représenter une collection d’éléments.

L’ajout/retrait des éléments dans cette collection doit suivre l’ordre : Premier Entré Premier Sorti (First In First Out).

Une nouvelle arrivée est placée en queue (à la fin) de la liste et doit attendre que tous les éléments précédents soient
servis afin d’être servie à son tour.

M
FS

Implémentation de la classe File

In [ ]: class File:
def __init__(self):
self.L= list()

def __len__(self):

return len(self.L)

def __str__(self):

return str(self.L)

def est_vide(self):

return self.L == [ ]

def sommet(self):

return self.L[0]

def enfiler(self, item):

[Link](item)

def defiler(self):

if self.est_vide() :

31
raise Exception("Erreur ")
else :
return [Link](0)

In [ ]: F= File()
[Link](1)
[Link](2)
[Link](3)

In [ ]: [Link]()

1
Out[ ]:

In [ ]: F.est_vide()

False
Out[ ]:

In [ ]: print(F)

[2, 3]

M
FS

32
Faculté des Sciences de Monastir

Informatique des Classes Préparatoires: MP2/PC2

Enseignant: Jaafar CHAAOURI

2ème Partie :

Simulation numérique
avec Python
Objectifs du cours

1. Savoir exploiter les modules de calcul numérique (numpy, scipy & matplotlib).
2. Implémenter les algorithmes standards de réduction et de décomposition matricielle.
M
3.
4.
5.
Implémenter les algorithmes standards d’intégration numérique et de résolution d’équations différentielles.
Implémenter les algorithmes standards de recherche approximative de zéro d’une fonction non linéaire à une ou à plusieurs inconnues.
Initiation au traitement d’images numériques.

Numerical Python Stack


FS
Python core : objets natifs haut niveau :
Numériques : bool, int, float, complex.
Itérables : str, list, tuple, set, frozenset, dict.

NumPy

NumPy est une extension du langage de programmation Python, destinée à manipuler des matrices ou des tableaux multidimensionnels ainsi
que des fonctions mathématiques opérant sur ces tableaux.
Cette bibliothèque logicielle libre et open source fournit de multiples fonctions permettant de manipuler des vecteurs, matrices et polynômes.
NumPy est la base de SciPy, regroupement de bibliothèques Python autour du calcul scientifique.

scipy "SCIentific PYthon" module offrant des fonctionnalités de calcul scientifique :

[Link] : calcul approché d'intégrales, résolution numérique d'ode.

[Link] : optimisation, recherche approchée du zéro de système non linéaire.

[Link] : traitement des images numériques, filtrage, convolution, etc.


</dd>

33
matplotlib : module de visualisation des données : traçage des courbes, visualisation d'images 2 ou 3D, etc.
</dl>

Chapitre 1 : NumPy
1. Démarrer avec Numpy
2. Les fonctions fabriques d' ndarray
3. Avantages des ndarrays par rapport aux itérables natifs :
4. Les propriétés "interessantes" d'un ndarray :
5. Quelques méthodes prédéfinies sur les ndarray:
6. Algèbre linéaire avec numpy

1. Démarrer avec Numpy

Objectifs :

Comprendre la différence entre les tableaux à une, deux et n dimensions dans NumPy;
Comprendre les propriétés des axes et des formes des tableaux à n dimensions.
Comprendre comment appliquer certaines opérations d'algèbre linéaire à des tableaux à n dimensions sans utiliser de boucles for;

M In [ ]: import numpy as np
print(np.__version__)

In [ ]: np.
1.18.5

Utilisez l'auto-complétion pour lister les objets numpy :

In [ ]: [Link].
FS
La rubrique d'aide est également précieuse

In [ ]: ?[Link]

Motivation : Numpy est plus rapide que les listes !

Voici quelques motivations avant de discuter les détails, soulignant pourquoi il est utile d'apprendre et d'utiliser NumPy. Nous examinons une
comparaison de perfermance pour le calcul du produit scalaire de deux vecteurs en Python :

1ère démarche en utilisant des listes,


2ème demarche avec la fonction de produit scalaire de NumPy.

Mathématiquement, le produit scalaire entre deux vecteurs x et w peut s'écrire comme suit:


z = ∑ x i wi = x 1 × w1 + x 2 × w2 +. . . +x n × wn = x w

Tout d'abord, l'implémentation Python utilisant une boucle for:

34
In [ ]: def python_forloop_list_approach(x, w):
z = 0.
for i in range(len(x)):
z += x[i] * w[i]
return z

a = [1., 2., 3.]


b = [4., 5., 6.]

print(python_forloop_list_approach(a, b))

32.0

Calculons le runtime pour deux vecteurs plus grands (1000 éléments) en utilisant la fonction %timeit d'IPython:

In [ ]: large_a = list(range(1000))
large_b = list(range(1000))

%timeit python_forloop_list_approach(large_a, large_b)

10000 loops, best of 3: 103 µs per loop

Ensuite, nous utilisons la méthode dot implémentée dans NumPy pour calculer le produit scalaire entre deux vecteurs et exécuter par la suite: %
timeit

In [ ]: import numpy as np

def numpy_dotproduct_approach(x, w):

M # same as [Link](x, w)
# and same as x @ w
return [Link](w)

a = [Link]([1., 2., 3.])


b = [Link]([4., 5., 6.])

print(numpy_dotproduct_approach(a, b))

32.0

In [ ]: large_a = [Link](1000)
large_b = [Link](1000)
FS
%timeit numpy_dotproduct_approach(large_a, large_b)

The slowest run took 19.15 times longer than the fastest. This could mean that an intermediate re
sult is being cached.
1000000 loops, best of 3: 1.54 µs per loop

Comme nous pouvons le voir, le remplacement de la boucle for par la fonction dot de NumPy rend le calcul du produit scalaire de deux vecteurs
environ 100 fois plus rapide.

2. Les fonctions fabriques d' ndarray

L’objet principal de NumPy est le tableau multidimensionnel homogène. C'est une table d'éléments (généralement des nombres), tous du même type,
indexés par un tuple d'entiers non négatifs. Dans NumPy, les dimensions sont appelées axes.

instantiation de ndarray
Le constructeur de la classe peut être invoqué pour construire des instances de vecteurs n-dimensionnels. Les paramètres principaux sont :

shape : un tuple d'entiers positifs qui indique le nombre d'éléménts par dimension.
dtype : le type des éléments du tableau ⇒ Les ndarray sont des vecteurs n-dimensionnels contenant des valeurs de même type.

35
In [ ]: import numpy as np
a3 = [Link](shape=(4,3,2))
a3

Out[ ]: array([[[2.4427301e-316, 0.0000000e+000],


[0.0000000e+000, 0.0000000e+000],
[0.0000000e+000, 0.0000000e+000]],

[[0.0000000e+000, 0.0000000e+000],
[0.0000000e+000, 0.0000000e+000],
[0.0000000e+000, 0.0000000e+000]],

[[0.0000000e+000, 0.0000000e+000],
[0.0000000e+000, 0.0000000e+000],
[0.0000000e+000, 0.0000000e+000]],

[[0.0000000e+000, 0.0000000e+000],
[0.0000000e+000, 0.0000000e+000],
[0.0000000e+000, 0.0000000e+000]]])

In [ ]: a2 = [Link](shape= (3,2), dtype= [Link])


a2

Out[ ]: array([[2.44083291e-316+2.22809558e-312j,
2.44029516e-312+2.31297541e-312j],
[2.18565567e-312+2.10077583e-312j,
2.29175545e-312+2.33419537e-312j],
[1.29441743e-312+8.27578359e-313j,
8.70018274e-313+0.00000000e+000j]])

In [ ]: type(a2)

Out[ ]: [Link]
M
2.1 La fonction array :

Cette fonction permet de construire et d'initialiser un vecteur multi-dimensionnel à partir d'un itérable python.

Construction de vecteur à une seule dimension.

In [3]: import numpy as np


FS
# en utilisant la fonction [Link], on crée le tableau array([1, 2, 3, 4, 5])
v= [Link]([1,2,3,4,5])
v

Out[3]: array([1, 2, 3, 4, 5])

In [2]: # On vérifie son type


type(v)

Out[2]: [Link]

In [4]: # On affiche le type de ses éléments


[Link]

Out[4]: dtype('int64')

In [5]: # On affiche la taille mémoire (en octets) de chaque élément


[Link]

Out[5]: 8

In [7]: # On retourne un tuple indiquant la longueur de chaque dimension


[Link]

Out[7]: (5,)

In [8]: # On retourne le nombre total d'éléments


[Link]

Out[8]: 5

36
In [9]: # On retourne le nombre de dimensions
[Link]

Out[9]: 1

In [10]: # On retourne l'occupation mémoire


[Link]

Out[10]: 40

In [11]: # taille du vecteur V


len(v)

Out[11]: 5

Toujours utiliser shape ou size pour les tableaux numpy plutôt que len
len est réservé aux tableaux 1D

Construction de matrice. On donne une liste de listes, où les listes filles sont de même taille et représentent les lignes de la matrice résultante.

In [16]: m = [Link]([[1,2,3], [4,5,6]])


m

Out[16]: array([[1, 2, 3],


[4, 5, 6]])

M
FS
In [ ]: [Link]

Out[ ]: (2, 3)

In [ ]: [Link] # le type des éléments de la matrice

Out[ ]: dtype('int64')

In [ ]: [Link]

Out[ ]: 6

Construction d'un vecteur à 3-dimensions. Une liste de listes de listes...

37
In [ ]: import numpy as np
a3= [Link](
[
[
[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]
],
[
[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19]
],
[
[20, 21, 22, 23, 24],
[25, 26, 27, 28, 29]
],
]
)
a3

Out[ ]: array([[[ 0, 1, 2, 3, 4],


[ 5, 6, 7, 8, 9]],

[[10, 11, 12, 13, 14],


[15, 16, 17, 18, 19]],

[[20, 21, 22, 23, 24],


[25, 26, 27, 28, 29]]])

In [ ]: [Link]

Out[ ]: (3, 2, 5)

M
FS

2.2 Les fonctions de discretisation d'intervalles :


retournent des vecteurs à une seule dimension résultant du découpage d'un intervalle (continue) en un ensemble fini de points (échantillons).

La fonction arange

In [20]: #un vecteur d'entiers allant de 0 à 4. (la borne sup est exclue)
[Link](5)

Out[20]: array([0, 1, 2, 3, 4])

38
In [12]: # #un vecteur de flottants de 0. à 4.
[Link](5, dtype=float)

Out[12]: array([0., 1., 2., 3., 4.])

In [13]: # un vecteur d'entiers de 2 à 6.


[Link](2,7)

Out[13]: array([2, 3, 4, 5, 6])

In [ ]: # un vecteur de flottants avec incrément de 0.5.


[Link](2,6,0.5)

Out[ ]: array([2. , 2.5, 3. , 3.5, 4. , 4.5, 5. , 5.5, 6. , 6.5])

In [ ]: #découpage de l'intervalle [0,1[ suivant le pas 0.2


[Link](0,1,0.2)

Out[ ]: array([0. , 0.2, 0.4, 0.6, 0.8])

In [ ]: # range(0, 1, 0.2) #Erreur : range prend uniquement des valeurs entières comme arguments

In [ ]: #découpage de l'intervalle ]0,1] suivant le pas -0.1


[Link](1,0,-0.1)

Out[ ]: array([1. , 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1])

La fonction linspace :

permet d’obtenir un tableau 1D allant d’une valeur de départ à une valeur de fin avec un nombre donné d’éléments.
M In [ ]: [Link](0,1)

Out[ ]: array([0. ,
0.10204082,
0.20408163,
0.30612245,
0.40816327,
0.51020408,
0.6122449 ,
0.71428571,
0.02040816,
0.12244898,
0.2244898 ,
0.32653061,
0.42857143,
0.53061224,
0.63265306,
0.73469388,
0.04081633,
0.14285714,
0.24489796,
0.34693878,
0.44897959,
0.55102041,
0.65306122,
0.75510204,
0.06122449,
0.16326531,
0.26530612,
0.36734694,
0.46938776,
0.57142857,
0.67346939,
0.7755102 ,
0.08163265,
0.18367347,
0.28571429,
0.3877551 ,
0.48979592,
0.59183673,
0.69387755,
0.79591837,
0.81632653, 0.83673469, 0.85714286, 0.87755102, 0.89795918,
FS
0.91836735, 0.93877551, 0.95918367, 0.97959184, 1. ])

In [ ]: _.shape #par défaut découpe l'intervalle en 50 pts équidistants

Out[ ]: (50,)

In [ ]: # 5 éléments régulièrement espacés entre 1 et 4, 1 et 4 inclus

Out[ ]: array([1. , 1.75, 2.5 , 3.25, 4. ])

In [ ]: # 10 éléments régulièrement espacés entre 0 et 1, 0 et 1 inclus

Out[ ]: array([0. , 0.11111111, 0.22222222, 0.33333333, 0.44444444,


0.55555556, 0.66666667, 0.77777778, 0.88888889, 1. ])

In [ ]: _.shape #10 pts équidistants

Out[ ]: (10,)

La fonction logspace :

découpage d'un intervalle selon une échelle logarithmique (par défaut en base 10).

39
In [16]: # 50 éléments espacés entre 10**0 et 10**1
[Link](0,1)

Out[16]: array([ 1. , 1.04811313, 1.09854114, 1.1513954 , 1.20679264,


1.26485522, 1.32571137, 1.38949549, 1.45634848, 1.52641797,
1.59985872, 1.67683294, 1.75751062, 1.84206997, 1.93069773,
2.02358965, 2.12095089, 2.22299648, 2.32995181, 2.44205309,
2.55954792, 2.6826958 , 2.8117687 , 2.9470517 , 3.0888436 ,
3.23745754, 3.39322177, 3.55648031, 3.72759372, 3.90693994,
4.09491506, 4.29193426, 4.49843267, 4.71486636, 4.94171336,
5.17947468, 5.42867544, 5.68986603, 5.96362332, 6.25055193,
6.55128557, 6.86648845, 7.19685673, 7.54312006, 7.90604321,
8.28642773, 8.68511374, 9.10298178, 9.54095476, 10. ])

In [17]: # 5 éléments régulièrement espacés entre 10^1 et 10^4


[Link](1,4,5)

Out[17]: array([ 10. , 56.23413252, 316.22776602, 1778.27941004,


10000. ])

Consulter l'aide contextuelle pour plus de fonctionnalités

In [ ]: ?[Link]()

2.3 Vecteurs n-dimensionnels homogènes :

zeros & ones :


M
permettent de générer des vecteurs formés par des 0 ou des 1.

In [19]: # générer un vecteur de 10 entiers comportant des zéros


[Link](shape=(10,), dtype=[Link])

Out[19]: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])

In [20]: # générer une matrice 5x5 formée par des 0.


[Link]((5,5))

Out[20]: array([[0., 0., 0., 0., 0.],


FS
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]])

In [21]: # utiliser la fonction [Link] pour générer une matrice 3x3 formée par des nombres complexes.
[Link]((3,3),[Link])

Out[21]: array([[1.+0.j, 1.+0.j, 1.+0.j],


[1.+0.j, 1.+0.j, 1.+0.j],
[1.+0.j, 1.+0.j, 1.+0.j]])

In [23]: # utiliser la fonction [Link] pour générer un ndarray de shape = (3,4,2)


[Link](shape=(3,4,2))

Out[23]: array([[[1., 1.],


[1., 1.],
[1., 1.],
[1., 1.]],

[[1., 1.],
[1., 1.],
[1., 1.],
[1., 1.]],

[[1., 1.],
[1., 1.],
[1., 1.],
[1., 1.]]])

La fonction full :

40
[Link] Return a new array filled with a fill_value.

In [24]: # générer une matrice d'entiers de taille 5x5 avec fill_value=3


m= [Link]((5,5),fill_value=3)

Out[24]: array([[3, 3, 3, 3, 3],


[3, 3, 3, 3, 3],
[3, 3, 3, 3, 3],
[3, 3, 3, 3, 3],
[3, 3, 3, 3, 3]])

In [ ]: [Link]

Out[ ]: (5, 5)

In [ ]: m+ (1+2j)

Out[ ]: array([[4.+2.j, 4.+2.j, 4.+2.j, 4.+2.j, 4.+2.j],


[4.+2.j, 4.+2.j, 4.+2.j, 4.+2.j, 4.+2.j],
[4.+2.j, 4.+2.j, 4.+2.j, 4.+2.j, 4.+2.j],
[4.+2.j, 4.+2.j, 4.+2.j, 4.+2.j, 4.+2.j],
[4.+2.j, 4.+2.j, 4.+2.j, 4.+2.j, 4.+2.j]])

In [ ]: [Link](m)

Out[ ]: array([[-0.9899925, -0.9899925, -0.9899925, -0.9899925, -0.9899925],


[-0.9899925, -0.9899925, -0.9899925, -0.9899925, -0.9899925],
[-0.9899925, -0.9899925, -0.9899925, -0.9899925, -0.9899925],
[-0.9899925, -0.9899925, -0.9899925, -0.9899925, -0.9899925],
[-0.9899925, -0.9899925, -0.9899925, -0.9899925, -0.9899925]])

M In [ ]: #en utilisant la méthode [Link] générer une matrice de taille 5x5


# avec dtype= [Link] et fill_value=3+2j

Out[ ]: array([[3.+2.j, 3.+2.j, 3.+2.j, 3.+2.j],


[3.+2.j, 3.+2.j, 3.+2.j, 3.+2.j]])

In [ ]: # ou encore
[Link]((2,4)) * (3+2j)

Out[ ]: array([[3.+2.j, 3.+2.j, 3.+2.j, 3.+2.j],


[3.+2.j, 3.+2.j, 3.+2.j, 3.+2.j]])
FS
Les fabriques de matrices :

La matrice identité :

In [25]: # générer en utilisant la méthode [Link]() une matrice identité de taille 5


# I5
[Link](5)

Out[25]: array([[1., 0., 0., 0., 0.],


[0., 1., 0., 0., 0.],
[0., 0., 1., 0., 0.],
[0., 0., 0., 1., 0.],
[0., 0., 0., 0., 1.]])

In [ ]: # la meme matrice en spécifiant dtype = [Link]


[Link](5,dtype=[Link])

Out[ ]: array([[1, 0, 0, 0, 0],


[0, 1, 0, 0, 0],
[0, 0, 1, 0, 0],
[0, 0, 0, 1, 0],
[0, 0, 0, 0, 1]])

In [ ]: # en utilisant la méthode [Link]() générer une matrice identité de taille 4 avec dtype=np.b
ool
[Link](4,[Link])

Out[ ]: array([[ True, False, False, False],


[False, True, False, False],
[False, False, True, False],
[False, False, False, True]])

41
La fonction eye

The eye() method of Python numpy class returns a 2-D array with ones on the diagonal and zeros elsewhere.

In [ ]: [Link](3) #[Link](3)

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


[0., 1., 0.],
[0., 0., 1.]])

In [26]: #remplir par des 1 la diagonale au dessous de la diagonale principale


[Link](3,k=-1)

Out[26]: array([[0., 0., 0.],


[1., 0., 0.],
[0., 1., 0.]])

In [ ]: #remplir par des 1 la diagonale au dessus de la diagonale principale


[Link](3, k=1)

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


[0., 0., 1.],
[0., 0., 0.],
[0., 0., 0.]])

In [27]: #remplir par des 1 la diagonale au dessus de la diagonale principale


# d'une matrice de taille 5x10
[Link](5,10,k=1)

M Out[27]: array([[0.,

La fonction diag :
[0.,
[0.,
[0.,
[0.,

prend deux arguments :


1.,
0.,
0.,
0.,
0.,
0.,
1.,
0.,
0.,
0.,
0.,
0.,
1.,
0.,
0.,
0.,
0.,
0.,
1.,
0.,
0.,
0.,
0.,
0.,
1.,
0.,
0.,
0.,
0.,
0.,
0.,
0.,
0.,
0.,
0.,
0.,
0.,
0.,
0.,
0.,
0.],
0.],
0.],
0.],
0.]])
FS
un ndarray a.
un entier k (par défaut = 0)
si a est de dimension 1 alors la fonction construit une matrice où sa diagonale numéro k est formée par les éléments du vecteur a.
si a est une matrice (dimension 2) alors la fonction extrait les éléments de la kième diagonale dans un vecteur unidimensionnel.

In [ ]: # construit une matrice où sa diagonale numéro k est formée par les éléments du vecteur v.
v= [Link]([1,5,7])
# par défaut k= 0

Out[ ]: array([[1, 0, 0],


[0, 5, 0],
[0, 0, 7]])

In [ ]: # extrait les éléments de la kième diagonale dans un vecteur unidimensionnel.

Out[ ]: array([1, 5, 7])

In [ ]: # construit une matrice où sa diagonale numéro k=-1 est formée par les éléments du vecteur v.
v=[Link]([1,2,3j])

Out[ ]: array([[0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],


[1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
[0.+0.j, 2.+0.j, 0.+0.j, 0.+0.j],
[0.+0.j, 0.+0.j, 0.+3.j, 0.+0.j]])

In [ ]: [Link](_,2)

Out[ ]: array([0.+0.j, 0.+0.j])

Vecteur en fonction de ses indices

42
In [ ]: f=lambda i,j : i-j
[Link](f, (3,3))

Out[ ]: array([[ 0., -1., -2.],


[ 1., 0., -1.],
[ 2., 1., 0.]])

In [ ]: [Link](lambda i : i **2 , (10,))

Out[ ]: array([ 0., 1., 4., 9., 16., 25., 36., 49., 64., 81.])

In [ ]: [Link](lambda i, j: i == j, (3, 3), dtype=int)

Out[ ]: array([[ True, False, False],


[False, True, False],
[False, False, True]])

In [ ]: [Link](lambda i, j: i + j, (3, 3), dtype=int)

Out[ ]: array([[0, 1, 2],


[1, 2, 3],
[2, 3, 4]])

Identifier et corriger l'erreur ci-dessous

In [ ]: f= lambda i,j : 1 if i == j else 0


[Link](f, (5,5)) # Erreur

---------------------------------------------------------------------------
ValueError Traceback (most recent call last)

M <ipython-input-35-755559699094> in <module>()
1 f= lambda i,j : 1 if i == j else 0
----> 2 [Link](f, (5,5)) # Erreur

/usr/local/lib/python3.6/dist-packages/numpy/core/[Link] in fromfunction(function, shape, **k


wargs)
1777
1778
-> 1779
1780
1781
dtype = [Link]('dtype', float)
args = indices(shape, dtype=dtype)
return function(*args, **kwargs)

<ipython-input-35-755559699094> in <lambda>(i, j)
FS
----> 1 f= lambda i,j : 1 if i == j else 0
2 [Link](f, (5,5)) # Erreur

ValueError: The truth value of an array with more than one element is ambiguous. Use [Link]() or
[Link]()

3. Avantages des ndarrays par rapport aux itérables natifs :

Les différences entre tableaux Numpy et listes Python :

un ndarray a une taille fixée à la création


un ndarray est composé d'éléments du même type
les opérations sur les tableaux sont réalisées par des routines C pré-compilées et optimisées (éventuellement parallèles)

In [ ]: import numpy as np
l = [1,2,3]
a = [Link](l)
a

Out[ ]: array([1, 2, 3])

In [ ]: [Link]()

Out[ ]: [1, 2, 3]

43
In [ ]: l + 1
# TypeError

---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-4-b0c55dc7f7d3> in <module>()
----> 1 l + 1
2 # TypeError

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

In [ ]: l + l # concaténation de séquences(list dans notre cas) avec l'opératuer +

Out[ ]: [1, 2, 3, 1, 2, 3]

In [ ]: l * 3 # duplication de séquences(list dans notre cas) avec l'opératuer +

Out[ ]: [1, 2, 3, 1, 2, 3, 1, 2, 3]

In [ ]: a

Out[ ]: array([1, 2, 3])

In [ ]: a + 1 # l'opérateur addition est vectorisé

Out[ ]: array([2, 3, 4])

In [ ]: a

Out[ ]: array([1, 2, 3])

In [ ]: a**2
M Out[ ]: array([1, 4, 9])

In [ ]: a + a

Out[ ]: array([2, 4, 6])

In [ ]: [Link](a-0.1)

Out[ ]: array([-0.10536052, 0.64185389, 1.06471074])


FS
In [ ]: # import math
# [Link](a)
#Erreur

In [ ]: [Link](a)

Out[ ]: array([ 0.54030231, -0.41614684, -0.9899925 ])

Les ndarry supporent les opérateurs Python natifs (+, - , * ...), ainsi qu'un ensemble de fonction mathématiques vectorisées disponibles dans le
module numpy ([Link], [Link], [Link] ...).

Fonctions vectorisées :

Application 1 :

Nous allons construire une fonction signe, permettant de calculer le singe d'une valeur
⎧1 si x > 0

⎨0 si x = 0

−1 sinon.

In [ ]: a

Out[ ]: array([1, 2, 3])

44
In [ ]: def signe(x):
if x == 0:
return 0
elif x > 0:
return 1
else:
return -1

In [ ]: f(a)

---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-34-730f2a0fa0b7> in <module>()
----> 1 f(a)

TypeError: <lambda>() missing 1 required positional argument: 'j'

In [ ]: fv = [Link](signe)

In [ ]: fv(a)

Out[ ]: array([1, 1, 1])

In [ ]: c = [Link]([[1,-1,0], [1,-1,-330]])

In [ ]: signe(c) # Erreur

In [ ]: signe_v = [Link](signe)

In [ ]: c
M Out[ ]: array([[
[

In [ ]: signe_v(c)
1,
1,

Out[ ]: array([[ 1, -1, 0],


[ 1, -1, -1]])
-1, 0],
-1, -330]])

Application 2 :
FS
In [ ]:
f = lambda i,j : 1 if i==j else 0
fv= [Link](f)
[Link](fv, (5,5))

Out[ ]: array([[1, 0, 0, 0, 0],


[0, 1, 0, 0, 0],
[0, 0, 1, 0, 0],
[0, 0, 0, 1, 0],
[0, 0, 0, 0, 1]])

In [ ]: [Link]([Link](lambda i,j : 1 if i == j else 0), (5,5))

Out[ ]: array([[1, 0, 0, 0, 0],


[0, 1, 0, 0, 0],
[0, 0, 1, 0, 0],
[0, 0, 0, 1, 0],
[0, 0, 0, 0, 1]])

Application 3 :

In [ ]: import math
def xlogx(x):
if x == 0:
return x
else:
return x * [Link](x)

45
In [ ]: a = [Link]([0,1,2,1,3], dtype= [Link])
xlogx = [Link](xlogx)
xlogx(a)

Out[ ]: array([0. , 0. , 1.38629436, 0. , 3.29583687])

4. Les propriétés "interessantes" d'un ndarray :

Les propriétés : shape, size et ndim

Deux relations invariantes :


[Link]−1
a. size = ∏ a. shape[i]
i=0
{
a. ndim = len(a. shape)

In [ ]: import numpy as np
a = [Link](0,1, num = 100)

shape donne un tuple contenant le nombre d'éléments par dimension. Cette propriété est en lecture /écriture.

In [ ]: [Link]

Out[ ]: (100,)

In [ ]: [Link] = 3

M ---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-13-4b87fd34d906> in <module>()
----> 1 [Link] = 3

AttributeError: attribute 'ndim' of '[Link]' objects is not writable

In [ ]: [Link] = (5,5,4)

In [ ]: a
FS
Out[ ]: array([[[0. , 0.01010101, 0.02020202, 0.03030303],
[0.04040404, 0.05050505, 0.06060606, 0.07070707],
[0.08080808, 0.09090909, 0.1010101 , 0.11111111],
[0.12121212, 0.13131313, 0.14141414, 0.15151515],
[0.16161616, 0.17171717, 0.18181818, 0.19191919]],

[[0.2020202 , 0.21212121, 0.22222222, 0.23232323],


[0.24242424, 0.25252525, 0.26262626, 0.27272727],
[0.28282828, 0.29292929, 0.3030303 , 0.31313131],
[0.32323232, 0.33333333, 0.34343434, 0.35353535],
[0.36363636, 0.37373737, 0.38383838, 0.39393939]],

[[0.4040404 , 0.41414141, 0.42424242, 0.43434343],


[0.44444444, 0.45454545, 0.46464646, 0.47474747],
[0.48484848, 0.49494949, 0.50505051, 0.51515152],
[0.52525253, 0.53535354, 0.54545455, 0.55555556],
[0.56565657, 0.57575758, 0.58585859, 0.5959596 ]],

[[0.60606061, 0.61616162, 0.62626263, 0.63636364],


[0.64646465, 0.65656566, 0.66666667, 0.67676768],
[0.68686869, 0.6969697 , 0.70707071, 0.71717172],
[0.72727273, 0.73737374, 0.74747475, 0.75757576],
[0.76767677, 0.77777778, 0.78787879, 0.7979798 ]],

[[0.80808081, 0.81818182, 0.82828283, 0.83838384],


[0.84848485, 0.85858586, 0.86868687, 0.87878788],
[0.88888889, 0.8989899 , 0.90909091, 0.91919192],
[0.92929293, 0.93939394, 0.94949495, 0.95959596],
[0.96969697, 0.97979798, 0.98989899, 1. ]]])

In [ ]: [Link]

Out[ ]: 3

46
La propriété shape permet de changer la forme du vecteur mais pas sa taille totale !!!

In [ ]: # [Link] = (10,10,10)
#Erreur

La propriété dtype , en lecture seule. Cette propriété nous renseigne sur le type des éléments du vecteur.

In [ ]: [Link]

Out[ ]: dtype('float64')

In [ ]: a = [Link]([[2+2j, 3, 0], [3, 5j, 1j]])

In [ ]: [Link]

Out[ ]: dtype('complex128')

Les propriétés size et ndim (en lecture seule).

In [ ]: [Link] # la taille totale du tableau

Out[ ]: 6

In [ ]: [Link]

Out[ ]: 2

M In [ ]: [Link]

Out[ ]: (2, 3)

Exemple 1:
FS
In [ ]: z= [Link]([
[2.+2.j, 3.+0.j, 0.+0.j],
[3.+0.j, 0.+5.j, 0.+1.j]
])
z

Out[ ]: array([[2.+2.j, 3.+0.j, 0.+0.j],


[3.+0.j, 0.+5.j, 0.+1.j]])

In [ ]: [Link]

Out[ ]: array([[2., 3., 0.],


[3., 0., 0.]])

In [ ]: [Link]

Out[ ]: array([[2., 0., 0.],


[0., 5., 1.]])

In [ ]: [Link] = 5

In [ ]: z

Out[ ]: array([[2.+5.j, 3.+5.j, 0.+5.j],


[3.+5.j, 0.+5.j, 0.+5.j]])

In [ ]: [Link] = [Link](2,3, k= 1)

In [ ]: z

Out[ ]: array([[2.+0.j, 3.+1.j, 0.+0.j],


[3.+0.j, 0.+0.j, 0.+1.j]])

47
In [ ]: z.T #transposée du vecteur

Out[ ]: array([[2.+0.j, 3.+0.j],


[3.+1.j, 0.+0.j],
[0.+0.j, 0.+1.j]])

Exemple 2:

In [ ]: a=[Link](6)
#[Link]=(3,2)
a

Out[ ]: array([0, 1, 2, 3, 4, 5])

In [ ]: [Link](a)

Out[ ]: array([ 1. , 0.54030231, -0.41614684, -0.9899925 , -0.65364362,


0.28366219])

In [ ]: [Link] = (2,3)
a

Out[ ]: array([[0, 1, 2],


[3, 4, 5]])

In [ ]: [Link]()

Out[ ]: array([[0, 3],


[1, 4],
[2, 5]])

M In [ ]: [Link] = (3,1)
# Erreur

---------------------------------------------------------------------------
ValueError

----> 1 [Link] = (3,1)


2 # Erreur
Traceback (most recent call last)
<ipython-input-44-fc2819e14055> in <module>()

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


FS
Exemple 3:

In [ ]: a = [Link](3)
b = [Link](1,5,9).reshape(3,3)

In [ ]: a

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


[0., 1., 0.],
[0., 0., 1.]])

In [ ]: b

Out[ ]: array([[1. , 1.5, 2. ],


[2.5, 3. , 3.5],
[4. , 4.5, 5. ]])

In [ ]: a*b #opération élémentaire terme-à-terme

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


[0., 3., 0.],
[0., 0., 5.]])

In [ ]: [Link](b)

Out[ ]: array([[1. , 1.5, 2. ],


[2.5, 3. , 3.5],
[4. , 4.5, 5. ]])

5. Quelques méthodes prédéfinies sur les ndarray:

48
La méthode trace

permet de calculer la trace (où les traces) d'un ndarray de dimension > 1 :

In [ ]: a = [Link]((10,))

In [ ]: # [Link]()
# Erreur

In [ ]: a = [Link]((5,5))

In [ ]: [Link]()

Out[ ]: 5.0

In [ ]: a = [Link]((5,5,5))

In [ ]: [Link]()

Out[ ]: array([5., 5., 5., 5., 5.])

La méthode transpose :
Elle retourne le même résultat que la propriété a.T

M In [ ]: a = [Link](0,1,10).reshape((2,5))

In [ ]: a

Out[ ]: array([[0.

In [ ]: [Link]()

Out[ ]: array([[0.
, 0.11111111, 0.22222222, 0.33333333, 0.44444444],
[0.55555556, 0.66666667, 0.77777778, 0.88888889, 1.

,
[0.11111111,
0.55555556],
0.66666667],
]])

[0.22222222, 0.77777778],
FS
[0.33333333, 0.88888889],
[0.44444444, 1. ]])

Les méthodes : reshape, flatten, concatenate :

La méthode reshape : retourne une nouvelle instance de la classe ndarray contenant le tableau source avec la nouvelle forme.

In [ ]: a = [Link](10)

In [ ]: a

Out[ ]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

In [ ]: b = [Link]((2,5))

In [ ]: b

Out[ ]: array([[0, 1, 2, 3, 4],


[5, 6, 7, 8, 9]])

In [ ]: a

Out[ ]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

Le vecteur retourné par reshape, n'est pas une copie indépendante du vecteur initial mais partage la même zone mémoire que lui

In [ ]: a[0] = -100

49
In [ ]: a

Out[ ]: array([-100, 1, 2, 3, 4, 5, 6, 7, 8, 9])

In [ ]: b

Out[ ]: array([[-100, 1, 2, 3, 4],


[ 5, 6, 7, 8, 9]])

In [ ]: c = [Link]((2,5)).copy() #créer une copie indépendante de a

In [ ]: c

Out[ ]: array([[-100, 1, 2, 3, 4],


[ 5, 6, 7, 8, 9]])

In [ ]: b[0,0] = 100

In [ ]: b

Out[ ]: array([[100, 1, 2, 3, 4],


[ 5, 6, 7, 8, 9]])

In [ ]: a

Out[ ]: array([100, 1, 2, 3, 4, 5, 6, 7, 8, 9])

In [ ]: c

Out[ ]: array([[-100, 1, 2, 3, 4],


[ 5, 6, 7, 8, 9]])
M
La méthode flatten :

In [ ]: import numpy as np
lst= [[1,2,3],[4,5,6]]
ary = [Link](lst)
ary

Out[ ]: array([[1, 2, 3],


[4, 5, 6]])
FS
In [ ]: [Link]()

Out[ ]: array([1, 2, 3, 4, 5, 6])

La méthode [Link] Pour combiner deux tableaux ou plus, nous pouvons utiliser la fonction de concaténation de NumPy comme indiqué
dans les exemples suivants:

In [29]: ary = [Link]([[1, 2, 3]])

In [31]: # stack along the first axis


[Link](ary,ary))

Out[31]: array([[1, 2, 3],


[1, 2, 3]])

In [ ]: # stack along the first axis : axis=0


[Link](ary,ary),axis=0)

Out[ ]: array([[1, 2, 3],


[1, 2, 3]])

In [ ]: # stack along the second axis : axis=1


[Link](ary,ary),axis=1)

Out[ ]: array([[1, 2, 3, 1, 2, 3]])

[Link]

Calcul de produit scalaire (pour les vecteurs unidimensionnels). Produit matriciel pour les vecteurs de diemsnion ≥ 2.

50
Exemple 1:

In [33]: v1 = [Link]([1,2,3,4])
v2 = [Link]([1,0,1,0])

In [34]: # produit terme à terme


v1*v2

Out[34]: array([1, 0, 3, 0])

In [35]: #produit scalaire


[Link](v2) # ou bien [Link](v1)

Out[35]: 4

Exemple 2:

In [37]: m = [Link]([1,2,3,4])
n = [Link]((4,4))
print(m)
print(n)

[[1 0 0 0]
[0 2 0 0]
[0 0 3 0]
[0 0 0 4]]
[[1. 1. 1. 1.]
[1. 1. 1. 1.]
[1. 1. 1. 1.]

M [1. 1.

# ou bien m @ n

Out[38]: array([[1.,
[2.,
[3.,
[4.,
1. 1.]]

In [38]: # Produit matriciel m @ n


[Link](n)

1.,
2.,
3.,
4.,
1.,
2.,
3.,
4.,
1.],
2.],
3.],
4.]])

In [39]: # Produit matriciel n @ m


FS
[Link](m)

Out[39]: array([[1., 2., 3., 4.],


[1., 2., 3., 4.],
[1., 2., 3., 4.],
[1., 2., 3., 4.]])

Exemple : 3

In [ ]: m1 = [Link]([[1,0,1,0]])
[Link]
m1

Out[ ]: array([[1, 0, 1, 0],


[2, 2, 2, 2]])

In [ ]: """
m1 = [Link]([1,0,1,0])
m2 = [Link]((4,3))
print([Link](m2))
print([Link](m1))
"""

# ValueError: shapes (4,3) and (4,) not aligned: 3 (dim 1) != 4 (dim 0)

[Link] :
C'est une fonction qui retourne le produit vectoriel.

51
In [40]: v1 = [Link]([1,2,3])
v2 = [Link]([1,0,1])
# calculer v3 le produit vectoriel de v1 et v2
v3 = [Link](v1,v2)

In [41]: # vérifier le produit sclaire des vecteurs v3 et v1


v3 @ v1

Out[41]: 0

In [42]: # vérifier le produit sclaire des vecteurs v3 et v2


v3 @ v2

Out[42]: 0

[Link] :
Permet de créer une nouvelle instance contenant les même valeurs que le vecteur source mais converties au type indiqué comme argument.

In [ ]: v1

Out[ ]: array([1, 2, 3])

In [ ]: [Link]([Link])

Out[ ]: array([1.+0.j, 2.+0.j, 3.+0.j])

M
Méthodes d'agrégation

[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
FS
[Link]
[Link]
[Link]
[Link]

Exemple 1: [Link], [Link]

In [43]: import numpy as np


a = [Link]([[67, 63, 87], [77, 69, 59], [85, 87, 99], [79, 72, 71],[63, 89, 93],[68, 92, 78]])

In [ ]: a

Out[ ]: array([[67, 63, 87],


[77, 69, 59],
[85, 87, 99],
[79, 72, 71],
[63, 89, 93],
[68, 92, 78]])

In [ ]: # Return the minimum along a given axis.


[Link](), [Link]() # [Link](a),[Link](a) equivalent functions

Out[ ]: (99, 59)

In [44]: # Return the maximum along axis 0


[Link](axis=0)

Out[44]: array([85, 92, 99])

52
In [45]: # Return the maximum along axis 1
[Link](axis=1)

Out[45]: array([87, 77, 99, 79, 93, 92])

Exemple 2: [Link]

In [ ]: import numpy as np

In [ ]: a=[Link]([[1.,2.],[3.,4.]])
[Link]() # [Link](a)

Out[ ]: 24.0

In [ ]: # [Link](a, axis=1)
[Link](axis=1)

Out[ ]: array([ 2., 12.])

Exemple 3 : [Link]()

In [ ]: [Link](axis=None)
# Renvoie la variance des éléments du tableau, une mesure de dispersion d'une distribution.
# La variance est calculée par défaut pour le tableau (flatten), sinon sur l'axe spécifié.
# La variance est la moyenne des carrés des écarts par rapport à la moyenne.

N
1 2

M In [ ]: a = [Link]([[1, 2], [3, 4]])


a

Out[ ]: array([[1, 2],

In [ ]: [Link]()

Out[ ]: 1.25
[3, 4]])
sN =
N
∑ (x i − x̄ )

i=1
FS
In [ ]: [Link](axis=0)

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

In [ ]: [Link](axis=1)

Out[ ]: array([0.25, 0.25])

[Link]()

In [ ]: # L'écart type est la racine carrée de la moyenne des carrés des écarts par rapport à la moyenne
a = [Link]([[1, 2], [3, 4]])
[Link]()

Out[ ]: 1.118033988749895

In [ ]: [Link]([Link]())

Out[ ]: 1.118033988749895

diffusion ou broadcasting
numpy interprète les opérations de la forme a opérateur b, où a et/ou b sont des instances de la classe ndarray comme suit :

Le vecteur ayant la taille la plus petite est diffusé dans le vecteur le plus large. Commençons par des exemples :

53
</figcaption></center> </figure>

In [ ]: # Exemple 1
[Link](3)+5

M Out[ ]: array([5, 6, 7])

In [46]: # Exemple 2
[Link]((3,3))+[Link](3)

Out[46]: array([[1., 2., 3.],


[1., 2., 3.],
[1., 2., 3.]])

In [47]: # Exemple 3
[Link](3).reshape((3,1))+ [Link](3)
FS
Out[47]: array([[0, 1, 2],
[1, 2, 3],
[2, 3, 4]])

Indexation et slicing

indexage 1D

In [49]: a = [Link](5)
a

Out[49]: array([0, 1, 2, 3, 4])

In [50]: [Link]

Out[50]: 5

In [52]: #Afficher le premier élément


print(a[0])

#Afficher le dernier
print(a[-1])

# print("a[[Link]]= ", a[[Link]]) #Erreur

0
4

54
indexage 2D

In [ ]: m = [Link]([1,2,3,4])
m

Out[ ]: array([[1, 0, 0, 0],


[0, 2, 0, 0],
[0, 0, 3, 0],
[0, 0, 0, 4]])

In [ ]: # Afficher la première ligne


m[0]

# Afficher la dernière ligne


m[-1]

m[0] = [1 0 0 0]
m[-1] = [0 0 0 4]

In [ ]: # Afficher l'élément : première ligne première colonne


print('m[0,0]=',m[0,0])

# Afficher l'élément : 4ième ligne dernière colonne


print('m[3,-1]=',m[3,-1])

m[0,0] = 1
m[3,-1] = 4

slicing
M
Pour les tableaux unidimensionnels, les règles de slicing sont les mêmes que pour les listes. Pour les tableaux multidimensionnels numpy, le slicing
permet d'extraire des séquences dans n'importe quelle direction. a[dep:fin:pas]

Exemple 1

In [53]: a = [Link](9).reshape(3, 3)

In [54]: print(a)
# Notez l'effet de la méthode reshape()
FS
[[0 1 2]
[3 4 5]
[6 7 8]]

In [57]: # Retourne la 3ème ligne


a[2]

Out[57]: array([6, 7, 8])

In [ ]: # Retourne la deuxième colonne


a[:,1]

Out[ ]: array([1, 4, 7])

In [58]: # Retourne le vecteur array([4, 7])


a[1:,1]

Out[58]: array([4, 7])

Exemple 2 :

In [ ]: a1 = [Link]([[10, 11, 12, 13, 14],


[15, 16, 17, 18, 19],
[20, 21, 22, 23, 24],
[25, 26, 27, 28, 29]])
# découper le tableau suivant :
# [[17 18]
# [22 23]
# [27 28]

55
Exemple : 3

In [59]: v = [Link](5)
v

Out[59]: array([0, 1, 2, 3, 4])

In [ ]: #inverser l'ordre des éléments de v


v[::-1]

Out[ ]: array([4, 3, 2, 1, 0])

In [60]: #Afficher les éléments de v avec pas de 2


v[::2]

Out[60]: array([0, 2, 4])

In [61]: m = [Link]([1,2,3,4])
m

Out[61]: array([[1, 0, 0, 0],


[0, 2, 0, 0],
[0, 0, 3, 0],
[0, 0, 0, 4]])

In [62]: #première colonne à partir de la deuxième ligne


m[1:,0]

Out[62]: array([0, 0, 0])

MIn [63]: #première colonne de bas en haut


m[::-1,0]

Out[63]: array([0, 0, 0, 1])

In [64]: #inverser les lignes de m


m[::-1]

Out[64]: array([[0,
[0,
[0,
[1,
0,
0,
2,
0,
0,
3,
0,
0,
4],
0],
0],
0]])
FS
In [65]: #inverser les colonnes de m
m[:,::-1]

Out[65]: array([[0, 0, 0, 1],


[0, 0, 2, 0],
[0, 3, 0, 0],
[4, 0, 0, 0]])

Exemple : 4

In [ ]: from scipy import misc


import [Link] as plt

In [ ]: face= [Link]()
[Link](face)
[Link]()

56
In [ ]: print(type(face))
print([Link])

<class '[Link]'>
(768, 1024, 3)

In [ ]: # on veut extraire le visage du raccon


fc = face[100:400, 400:800, :]
[Link](fc)
[Link]()

In [ ]: fci = fc[:,::-1,:] # inverser les colonnes de l'image


[Link](fci)
[Link]()

M
FS
In [ ]: fci = fc[::-1,:,:] # inverser les lignes de l'image
[Link](fci)
[Link]()

57
In [ ]: f = [Link]()
fr, fg, fb = ([Link]() for i in range(3))

fr[:,:,1:] = 0
fg[:,:,::2] = 0
fb[::, ::, :2] = 0
[Link](figsize=(15,5))

[Link](1,3,1)
[Link](fr)
[Link](1,3,2)
[Link](fg)
[Link](1,3,3)
[Link](fb)

[Link]()

M
Sorting Arrays

The NumPy ndarray object has a function called sort(), that will sort a specified array.

In [ ]: import numpy as np
a = [Link]([3, 2, 0, 1])
[Link]()

[0 1 2 3]

In [ ]: # Sort a 2-D array with given axis :


FS
import numpy as np
a = [Link]([[3, 2, 4], [5, 0, 1]])
a

Out[ ]: array([[3, 2, 4],


[5, 0, 1]])

In [ ]: # axis = 1
[Link](axis=1)

Out[ ]: array([[2, 3, 4],


[0, 1, 5]])

In [ ]: # axis = 0
[Link](axis=0)

Out[ ]: array([[3, 0, 1],


[5, 2, 4]])

6. Algèbre linéaire avec numpy

transpose method

In [ ]: matrix = [Link]([[1, 2, 3],


[4, 5, 6]])

[Link]()

Out[ ]: array([[1, 4],


[2, 5],
[3, 6]])

58
In [ ]: matrix.T

Out[ ]: array([[1, 4],


[2, 5],
[3, 6]])

In [ ]: [Link](matrix, [Link]())

Out[ ]: array([[14, 32],


[32, 77]])

M In [ ]: matrix @ matrix.T

Out[ ]: array([[14, 32],

Importation
[32, 77]])
FS
In [66]: from numpy import linalg

Déterminant : La fonction det :

In [67]: m = [Link]([[1.0, 2.0], [3.0, 4.0]])


m

Out[67]: array([[1., 2.],


[3., 4.]])

In [68]: # calculer le déterminant de la matrice m


[Link](m)

Out[68]: -2.0000000000000004

In [69]: # Calculer le rang de la mtrice m en utilisant la fonction matrix_rank :


linalg.matrix_rank(m)

Out[69]: 2

Calcul de matrice inverse la fonction inv

In [37]: [Link](m)

Out[37]: array([[-2. , 1. ],
[ 1.5, -0.5]])

Puissance matricielle : La fonction matrix_power

59
In [41]: linalg.matrix_power(m,2)

Out[41]: array([[ 7., 10.],


[15., 22.]])

In [39]: m**2

Out[39]: array([[ 1., 4.],


[ 9., 16.]])

calcul de valeurs propres avec la fonction eigvals

In [ ]: [Link](a)

Out[ ]: array([-0.37228132, 5.37228132])

Calcul de valeurs & vecteurs propres avec La fonction eig

In [ ]: [Link](a)

Out[ ]: (array([-0.37228132, 5.37228132]), array([[-0.82456484, -0.41597356],


[ 0.56576746, -0.90937671]]))

Résolution de système d'équations linéaires La fonction solve :

In [ ]: # Solve a linear matrix equation, or system of linear scalar equations.


# Computes the “exact” solution, x, of the well-determined, i.e., full rank, linear matrix equat
ion ax = b.
M # [Link]()

Exemple : Résoudre le système d'équations: :

In [44]: #
a
b
solution array([2., 3.])
= [Link]([[3,1], [1,2]])
= [Link]([9,8])
(S ) {
3x + y = 9

x + 2y = 8

x = [Link](a, b)
FS
x

Out[44]: array([2., 3.])

In [48]: # Check that the solution is correct:


[Link]([Link](a, x), b)

Out[48]: True

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


⎧3 x + 6 y − 5 z = 12

(S ) ⎨ x − 3 y + 2 z = −2

5 x − y + 4 z = 10

In [70]: #solution : array([1.75, 1.75, 0.75])

import numpy as np
a = [Link]([[3,6,-5], [1,-3,2], [5,-1,4]])
b = [Link]([12,-2,10])
x = [Link](a, b)
x # array([1.75, 1.75, 0.75])

Out[70]: array([1.75, 1.75, 0.75])

Chapitre 2 : SciPy (calcul scientifique avec python)

60
SciPy est un projet visant à unifier et fédérer un ensemble de bibliothèques Python à usage scientifique. Scipy utilise les tableaux et matrices du
module NumPy.
Cette distribution de modules est destinée à être utilisée avec le langage interprété Python afin de créer un environnement de travail scientifique
très similaire à celui offert par Matlab.
Il contient par exemple des modules pour l'optimisation, l'algèbre linéaire, les statistiques, le traitement du signal ou encore le traitement
d'images.

Plan :

1. Fonctions d'intégration numérique [Link]


2. Résolution d'équations différentielles ordinaires : [Link]
3. Recherche de racine et optimisation: [Link]
4. Initiation au traitement des images numériques [Link]
5. Problèmes d’interpolations (Interpolation de Lagrange) [Link]

1. Fonctions d'intégration numérique


[Link]

importation du module

M In [ ]: from [Link] import *

Intégration numérique de fonctions

Évaluation numérique d'une fonction de type : ∫


a
b

f (x)dx

SciPy fournit une série de fonctions pour différents types de quadrature, par exemple les quad , dblquad et tplquad pour les intégrales
simples, doubles et triples, respectivement.
FS
quad(func, a, b, args = (), ...) retourne un tuple (r, ε) où :

r est la valeur approchée de l'intégrale.


ε est une estimation de l'erreur absolue

Exemples :

In [50]: from [Link] import quad

Exemple 1 :

In [ ]: # define a simple function for the integrand


def f(x):
return x

In [ ]: x_lower = 0 # the lower limit of x


x_upper = 1 # the upper limit of x
val, abserr = quad(f, x_lower, x_upper)

print ("integral value =", val, ", absolute error =", abserr)

integral value = 0.5 , absolute error = 5.551115123125783e-15

Exemple 2 :

61
4
2
∫ x dx
0

Pour les fonctions simples, nous pouvons utiliser une fonction lambda (fonction sans nom) au lieu de définir explicitement une fonction pour
l'intégrande:

In [51]: f= lambda x:x**2


val, abserr = quad(f,0,4)

print ("integral value =", val, ", absolute error =", abserr)

integral value = 21.333333333333336 , absolute error = 2.368475785867001e-13

Exemple 3 :

+∞
2
−x
∫ exp dx
−∞

In [55]: val, abserr = quad(lambda x: [Link](-x ** 2),-[Link],[Link])


print ("numerical =", val, abserr)
analytical = [Link]([Link])
print ("analytical =", analytical)

numerical = 1.7724538509055159 1.4202636780944923e-08


analytical = 1.7724538509055159

M
Principe :

Les méthodes d'intégration numérique se basent sur la définition de Reiman de l'intégrale sous forme d'une limite de série numérique, par exemple la
méthode de rectangle utilise la sommation suivante :


a
b

f (x)dx =

La sommation suivante est approchée pour une valeur de n assez large


lim
n→+∞
b − a

n
n

∑ f (a +

i=0
b − a

n
i)
FS
1
Visualisons les rectangles dans les sommes de Riemann médiane pour la fonction f (x) =
1+x2

sur l'intervalle [0,5] avec une partition de taille N = 10 .

In [57]: import numpy as np


import [Link] as plt

62
In [68]: f = lambda x : 1/(1+x**2)
a = 0; b = 5; N = 10
n = 10 # Use n*N+1 points to plot the function smoothly
x = [Link](a,b,N+1)
y = f(x)
x_mid = (x[:-1] + x[1:])/2 # Midpoints
y_mid = f(x_mid)
###############################""
X = [Link](a,b,n*N+1)
Y = f(X)
[Link](figsize=(10,7))
[Link](X,Y,'b')
###############################""
[Link](x_mid,y_mid,'b.',markersize=10)
[Link](x_mid,y_mid,width=(b-a)/N,alpha=0.2,edgecolor='b')
[Link]('Midpoint Riemann Sum, N = {}'.format(N))
###################################
[Link]()

M
FS
In [ ]: dx = (b-a)/N
x_midpoint = [Link](dx/2,b - dx/2,N)
midpoint_riemann_sum = [Link](f(x_midpoint) * dx)
print("Midpoint Riemann Sum:",midpoint_riemann_sum)

Midpoint Riemann Sum: 1.373543428316664

Nous connaissons la valeur exacte:

et nous pouvons comparer les sommes de Riemann à la valeur

In [ ]: I = [Link](5)
print(I)

1.373400766945016

In [ ]: from [Link] import quad


quad(f,a,b)

Out[ ]: (1.3734007669450166, 7.167069904541812e-09)

Exemple :

π/2
nous savons que ∫0 sin(x) dx = 1

63
In [69]: a = 0
b=[Link]/2
N= 10
dx = (b-a)/N

x_midpoint = [Link](dx/2,b - dx/2,N)


midpoint_riemann_sum = [Link]([Link](x_midpoint) * dx)
print("Midpoint Riemann Sum:",midpoint_riemann_sum)

Midpoint Riemann Sum: 1.0010288241427086

In [ ]: quad([Link],0,[Link]/2)

Out[ ]: (0.9999999999999999, 1.1102230246251564e-14)

Intégration de données (vecteurs)


Parfois les mesures à intégrer sont présentes sous forme de vecteur (aucune forme analytique pour les décrire). Il est possible d'utiliser la fonction
trapz(y, x = None, dx = 1.0, axis = -1) pour intégrer un vecteur selon la méthode des trapèzes.

In [ ]: import numpy as np
from [Link] import trapz
y = [Link]([1,2,3])
#par défaut x = indices de y
trapz(y)

Out[ ]: 4.0

In [ ]: trapz(y, [4,6,8])

M Out[ ]: 8.0

2. Résolution d'équations différentielles ordinaires :


La fonction odeint(func, y0, t, args=(), ....) retourne la solution sous forme d'un vecteur colonne.

2.1 Equation différentielle d'odre 1



y = F (y, t)
FS
{ où t = domaine d'integration
y(t[0]) = y0

Algorithme d'Euler pour la résolution des EDO :

Les algorithmes de résolution d'équations différentielles ordinaires se basent sur des variantes de l'algorithme d'Euler.

L'idée principale de cet algorithme est d'approcher la dérivée par la tangente de la courbe et d'utiliser cette approximation pour déduire la valeur
suivante. Pour simplifier nous allons traiter le cas d'EDO d'odre 1 :

y (t) = f (y(t), t)
(E) { à résoudre sur t = [a, b]
y(a) = y0

y(t + h) − y(t) y(t + h) − y(t)


′ ′
y (t) = lim ⇒ y (t) ≈ pour h > 0 suffisamment petit
h→0 h h

On en déduit alors que



y(t + h) ≈ hy (t) + y(t) pour h > 0 suffisamment petit

En découpant l'intervalle t, avec le pas h on peut constuire deux suites récurrentes :


tn+1 = tn + h
{
t0 = a

⎧ yn+1 = hf (yn , tn ) + yn


⎨ ′
y (t)


y0 = y(a)

Ecrire une fonction Euler permettant de résoudre une EDO d'ordre 1. Etendez là pour les systèmes d'ordre 1.

64
In [ ]: # Méthode d'Euler
def odeEuler(f,y0,t):
'''Approximate the solution of y'=f(y,t) by Euler's method.
Parameters
----------
f : function
Right-hand side of the differential equation y'=f(t,y), y(t_0)=y_0
y0 : number
Initial value y(t0)=y0 wher t0 is the entry at index 0 in the array t
t : array
1D NumPy array of t values where we approximate y values. Time step
at each iteration is given by t[n+1] - t[n].
Returns
-------
y : 1D NumPy array
Approximation y[n] of the solution y(t_n) computed by Euler's method.
'''
y = [Link](len(t))
y[0] = y0
for n in range(0,len(t)-1):
y[n+1] = y[n] + f(y[n],t[n])*(t[n+1]-t[n])
return y

Exemple 1 :


y = y
{ sur t = [0, 1]
y(0) = 1

On sait que la solution analytique de cette équation est f (x) = exp


x

M In [ ]: from [Link] import odeint

In [ ]: t = [Link](0,2,21)
y0 = 1
f = lambda y,t: y
y1 = odeEuler(f,y0,t)
#y1 = odeint(f,y0,t)
y_true = [Link](t)
[Link](t,y1,'b.-',t,y_true,'r-') # ,t,y2,'g-')
[Link](['odeEuler','true','odeint'])
[Link]([0,2,0,9])
FS
[Link](True)
[Link]("Solution of $y'=y , y(0)=1$")
[Link]()

Exemple 2 :

In [ ]: from scipy import integrate as itg


from [Link] import odeint
import numpy as np
import [Link] as plt

65
′ 2
y = y
{ à intégrer sur t = [0, 2]
y(0) = −1

−1
On sait que la solution analytique de cette équation est f (x) =
1+x

In [ ]: t = [Link](0,5,25)
y0 = -1
f = lambda y,t: y**2
y = odeEuler(f,y0,t)
#y = odeint(f,y0,t)
t_true = [Link](0,5,25)
y_true = -1/(t_true + 1)
[Link](t,y,'r.-',t_true,y_true,'b.-')
[Link](['Euler','True'])
[Link](True)
[Link]([0,5,-1,0])
[Link]("Solution of $y'=y^2 , y(0)=1$")
[Link]()

M
2.2 Résolution d'un système d'équations différentielles d'ordre 1

Exemple :
FS
tracer la trajectoire d'un point dans le plan dont le mouvement est régie par l'équation suivante :

x (t) = x(t) + 2t y(t) 1
{ avec Y0 = ( ) et t = [−1, 1]

y (t) = 2 x(t) + 4 y(t) 2

In [ ]:

In [ ]:

2.3 Résolution d'une équation différentielle d'odre p > 1

66
(p) ′ ′′ (p−1)
⎧y = f (y, y , y ,…,y , t)





⎪ y(t[0]) = y0

′ ′
y (t[0]) = y
(E) ⎨ 0




⎪ ⋮



⎪ (p−1) (p−1)
y (t[0]) = y
0

Il est possible de transformer (E) en un système d'équations différentielles d'ordre 1, en effectuant le changement de variable suivant :
y1 = y
{

yi = y ∀i > 1
i−1

Le système (E) s'écrira alors :


y1 = y
⎛ ⎞ ′
y
′ ⎛ 1 ⎞
⎜ y2 = y ⎟
⎜ ⎟ ′
Y

= F (Y , t) ⎜ y ⎟
⎜ ⎟ ⎜ 2 ⎟
{ (i)
avec Y = ⎜ ⎟ et F (Y , t) = ⎜ ⎟ avec la condition initiale
yi (t[0]) = y ∀i ≥ 1 ⎜ ⎟ ⎜ ⎟
0 ⎜ ⎟ ⎜ ⋮ ⎟
⎜ ⋮ ⎟
⎝ ⎠
f (t, y1 , y2 , … yp )
⎝ (p−1) ⎠
yp = y

y(t[0])
⎛ ⎞

M
Exercice : Etude de pendule
Y0

Le mouvement d'un pendule au cours du temps est décrit par l'équation suivante :


= Y (t[0]) = ⎜


y

y (t[0])

(p−1)

(t[0])





FS
′′ ′
(E)θ (t) + bθ (t) + csin(θ(t)) = 0

avec b, c constantes réelles positives.

Ecrire sous forme d'un système différentiel d'odre 1, l'équation (E).


Tracer l'évolution de l'angle du pendule en fonction du temps sachant que :
⎧ t = [0, 10]




⎪ θ(0) = π

⎨ θ′ (0) = 0


⎪ b = 0.25



c = 5

En définissant la vitesse angulaire ω(t) ′


= θ (t) , on obtient le système:


θ (t) = ω(t)


ω (t) = −b ∗ ω(t) − c ∗ sin(θ(t))

In [ ]: # Soit y le vecteur [theta, omega]. Nous implémentons ce système en Python comme:


def pend(y, t, b, c):
theta, omega = y
dydt = [omega, -b*omega - c*[Link](theta)]
return dydt

In [ ]: # We assume the constants are b = 0.25 and c = 5.0:


b = 0.25
c = 5.0

In [ ]: # For initial conditions, we assume the pendulum is nearly vertical with theta(0) = pi - 0.1, an
d is initially at rest, so omega(0) = 0. Then the vector of initial conditions is
y0 = [[Link] - 0.1, 0.0]

67
In [ ]: # We will generate a solution at 101 evenly spaced samples in the interval 0 <= t <= 10. So our
array of times is:
t = [Link](0, 10, 101)

In [ ]: # Call odeint to generate the solution. To pass the parameters b and c to pend, we give them to
odeint using the args argument.

from [Link] import odeint


sol = odeint(pend, y0, t, args=(b, c))
# The solution is an array with shape (101, 2). The first column is theta(t), and the second is
omega(t). The following code plots both components.

In [ ]: import [Link] as plt


[Link](t, sol[:, 0], 'b', label='theta(t)')
[Link](t, sol[:, 1], 'g', label='omega(t)')
[Link](loc='best')
[Link]('t')
[Link]()
[Link]()

M
3. Recherche de racine et optimisation:

[Link] fournit des fonctions pour minimiser (ou maximiser) les fonctions objectives, éventuellement soumises à des contraintes.
FS
Le package [Link] fournit une fonction nommée bisect() qui permet de calculer la ou les racines d'une fonction sur un intervalle donné.
Cette fonction est performante mais présente un inconvénient certain : il faut avoir une idée relativement précise de l'intervalle dans lequel se
trouve la racine recherchée, ce qui signifie qu'il faut d'abord se faire une idée de la fonction, en la traçant par exemple...
Il existe une autre fonction plus puissante, la fonction fsolve(), qui ne necéssite pas de connaitre l'intervalle dans lequel la fonction change de
signe. Elle utilise l'algorithme de Newton-Raphson (si on lui fournit la dérivée de la fonction).

Dans les exemples, nous utiliserons les deux fonctions pour les comparer :

In [ ]: #importation du module
from scipy import optimize

3.1 Chercher les zéros d’une fonction :


Chercher le ou les zéros d’une fonction f revient à résoudre l’équation f (x) = 0. Cela peut être trivial, si on sait le faire analytiquement, par
exemple dans le cas d’un polynôme de degré 1 ou 2, plus difficilement pour les degrés supérieurs. Et cela peut être très complexe et impossible
analytiquement dans le cas de fonctions non linéaires.
Il existe plusieurs méthodes numériques pour rechercher les racines d’une équation.

Méthode des dichotomies pour la recherche du zéro d'une fonction

bisect(func, a, b, args = (), maxiter=100, ...)


Hypothèses :

func : monotone sur [a, b] .


f (a) × f (b) < 0.

68
L'idée est simple: diviser l'intervalle en deux, une solution doit exister dans un sous-intervalle, sélectionner le sous-intervalle où le signe de f (x)
change et répéter.

Exemple :

Résoudre f (x) = 0 avec f (x) = x


2
− 2 sur les intervalles :

[1, 2]
[-2, -1]
[-2, 2]

In [ ]: f = lambda x: x**2 - 2
[Link](f,1,2)

Out[ ]: 1.4142135623715149

In [ ]: f = lambda x: x**2 - 2
[Link](f,-2,-1)

Out[ ]: -1.4142135623715149

In [ ]: f = lambda x: x**2 - 2
# [Link](f,-2,2)
# ValueError: f(a) and f(b) must have different signs

M
Exercice : Ecrivez votre propre version de la méthode bisect.

In [ ]: def bisection(f,a,b,N):

if f(a)*f(b) >= 0:
print("Bisection method fails.")
return None
a_n = a
b_n = b
for n in range(1,N+1):
m_n = (a_n + b_n)/2
f_m_n = f(m_n)
FS
if f(a_n)*f_m_n < 0: b_n = m_n
elif f(b_n)*f_m_n < 0: a_n = m_n
elif f_m_n == 0:
print("Found exact solution.")
return m_n

return (a_n + b_n)/2

In [ ]: f = lambda x: x**2 - x - 1

In [ ]: bisection(f,1,2,25)

Out[ ]: 1.618033990263939

In [ ]: [Link](f,1,2)

Out[ ]: 1.6180339887487207

In [ ]: f = lambda x: (2*x - 1)*(x - 3)

In [ ]: bisection(f,0,1,10)

Found exact solution.

Out[ ]: 0.5

In [ ]: [Link](f,0,1)

Out[ ]: 0.5

In [ ]: [Link](f,2,4)

Out[ ]: 3.0

69
Méthode de newton pour la recherche du zéro d'une fonction

La méthode de Newton est une méthode numérique itérative de résolution numérique des équations du type f (x) = 0 ,

newton(func, x0, fprime = None, args=(), maxiter = 50 ...)


Hypothèses

f

définie et non nulle au voisinage de x0

Soit f (x) une fonction différenciable. Si x0 est proche d'une solution de f (x) = 0

L'équation de la tangente en x0 est y ′


= f (x 0 )(x − x 0 ) + f (x 0 )

x1 est la solution de l'équation 0 = f ′ (x0 )(x − x0 ) + f (x0 )


n’est rien d’autre que l’abscisse du point d’intersection de cette tangente avec l’axe (Ox), en effet

f (x0 )
x1 = x0 − ′
f (x0 )

Si nous implémentons cette procédure à plusieurs reprises, alors nous obtenons une séquence donnée par la formule récursive :
f (x n )
x n+1 = x n − ∀n > 0

f (x n )

qui (potentiellement) converge vers une solution de l'équation f (x) = 0 .

Exercice : Ecrivez votre propre version de la méthode newton

M In [ ]: def newton(f,Df,x0,epsilon,max_iter):
xn = x0
for n in range(0,max_iter):
fxn = f(xn)
if abs(fxn) < epsilon:
print('Found solution after',n,'iterations.')
return xn
Dfxn = Df(xn)
if Dfxn == 0:
print('Zero derivative. No solution found.')
return None
xn = xn - fxn/Dfxn
FS
print('Exceeded maximum iterations. No solution found.')
return None

In [ ]: f = lambda x: x**3 - x**2 - 1


Df = lambda x: 3*x**2 - 2*x
approx = newton(f,Df,1,1e-10,10)
print(approx)

Found solution after 6 iterations.


1.4655712318767877

In [ ]: f = lambda x: x**3 - x**2 - 1


[Link](f,1)

3.2 Résolution de systèmes non linéaires :


fsolve(func, x0, args =() , maxiter = 50, ,...)

Find the roots of a function.


Return the roots of the (non-linear) equations defined by func(x) = 0 given a starting estimate.

Fonction scalaire

Voyons comment approcher la solution d’une équation du type f (x) = 0 avec f une fonction réelle quelconque. Considérons pour commencer la
fonction scalaire f (x) = x − exp(−x) qui dispose d’une racine comprise entre 0 et 1 . La première étape consiste à déclarer cette fonction :

70
In [ ]: import numpy as np
def f(x):
"""Fonction dont on cherche une racine."""
return [Link](-x)

# Pour se convaincre de l’existence de cette racine, on peut par exemple tracer l’allure de cett
e fonction
# entre 0 et 1 à l’aide de matplotlib :
import [Link] as plt
x = [Link](0,1,101)
[Link](x,f(x),'b-')
[Link](True)

In [ ]: import [Link] as op
# point de départ x0= 0.0 , la solution est ainsi :
[Link](f,0.0)
# Returns xndarray : The solution (or the result of the last iteration for an unsuccessful cal
M l).

Out[ ]: array([0.56714329])

Fonction vectorielle

Une démarche strictement identique doit être suivie pour obtenir la solution à un système d’équation non linéaires, à condition de n’utiliser qu’un seul
argument (list ou tuple) pour stocker les différentes composantes du vecteur X = (x1 , x2 , . . , xN ) considéré. Considérons le système non-linéaire
formé par les fonctions

2
FS
f1 (x 1 , x 2 ) = x 1 + 3log10 (x 1 ) − x
2

f2 (x 1 , x 2 ) = 2x
2
1
− x 1 . x 2 − 5x 1 + 1 .

In [ ]: def f(x):
return [x[0]+3*np.log10(x[0])-x[1]**2,
2*x[0]**2-x[0]*x[1]-5*x[0]+1
]

En considérant comme point de départ le vecteur X0 = (5.0, 5.0) , on obtient :

In [ ]: [Link](f,(5.0,5.0))

Out[ ]: array([3.48744279, 2.26162863])

Exemple :

Résoudre dans R2 :
1 3
⎧x +
⎪ (x − y) = 1
2

(E) ⎨ avec x 0 = 0 2
R

⎪ 1 3
(y − x) + y = 0
2

In [ ]: def F(x):
return [x[0]+ 0.5*(x[0]-x[1])**3 - 1,
x[1] + 0.5*(x[1]-x[0])**3]
from scipy import optimize
x= [Link](f,(0.,0.))

Out[ ]: array([0.8411639, 0.1588361])

71
4. Initiation au traitement des images numériques

Le sous-module SciPy ndimage est dédié au traitement d'images. Ici, ndimage signifie une image à n dimensions.

Certaines des tâches les plus courantes du traitement d'image sont les suivantes:

Entrée / sortie, affichage d'images


Manipulations de base - Recadrage, retournement, etc.
Filtrage d'images - Débruitage, netteté, etc.
Segmentation d'image - Étiquetage des pixels correspondant à différents objets
Classification
Extraction de caractéristiques

Ouverture et écriture dans des fichiers image :

Le paquet misc dans SciPy est livré avec quelques images. Nous utilisons ces images pour apprendre les manipulations d'images. Prenons l'exemple
suivant.

In [ ]: from scipy import misc, ndimage


import [Link] as plt
f = [Link]()
[Link](f)
[Link]()
# Le programme ci-dessus générera la sortie suivante.

M
FS
Toute image dans son format brut est la combinaison de couleurs représentées par les nombres dans le format matriciel.
Une machine comprend et manipule les images uniquement sur la base de ces chiffres.
RVB est un mode de représentation populaire.

In [ ]: print ([Link](), [Link](), [Link]())

110.16274388631184 255 0

Une image = une matrice


un élément de la matrice décrit un pt élémentaire de l'image = pixel (PICture ELement)

P0,0 … P0,w−1
⎛ ⎞
w = largeur de l'image
I mage = P = ⎜ ⎟ avec {
⎜ ⋮ ⋱ ⋮ ⎟
h = hauteur de l'image
⎝ ⎠
Ph−1,0 … Ph−1,w−1

Images en noir & blanc (bw images)


pixels bivalués (noir& blanc)

⎪ Pi,j ∈ {0, 1} si [Link] = [Link]

⎨ Pi,j ∈ {0, 255} si [Link] = np.uint8




Pi,j ∈ {T rue, F alse} si [Link] = [Link]

0 = absence totale de la lumière ⇒ Noir.


1 = éclairage maximal ⇒ Blanc.

72
Fonction interessantes

In [ ]: import [Link] as plt

[Link](img, cmap = None, vmin = None, vmax = None) pour afficher une image.
[Link](path) pour charger un fichier image
[Link](path,img, vmin = None, vmax= None, cmap = None) pour enregistrer une image.

Exercice 1 :

In [ ]: import numpy as np
import [Link] as plt
a = [Link](shape= (7, 7))
a[1:-1, 1:-1] = 1
a[:,::]
[Link](figsize=(6, 6))
[Link](a)
[Link]('off')
[Link]()
[Link]()

M
FS
In [ ]:

Exercice 2 : Création d'un échiquier

construire un tableau numpy puis le représenter sous forme d’image à l’aide du module pyplot de matplotlib .

73
In [ ]: import numpy as np
import [Link] as plt
check=[Link]((8,8))
#exemple pour image en niveau de gris
check[::2,1::2]=255
#check[1::2,::2]=255
[Link](check)
[Link]()
[Link]()
# [Link]("[Link]")

Images en niveaux de gris (image monochromatiques) :

valeur d'un pixel ∝ intensité de lumière blanche perçue au niveau de ce pixel.

M
Exercice 1
{
Pi,j ∈ [0, 1]

Pi,j ∈ {0, … , 255}


si [Link] = [Link]

si [Link] = np.uint8

Ecrire une fonction hdegrade qui prend en entrée un entier n et qui retourne une image carrée de taille n avec un dégradé de lumière horizontal de
la gauche (zones sombres) vers la droites (zones claires).

In [ ]: import numpy as np
import [Link] as plt
FS
def hdegrade(n):
img = [Link]([ [j for i in range(n) ] for j in range(n) ])

return img

img = hdegrade(256)

[Link]()
[Link](img)
[Link]()

Exercice 2

Ecrire une fonction vdegrade qui prend en entrée un entier n et qui retourne une image carrée de taille n avec un dégradé de lumière vertical du
haut (zones sombres) vers le bas (zones claires).

74
In [ ]: import numpy as np
import [Link] as plt
def vdegrade(n):
img = [Link]([ [j for i in range(255) ] for j in range(255) ])
return img
img= vdegrade(255)
[Link](img)
[Link]()
[Link]()

Exercice 3 :

Ecrire une fonction ddegrade qui prend en entrée un entier n et qui retourne une image carrée de taille n formée par un dégradé de lumière sur la
diagonale. allant du coin supérieur gauche (zones sombres) vers le coin inférieur droit (zones claires).

M In [ ]: import numpy as np
import [Link] as plt
def ddegrade(n):
img = [Link]([ [i+j for i in range(255)
return img
img = ddegrade(255)
[Link](img)
[Link]()
[Link]()
] for j in range(255) ])
FS

Images couleurs

La couleur n'existe pas dans les objets mais dans la lumière qui les éclaire.

Un pixel = un Triplet de valeurs quantifiant les intensités des lumières (Rouges, vertes, bleues) perçues au niveau de ce dernier.
3
Pi,j ∈ [0, 1] si [Link] = [Link]
{
3
Pi,j ∈ {0, … , 255} si [Link] = np.uint8

généralement en numpy une image couleur est une matrice P tel que P . shape = (h, w, 3) .

Exercice 1 :

75
Cet exercice a pour but de s’entraîner

au slicing des tableaux numpy et


à la représentation d’images couleurs sous la forme de tableaux numpy à trois canaux.

réaliser une image ressemblant à l’image ci-dessus, sous la forme d’un tableau numpy. On
pourra par exemple prendre l’image de forme 32x32, et de type np.uint8 (entiers de 0 à 255).

Indices :

Les trois canaux de couleur sont dans l’ordre R, V, B (rouge vert bleu).
Le jaune correspond au triplet (R, V, B) = (255, 185, 15)

In [ ]: import numpy as np
a = 255 * [Link]((32, 32, 3), dtype=np.uint8)
a[10] = 0
a[::,::,::]
a[23,::,::] = 0
a[:, 5] = 0
M a[:, 26] = 0
"""
a[11:17, 6:14, 1:] = 0
a[:18, 14] = 0
a[17, :14] = 0

a[27:, 6:26, 1] = 0
a[24:, 6:26, 0] = 0

a[:10, 27:, 0] = 255


a[:10, 27:, 1] = 185
a[:10, 27:, 2] = 15
FS
"""
[Link](figsize=(6, 6))
[Link](a)#
[Link]('off')
[Link]()

Exercices : Traitement des images sous Python

76
Binarisation :

Binariser une image consiste à la partitionner en deux parties : une partie sombre et une partie claire selon un seuil s de niveau de gris.

1. Ecrire le script de la fonction Python permettant la binarisation d’une image donnée.

In [ ]: import numpy as np
import [Link] as plt
def Binariser(M,s):
n,p=[Link](M) n,p= [Link]
M1=[Link](shape= (n,p))
for i in range(n):
for j in range(p):
if M[i,j]>s:
M1[i,j]=255
return M1
A=[Link]("[Link]")
B=Binariser(A,127)
[Link](B)
[Link]()
[Link]("[Link]")

Contraste :

Le contraste peut être modifié par l’application de fonctions mathématiques. Par exemple, en remplaçant la valeur de chaque pixel par sa racine
carrée, l’image assombrie alors qu’elle s’éclaircit si la valeur du pixel est remplacée par son carré. Ces fonctions ont pour effet de diminuer le
contraste.

M
Une autre idée consiste à faire un réajustement linéaire des valeurs des pixels selon : f

x ↦ ⎨0

⎧ y = x + 0, 4.(x − 127)

255
si

si
y < 0

y > 255
si
: [0, 256[↦ [0, 256[

y ∈ [0, 255]

Il s’agit d’augmenter l’écart entre la valeur du pixel et la valeur moyenne (127) pour une image dont les valeurs sont comprises entre 0 et 255. Cette
fonction permet d’augmenter le contraste, les "noirs" sont plus noirs et les "blancs" plus blancs.

1. Ecrire le script de la fonction Python permettant de modifier le contraste d’une image donnée.
FS
In [ ]: f=lambda x:x-0.4*(x-127)
def Contraste(M):
n,p=[Link](M)
M1=[Link]((n,p))
for i in range(n):
for j in range(p):
y=f(M[i,j])
if y>255:
M1[i,j]=255
elif y<0:
M1[i,j]=0
else:
M1[i,j]=y
return M1

Négatif d’une image :

Une image négative est une image dont les niveaux de gris sont inversés par rapport à l’originale. La valeur x de chaque pixel est remplacée par 255
– x.

1. Ecrire le script de la fonction Python permettant de déterminer le négatif d’une image donnée.

In [ ]: def Negatif(M):
n,p=[Link](M)
M1=[Link]((n,p))
for i in range(n):
for j in range(p):
M1[i,j]=255-M[i,j]
return M1

77
In [ ]: f= lambda x: 255-x
fv = [Link](f)
M1 = fv(M)

In [ ]: M1 = 255- M

Filtrage (enlever le bruit)

Les images sont parfois de mauvaise qualité. Un exemple typique de défaut est le bruit qui apparait quand une photo est sous-exposée, c’est-à-dire
qu’il n’y a pas assez de luminosité. Ce bruit se manifeste par de petites fluctuations aléatoires des niveaux de gris.

Afin d’enlever le bruit dans les images, il convient de faire une modification aux valeurs de pixels. L’opération la plus simple consiste à remplacer la
valeur a de chaque pixel par la moyenne de a et des 8 valeurs b, c, d, e, f , g, h, i des 8 pixels qui entourent a.
a+b+c+d+e+f +g+h+i
On obtient ainsi une image modifiée en remplaçant a par : 9

1. Ecrire la fonction Python permettant de filtrer une image donnée en utilisant la méthode de moyennage.

In [ ]: def Filtrer_moy(M):
n,p=[Link](M)
M1=[Link]()
for i in range(1,n-1):
for j in range(1,p-1):
I=M[i-1:i+2,j-1:j+2]
M1[i,j]=sum(I[x,y] for y in range(3) for x in range(3))/9
= np.
return M1

MEn effectuant cette opération pour chaque pixel, on supprime une partie du bruit, car ce bruit est constitué de fluctuations aléatoires, qui sont
diminuées par un calcul de moyennes.
Le moyennage des pixels est très efficace pour enlever le bruit dans les images, malheureusement il détruit également une grande partie de
l’information de l’image. On peut en effet s’apercevoir que les images obtenues par moyennage sont floues. Ceci est en particulier visible près
des contours, qui ne sont pas nets.
Afin de réduire ce flou, il faut remplacer le moyennage par une opération un peu plus complexe, que l’on nomme médiane. Etant donné la valeur
a d’un pixel, et les valeurs b, c, d, e, f , g, h, i , on commence par les classer par ordre croissant. La médiane des neuf valeurs

a, b, c, d, e, f , g, h, i est la 5 ème valeur de ce classement (c’est-à-dire la valeur centrale de ce classement).

1. Ecrire le script de la fonction Python permettant de filtrer une image donnée en utilisant la méthode de médiane.
FS
In [ ]: def Filtrer_mediane(M):
n,p=[Link](M)
M1=M[:,:]
for i in range(1,n-1):
for j in range(1,p-1):
I=M[i-1:i+2,j-1,j+2]
L=[I[x,y] for y in range(3) for x in range(3)]
[Link]()
M1[i,j]=L[4]
return M1

Détection de contours :

Pour localiser des objets dans les images, il est nécessaire de détecter les bords de ces objets. Ces bords correspondent à des zones de l’image où
les valeurs des pixels changent rapidement.

Afin de savoir si un pixel avec une valeur a est le long d’un bord d’un objet, on prend en compte les valeurs b, c, d, e de ses quatre voisins (deux
horizontalement et deux verticalement), qui sont disposés par rapport à a. Notons que l’on utilise ici seulement les 4 voisins qui ont un coté
commun avec le pixel considéré, ce qui est différent du calcul de moyennes et de médianes où l’on utilisait 8 voisins. Ceci est important afin de
détecter aussi précisément que possible les bords des objets.
−−− −− −−− −− −− −
On calcule une valeur l suivant la formule : l = √(b − d) + (c − e)
On peut remarquer que si l = 0, alors on a :
b = d et c = e .

Au contraire, si l est grand, ceci signifie que les pixels voisins ont des valeurs très différentes, le pixel considéré est donc probablement sur le
bord d’un objet.

On affiche ainsi ces valeurs avec du noir quand l = 0 , du blanc quand l est grand, et on utilise des niveaux de gris pour les valeurs intermédiaires.

1. Ecrire le script de la fonction Python permettant de détecter les contours des objets d’une image donnée.

78
In [ ]: def Detecter_contours(M):
n,p=[Link](M)
M1=M[:,:]
for i in range(1,n-1):
for j in range(1,p-1):
I=M[i-1:i+2,j-1,j+2]
l=int([Link]((I[1,0]-I[0,1])**2+(I[1,2]-I[2,1])**2))
if l==0:
M1[i,j]=0
elif l>200:
M1[i,j]=255
return M1

5. Problèmes d’interpolations: Interpolation de Lagrange

Soit N points (x1 , y1 ), … (xN , yN ) telque

x1 < x2 < x3 < … < xN et x i ∈ [a, b] ∀1 ≤ i ≤ N .

Le polynome de Lagrange est l'unique polynôme P de degré N − 1 dont la courbe passe par les N pts :
P (x i ) = yi ∀ 1 ≤ i ≤ N

Lagrange propose la formule suivante pour l'interpolation :

P (X) = ∑ yi Q i (X) où
i=1
n X−xk
Q i (X) = ∏
k=1:k≠i xi −xk

M
En numpy , la classe poly1d permet de créer un objet qui représente un polynome à une seule inconnue. Par exemple :

In [ ]: import numpy as np
v1 =[Link]([1,2,3,4,5])
P = np.poly1d(v1)
print(P)

In [ ]: P(1)
4 3 2
1 x + 2 x + 3 x + 4 x + 5
FS
Out[ ]: 15

Les instances de cette classe supportent toutes les opération natives de Python.

In [ ]: v2=[Link]([3,1])
Q = np.poly1d(v2)
print(Q)

3 x + 1

In [ ]: print(2*P)

4 3 2
2 x + 4 x + 6 x + 8 x + 10

In [ ]: print(P+Q)

4 3 2
1 x + 2 x + 3 x + 7 x + 6

In [ ]: print(P*Q)

5 4 3 2
3 x + 7 x + 11 x + 15 x + 19 x + 5

Ecrire un sous programme PolynomeQ qui prend en entrée un vecteur X contenant les xk et un indice i et retourne une instance de la classe
n X−xk
np.poly1d décrivant le polynome Q i (X). telque Q i (X) = ∏
k=1:k≠i xi −xk

79
In [ ]: import numpy as np
def PolynomeQ(X,i):
X1=list(X[:])
xi = [Link](i)
Q = np.poly1d([1])
for xk in X1:
Q= Q* (1/(xi-xk)) * np.poly1d([1,-xk])
# produit de deux plolynomes Q*(X-xk)
# multiplication par un scalaire avec xi != xk
return(Q)

In [ ]: L= [5,4,3,2,1]
import numpy as np
a = [Link](L)
print(PolynomeQ(a,2))

4 3 2
0.25 x - 3 x + 12.25 x - 19.5 x + 10

Ecrire une fonction Lagrange qui retourne une instance de la classe np.poly1d le polynome d'interpolation P . Le programme prendra en entrée
les deux vecteurs X et Y chacun de taille N . Les (xi , yi ) sont présents respectivement dans X[i] , Y [i]. Tracer la courbe du polynome obtenu.
n

P (X) = ∑ yi Q i (X)

i=1

In [ ]: def Lagrange(X,Y):
""" Polynôme d'interpolation aux points (X,Y) """
L = []
P=np.poly1d(L)

M for i, y in enumerate(Y):
P = P + y*PolynomeQ(X,i)
#print(P)
return(P)

In [ ]: X = [Link](0, 10, num=15, endpoint=True)


X

Out[ ]: array([ 0. ,
3.57142857,
7.14285714,
0.71428571,
4.28571429,
7.85714286,
1.42857143,
5. ,
8.57142857,
2.14285714, 2.85714286,
5.71428571, 6.42857143,
9.28571429, 10. ])
FS
In [ ]: Y = [Link](-X**2/9.0)
Y

Out[ ]: array([ 1. , 0.99839359, 0.97440052, 0.87264486, 0.61608828,


0.15295994, -0.45290412, -0.93454613, -0.88396283, -0.12026046,
0.81720532, 0.83852541, -0.30437638, -0.98789998, 0.11527995])

In [ ]: print(Lagrange(X, Y))

14 13 12 11
1.387e-09 x - 6.799e-08 x + 1.324e-06 x - 1.181e-05 x
10 9 8 7 6
+ 1.707e-05 x + 0.0007083 x - 0.008287 x + 0.04953 x - 0.1866 x
5 4 3 2
+ 0.4637 x - 0.7607 x + 0.7651 x - 0.4318 x + 0.1011 x + 1

80
In [ ]: X = [Link](0, 10, num=30, endpoint=True)
Y = [Link](X)
import [Link] as plt
[Link](X ,Y , 'o')
[Link](['data'])
[Link]()

In [ ]: X = [Link](0, 10, num=20, endpoint=True)


#Y = [Link](-X**2/9.0)
Y = [Link](X)
P = Lagrange(X, Y)
import [Link] as plt
[Link](X ,Y , 'o', X, P(X),'-') #, X, f1(X), '--')
[Link](['data', 'Lagrange'], loc='best')
[Link]()

M
FS
In [ ]: from [Link] import interp1d
X = [Link](0, 10, num=20, endpoint=True)
Y = [Link](-X**2/9.0)
#Y = [Link](X)
f = interp1d(X, Y)

import [Link] as plt


[Link](X ,Y , 'o', X, f(X),'-')
[Link](['data', 'interp1d'], loc='best')
[Link]()

In [ ]:

81
Faculté des Sciences de Monastir

Département des Sciences de l’Informatique

Informatique des Classes Préparatoires: MP2/PC2

Enseignant: Jaafar CHAAOURI

3ème Partie :
Les bases de données
avec Python

Les objectifs :

Assimiler les notions de base de données.


Savoir créer et alimenter une base de données avec Python.
Savoir écrire des requêtes en langage algébrique et en langage SQL.

Plan
1. Concepts fondamentaux
2. LDD : Langage de description des données
M
3. Algèbre relationnelle
4. LMD : Langage de manipulation de données
5. Accès aux données : module SQlite3 de Python
6. Exemples et Exercices d'application
FS
1. Concepts fondamentaux

1.1 Système de gestion de base de données


Un Système de gestion de bases de données (SGBD) est un logiciel qui permet à différents utilisateurs/programmes
concurrents de manipuler les informations stockées dans une base de données (indépendamment de leurs
représentations physique (emplacement des fichiers).
SQL (Structured Query Language, en français langage de requête structurée) est un langage informatique normalisé
servant à exploiter des bases de données relationnelles.
LMD : langage de manipulation des données de SQL permet de rechercher, d'ajouter, de modifier ou de supprimer
des données.
LDD : langage de définition des données permet de créer et de modifier l'organisation des données.
Le SGBD se charge de séquencer les opérations nécessaires pour satisfaire la requête de l’utilisateur

1.2 Base de données


Une base de données est un ensemble (volumineux) de données persistantes et structurées (informations inter reliées)
gérées par un SGBD.

1.3 Attribut
Un attribut (champ ou colonne) représente une information spécifique à une entité. Par exemple pour un candidat à un
coucours, nous pouvons enregistrer les attributs suivants {idC, nom, date_naissance, sexe, nationalite, adresse, section}

82
1.4 Domaine
Un domaine est un ensemble d’instances d’un type élémentaire (les entiers, les réels, les textes, etc.).
Chaque SGBR possède un système de types figés qui représentent les domaines des attributs qu’il est possible de
créer.
Par exemple :
Domaine(idC) = Entier,
Domaine(section) = Texte.

1.5 Schéma d’une relation


Le schéma d’une relation est le nom de cette relation suivi de la liste de ses attributs,
chaque attribut est associé à son domaine. Le schéma d’une relation noté comme suit :
nomrelation(A1 : D1, A2 : D2, . . . , An : Dn) où Ai est le nom de l’attribut et Di son domaine.
Exemple :
Etablissement (idEtab: TEXTE , nom:TEXTE, adresse:TEXTE, gouv:TEXTE)
Candidat (idC : Entier, nom:TEXTE, date_naissance: DATE, sexe:TEXTE, nationalite:TEXTE, adresse:TEXTE,
section:TEXTE, #idEtab:TEXTE)
Deux relations ont le même schéma, si et seulement si, elles ont le même nombre, noms et domaines d’attributs.

1.6 Instance d’une relation

Une instance de relation se représente sous forme de table. Par abus de langage, les termes relation et table sont
utilisés pareillement.
La figure ci-dessous montre les instances des deux relations :
M
Etablissement (idEtab: TEXTE , nom:TEXTE, adresse:TEXTE, gouv:TEXTE)
Candidat (idC : Entier, nom:TEXTE, date_naissance: DATE, sexe:TEXTE, nationalite:TEXTE, adresse:TEXTE,
section:TEXTE, #idEtab:TEXTE)
FS

1.7 Clé primaire


La clé d’une relation est un sous ensemble minimal d’attributs (idéalement un singleton) qui permet d’identifier chaque
ligne de la relation d’une manière unique.
Syntaxiquement dans le schéma le/les attribut(s) clé(s) est/sont souligné(s).
Exemple : l’attribut idC de la relation Candidat.

Candidat (**idC**, nom, date_naissance, sexe, nationalite, adresse, section, #idEtab)

1.8 Clé étrangère

Une clé étrangère est un attribut qui fait référence à une ligne dans une autre table. Autrement dit c’est une copie de la

83
clé primaire d’un enregistrement situé dans une autre table.
Ainsi, une clé étrangère établit un lien entre deux tables de la base de données.
Le SGBD se charge de vérifier les contraintes référentielles (c.-à-d. que la valeur attribuée à la clé étrangère correspond
bien à une ligne existante dans la table référencée).
Exemple : l’attribut idEtab dans la relation Candidat permet de référencer la clé primaire de l'établissment auquel
appartient le candidat.
Candidat (idC, nom, date_naissance, sexe, nationalite, adresse, section, #idEtab)

1.9 Tuple

Un tuple (ligne ou aussi enregistrement) d’une relation R(A1 : D1 , . . . , A n : Dn ) est un n-uplet de valeurs
e = (v1 , v2 , . . . , vn ) où chaque vi ∈ Di ou bien vi = N U LL .
Exemple : ('001' , 'Fourat', '2000/06/19', 'H', 'Tunisienne', 'Monastir' , 'MP', 'FSM' ), est un enregistrement de la table
(relation) Candidat.

1.10 Instance d’une base de données

C’est un ensemble fini d’instances de relations (tables).


Le schéma de la base de données est l’ensemble des schémas des relations de cette base( l’ensemble des requêtes
CREATE TABLE ...)

2. LDD : Langage de description des données

tables qui vont former la base de données.


M
Ce langage est un sous ensemble du langage SQL(Structured Query Language), il permet de décrire les schémas des

La syntaxe générale de la requête de création de table est illustrée ci-dessous :

CREATE TABLE nom_table


(
FS
nom_colonne1 Domaine Contrainte,
...
nom_colonne_k Domaine Contrainte,

Contrainte_1,
...
Contrainte_K
);

Les domaines supportés par l’SGBD (sqlite) sont :

INTEGER : pour les entiers.


REAL : pour les réels.
TEXT : pour les chaines de caractères.
DATE : pour les dates représentées sous la forme ’AAAA-MM-JJ’.
TIME : pour les temps représentés sous la forme ’HH:MM:SS’
NULL : une valeur qui exprime l’absence de valeur. Un champ est attribué à cette valeur lorsqu’il n’est pas possible de
connaitre sa valeur.

Les contraintes qu’il est possible d’exprimer sont décrites ci-dessous :

PRIMARY KEY : indique le(s) attribut(s) qui forme la clé primaire d’une table.
AUTOINCREMENT : pour une clé auto-incrémentée (uniquement pour les entiers).
FOREIGN KEY : indique le(s) attribut(s) qui référencent les clés primaires d’enregistrements externes.
CHECK: permet de forcer une condition sur l’attribut.
NOT NULL : la valeur de l’attribut doit être connue.
DEFAULT : indiquer une valeur par défaut pour l’attribut si sa valeur n’est pas connue (la valeur par défaut remplace
NULL)
UNIQUE : Interdit d’avoir des doublons pour un sous ensemble d’attributs.

84
Exemple de création d'une base de donées

Un concours national d’entrée aux cycles de formation d’ingénieurs réunit chaque année des milliers de candidats qui
passent un ensemble d’épreuves spécifiques aux sections MP (Mathématiques et Physique), PC (Physique et Chimie),
T (Technologie) et BG (Biologie et Géologie).

on considère une base de données d'un concours schématisée par les relations :

Etablissement (idEtab, nom, adresse, gouv)


Candidat (idC, nom, date_naissance, sexe, nationalite, adresse, section, #idEtab)
Epreuve (idEpr, nomEpr, section, date_ep, heure , duree, coeff)
Evaluation (idC,idEpr, note:Réel)

M
FS
Les requêtes de création de tables :

Etablissement (idEtab: TEXTE , nom:TEXTE, adresse:TEXTE, gouv:TEXTE)

In [ ]: CREATE TABLE Etablissement


(
idEtab TEXT PRIMARY KEY ,
nom TEXT NOT NULL,
adresse TEXT,
gouv TEXT

);

Candidat (idC : Entier, nom:TEXTE, date_naissance: DATE, sexe:TEXTE, nationalite:TEXTE, adresse:TEXTE,


section:TEXTE, #idEtab:TEXTE)

In [ ]: CREATE TABLE Candidat


( idC INTEGER PRIMARY KEY,
nom TEXT NOT NULL,
date_naissance DATE,
sexe TEXT,
nationalite TEXT,
adresse TEXT,
section TEXT,
idEtab TEXT,
FOREIGN KEY(idEtab) REFERENCES Etablissement(idEtab)
);

Epreuve (idEpr:Entier, nomEpr:TEXTE, section:TEXTE, date_ep:DATE, heure HEURE, duree:Entier, coeff:Entier)

In [ ]: CREATE TABLE Epreuves


( idEpr INTEGER PRIMARY KEY,
nomEpr TEXT,

85
section TEXT,
date_ep DATE,
heure INT,
duree INT,
coeff INT
);

Evaluation (idC:Entier, idEpr:Entier, note:Réel)

In [ ]: CREATE TABLE Evaluation


( idC INTEGER,
idEpr INTEGER,
note REAL,
PRIMARY KEY(idC,idEpr),
FOREIGN KEY (idC) REFERENCES Candidat(idC),
FOREIGN KEY (idEpr) REFERENCES Epreuves(idEpr)
);

Suppression d’une table : Toute table peut être supprimée à l’aide de DROP .

Par exemple : DROP TABLE Epreuve

Ajout d’une colonne : Pour ajouter une colonne à une table, on utilise ALTER.

Par exemple : ALTER TABLE Candidat ADD COLUMN score REAL

A l’exécution de cette commande, la table possède une nouvelle colonne qui ne contient que des valeurs NULL pour toutes
les lignes. On ne peut ajouter une colonne obligatoire ( NOT NULL ) que si la table est vide ou si cette colonne possède une
valeur par défaut(DEFAULT).

3. Algèbre relationnelle
M
L’algèbre relationnelle offre un ensemble d’opérateurs permettant d’interroger une base de données. Les expressions
formulées par ces opérateurs sont Traduites en SQL avec le langage de manipulation des données.
FS
3.1 Affectation de relation
Il est possible d’utiliser la notation R1 = R2 en algèbre relationnelle, ceci indique que la relation R1 est une copie de la
relation R2.

Par Exemple si nous désirons désigner la relation Candidat par C nous pouvons écrire : C = Candidat ,

en SQL ceci ce traduit par : SELECT * FROM Candidat

3.2 Projection

L’opérateur de projection est utilisé pour la réduction des colonnes (attributs) d’une relation.
Soit une relation R(A1 : D1 , . . . , A n : Dn )

La Projection de R sur un seul attribut Ai est définie comme suit : πA i


(R) = { e. Ai : e ∈ R }

La relation résultante contient une seule colonne dans ce cas.

En SQL cette opération est traduite par

SELECT DISTINCT Ai FROM R;

Exemple :

In [ ]: # la table Candidat toute entière


select * from Candidat

Projection de la relation Candidat sur les deux attributs idC et nom:

86
πidC,nom (Candidat)

In [ ]: # en sql
select idC, nom
from Candidat

3.3 Sélection

C’est un opérateur unaire et homogène qui permet d’appliquer une sélection de lignes (tuples) d’une relation R
La condition est évaluée pour chaque ligne de la relation, les lignes pour lesquels la condition donne FAUX sont
écartées du résultat.
La sélection à partir d’une relation R selon une condition c est définie comme suit :

σc (R) = {e ∈ R : c(e) = V rai }

en SQL cette opération est traduite comme suit :

SELECT * FROM R WHERE C;

Exemple : Exprimer en algèbre relationnelle les requêtes permettant de donner :

La liste des étudiants de la section MP

L’expression :

σsection=′ M P ′ (Candidat)

In [ ]: # traduite en SQL par :


SELECT *
M
FROM Candidat
WHERE section ='MP';

Les noms des candidats libres de la section 'PC'.


FS
In [ ]:

πnom (σidEtab=′ Libre′ ′


section= P C
′ (Candidat))

In [ ]: # en SQL
SELECT nom
FROM Candidat
WHERE section ='MP' and idEtab = 'Libre';

Notons qu’en SQL il est possible d’utiliser les opérateurs suivants :

Opérateurs arithmétiques : Addition (+), Soustraction(−), Multiplication(∗), Modulo(%), Division(/)

Division entière si les deux opérandes sont des INTEGER


Division réelle si l’un des opérandes est de type REAL
CAST(colonne AS REAL) pour changer le type d’une colonne.

Opérateurs Relationnels :
Égalité =, Inférieur <, Supérieur >, Inférieur ou égal <=, supérieur ou égal >=,
Différent <> ou != .
BETWEEN V1 AND V2 : tester si une valeur est entre les deux bornes V1 et V2.
IN (V1, V2,...,Vk) : tester si une valeur figure dans la séquence (V1 .. VK)
EXISTS(SOUS REQUÊTE) : Donne vrai si la requête indiquée produit au moins une ligne
Il est possible de précéder, ces opérateurs par NOT :
NOT BETWEEN
NOT IN

87
NOT EXISTS
LIKE : Pour comparer un texte avec un motif de texte :
% remplace une séquence de zéro ou de plusieurs caractères.
_ remplace un seul caractère.
IS NULL et IS NOT NULL pour vérifier si une colonne est NULL ou pas NULL.
Opérateurs logiques : OR (ou), AND(et), NOT (non)

3.4 Produit cartésien


C’est un opérateur binaire et hétérogène. Le résultat du produit cartésien R1 × R2 est une relation R dont le schéma résulte
de la concaténation des schémas de R1 et de R2 Formellement Si R1 (A1 , . . . , An ) et R2 (B1 , . . . , Bm ) :

R1 × R2 = (e1 . A1 , . . . e1 . An , e2 . B1 , . . . , e2 . Bm ) : e1 ∈ R1 et e2 ∈ R2

Le schéma de R1 × R2 = R(A1 , A2 , . . . , An , B1 , B2 , . . . , Bm ) .

En SQL cette opérateur ce traduit comme suit :

SELECT * FROM R1, R2;

ou bien

SELECT * FROM R1 CROSS JOIN R2;

Exemple : Pour les relations

Etablissement (idEtab, nom, adresse, gouv)


M
Candidat (idC, nom, date_naissance, sexe, nationalite, adresse, section, #idEtab)

Le produit cartésien : Candidat × Etablissement

ou en SQL

SELECT * FROM Candidat CROSS JOIN Etablissement;


FS
3.6 Jointure
C’est un opérateur binaire et hétérogène qui permet de fusionner les lignes de deux relations ayant des valeurs communes
(généralement une clé étrangère.

Soit c une condition de jointure qui relie un sous ensemble des colonnes de R1 à un sous ensemble des colonnes de R2
alors :

R1 ⋈c R2 = σc (R1 × R2 )

Exprimée en SQL comme suit :

In [ ]: select *
from R1, R2
where C;
# ou bien
SELECT * FROM R1 JOIN R2 ON C;

Exemple: Pour les relations Etablissement, Candidat de l’exemple précédent, l’opérateur de jointure permet de ramener les
information d'un candidat et l'établissement auquel il appartient :

Candidat ⋈ [Link] = [Link]


Etablissement

Traduite en SQL par :

SELECT * FROM Candidat C JOIN Etablissement E ON [Link] = [Link];

In [ ]: select *
from Etablissment E, Candidat C
where [Link] = [Link]
88
Le résultat est illustré dans la figure ci-dessous.

3.7 Division
C’est un opérateur binaire hétérogène (c’est la réciproque du produit cartésien) c’est à dire : Si R1 × R2 = R ⇒

R ÷ R1 = R2

R ÷ R2 = R1

Tous les attributs du schéma de la relation diviseur (à droite de l’opérateur ÷ doivent être inclus dans le schéma de la
relation dividende (celle à gauche de l’opérateur ÷).
La relation résultante R ÷ R1 contient les attributs qui figurent dans R mais pas dans R1 ,

Formellement : Si R(A1 , A2 , . . . , An , B1 , . . . , Bm ) et R1 (A1 , A2 , . . . , An )

⇒ R ÷ R1 = R2 (B1 , B2 , . . . , Bm ) ={e : R1 ×{e} ⊆ R }

Cet opérateur permet de ramener les éléments de R2 qui ont figurés avec toutes les lignes de R1 .

Exemples :
M
Les candidats de la section 'PC' qui ont passé toutes les épreuves

πidC,idEpr (Candidat ⋈[Link]=[Link] et section= P C


′ ′ Evaluation) ÷
πidEpr (σsection=′ P C ′ (Epreuves))
FS
Les épreuves de la section 'PC' qui ont été passé par tout les candidats

πidC,idEpr (Candidat ⋈[Link]=[Link] et



section= P C Evaluation) ÷ πidC (σsection= P C
′ ′ (Candidat)

3.8 Union
C’est un opérateur binaire homogène. Pour R1 et R2 deux relation de même schéma alors :

R1 ∪ R2 = {e : e ∈ R1 ou e ∈ R2 }

En SQL elle se traduit par :

SELECT * FROM R1
UNION
SELECT * FROM R2;

3.9 Intersection
C’est un opérateur binaire homogène. Pour R1 et R2 deux relation de même schéma alors :

R1 ∩ R2 = {e : e ∈ R1 et e ∈ R2 }

En SQL elle se traduit par :

SELECT * FROM R1
INTERSECT
SELECT * FROM R2;
89
3.10 Différence Ensembliste
C’est un opérateur binaire homogène. Pour R1 et R2 deux relation de même schéma alors :

R1 − R2 = {e : e ∈ R1 et e ∉ R2 }

En SQL elle se traduit par :

SELECT * FROM R1
EXCEPT
SELECT * FROM R2;

Exemple :

Les identifiants des candidats qui n'ont passé aucune épreuve du concours.

πidC (Candidat) − πidC (Evaluation)

In [ ]: # en SQL
select idC from Candidat
EXCEPT
select DISTINCT idC from Evaluation

4. LMD : Langage de manipulation de données


M
C’est un sous ensemble de SQL permettant d’interroger, d’insérer, de mettre à jour ou de supprimer des données.

4.1 Interrogation des données


La syntaxe générale de la requête d’interrogation de données est décrite ci-dessous :
FS
In [ ]: SELECT (optionnellement DISTINCT) # arrtibut(s) ou bien (*)
FROM table(s) # une seule table, un produit cartésien ou une jointure d’une séque
WHERE critère # critère de sélection
GROUP BY attribut(s) # attribut(s) de groupement
HAVING condition_groupe # filtrage des groupes
ORDER BY Attribut1 (ASC ou DESC)) # Ordonner les lignes
LIMIT N # se limiter à N lignes */
OFFSET v; # commencer à partir de la ligne v

4.2 Fonction d’agrégation


Les fonction d’agrégation permettent d’effectuer des calculs verticaux (en agrégeant les lignes) d’une table toute entière
ou bien d’un groupe formé par la clause (GROUP BY) de SQL.
Les fonction d’agrégation les plus connues sont :

Nombre total d’éléments : COUNT(attribut(s)) ou COUNT(*).


Nombre d’éléments distincts : COUNT(DISTINCT attribut(s)) ou COUNT(DISTINCT *).
Somme : SUM(attribut) ou SUM(DISTINCT attribut).
Moyenne : AVG(attribut) ou AVG(DISTINCT attribut).
Maximum : MAX(attribut)
Minimum : MIN(attribut)
Les agrégations sont effectuées sur deux phases :

1. Regrouper les lignes ayant des valeurs communes pour un sous ensemble d’attributs.
2. Appliquer des fonctions d’agrégation pour effectuer des calculs verticaux sur les groupes obtenus.

Exemples:

90
Déterminer le Nombre de Candidat par section

In [ ]: select section, count(idC) as NbreCandidat


from candidat
Goupby section
# la phase 1: un groupe est créé pour chaque ensemble de lignes ayant la même section
# La phase 2: donnera le résultat final de la requête
# où chaque groupe est remplacé par une seule ligne
# contenant la section et le nombre de Candidats appartenant à cette section.

Calculer, pour chaque section, le total des coefficients des épreuves.

In [ ]: select section, sum(coef) as totalCoef


from Epreuves
group By section

Déterminer pour chaque épreuve le nombre des candidats ayant obtenu des notes supérieures à 10.

In [ ]: select idEpr, count(*) as Nbre


from Evaluation
where note > 10
groupBy idEpr

4.3 Insertion des données


Cette requête permet l’insertion d’une nouvelle ligne dans une table, elle existe en 3 variantes :

Les valeurs doivent concorder suivant l’ordre et le nombre des attributs déclarés dans la Table (CREATE TABLE ).
M
INSERT INTO nom_table VALUES(V1, V2, ..., VK);

L’ordre des valeurs doit concorder avec les noms des colonnes indiquées après nom table.
FS
INSERT INTO nom_table(nom(s) colonne(s)) VALUES(V1, ..., Vk);

Les lignes retournées par la requête SELECT sont insérées dans la table nom_table

INSERT INTO nom_table SELECT attribut(s) FROM Table(s) ...;

Exemples :

In [ ]: # insertion d'une ligne d'un la table Etablissement


insert into Etablissement values('FSM',"Faculté des sciences","avenue de l'environnement", "Moanstir"

In [ ]: # insertion de plusieurs lignes.


Etabs = [ ('FSM', 'faculté des scienecs de Monastir', 'avenue de l environnement', 'Monastir'),
('IPEIT', 'Institut préparatoire de Tunis','','Tunis'),
('IPEIN', 'Institut préparatoire de Nabeul','','Nabeul'),
('Libre','','','')
]
req= 'insert into Etablissement values(?,?,?,?)'
[Link](req,Etabs)

In [ ]: req = "SELECT * FROM Etablissement"


for row in [Link](req):
print (row)

('FSM', 'faculté des scienecs de Monastir', 'avenue de l environnement', 'Monastir')


('IPEIT', 'Institut préparatoire de Tunis', '', 'Tunis')
('IPEIN', 'Institut préparatoire de Nabeul', '', 'Nabeul')
('Libre', '', '', '')

In [ ]: Candidats =[
('001','Fourat','2000/06/19', 'H','Tunisienne','','MP','FSM'),
('002','Aymen','1999/05/10', 'H','Tunisienne','','PC','FSM'),
('003','Mariem','2001/01/15', 'F','Tunisienne','','MP','FSM'),
('004','Farah','1998/10/03', 'F','Tunisienne','','PC','Libre'),

91
('005','Aziz','2002/07/20', 'H','Tunisienne','','MP','IPEIT'),
('006','Rania','2002/07/20', 'F','Tunisienne','','BG','IPEIN'),
('007','Edriss','2002/07/20', 'H','Tunisienne','','MP','FSM'),
('008','Karim','2001/08/17', 'H','Tunisienne','','MP','IPEIT'),
('009','Med Ali','2001/09/04', 'H','Tunisienne','','MP','FSM'),
('010','Akrem','2002/05/13', 'H','Tunisienne','','BG','FSM')
]
req= '''insert into Candidat values (?,?,?,?,?,?,?,?)'''
[Link](req, Candidats)
[Link]()

In [ ]: req = "SELECT * FROM candidat"


for row in [Link](req):
print (row)

(1, 'Fourat', '2000/06/19', 'H', 'Tunisienne', '', 'MP', 'FSM')


(2, 'Aymen', '1999/05/10', 'H', 'Tunisienne', '', 'PC', 'FSM')
(3, 'Mariem', '2001/01/15', 'F', 'Tunisienne', '', 'MP', 'FSM')
(4, 'Farah', '1998/10/03', 'F', 'Tunisienne', '', 'PC', 'Libre')
(5, 'Aziz', '2002/07/20', 'H', 'Tunisienne', '', 'MP', 'IPEIT')
(6, 'Rania', '2002/07/20', 'F', 'Tunisienne', '', 'BG', 'IPEIN')
(7, 'Edriss', '2002/07/20', 'H', 'Tunisienne', '', 'MP', 'FSM')
(8, 'Karim', '2001/08/17', 'H', 'Tunisienne', '', 'MP', 'IPEIT')
(9, 'Med Ali', '2001/09/04', 'H', 'Tunisienne', '', 'MP', 'FSM')
(10, 'Akrem', '2002/05/13', 'H', 'Tunisienne', '', 'BG', 'FSM')

4.4 Mise à jour des données


cette requête permet de mettre à jour les attributs des lignes vérifiant un critère :

UPDATE nom_table SET attr1 = v1,


attr2 = v2,

WHERE Critère;
attrN = vN
M
Exemple :

Modifier à 2 heures, la durée de l'épreuve ayant le nom 'Informatique' de la section 'T'.


FS
In [ ]: update Epreuves
set duree = 2
where section = 'T' and
nomEpr = 'Informatique '

4.5 Suppression des données


Supprimer toutes les lignes qui vérifient un critère de suppression :

DELETE FROM nom_table WHERE Critère;

Exemple :

In [ ]: # supprimer les épreuves de la section BG


DELETE FROM Epreuve WHERE section = 'BG';

5. Accès aux données : module SQlite3 de Python


Sqlite3 est un module (développé en langage C) qui permet à une application d’imiter un SGBD (pas de processus serveur).

In [ ]: import sqlite3
#permet d’accéder aux fonctionnalités exposés par ce module à partir d’un script python

L’utilisation de ce module est axée sur deux classes principales :

Connection : permet d’établir à une base de données sqlite

92
In [ ]: cnx = [Link](path) # path: chemin de la base de données
''' si le fichier indiqué par path n’existe pas il est créé, ensuite une instance
de la classe Connection qui représente une connexion à la base indiquée par
path est instanciée puis retournée.'''

In [ ]: cnx = [Link]('[Link]')
#permet de se connecter à la base de données [Link]

Curseur : permettant d’envoyer des requêtes et de recevoir les résultats

In [ ]: cur = [Link]()
'''retourne une instance de la classe Cursor permettant de manipuler la base de
données connectée '''

- Manipuler une BD
— Envoyer des requêtes SQL (sous forme de str)
— Récupérer le résultat d’une requête (SELECT)
— Confirmer la transaction courante :
— Fermer la connexion :

Envoyer des requêtes SQL (sous forme de str)

In [ ]: [Link](requêteSQL)
[Link](requêteSQL, itérable_paramètres)
[Link](requêteSQL, itérable_de_paramètres)

Récupérer le résultat d’une requête (SELECT) :

In [ ]: [Link]()
M
#retourne un tuple contenant une ligne du dernier SELECT renvoyé par le curseur
#(None) si la requête ne retourne pas de lignes
[Link](nbre_lignes)
#ramène une liste de tuple de taille (<= nbre_lignes)
[Link]()
#ramène une liste de tuples contenant toutes les lignes retournées par la requête.
[Link]
FS
#contient les titres des colonnes ramenés

Confirmer la transaction courante :

In [ ]: [Link]()

Fermer la connexion :

In [ ]: [Link]()

6. Exemples et Exercices d'application:


In [ ]: # création de la base de données [Link]
import sqlite3
cnx = [Link]('[Link]')
cur = [Link]()
req= '''
CREATE TABLE Etablissement
(
idEtab TEXT PRIMARY KEY ,
nom TEXT NOT NULL,
adresse TEXT,
gouv TEXT
);
'''
[Link](req) # Création de la table Etablissement
req='''
CREATE TABLE Candidat
( idC INT PRIMARY KEY,
nom TEXT,

93
date_naissance DATE,
sexe TEXT,
nationalite TEXT,
adresse TEXT,
section TEXT,
idEtab TEXT,
FOREIGN KEY(idEtab) REFERENCES Etablessment(idEtab)
);
'''
[Link](req) # Création de la table Candidat

In [ ]: req='''
CREATE TABLE Epreuves
( idEpr INT PRIMARY KEY,
nomEpr TEXT,
section TEXT,
date_ep DATE,
heure HEURE,
duree INT,
coeff INT
);
'''
[Link](req) # Création de la table Epreuves
req ='''
CREATE TABLE Evaluation
( idC INT,
idEpr INT,
note REAL,
PRIMARY KEY(idC,idEpr),
FOREIGN KEY (idC) REFERENCES Candidat(idC),
FOREIGN KEY (idEpr) REFERENCES Epreuves(idEpr)
);
'''
[Link](req) # Création de la table Evaluation
[Link]()
M
In [ ]: Etabs = [ ('FSM', 'faculté des scienecs de Monastir', 'avenue de l environnement', 'Monastir'),
('IPEIT', 'Institut préparatoire de Tunis','','Tunis'),
('IPEIN', 'Institut préparatoire de Nabeul','','Nabeul'),
('Libre','','','')
]
req= 'insert into Etablissement values(?,?,?,?)'
FS
[Link](req,Etabs)

In [ ]: Candidats =[
('001','Fourat','2000/06/19', 'H','Tunisienne','','MP','FSM'),
('002','Aymen','1999/05/10', 'H','Tunisienne','','PC','FSM'),
('003','Mariem','2001/01/15', 'F','Tunisienne','','MP','FSM'),
('004','Farah','1998/10/03', 'F','Tunisienne','','PC','Libre'),
('005','Aziz','2002/07/20', 'H','Tunisienne','','MP','IPEIT'),
('006','Rania','2002/07/20', 'F','Tunisienne','','BG','IPEIN'),
('007','Edriss','2002/07/20', 'H','Tunisienne','','MP','FSM'),
('008','Karim','2001/08/17', 'H','Tunisienne','','MP','IPEIT'),
('009','Med Ali','2001/09/04', 'H','Tunisienne','','MP','FSM'),
('010','Akrem','2002/05/13', 'H','Tunisienne','','BG','FSM')
]
req= '''insert into Candidat values (?,?,?,?,?,?,?,?)'''
[Link](req, Candidats)
[Link]()

In [ ]: for row in [Link]("SELECT * FROM candidat"):


print (row)

In [ ]: [Link]()
[Link]()

SQL
Dans la suite, en supposant que toutes les tables de la base de données [Link] ont été créées et remplies en
respectant les règles d'intégrités, exprimer en SQL les requêtes suivantes permettant de :

1. Déterminer les noms des établissements assurant un cycle préparatoire pour la section 'BG'.

In [ ]: select [Link]
from Etablissement E, Candidat C
94
where [Link] = [Link] and [Link] ='BG'

1. Déterminer les noms des candidats ainsi que leurs notes aux épreuves passées le 10 juin 2019. Le résultat doit être trié
par ordre décroissant suivant le nom.

In [ ]: select [Link] , [Link] , [Link]


from Candidat C , Evaluation Ev , Epreuves Ep
where [Link] = [Link] and
[Link] = [Link] and
Ep.date_ep = ' 2019/06/10'
orderBy [Link] DESC

1. Déterminer les identifiants des candidats ayant obtenu des notes supérieures à 15 à au moins 3 épreuves.

In [ ]: select idC, count(idEpr) as s


from Evaluation
where note > 15
groupBy idC
having s >= 3

1. Déterminer le nom et la date de naissance de la plus jeune candidate au concours.

In [ ]: select nom
from Candidat
where sex='F' and
date_naissance = ( select max(date_naiss)
from candidat
where sex='F'
)

Partie 3 : SQLITE
M
Dans la suite, on désigne par cur, le curseur d'exécution de requêtes associé à la base '[Link]' ayant le schéma
relationnel décrit précédemment. Les fonctions demandées doivent être écrites en Python.
FS
1. Ecrire la fonction Score_ candidat qui prend en paramètres cur et l'identifiant id d'un candidat, puis calcule et retourne
la valeur du score du candidat. On considère que le score d’un candidat est la somme des notes obtenues aux épreuves
multipliées chacune par le coefficient associé.

In [ ]: def Score_candidat(cur,id) :
req='''
select sum([Link] * [Link])
from Epreuve Ep , Evaluation Ev
where [Link] = [Link] and
[Link]=''' + str(id)
[Link](req)
L = [Link]()
score = L[0][0]
return score

1. Ecrire la fonction Maj_candidats qui, à partir du paramètre cur, ajoute une colonne nommée score à la table Candidat et
la met à jour en calculant le score de chaque candidat.

In [ ]: def maj_candidats(cur) :
# ajouter une colonne score à la table Candidat
req = 'alter table Candidat add column score real '
[Link](req)
[Link]()
req= 'select idC from Candidat'
L = [Link](req)
for elt in L :
idC= elt[0]
score = Score_candidat(cur, idC)
req ='update Candidat set score='+str(score) +'where idC='+ str(idC)
[Link](req)

95
1. Ecrire la fonction Admis qui prend en paramètres cur et un dictionnaire d_nbplaces où chaque clé est le nom d'une
section et la valeur est le nombre total de places disponibles associé. Cette fonction retourne un dictionnaire des admis
d_admis où chaque clé est le nom d'une section et la valeur est la liste des identifiants des candidats admis, triée par
leurs scores en ordre décroissant.

In [ ]: # d_nbplaces={'MP':1230, 'PC': 980 }


def Admis(cur, d_nbplaces):
d_admis=dict()
for section in d_nbplaces:
req='select idC from Candidat where section'+section+'order by score desc'
[Link](req)
L = [Link]()
L=[ t[0] for t in L]
N = d_nbplaces[section]
d_admis[section] = L[:N]
return d_admis

Une épreuve est dite discriminante si elle a le plus d’influence sur les résultats du concours. Le calcul de l’écart type des
notes peut permettre de déterminer l’épreuve discriminante du concours.
L’écart-type des notes d’une épreuve modélise le degré de dispersion des notes des candidats autour de la moyenne.
Ainsi, plus les notes sont largement distribuées autour de la moyenne, plus l’écart-type est élevé et plus l’épreuve est
discriminante. Dans le cas contraire, les notes seraient concentrées autour de la moyenne et l’épreuve n’aurait donc pas
une influence significative sur les scores des candidats.

Pour une épreuve donnée, considérons n candidats ayant obtenu les notes xi (1 < i <= n) .
La moyenne des notes à cette épreuve étant notée x̄,
n
2
l’écart-type des notes de cette épreuve s’écrit : σ
1
= √ ∑ (xi − x̄)
M n
i=1

1. Ecrire la fonction Notes qui prend en paramètres cur et l’identifiant idEpr d’une épreuve, puis retourne une liste
contenant les notes de tous les candidats qui ont passé cette épreuve.

In [ ]: def Notes(cur,idEpr):
FS
req= 'select note from Evaluation where idEpr='+str(idEpr)
[Link](req)
L=[Link]() # L= [(note1,), (note2,) ....]
return [i[0] for i in L]

1. Ecrire la fonction EcartType qui prend en paramètres cur et l’identifiant idEpr d’une épreuve puis calcule et retourne
l’écart-type des notes de l'épreuve.

In [ ]: def ecart_type(cur,idEpr):
L=Notes(cur,idEpr)
m= sum(L)/len(L)
Ecrt=0
for x in L:
Ecrt+=(x-m)**2
return [Link](Ecrt/len(L))

1. Ecrire la fonction Epreuves qui prend en paramètres cur et le nom s d’une section, puis retourne un ensemble
contenant des identifiants des épreuves de s.

In [ ]: def Epreuves(cur,s):
req= 'select idEpr from Epreuve where section="'+s+'"'
[Link](req)
L=[Link]()
return {i[0] for i in L}

1. Ecrire la fonction EcartTypesEpreuves qui prend en paramètres cur et le nom s d’une section, puis retourne un
dictionnaire où chaque clé est l'identifiant d’une épreuve de s et chaque valeur est l’écart-type des notes de cette
épreuve.

In [ ]: def ecartypeEpreuves(cur,s): l'identifiant

96
E=Epreuves(cur,s)
d_ecart={}
for idEpr in E:
d_ecart[idEpr]=ecart_type(cur, idEpr)
return d_ecart

1. Ecrire la fonction discriminante qui prend en paramètres cur et le nom s d’une section, puis retourne le nom de
l’épreuve la plus discriminante.

In [ ]: def discriminante(cur,s):
d=ecartypeEpreuves(cur,s)
m=-1
for idEpr in d :
if d[idEpr]>m:
m=d[idEpr]
discri=idEpr
req='select nom from epreuve where idEpr="'+str(discri)'"'
[Link](req)
return [Link][0]

M
FS

97

Vous aimerez peut-être aussi