Révision Python pour Classes Préparatoires
Révision Python pour Classes Préparatoires
A.U 2022-2023
M
FS
Faculté des Sciences de Monastir
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
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
int(22.5) #22
# Nombres flottants :
x = float('22.2')
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 [ ]: #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
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.
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 [ ]: 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
In [ ]: '/'.join(L)
Out[ ]: 'python1/python2/python3/python4/python5'
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).'''
5
In [ ]: ch=f'A.U {21}/{22} FSM'
ch
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 [ ]: 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
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)
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
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 [ ]: # Exemple :
5 in (1,5,[1,3]) # True
3 in (1,5,[1,3]) # False
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]
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 [ ]: #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
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 :
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.
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 [ ]: # Exemple :
d = {}
d["a"] = 33 #insertion
d #{"a" :33}
d["a"] = 22 #mise à jour
d # {"a" :22}
[Link]({'b':11})
d
# Exemple :
d = {1:2, "a":10}
for k in d:
print(k)
for k, v in [Link]():
print(k,v)
In [ ]: for i in range(len(d)):
d[i] # KeyError
In [ ]: L=[(1,'a'),(2,'b')]
d=dict(L)
d
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
Out[ ]: 11j
In [ ]: def f(z) :
return [Link]
# ou bien
f = lambda z:[Link]
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)
In [ ]: L=[1,2,3]
L*3
Out[ ]: [1, 2, 3, 1, 2, 3, 1, 2, 3]
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
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))
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 [ ]: # Exemple :
def f(x,y) :
import math
z = x**2 + [Link](y)
return z
result = f(2,3)
result
Out[ ]: 4.141120008059867
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
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.)
Out[ ]: 8
La récursivité
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:])
Les exceptions sont des objets spéciaux permettant de représenter une erreur d’exécution dans un script Python.
Ces derniers sont des classes Python héritant toutes de la classe de base Exception permettant de représenter une Erreur quelconque.
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
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")
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 [ ]: [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. :
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
Analyse de la complexité :
Exemple :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
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
Augmentation très faible du temps d’exécution quand la taille des données s'accroît
18
Faculté des Sciences de Monastir
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.
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.
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().
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)
'P(-1 ,5 , 3)'
Out[ ]:
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 [ ]: compte2 = CompteBancaire()
[Link]()
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.
+ : __add__(self,other)
* : __mul__(self, other)
- : __sub__(self,other)
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[ ]:
(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 :
13
Out[ ]:
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.
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 ‘*’
In [ ]: class Complexe:
def __init__(self,reelle ,imaginaire):
# C'est le constructeur de la classe Complexe
[Link]=reelle
[Link]=imaginaire
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 '*' """
def __str__(self):
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])
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])
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 :
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()
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:
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"
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.
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.
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
[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
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)
[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]
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 :
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
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]
[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
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.
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.
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
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
In [ ]: [Link].
FS
La rubrique d'aide est également précieuse
In [ ]: ?[Link]
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 :
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
34
In [ ]: def python_forloop_list_approach(x, w):
z = 0.
for i in range(len(x)):
z += x[i] * w[i]
return z
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))
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
M # same as [Link](x, w)
# and same as x @ w
return [Link](w)
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.
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
[[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]]])
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.
Out[2]: [Link]
Out[4]: dtype('int64')
Out[5]: 8
Out[7]: (5,)
Out[8]: 5
36
In [9]: # On retourne le nombre de dimensions
[Link]
Out[9]: 1
Out[10]: 40
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.
M
FS
In [ ]: [Link]
Out[ ]: (2, 3)
Out[ ]: dtype('int64')
In [ ]: [Link]
Out[ ]: 6
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
In [ ]: [Link]
Out[ ]: (3, 2, 5)
M
FS
La fonction arange
In [20]: #un vecteur d'entiers allant de 0 à 4. (la borne sup est exclue)
[Link](5)
38
In [12]: # #un vecteur de flottants de 0. à 4.
[Link](5, dtype=float)
In [ ]: # range(0, 1, 0.2) #Erreur : range prend uniquement des valeurs entières comme arguments
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. ])
Out[ ]: (50,)
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)
In [ ]: ?[Link]()
In [21]: # utiliser la fonction [Link] pour générer une matrice 3x3 formée par des nombres complexes.
[Link]((3,3),[Link])
[[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 [ ]: [Link]
Out[ ]: (5, 5)
In [ ]: m+ (1+2j)
In [ ]: [Link](m)
In [ ]: # ou encore
[Link]((2,4)) * (3+2j)
La matrice identité :
In [ ]: # en utilisant la méthode [Link]() générer une matrice identité de taille 4 avec dtype=np.b
ool
[Link](4,[Link])
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)
M Out[27]: array([[0.,
La fonction diag :
[0.,
[0.,
[0.,
[0.,
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
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])
In [ ]: [Link](_,2)
42
In [ ]: f=lambda i,j : i-j
[Link](f, (3,3))
Out[ ]: array([ 0., 1., 4., 9., 16., 25., 36., 49., 64., 81.])
---------------------------------------------------------------------------
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
<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]()
In [ ]: import numpy as np
l = [1,2,3]
a = [Link](l)
a
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
Out[ ]: [1, 2, 3, 1, 2, 3]
Out[ ]: [1, 2, 3, 1, 2, 3, 1, 2, 3]
In [ ]: a
In [ ]: a
In [ ]: a**2
M Out[ ]: array([1, 4, 9])
In [ ]: a + a
In [ ]: [Link](a-0.1)
In [ ]: [Link](a)
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
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)
In [ ]: fv = [Link](signe)
In [ ]: fv(a)
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,
Application 2 :
FS
In [ ]:
f = lambda i,j : 1 if i==j else 0
fv= [Link](f)
[Link](fv, (5,5))
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)
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
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]],
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 [ ]: [Link]
Out[ ]: dtype('complex128')
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
In [ ]: [Link]
In [ ]: [Link]
In [ ]: [Link] = 5
In [ ]: z
In [ ]: [Link] = [Link](2,3, k= 1)
In [ ]: z
47
In [ ]: z.T #transposée du vecteur
Exemple 2:
In [ ]: a=[Link](6)
#[Link]=(3,2)
a
In [ ]: [Link](a)
In [ ]: [Link] = (2,3)
a
In [ ]: [Link]()
M In [ ]: [Link] = (3,1)
# Erreur
---------------------------------------------------------------------------
ValueError
In [ ]: a = [Link](3)
b = [Link](1,5,9).reshape(3,3)
In [ ]: a
In [ ]: b
In [ ]: [Link](b)
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]()
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. ]])
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
In [ ]: b = [Link]((2,5))
In [ ]: b
In [ ]: a
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
In [ ]: b
In [ ]: c
In [ ]: b[0,0] = 100
In [ ]: b
In [ ]: a
In [ ]: c
In [ ]: import numpy as np
lst= [[1,2,3],[4,5,6]]
ary = [Link](lst)
ary
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:
[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])
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.]]
1.,
2.,
3.,
4.,
1.,
2.,
3.,
4.,
1.],
2.],
3.],
4.]])
Exemple : 3
In [ ]: m1 = [Link]([[1,0,1,0]])
[Link]
m1
In [ ]: """
m1 = [Link]([1,0,1,0])
m2 = [Link]((4,3))
print([Link](m2))
print([Link](m1))
"""
[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)
Out[41]: 0
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
In [ ]: [Link]([Link])
M
Méthodes d'agrégation
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
FS
[Link]
[Link]
[Link]
[Link]
In [ ]: a
52
In [45]: # Return the maximum along axis 1
[Link](axis=1)
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)
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
In [ ]: [Link]()
Out[ ]: 1.25
[3, 4]])
sN =
N
∑ (x i − x̄ )
i=1
FS
In [ ]: [Link](axis=0)
In [ ]: [Link](axis=1)
[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
In [46]: # Exemple 2
[Link]((3,3))+[Link](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
In [50]: [Link]
Out[50]: 5
#Afficher le dernier
print(a[-1])
0
4
54
indexage 2D
In [ ]: m = [Link]([1,2,3,4])
m
m[0] = [1 0 0 0]
m[-1] = [0 0 0 4]
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]]
Exemple 2 :
55
Exemple : 3
In [59]: v = [Link](5)
v
In [61]: m = [Link]([1,2,3,4])
m
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]
Exemple : 4
In [ ]: face= [Link]()
[Link](face)
[Link]()
56
In [ ]: print(type(face))
print([Link])
<class '[Link]'>
(768, 1024, 3)
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 [ ]: # axis = 1
[Link](axis=1)
In [ ]: # axis = 0
[Link](axis=0)
transpose method
[Link]()
58
In [ ]: matrix.T
In [ ]: [Link](matrix, [Link]())
M In [ ]: matrix @ matrix.T
Importation
[32, 77]])
FS
In [66]: from numpy import linalg
Out[68]: -2.0000000000000004
Out[69]: 2
In [37]: [Link](m)
Out[37]: array([[-2. , 1. ],
[ 1.5, -0.5]])
59
In [41]: linalg.matrix_power(m,2)
In [39]: m**2
In [ ]: [Link](a)
In [ ]: [Link](a)
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[48]: True
(S ) ⎨ x − 3 y + 2 z = −2
⎩
5 x − y + 4 z = 10
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])
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 :
importation du module
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ù :
Exemples :
Exemple 1 :
print ("integral value =", val, ", absolute error =", abserr)
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:
print ("integral value =", val, ", absolute error =", abserr)
Exemple 3 :
+∞
2
−x
∫ exp dx
−∞
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 =
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
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)
In [ ]: I = [Link](5)
print(I)
1.373400766945016
Exemple :
π/2
nous savons que ∫0 sin(x) dx = 1
63
In [69]: a = 0
b=[Link]/2
N= 10
dx = (b-a)/N
In [ ]: quad([Link],0,[Link]/2)
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
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
⎧ 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
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 :
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 [ ]:
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
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
⎨ θ′ (0) = 0
⎪
⎪
⎪ b = 0.25
⎪
⎩
⎪
c = 5
′
θ (t) = ω(t)
′
ω (t) = −b ∗ ω(t) − c ∗ sin(θ(t))
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.
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
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 :
[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
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 [ ]: bisection(f,0,1,10)
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 ,
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
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 )
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
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
]
In [ ]: [Link](f,(5.0,5.0))
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.))
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:
Le paquet misc dans SciPy est livré avec quelques images. Nous utilisons ces images pour apprendre les manipulations d'images. Prenons l'exemple
suivant.
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.
110.16274388631184 255 0
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
72
Fonction interessantes
[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 [ ]:
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]")
M
Exercice 1
{
Pi,j ∈ [0, 1]
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
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
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.
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
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
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
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
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
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)
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
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]()
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)
In [ ]:
81
Faculté des Sciences de Monastir
3ème Partie :
Les bases de données
avec Python
Les objectifs :
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.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.
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
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.
Contrainte_1,
...
Contrainte_K
);
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 :
M
FS
Les requêtes de création de tables :
);
85
section TEXT,
date_ep DATE,
heure INT,
duree INT,
coeff INT
);
Suppression d’une table : Toute table peut être supprimée à l’aide de DROP .
Ajout d’une colonne : Pour ajouter une colonne à une table, on utilise ALTER.
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 ,
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 )
Exemple :
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 :
L’expression :
σsection=′ M P ′ (Candidat)
In [ ]: # en SQL
SELECT nom
FROM Candidat
WHERE section ='MP' and idEtab = 'Libre';
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)
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 ) .
ou bien
ou en SQL
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 )
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 :
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 ,
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
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 }
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 }
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 }
SELECT * FROM R1
EXCEPT
SELECT * FROM R2;
Exemple :
Les identifiants des candidats qui n'ont passé aucune épreuve du concours.
In [ ]: # en SQL
select idC from Candidat
EXCEPT
select DISTINCT idC from Evaluation
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
Déterminer pour chaque épreuve le nombre des candidats ayant obtenu des notes supérieures à 10.
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
Exemples :
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]()
WHERE Critère;
attrN = vN
M
Exemple :
Exemple :
In [ ]: import sqlite3
#permet d’accéder aux fonctionnalités exposés par ce module à partir d’un script python
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]
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 :
In [ ]: [Link](requêteSQL)
[Link](requêteSQL, itérable_paramètres)
[Link](requêteSQL, itérable_de_paramètres)
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
In [ ]: [Link]()
Fermer la connexion :
In [ ]: [Link]()
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 [ ]: [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.
1. Déterminer les identifiants des candidats ayant obtenu des notes supérieures à 15 à au moins 3 épreuves.
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.
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.
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