Académique Documents
Professionnel Documents
Culture Documents
Programmation
Algorithmie
• Solution « informatique » relative à un problème
• Suite d’actions (instructions) appliquées sur des données
• 3 étapes principales :
1. saisie (réception) des données
2. Traitements
3. restitution (application) des résultats
Programme
• Transcription d’un algorithme avec une syntaxe prédéfinie
• Python
• Même principes fondamentaux que les autres langages objets (Delphi, Java, C#, etc.)
• Python s’enrichit de bibliothèques de calcul spécialisées (mathématique, bio
informatique, etc.)
Mode compilé vs. mode interprété
Langage interprété : + portabilité application ; - lenteur (R,
VBA, Python...)
Langage compilé : + rapidité ; - pas portable
(solution possible : write once, compile anywhere ; ex.
Lazarus)
Langage pseudo-compilé : + portabilité plate-forme ; -
lenteur (?) (principe : write once, run anywhere ; ex. Java et
le principe JIT)
Affectation simple
La seconde évite les ambiguïtés.
#typage automatique
a = 1.0
#typage explicite
a = float(1)
Affectations multiples
Pas fondamental
Conversion en numérique
a = « 12 » # a est de type chaîne caractère
b = float(a) #b est de type float
N.B. Si la conversion n’est pas possible ex. float(« toto »), Python
renvoie une erreur
Conversion en logique
a = bool(« TRUE ») # a est de type bool est contient la valeur True
a = bool(1) # renvoie True également
Conversion en chaîne de caractères
a = str(15) # a est de type chaîne et contient « 15 »
Opérateurs de comparaison
Sous Python, ces opérateurs sont <, <=, >, >=, != , ==
Saisie
a = input(« Saisir votre valeur »)
a = float(a)
Affichage
#Affichage explicite
print(a)
if condition:
bloc d’instructions
else:
bloc d’instructions
while condition:
bloc d’instructions
Remarque :
• Attention à l’indentation toujours
• On peut « casser » la boucle avec break
Définition des fonctions
• Fonction#Bloc d’instructions
• Prend (éventuellement) des paramètres en
entrée (non typés)
• Renvoie une valeur en sortie (ou plusieurs
valeurs, ou pas de valeurs du tout : procédure)
print(petit(10, 12))
print(petit(a=10,b=12))
print(petit(b=12, a=10))
print(petit(12, 10))
Valeur par défaut
#écriture de la fonction
10 15
def modifier_mutable(a,b):
a.append(8) [10, 8] [6]
b[0] = 6
print(a,b)
#écriture de la fonction
def extreme(a,b): if (a < b):
return a,b
else:
return b,a
#appel
x = 10
y = 15
vmin =10 et vmax=15
vmin,vmax = extreme(x,y)
print(vmin,vmax)
Fonction renvoyant plusieurs valeurs (1)
<class ‘tuple’>
v est un « tuple », une collection de valeurs, à
voir plus tard.
Fonction renvoyant plusieurs valeurs (2)
Nous pouvons aussi passer par une structure
intermédiaire telle que la liste ou le dictionnaire
d’objets. Les objets peuvent être de type différent, au
final l’outil est très souple. (nous verrons plus en
détail les listes et les dictionnaires plus loin)
#appel #appel
x = 10
x = 10
y = 15
y = 15
res = extreme_liste(x,y) res = extreme_dico(x,y)
print(res[0])
print(res['mini'])
Visibilité (portée) des variables
1. Les variables définies localement dans les fonctions sont
uniquement visibles dans ces fonctions.
2. Les variables définies (dans la mémoire globale) en dehors de
la fonction ne sont pas accessibles dans la fonction
3. Elles ne le sont uniquement que si on utilise un mot clé
spécifique
#fonction #fonction #fonction
def modif_1(v): def modif_2(v): def modif_3(v):
x=v x=x+v
global x
#appel x=x+v
#appel x = 10
x = 10 modif_2(99) #appel
modif_1(99) print(x) x = 10
print(x)# 10 modif_3(99)
x n’est pas assignée ici,
l’instruction provoque une ERREUR
print(x)# 109
Imbrication des fonctions
#appel
x = 10
print(externe(x)) # renvoie 60
print(interne(x)) # provoque une erreur
Principe des Modules
• Un module est un fichier « .py » contenant un
ensemble de variables, fonctions et classes que l’on peut
importer et utiliser dans le programme principal (ou
dans d’autres modules).
• Le mot clé import permet d’importer un module
• C’est un pas supplémentaire vers la modularité : un
module maximise la réutilisation et facilite le partage du
code
• Des modules standards prêts à l’emploi sont livrés
avec la distribution Python. Ex. random, math, os,
hashlib, etc.
• Ils sont visibles dans le répertoire « Lib » de Python
Exemple d’utilisation de modules standards
#importer les modules
#math et random
import math, random
#affichage
print(abslog)
Autres utilisations possibles
#importer le contenu
#définition d'alias #des modules
import math as m, random as r from math import log, pow
from random import seed, random
#utilisation de l'alias
r.seed(None)
#utilisation directe
value = r.random()
seed(None)
logv = m.log(value) value = random()
logv = log(value)
abslog = m.pow(logv,2.0)
abslog = pow(logv,2.0)
LES TUPLES Tableau statique en lecture seule d’objets hétérogènes
#plage d'indices
#définition d'un
b = t1[2:5]
tuple
print(b)
t1 = (2,6,8,10,15,26)
#autre plage
print(t1)
#taille du tuple c = t1[:4]
print(c)
print(len(t1))
#indiçage négatif
#accès indicé
a = t1[0] d = t1[-1]
print(a) print(d)
#modification ? #indiçage négatif
t1[2] = 3
ERREUR e = t1[-3:]
print(e)
Plus loin avec les tuples
#concaténation
t2 = (7, 9,31)
t3 = t1 + t2
print(t3)
#réplication
t4 = 2 * t2
print(t4)
#tuples d'objets hétérogènes
v1 = (3,6,"toto",True,34.1)
print(v1)
Plus loin avec les tuples
#tuple de tuples
x = ((2,3,5),(6,7,9),(1,8))
print(x)
#accès indicé
print(x[2][1])
#accès aux tailles
print(len(x))
print(len(x[2]))
LES LISTES
Liste ≈ tuple de taille dynamique et modifiable
#accès indicé = 2
• indiçages négatifs
a = L1[0] • objets hétérogènes
print(a)
• liste de listes (tableaux 2D ou +)
#modification ! Possible ! • concaténation, réplication
L1[2] = 3
print(L1)
Plus loin avec les listes
#autre liste #accès + suppression elt n°1
L2 = [32,69,28,69] a = L2.pop(1)
#ajout
[32,69,69,21]
L2.append(21)
print(L2) print(a) ! renvoie 53
[32,69,28,69,21] #inversion
L2.reverse()
#insertion à l'indice 1 print(L2)
L2.insert(1,53) [21,69,69,32]
print(L2) #étendre
[32,53,69,28,69,21] L2.extend([34,55])
print(L2)
[21,69,69,32,34,55]
#suppression elt n°3
del L2[3]
#Permet de vider la liste
print(L2) L2.clear()
[32,53,69,69,21]
Les « List Comprehensions »
Objectif : un mécanisme simple (et concis) pour générer une liste à partir d’une autre liste.
source = [1,5,8,12,7]
resultat = []
for v in source: resultat = [v**2 for v in source]
resultat.append(v**2) print(resultat)
print(resultat)
source = [1,5,8,12,7]
resultat = []
for v in source:
if (v % 2 == 0):
resultat = [v**2 for v in source if (v % 2 == 0)]
resultat.append(v**2) print(resultat)
print(resultat)
Plus loin avec les listes
L2 = [21,69,69,32,34,55]
#recherche d'élément
trouve = 32 in L2
print(trouve)
#index
id = L2.index(34)
print(id)
#comptage
nb = L2.count(69)
print(nb)
#retrait par valeur
L2.remove(69)
print(L2)
Une variable de type liste est une référence
#L3
L3 = [61,92,17]
print(L3)
#affectation ?
L4 = L3
print(L4)
#modification d'une valeur L4[1] = 55
#répercussions
print(L4) ! [61,55,17] #mais aussi sur
L3
print(L3) ![61,55,17] ???
Une variable de type liste est une référence
#L3
L3 = [61,92,17]
#copie des valeurs
L4 = L3.copy() print(L4)
L4[1] = 55
print(L4) ! [61,55,17]
print(L3) ! [61,92,17] !!!
CHAÎNE DE CARACTÈRES
Une chaîne de caractères est une liste particulière avec des méthodes associées
#méthodes associées
#définir une chaîne S = s1.upper()
s1 = "bonjour le monde"
print(S)
print(s1)
#longueur
#recherche d'une sous-chaîne
id = S.find("JO")
long = len(s1)
print(id)! 3 (1ère occurrence
print(long) si plusieurs)
#accès indicé #nb d'occurences
s2 = s1[:7] nb = S.count("ON")
print(nb)! 2
print(s2)
#remplacement de « O » par « A »
#non modifiable
SA = S.replace("O","A")
#s1[0] = "B" print(SA)
Transformation explicite en liste
#transf. en liste
liste = list(S)
print(liste)
[‘B’,’O’,’N’,’J’,’O’,’U’,’R’,’ ‘,’L’,’E’,’ ‘,’M’,’O’,’N’,’D’,’E’]
Termes techniques :
• « Classe » est la structure ;
• « Objet » est une instance de la classe (variable obtenue après instanciation) ;
• « Instanciation » correspond à la création d’un objet
• L’objet est une référence (traité par le ramasse-miettes, destruction explicite
inutile)
Définition et implémentation d’une classe
#début définition
class Personne:
"""Classe Personne"""
...
#copie des infos
def copie(self):
q = Personne()
q.nom = self.nom
q.age = self.age
q.salaire = self.salaire
return q
#fin copie
#fin définition
Une fonction peut renvoyer un objet (instance de classe)
#instanciation
p = MP.Personne()
#saisie
p.saisie()
print(">> Affichage de p")
p.affichage()
#copie
q = p.copie()
print(">> Affichage de q")
q.affichage()
#comp. références
pareil = (p == q)
print("ref. identiques : %s" % (pareil))
Héritage
Déclaration en Python
class Employe(Personne):
...
Surcharge des méthodes
#classe Employé
class Employe(Personne): Surtout pas de copier/coller de code !
#constructeur Noter comment sont réutilisées les
méthodes programmées dans la classe
def __init__(self):
ancêtre Personne.
Personne.__init__(self) Remarque : Noter l’utilisation de self dans
self.prime = 0.0 ce contexte.
#fin constructeur
#saisie # -*- coding: utf -*-
def saisie(self): #appel du module
Personne.saisie(self)
import ModulePersonne as MP
self.prime = float(input("Prime : ")) #instanciation
#fin saisie e = MP.Employe()
#affichage #saisie
def affichage(self): e.saisie()
Personne.affichage(self) #affichage
print("Sa prime : ", self.prime) print(">> Affichage")
#fin affichage #fin classe Employé e.affichage()
polymorphisme
# -*- coding: utf -*-
#appel du module
import ModulePersonne as MP
liste = [] #liste vide
n = int(input("Nb de pers : ")) #nb. de pers ?
#instanciation
for i in range(0,n):
code = input("1 Personne, 2 Employé : ")
if (code == "1"):
m = MP.Personne()
else:
m = MP.Employe()
liste.append(m)
#saisie liste
for p in liste:
Selon la classe réellement instanciée
print("-------")
p.saisie() (Employe ou Personne), les méthodes saisie()
#affichage et affichage() adéquates seront appelées.
for p in liste: C’est l’idée du polymorphisme.
print("-------")
p.affichage()
Variable de classes
x = np.array([1.2,1.3,1.0])
a = np.array([True,True,False,True],dtype=bool)
y = np.array([2.1,0.8,1.3]) b = np.array([True,False,True,False],dtype=bool)
#opérations ensemblistes
x = np.array([1,2,5,6])
y = np.array([2,1,7,4])
#intersection
print(np.intersect1d(x,y)) # [1 2]
#union – attention, ce n’est pas une concaténation
print(np.union1d(x,y)) # [1 2 4 5 6 7]
#différence c.à-d. qui sont dans x et pas dans y
print(np.setdiff1d(x,y)) # [5 6]
CRÉATION D’UNE MATRICE
import numpy as np
a = np.array([[1.2,2.5],[3.2,1.8],[1.1,4.3]])
Noter le rôle des [ ] et [ ] pour délimiter les portions de la matrice
#type de la structure
print(type(a)) #<class ‘numpy.ndarray’>
#type des données
print(a.dtype) #float64
#nombre de dimensions
print(a.ndim) #2 (car c’est une matrice)
#nombre de lignes et col, shape renvoie un tuple
print(a.shape) #(3,2)!3 lignes et 2 colonnes
#nombre totale de valeurs
print(a.size) #6, nb.lignes x nb.colonnes
Création d’une matrice à partir d’une séquence
#création à partir d'une séquence. Les dim. doivent être compatibles
a = np.arange(0,10).reshape(2,5)
print(a)
#un vecteur peut être converti en matrice
a = np.array([2.1,3.4,6.7,8.1,3.5,7.2])
print(a.shape) # (6,)
#redim. en 3 lignes x 2 col.
b = a.reshape(3,2)
print(b.shape) # (3, 2)
print(b)
#matrices de valeurs identiques
#ex. pour une initialisation
a = np.zeros(shape=(2,4))
print(a)
#plus généralement
a = np.full(shape=(2,4),fill_value=0.1)
print(a)
Chargement à partir d’un fichier
#charger à partir d'un fichier, typage explicite
#séparateur de colonne = tabulation « \t »
a = np.loadtxt("matrice.txt",delimiter="\t",dtype=float)
La première ligne doit être ignorée dans ce fichier, d’où le symbole # en début
de 1ère ligne.
Conversion d’une collection (type standard Python) en type
array de « numpy »
#liste de valeurs
lst = [1.2,3.1,4.5,6.3]
print(type(lst)) # <class ‘list’>
#conversion à partir d'une liste : 2 étapes asarray() et reshape()
a = np.asarray(lst,dtype=float).reshape(2,2)
print(a)
Redimensionnement
#matrice de valeurs
a = np.array([[1.2,2.5],[3.2,1.8],[1.1,4.3]])
#ajouter une ligne – marche pour la concaténation de matrices
b = np.array([[4.1,2.6]])
c = np.append(a,b,axis=0)
#ajouter une colonne
d = np.array([[7.8],[6.1],[5.4]])
print(np.append(a,d,axis=1))
#insertion
print(np.insert(a,1,b,axis=0))
#suppression
print(np.delete(a,1,axis=0))
#modifier la dimension d'une matrice existante
#parcourt les données lignes par ligne
np.resize(a,new_shape=(2,3))
Accès indicé – Plages d’indices
v = np.array([[1.2,2.5],[3.2,1.8],[1.1,4.3]])
print(v) #affichage de la structure dans son ensemble
#accès indicé - première valeur
print(v[0,0]) # 1.2
#dernière valeur – noter l’utilisation de shape (qui est un tuple)
print(v[v.shape[0]-1,v.shape[1]-1]) # 4.3
#autre solution pour affichage de toutes les valeurs, noter le rôle des :
print(v[:,:])
#plage d'indices contigus : lignes 0 à 1 (2 non inclus), toutes les colonnes
print(v[0:2,:])
#extrêmes, début to 2 (non-inclus)
print(v[:2,:])
#extrêmes, lignes 1 à dernière
print(v[1:,:])
#indice négatif – dernière ligne et toutes les colonnes
print(v[-1,:])
#indices négatifs – deux dernières lignes et toutes les colonnes
print(v[-2:,:])
Tri et recherche
#recherche valeur max des lignes (axis = 0) pour chaque colonne
print(np.max(v,axis=0)) # [ 3.2 4.3 ] -- décryptage : 3.2 est la max
des lignes pour la colonne 0, 4.3 est la max des lignes pour la
colonne 1
#recherche valeur max des colonnes (axis = 1) pour chaque ligne
print(np.max(v,axis=1)) # [ 2.5 3.2 4.3]
#recherche indice de valeur max des lignes (axis = 0)pour chaque
colonne
print(np.argmax(v,axis=0)) # [ 1 2 ]
#tri des lignes (axis = 0) pour chaque colonne
#la relation entre les valeurs d'une même ligne est perdue !!!
print(np.sort(v,axis=0))
#récupération des indices triés
print(np.argsort(v,axis=0))
Parcours d’une matrice : boucle indicées
#boucles indicées
s = 0.0
for i in range(0,v.shape[0]):
for j in range(0,v.shape[1]):
print(v[i,j])
s = s + v[i,j]
print("Somme = ",s)
Parcours d’une matrice : les itérateurs
#itérateur - accès ligne par ligne
s = 0.0
for x in np.nditer(v):
print(x)
s=s+x
print("Somme = ",s)
#itérateur - accès colonne par colonne
#"F" pour " Fortran order "
s = 0.0
for x in np.nditer(v,order="F"):
print(x)
s = s +x
print("Somme = ",s)
CALCUL MATRICIEL
#transposition
print(np.transpose(x))
#multiplication
print(np.dot(x,y))
#déterminant
print(np.linalg.det(y))
#inversion
print(np.linalg.inv(y))
CALCUL MATRICIEL
#résolution d'équation
z = np.array([1.7,1.0])
print(np.linalg.solve(y,z))
#vérification
print(np.dot(np.linalg.inv(y),z))
#matrice symétrique avec XTX
s = np.dot(np.transpose(x),x)
print(s)
#val. et vec. propres d'une matrice symétrique
print(np.linalg.eigh(s))