Qui ne tente rien n’a rien ! 1 Python Proverbe Français Chapitre 0 : Rappel général Résumé du cours 1ère année 2 Plan o Introduction o Les types de bases o Les types élémentaires o Les conteneurs : les séquences o Les types mutables o Les types non mutables o Le langage Python o Les Opérations élémentaires o o o o o Affectation o Entrée / Sortie Les structures conditionnelles Les structures itératives Les sous programmes Gestion des erreurs 3 Introduction Python est un Langage Orienté Objet Tout est objet : données, fonctions, modules... Un objet B possède: o identité id (adresse mémoire), id(B) o Un type type(B): (intrinsèque : int, float, str, bool ... Ou définit par l’utilisateur à l’aide d’une classe) o contient des données (valeurs). o L’opérateur is compare l’identité de 2 objets (adresses) o L’opérateur == compare le contenu de deux objets 4 Les types sous Python Les types sous Python Les types élémentaires Les conteneurs Non Mutables Ordonnés Tuples Chaines de caractères Ordonnés Les listes Mutables Non Ordonnés Ensembles Dictionnaires 5 Les types élémentaires • le NoneType : seule valeur possible None Ex: c’est la valeur retournée par une fonction qui ne retourne rien • Le type bool : deux valeurs possible True et False (1ou 0) • Les types numériques Le type int x=898 Le type float x=8.98 Le type complex z=8+1j*8, z.real; z.imag; z.conjugate() 6 Les types élémentaires (suite) Le type entier : <classe int> >>> x=3 >>> y=6 >>> type(x),type(y) (<class 'int'>, <class 'int'>) Les opérations arithmétiques , + , *, **, /, //, % >>> z=x+y z= x.__add__(y) 9 >>> z 9 >>> x-y z= x.__sub__(y) -3 >>> x*y 18 7 Les types élémentaires (suite) >>> x**y # puissance 729 >>> pow(x,y) 729 >>> x/y # division réelle 0.5 >>> x//y #quotient de la division entière 0 >>> x%y #reste de la division entière 3 Les opérateurs de comparaison : <, <=, !=, ==, >, >= >>>x==y False >>>x>=y False >>>x<=y True >>>x!=y True 8 Les types élémentaires (suite) Le type réel: <Class float> >>> x=12/7; y=4. >>> x;y 1.7142857142857142 4.0 >>> type(x); type(y) <class 'float'> <class 'float'> Les opérations arithmétiques + , *, **, /, //, % >>> x+y 5.714285714285714 >>> x-y -2.2857142857142856 >>> x*y 6.857142857142857 Les opérateurs de comparaison <, <=, >,>=,==, != >>> x/y 0.42857142857142855 >>> x**y 8.636401499375259 >>> x/y 0.42857142857142855 >>> x//y 0.0 >>> x%y 1.7142857142857142 >>> x=12/5 >>> x 2.4 >>> int(x)# Passage de réel en entier l’objet retourné est un nouvel objet 2 9 Les types élémentaires (suite) Le type booléen : class Bool La classe Bool hérite de la classe int >>> x=3 ; y=4 ; z=3 >>> B=x==y >>> B False >>> E=x<y >>> E True >>> B and E False >>> B or E True >>>int(True) 1 >>>int(False) 0 Les opérations logiques and, or, not… Les conteneurs sous Python : types structurés Un conteneur est un objet composite destiné à contenir d’autres objets: nous distinguons les séquences, les tableaux associatifs, les ensembles et les fichiers textuels. Les conteneurs sont des objets itérables. Deux classements sont possibles : 1) Mutables et Non Mutables mutable : modification autorisée non mutable: modification non autorisée 2) Ordonnés et Non ordonnés 10 11 Les conteneurs sous Python : Les séquences Une séquence est un conteneur ordonné d’éléments indexés par des entiers indiquant leur position dans le conteneur. Les indices commencent par 0 Si S est une séquence o S[i] retourne (i+1)ième élément de S o S[ :a] :sous séquence d’éléments de début jusqu’à l’élément d’indice a exclu o S[a: ] : sous séquence d’éléments de l’indice a inclus jusqu’à la fin o S[ : ] : toute la séquence o S[a:b] : sous séquence d’éléments allant de l’indice a inclu jusqu’à l’élément d’indice b exclu o S[a:b:c] :sous séquence d’éléments de l’indice a inclu jusqu’à indice b exclu par pas égal à c 12 Les séquences : Les listes Une liste est une collection ordonnée et modifiable d’objets éventuellement hétérogènes séparés par des virgules et définis entre crochets []. • len(L) nombre d’éléments . • L[i] élément de rang i. • Un indice négatif permet d'accéder aux éléments à partir de la fin (dernier L[-1] et son premier L[-len(L)]) 13 Les listes : Indexation et Slicing Création et Accès Slicing >>> L=[1,2, 3,6,1.3, ‘hello’, ‘’bb’’] >>> len(L) 7 >>> L[3:] [6, 1.3, 'hello', 'bb'] >> L[0] 1 >>> L[:5] [1, 2, 3, 6, 1.3] >>> L[len(L)-1] ‘bb’ >>> L[2:5] [3, 6, 1.3] >>> L[-1] ‘bb’ >>L[1:7:2] ou L[1::2] [2, 6, 'hello'] >>> L[:] [1, 2, 3, 6, 1.3, 'hello', 'bb'] >>> L[7] >>L[::2] #parcourir la liste par 2 [1, 3, 1.3, 'bb'] >>> L[::-1] #inverser l’ordre de L ['bb', 'hello', 1.3, 6, 3, 2, 1] ...IndexError: list index out of range Les listes (suite) Création (suite) >>>L_vide=[] >>>L=list(range(5)) >>>L+[0,3,1] # l’opérateur + concatène les listes et donne une nouvelle liste [0,1,2,3,4,0,3,1] >>> L # L reste inchangée !!!! [0,1,2,3,4] >>>L*2 # L’opération list*n ou n*list concatène n copies de la liste [0,1,2,3,4, 0,1,2,3,4] >>>L=L*2 >>>L [0,1,2,3,4, 0,1,2,3,4] >>>L=list(range(5)) >>> L [0, 1, 2, 3, 4] >>> L+[1]*4 [0, 1, 2, 3, 4, 1, 1, 1, 1] >>> L [0, 1, 2, 3, 4] 14 15 Les listes(suite) Copie d’une liste >>> L=list(range(10)) >>> L [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> L1=L # Attention les deux listes référencient le même objet en mémoire >>> L.append(5) # ajoute 5 en fin de liste >>> L1 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 5] >>> id(L), id(L1) (46713952, 46713952) 16 Liste -copie de liste (suite) • Pour recevoir une copie de liste indépendante, plusieurs manières existent: >>> L2=L[:] >>> id(L),id(L1),id(L2) (46713952, 46713952, 37856880) Ou encore >>>from copy import * >>> L3=copy(L) >>> id(L), id(L1),id(L2), id(L3), (46713952, 46713952, 37856880, 46752632) Ou encore >>>L4=deepcopy(L) 17 Listes : Méthodes prédéfinies >>> nbr=[17,38,10,25,72] >>> nbr.sort() >>> nbr [10, 17, 25, 38, 72] >>> nbr.append(12) >>> nbr [10, 17, 25, 38, 72, 12] >>> nbr.reverse() >>> nbr [12, 72, 38, 25, 17, 10] >>> nbr.remove(38) >>> nbr [12, 72, 25, 17, 10] >>> nbr.index(17) 3 >>> nbr[0]=11 >>> nbr [11, 72, 25, 17, 10] >>> nbr[1:3]=[14,17,2] >>> nbr [11, 14, 17, 2, 17, 10] >>> nbr.pop() 10 >>> nbr.pop() 17 >>> nbr [11, 14, 17, 2] >>> nbr.extend([17,3,6]) >>> nbr [11, 14, 17, 2, 17, 3, 6] >>> nbr.count(17) 2 18 Les séquences : Les chaînes de caractères Une chaîne de caractère est une séquence de caractère unicode. la classe str, Syntaxe • C’est une séquence de caractères entre simple ou double côtes non modifiable ! • Même principe d’indexation que les listes Exemple: >>> ch1='toto' >>> type(ch1) <class 'str'> >>> ch_vide=‘’ >>>ch_vide1="" >>>ch_vide==ch_vide1 True 19 Les chaînes de caractères (suite) >>> ch="bonjour" >>> ch_vide="" >>> ch_n_vide=" " >>> ch_vide==ch_n_vide False >>> ch[0] 'b' >>> ch[-1] 'r' >>> len(ch) 7 >>> ch[:3] 'bon' >>> ch[3:] 'jour' >>> ch[2:5] 'njo' >>> ch[::-1] 'ruojnob' Opérateurs + et * >>> ch='bon' >>> ch1='jour' >>> ch +ch1 'bonjour' >>> ch2=ch +ch1 >>> ch2*3 'bonjourbonjourbonjour' Mais >>> ch[0]='t' TypeError: 'str' object does not support item assignment 20 Les chaînes de caractères : Méthodes pour les chaînes >>>ch=’’TototiTi’’ • isupper() et islower() : retournent True si la chaîne ne contient respectivement que des majuscules/ minuscules : >>> ch.isupper() False • istitle() : retourne True si seule la première lettre de chaque mot de la chaîne est en majuscule : >>> ch.istitle() False • isalnum(), isalpha(), isdigit() et isspace() : retournent True si la chaîne ne contient respectivement que des caractères alphanumériques, alphabétiques, numériques ou des espaces : >>> ch.isalpha() True 21 Les chaînes de caractères : Méthodes pour les chaînes >>> mot.upper() # le résultat est une nouvelle chaîne 'TOTOTITI' >>> mot 'TotoTiTi' >>> mot.lower() 'tototiti' >>> mot=mot.upper() >>> mot 'TOTOTITI‘ Autres Méthodes utiles >>> ch='bonjour tout le monde \n' >>> ch.strip() 'bonjour tout le monde' >>> ch.split() ['bonjour', 'tout', 'le', 'monde'] 22 Les séquences : Les tuples Un tuple (appelé également n-uplet) est une collection ordonnée non modifiable d’éléments éventuellement hétérogènes. Syntaxe Éléments séparés par des virgules, et entourés de parenthèses. >>> t = (12345, 54321, ’salut!’ ) >>> t[0] 12345 >>> t (12345, 54321, ’salut!’) Les Tuples peuvent être imbriqués: >>> u = (t, (1, 2, 3, 4, 5)) >>> u ((12345, 54321, ’salut!’), (1, 2, 3, 4, 5)) et 23 Les tuples (suite) Un problème particulier (tuple à 0 ou 1 élément): • Les tuples vides construits avec des parenthèses vides; • Un tuple avec un élément est construit en faisant suivre une valeur d’une virgule Par exemple : >>> empty = () >>> singleton = ’salut’, # notez la virgule en fin de ligne >>> len(empty) , len(singleton), singleton (0, 1, ’salut’,) 24 Les tuples (suite) Remarque : Les chaînes et les Tuples n’étant pas modifiable il est possible de migrer vers des listes au moyen de l’instruction suivante list: >>> t=(1,2,3) >>> t=list(t) >>> type(t) <class 'list'> >>> t.append(5) >>> t [1, 2, 3, 5] >>> ch=‘’Bonjour ‘’ >>>List (ch) ['b', 'o', 'n', 'j', 'o', 'u', 'r'] 25 Les dictionnaires Un dictionnaire (tableau associatif) est un type de données permettant de stocker des couples cle:valeur, avec un accès très rapide à la valeur à partir de la clé, la clé ne pouvant être présente qu’une seule fois dans le tableau. Caractéristiques: • l’opérateur d’appartenance d’une clé (in) ; • la fonction taille (len()) donnant le nombre de couples stockés ; • Permet de retrouver un objet par sa clef • Il est itérable (on peut le parcourir) • Non ordonné • Mutable. Python propose la class dict. 26 Les dictionnaires (suite) >>>d={1:'un', 2:'Deux',3:'trois',4:'Quatre', 5:'cinq'} >>> type(d) <class 'dict'> >>> dir(dict) ['__class__', ….. '__repr__', '__setattr__', ‘__setitem__', '__str__', '__sizeof__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values'] >>>d.__setitem__(6,’six’) #ajoute un couple clé valeur >>>d {1: 'un', 2: 'Deux', 3: 'trois', 4: 'Quatre', 5: 'cinq', 6: 'six'} Les dictionnaires (suite) >>> d.pop(6) 'six' >>> d {1: 'un', 2: 'Deux', 3: 'trois', 4: 'Quatre', 5: 'cinq'} >>>len(d) 5 >>>coef={‘’maths’’:5,’’physique’’:4, ’’info’’:4} >>>coef.items() dict_items([('maths', 5), ('info', 4), ('physique', 4)]) >>>coef.keys() dict_keys(['maths', 'info', 'physique']) >>>for mat,co in coef.items(): print(mat, ':', co) maths : 5 info : 4 physique : 4 27 28 Les ensembles Un ensemble est une collection non ordonnée et mutable d’objets uniques. Les ensembles sont des structures non indexées ! Syntaxe Ensemble d’objets séparés par des virgules entre {} Exemple >>>S={1,1,3,3,'a','b','ccc',2,2,1,'a','a','bb'} >>>S {'a', 1, 2, 'b', 'bb', 3, 'ccc'} >>>S.add(9) >>>S {'a', 1, 2, 'b', 'bb', 3, 'ccc‘,9} >>> e=set([1,2,3,'E','E','R','A',3,3,2,6]) >>> e1=set([1,2,3,'k','j',2,2,'L','A',3,3,2,6]) >>> type(e),type(e1) <class 'set'><class 'set'> >>> e|e1 #opération d'union (or) {'A', 1, 2, 3, 'E', 6, 'k', 'j', 'L', 'R'} >>> e&e1 # opération d’intersection {'A', 1, 2, 3, 6} >>> e-e1 # opération de différence {'R', 'E'} >>> e^e1 # xor {'E', 'k', 'j', 'L', 'R'} 29 Le langage Python: L’affectation Une affectation crée un nom (identificateur, variable) qui référence un objet (les identifiants au format __nom__ sont réservés à l’interpréteur Python) C’est l’objet qui porte le type et les données (valeur, pour un objet numérique). Un même objet peut être référencé sous plusieurs noms (alias). >>>x=5 >>>y=5 >>> x,id(x),type(x), (5, 505626168, <class 'int'>) >>>y,id(y),type(y) (5, 505626168, <class 'int'>) 30 Le langage Python: L’affectation (suite) 31 Le langage Python: L’affectation 32 Autre Utilisation des opérateurs ! >>> x=8 >>> x+=5 >>> x 13 >>> x-=2 >>> x 11 >>> x*=3 >>> x 33 >>> x**=2 >>> x 1089 >>> x%=2 >>> x 1 >>> x/=3 >>> x 0.3333333333333333 >>> print("%5.3f"%x) 0.333 >>> x,y=45,23 >>> id(x),id(y) (505626808, 505626456) >>> x,y=y,x >>> x,y (23, 45) >>> id(x),id(y) (505626456, 505626808) 33 Les opérations d’entrée/ sortie • Opération d’affichage : print() >>> print('ceci est un message') ceci est un message >>> print("ceci est un message") ceci est un message >>> print("ceci un message \n avec retour à la ligne") ceci un message avec retour à la ligne >>> print(""" Ceci est un message sur plusieurs lignes avec beaucoup d'espaces et des sauts de ligne""") Ceci est un message sur plusieurs lignes avec beaucoup d'espaces et des sauts de ligne 34 Les opérations d’entrée/sortie (suite) >>> x=10;y=10; z=10; • Opération de lecture : input() >>> print (x, y, z, sep=' '); >>> x=input("saisir : ") 10 10 10 Saisir : 3498392483 >>> print (x, y, z, sep=';'); >>> print("la saisie",x, "est de type",type(x)) 10;10;10 la saisie 3498392483 est de type >>> print (x, y, z , sep='\n'); <class 'str'> 10 10 10 >>> print ('x =',x,'y =',y, 'z =', z, sep= ' ' , end =';'); x = 10 y = 10 z = 10; sep désigne le caractère de séparation end désigne le caractère de marquage de fin 35 Les opérations d’entrée/ sortie (suite) Il est toutefois possible de convertir la quantité saisie en entier, réel ou même booléen au moyen de int, float, et bool >>> x=int(input("saisir un entier")) saisir un entier 12 >>> print(x, "de type", type(x)) 12 de type <class 'int'> #Ou encore en réel >>> x=float(input("saisir un réel")) saisir un réel 12 >>> print(x, "de type", type(x)) 23.0 de type <class 'float'> 36 Les structures conditionnelles Attention à l’indentation !!! if condition1: instruction 1 elif condition2: instruction 2 elif condition3: instruction 3 instruction 4 else : instruction 5 instruction 6 37 Les structures conditionnelles (suite) Ecrire un programme qui saisi un nombre et teste si l’entier est nul, pair ou impair Les structures conditionnelles : Application • Ecrire un programme qui saisi trois entiers a, b et c et résout dans l’ensemble C l’équation de second degré ax2+bx+c= 0. • On discutera tous les cas possibles pour a, b et c ! 38 39 Application 2 : Résolution d’équation de 2nd degré 40 Les structures itératives Les non conditionnelles : Boucle For Syntaxe for i in range(a): instructions for i in range(a,b): instructions for i in range(a,b,c): instructions for i in iter: instructions NB: range (a) désigne l’intervalle [0,a[ range (a,b) désigne l’intervalle [a,b[ range (a,b,c) désigne l’intervalle [a,b[ par pas entier égal à c Le quatrième cas est un parcours par élément que nous pourrons effectuer avec les intérables tel que les listes, les tuples, les chaînes de caractères ou même les fichiers… Exemple: 41 42 L’instruction : for …. in L’instruction for in : permet d’itérer sur le contenu d’une liste, d’un tuple, les caractères d’une chaîne ou même un fichier … >>>L=list(range(5)) >>>L [0,1,2,3,4] >>>L1=[] >>>for k in L: L1.append(k**2) >>>L1 [0, 1, 4, 9, 16] >>>ch=”azerty” >>>ch1='' >>>for c in ch: ch1=ch1+c*2 aazzeerrttyy 43 Construction de listes par compréhension !! >>> L= [i for i in range(1,21,2)] >>>L [1, 3, 5, 7, 9, 11, 13, 15, 17, 19,20] >>>L=[(i,j) for i in range(1,5) for j in range(1,5)] >>>L [(1, 1), (1, 2), (1, 3), (1, 4), (2, 1), (2, 2), (2, 3), (2, 4), (3, 1), (3, 2), (3, 3), (3, 4), (4, 1), (4, 2), (4, 3), (4, 4)] >>>L=[(i,j) for i in range(1,5) for j in range(1,5) if (i+j) %2 ==0] >>>L [(1, 1), (1, 3), (2, 2), (2, 4), (3, 1), (3, 3), (4, 2), (4, 4)] 44 Les structures itératives conditionnelles : Boucle tant que • Syntaxe while condition : instructions • Exemple i=1 while i<=5: print(i) i+=1 1 2 3 4 5 45 Application : Ecrire une fonction Python nommée sequence, ayant comme paramètres un tableau T (à une dimension) et sa taille N, permettant de : •déterminer Nbs, le nombre de séquences strictement croissantes de ce tableau, •déterminer le nombre d’éléments Ta, de la séquence strictement croissante contenant le plus grand nombre d’éléments, •placer, à partir de T, tous les éléments positifs ou nuls au début d’un tableau TR et tous les éléments négatifs à sa fin, •retourner une liste contenant Nbs, Ta et TR. Exemple : Soit T un tableau de 15 éléments : T= 1 2 3 4 5 6 7 8 1 2 5 3 12 25 13 -8 9 10 11 12 13 14 15 4 7 24 28 32 -14 -11 Les séquences strictement croissantes sont : < 1; 2; 5 >; < 3; 12; 25 >; < 13 >; < -8 ; 4; 7; 24; 28; 32 >; < -14; -11 >. Le nombre de séquence est : Nbs=5 La séquence contenant le plus grand nombre d’éléments est : < -8 ;4; 7; 24; 28; 32 >. Son nombre d’éléments : Ta=6 Le tableau (TR) est : TR = 1 2 5 3 12 25 13 4 7 24 28 32 -8 -14 -11 Proposition de solution $ cat DeterminerSequence.py import numpy as np def DeterminerSequence(tab,n): Nbs = 1 debut = 0 fin = 0 nouveauDebut=0 i=0 while (i<n): if (tab[i]> tab[i+1]): Nbs=Nbs+1 if(i-nouveauDebut)>(fin-debut): debut=nouveauDebut fin = i nouveauDebut=i+1 i=i+1 if(n-nouveauDebut)>(fin-debut): debut=nouveauDebut fin = n Ta = fin - debut + 1 TR = np.array([],int) nbnegatif = 0 for i in range(n+1): 46 if(i<debut): TR=np.append(TR,tab[i]) elif(i<=fin): if(tab[i]<0): nbnegatif = nbnegatif + 1 else: TR=np.append(TR,tab[i]) else: if(i==fin+1): for j in range(nbnegatif): TR=np.append(TR,tab[debut+j]) TR=np.append(TR,tab[i]) print " T = " + str(tab) print " Le nombre de sequence est : Nbs = " + str(Nbs) print " La sequence contenant le plus grand nombre d elements est : " + str(tab[debut:fin+1]) print " Son nombre d elements : Ta = " + str(Ta) print " TR = " + str(TR) print " nbnegatif = " + str(nbnegatif) 47 import numpy as np def sequence(T,N): TR=T[:] Nbs=1 c=0 Ta=1 i=0 while i<N-1: c+=1 if T[i+1]<T[i] : Nbs=Nbs+1 if Ta<c: Ta=c c=0 i+=1 i=j=0 while i<N-1: if T[i]>=0: TR[j]=T[i] j+=1 i+=1 i=0 while i<N-1: if T[i]<0: TR[j]=T[i] j+=1 i+=1 return([Nbs,Ta,TR]); **************************************** >>>TAB=[1,2,5,3,12,25,13,8,4,7,24,28,32,-14,-11] >>>Nbs,Ta,TR=sequence(TAB,len( TAB)) >>>Nbs,Ta,TR 48 Exécution >>>T=np.array([1,2,5,3,12,25,13,-8,4,7,24,28,32,-14,11],int) >>>mT = len(T)-1 >>>DeterminerSequence(T,mT) Le nombre de sequence est : Nbs = 5 La sequence contenant le plus grand nombre d elements est : [-8 4 7 24 28 32] Son nombre d elements : Ta = 6 TR = [ 1 2 5 3 12 25 13 4 7 24 28 32 -8 -14 -11] nbnegatif = 1 49 Les sous programmes Un programme sous Python se déclare à l’aide de l’instruction def : Sytnaxe def nom_programme(liste_paramètres p1,p2…): instructions return(résultat) Exemple def saisi(): """ cette fonction permet de saisir un entier >0 et retourne cet entier """ while True : x=int(input("saisir un entier >0")) if x>0: break return(x) 50 Les sous programmes (suite) >>> saisi() saisir un entier >0 -5 saisir un entier >0 45 >>> help(saisi) Help on function saisi in module __main__: saisi() cette fonction permet de saisir un entier >0 et retourne cet entier 51 Les sous programmes -exemples >>> #trace d’exécution saisir un entier12 12 saisir un entier34 saisir un entier12 34 12 >>> A 12 >>> B,C (34, 12) 52 Les sous programmes - Passage de paramètres: exemples 53 Les sous programmes - Passage de paramètres: exemples 54 Les sous programmes - Passage de paramètres: exemples >>>Saisir un entier > 0: 23 Traceback (most recent call last): File "C:\Users\sousou\Desktop\livre python\Code Python\saisi.py", line 71, in <module> A=double_4(A,B) NameError: name 'B' is not defined 55 Les sous programmes - Passage de paramètres par référence : exemple >>> #trace d’exécution [0, 1, 2, 3, 4, 5] [0, 1, 2, 3, 4, 5, 45] >>> 56 Les sous programmes – Passage de paramètres par défaut: 57 Variables locales et variables globales • Variable Locale: Une variable locale est une variable interne à la procédure et n’est visible qu’à l’intérieur de celle-ci. Les valeurs des variables locales ne sont donc pas communiquées à l’extérieur. Une variable locale n’a plus d‘existence à la fin du sous-programme. • Variable globale : toute variable définie à l'extérieur des fonctions, connue et utilisable partout dans le fichier où elle est définie, en particulier dans n'importe quelle fonction de ce fichier. 58 Variables locales et variables globales 59 Fonction lambda La fonction lambda est utilisée lorsque la fonction est définie par une expression simple : F=lambda x:x**2 X=list(range(11)) Y=[] for e in X: Y.append(F(e)) print(X,'\n',Y) >>> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100] Gestion des erreurs la clause TRY….EXCEPT 60 try: instruction_à_faire except <<type_exception_optionnel>> instruction_à_exécuter_si_une_exception_se_déclenche D’abord, la clause d’essai (clause try : les instructions entre try et except) est exécutée. Si pas d’exception, la clause d’exception est ignorée, et l’exécution du try est terminée. Si une exception se produit à un moment de l’exécution de la clause d’essai, le reste de la clause try est ignoré. Puis si son type correspond à l’exception donnée après le mot-clé except, la clause except est exécutée, puis l’exécution reprend après l’instruction try. –Si une exception se produit qui ne correspond pas à l’exception donnée dans la clause except, elle est renvoyée aux instructions try extérieures; s’il n’y a pas de prise en charge, il s’agit d’une exception non gérée et l’exécution est arrêtée avec un message. 61 Try… except Exemple.. Try… except Exemple.. def saisi_controlée(): x=-1 while x<0: try : x=int(input("donner un entier")) if x>0: break except: print("erreur de saisie, saisissez un entier SVP") return x >>> saisi_controlée() >>> donner un entier -5 >>> donner un entier m >>> erreur de saisie, saisissez un entier SVP >>> donner un entier 5 5 62 63 Récursivité o En informatique « pratique » les fonctions récursives sont simplement des fonctions dont le calcul nécessite d'invoquer la fonction elle-même. C'est l'analogue des formules de récurrences en mathématiques. o Les fonctions non récursives seront appelées fonctions itératives. o Exemple. La fonction factorielle vérifie 0! = 1 et (n +1)! = (n +1)*n!. fonction itérative def factorielle(n): fact =1 for k in range (2,n+1): fact= fact*k return fact fonction récursive 1def factrl_rec(n): 2 if n==0 or n==1: 3 return 1 4 else : 5 return n*factrl_rec(n-1) 64 Principes Cette exemple montre les trois grands principes d'une fonction récursive : Une fonction récursive doit comporter une clause d'arrêt qui va déterminer le type de la sortie de la fonction. Une fonction récursive doit appeler la clause d'arrêt au bout d'un nombre fini d'étapes (ce qui assure la terminaison de l'algorithme). Une fonction récursive s'appelle elle-même, mais avec différentes valeurs de (ou des) l'argument(s). Récursivité Structure générale 65 • La structure générale est donc la suivante : 1 2 3 4 5 def fonction_recursive( paramètre ): if ... : #close d'arrêt return ... #cette ligne détermine le type de la variable de sortie else: return ... # instructions contenant un appel à la fonction_recursive Calcul de xn en version récursive et itérative : 1 def puissance_rec(x,n): 2 if n==0: 3 return 1 4 elif n==1: 5 return x 6 else: 7 return x*puissance_rec(x,n-1) 1. def puissance_it (x,n): 2. puiss =1 3. for k in range (n): 4. puiss *=x 5. return puiss Complexité algorithmique La théorie de la complexité algorithmique vise à: • classer les problèmes selon leur difficulté, • classer les algorithmes selon leur efficacité, • comparer les algorithmes résolvant un même problème. Dans l’étude de la complexité d’un algorithme on ne mesure pas la durée en heures, minutes, secondes, ...: Ces mesures ne seraient pas pertinentes car le même algorithme sera plus rapide sur une machine plus puissante; L’étude de la complexité consiste donc à utiliser des unités de temps abstraites proportionnelles au nombre d'opérations effectuées ; On pourra par la suite adapter ces quantités en fonction de la machine sur laquelle l'algorithme s'exécute ; 66 Complexité Règle de calcul de complexité • Chaque instruction basique consomme une unité de temps ;(affectation d'une variable, comparaison, +, -, *, /, ...) • Chaque itération d'une boucle rajoute le nombre d'unités de temps consommées dans le corps de cette boucle ; • Chaque appel de fonction rajoute le nombre d'unités de temps consommées dans cette fonction ; • Pour avoir le nombre d'opérations effectuées par l'algorithme, on additionne le tout ; 67 68 Exemple • Calcul de la factorielle de n (n!) : def factorielle(n) : fact=1 i=2 while i<=n : fact=fact*i i=i+1 return fact affectation : 1 affectation : 1 itérations : au plus n-1 multiplication + affectation : 2 addition + affectation : 2 renvoi d'une valeur : 1 Nombre total d'opérations : 1 + 1 + (n - 1)*5 + 1 = 5n - 2 69 Règle de calcul de complexité Généralement, la complexité d'un algorithme est une mesure de sa performance asymptotique dans le pire cas ; Que signifie ‘asymptotique’ ? ◦ on s'intéresse à des données très grandes ; Que signifie ‘dans le pire cas’ ? ◦ on s'intéresse à la performance de l'algorithme dans les situations où le problème prend le plus de temps. Pourquoi ? ◦ pour être sûr que l'algorithme ne prendra jamais plus de temps que ce qu'on a estimé. Ce qui correspond à donner une majoration du nombre d’opérations effectuées par l’algorithme. Complexité Règle de calcul de complexité • On aura donc recours a une approximation de ce temps de calcul, représentée par la notation O(). La notation 𝑂 est utilisé pour désigner une borne supérieure asymptotique ; • Soit n la taille des données a traiter ; on dit qu'une fonction f (n) est en O(g(n)) ("en grand O de g(n)") si : 70 71 𝑂 𝑔 𝑛 = { 𝑓 𝑛 : il existe des constantes positives 𝑐 et 𝑛0 telles que 0 ≤ 𝑓 𝑛 ≤ 𝑐 𝑔 𝑛 pour tout 𝑛 > 𝑛0 }. Complexité 72 Règle de calcul de complexité • On calcule le temps d'exécution comme avant, mais on effectue les simplifications suivantes : 1. on oublie les constantes multiplicatives (elles valent 1) ; 2. on annule les constantes additives ; 3. on ne retient que les termes dominants ; Reprenons le calcul de la factorielle, qui nécessitait 5n – 2 opérations : def factorielle(n) : initialisation : O(1) fact=1 initialisation : O(1) i=2 n-1 itérations : O(1) while i<=n : fact=fact*i multiplication : O(1) i=i+1 incrémentation : O(1) return fact renvoi : O(1) Complexité de la fonction : 2*O(1) + (n-1) *5*O(1) + O(1) = O(n) Complexité 73 Règle de calcul de complexité • O(1) : complexité constante, pas d'augmentation du temps d'exécution quand le paramètre croit. • O(log(n)) : complexité logarithmique, augmentation très faible du temps d'exécution quand le paramètre croit. Exemple : algorithmes qui décomposent un problème en un ensemble de problèmes plus petits (dichotomie). • O(n) : complexité linéaire, augmentation linéaire du temps d'exécution quand le paramètre croit (si le paramètre double, le temps double). Exemple : algorithmes qui parcourent séquentiellement des structures linéaires. • O(nlog(n)) : complexité quasi-linéaire, augmentation un peu supérieure a O(n). Exemple : algorithmes qui décomposent un problème en d'autres plus simples, traites indépendamment et qui combinent les solutions partielles pour calculer la solution générale. Complexité 74 Règle de calcul de complexité • O(n2) : complexité quadratique, quand le paramètre double, le temps d'exécution est multiplie par 4. Exemple : algorithmes avec deux boucles imbriquées. • O(ni) : complexité polynomiale, quand le paramètre double, le temps d'exécution est multiplie par 2i. Exemple : algorithme utilisant i boucles imbriquées. • O(in) : complexité exponentielle, quand le paramètre double, le temps d'exécution est élevé a la puissance 2. • O(n!) : complexité factorielle, asymptotiquement équivalente à nn Complexité O(1) O(log n) O(n) O(n log n) O(n2) O(n3) O(2n) Classe constant logarithmique linéaire sous-quadratique quadratique cubique exponentiel 75 76 Les fichiers • L'utilisation d'un fichier ressemble beaucoup à l'utilisation d'un livre. Pour utiliser un livre, vous devez d'abord le trouver (à l'aide de son titre), puis l'ouvrir. Lorsque vous avez fini de l'utiliser, vous le refermez. Tant qu'il est ouvert, vous pouvez y lire des informations diverses, et vous pouvez aussi y écrire des annotations, mais généralement vous ne faites pas les deux à la fois. Dans tous les cas, vous pouvez vous situer à l'intérieur du livre, notamment en vous aidant des numéros de pages. Vous lisez la plupart des livres en suivant l'ordre normal des pages, mais vous pouvez aussi décider de consulter n'importe quel paragraphe dans le désordre. • Tout ce que nous venons de dire des livres s'applique aussi aux fichiers informatiques. 77 Création d'un objet fichier avec open f = open(filename, mode = 'r') • 'r' : ouverture en mode read, le fichier doit exister, s’il n’existe pas un erreur se produit • ‘w’ : ouverture en mode write, si le fichier existe il l’ouvre écrase le contenu et positionne le curseur au début, sinon le fichier sera créé. • 'a' : ouverture en mode ajout ‘’append’’. Son contenu est conservé. Si le fichier n’existe pas il sera crée. • l'option '+' : le fichier est ouvert en lecture et en écriture. • l'option 'b' : ouverture d'un fichier binaire. 78 Méthodes sur les fichiers • f.read() : lit l'ensemble du fichier et le renvoie sous forme de chaîne. • f.readline() : La méthode readline() (sans s) lit une ligne d'un fichier et la renvoie sous forme d'une chaîne de caractères. À chaque nouvel appel de readline(), la ligne suivante est renvoyée. Associée à la boucle while, cette méthode permet de lire un fichier ligne par ligne. • f.readlines() : lit et renvoie une liste contenant toutes les lignes du fichier, où chaque ligne est représentée par une chaîne se terminant par \n. • f.write(s) : écrit la chaîne s dans le fichier de f • f.writelines(lst) : écrit la liste de chaîne lst dans le fichier de f • f.close() : ferme le fichier 79 girafe tigre fichier avec le nom zoo.txt : singe souris Méthode read() >>> filin = open(’zoo.txt’, ’r’) >>> filin.read() ’girafe\ntigre\nsinge\nsouris\n’ >>> filin.close() Méthode readlines() >>> filin = open(’zoo.txt’, ’r’) >>> filin.readlines() [’girafe\n’, ’tigre\n’, ’singe\n’, ’souris\n’] >>> filin.close() Méthode readline() >>> filin = open(’zoo.txt’, ’r’) >>> ligne = filin.readline() >>> while ligne != "": print (ligne) ligne = filin.readline() girafe tigre singe souris >>> filin.close() Fichiers Utilisation du Module Pickle Soit: a=2.34 ; b="bonjour" ;c=100 Un problème lié à la lecture !!!! Comment distinguer les trois valeurs? Entier, réel chaîne de caractères • En utilisant le module pickle f=open("test2 ’’,"rb") import pickle a1=pickle.load(f) f=open("test2","wb") print(a1, type(a1)) a=2.34;b="bonjour";c=100 a2=pickle.load(f) print(a2, type(a2)) pickle.dump(a,f) a3=pickle.load(f) pickle.dump(b,f) print(a3, type(a3)) pickle.dump(c,f) >>> #trace d’exécution f.close() 2.34 <class 'float'> bonjour <class 'str'> 100 <class 'int'> 80 Fichiers Application : fichier Soit f définie sur [0 ; 5] par f(x) = sin(4x) exp(-x2 + 3x). • Ecrire la définition de la fonction f. • Construire la liste lx des abscisses x variant de 0 à 5 avec un pas de 0.01 puis la liste ly des ordonnées correspondantes y = f(x). • Ecrire dans un fichier "data.txt" les coordonnées x et y des deux listes précédentes. Chaque ligne du fichier contiendra deux nombres x et y séparés par une tabulation ("\t"). • Vérifier le contenu du fichier "data.txt". 81 Fichiers Correction import numpy as np def f(x): return np.sin(4*x)*np.exp(-x**2+3*x) lx=np.linspace(0,5,501) ly=f(lx) fic=open(’data.txt’,’w’) for i in range(len(lx)): fic.write(str(lx[i])+"\t"+str(ly[i])+"\n") fic.close() 82 Calcul scientifique 83 Bibliothèque Numpy • Python ne propose de base que le type list, conteneur • • • • • dynamique hétérogène puissant, mais non orienté calcul numérique!! Le module numpy propose un ensemble de classes, d’objets et de fonctions dédiés aux calculs numériques. La classe ndarray (N dimensional array): tableaux homogènes multi-dimensionnels, numpy.linalg : un module d’algèbre linéaire basique, numpy.random : un module pour les générateurs aléatoires, Numpy.fft : un module basique de calculs de FFT (Fast Fourier Transform). Calcul scientifique 84 Bibliothèque scipy • Scipy est une bibliothèque numérique d’algorithmes et de fonctions mathématiques, basée sur les tableaux numpy, complétant ou améliorant (en terme de performances) les fonctionnalités numpy. • La bibliothèque Scipy présente un grand choix de modules pour le calcul scientifique: • Scipy.optimize • Scipy.integrate • Scipy.linalg • Scipy.stats… Calcul scientifique Bibliothèque Numpy: La fonction array >>> M=np.ndarray((2,2)) #création de tableau (2,2) de valeurs aléatoires par défaut réelles mais on peut changer à l’aide du paramètre dtype ! >>> print(M) [[ 4.24510811e+175 1.66039110e+243] [ 2.59345432e+161 1.96507163e-147]] • La fonction array convertit un objet list en objet ndarray bidimensionnel: >>> m1 = np.array([1, 2, 3]) ; # print(m1) array([1, 2, 3]) • La méthode tolist fait le travail inverse elle crée un objet list, copie de l’objet ndarray : >>> m3.tolist() [[1, 2, 3],[4, 5, 6]] 85 Calcul scientifique Bibliothèque Numpy: Autres générateurs de tableaux…. • Les fonctions numpy zeros, ones, eye et diag : >>> m1 = np.zeros(4) ;# print(m1), création de tableau de 0 [ 0., 0., 0., 0.] >>> m2 = np.ones(3, bool) ; # print(m2) [ True True True] >>> np.eye(3); #matrice identité array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., 1.]]) >>> np.diag([3,2,8]) #matrice diagonale array([[3, 0, 0], [0, 2, 0], [0, 0, 8]]) 86 Calcul scientifique 87 Bibliothèque Numpy : Autres générateurs de tableaux…. • Les fonctions linspace, logspace créent des vecteurs de float : >>> np.linspace(0, 10, 5) # début, fin, nombre de points, très utile pour le traçage des courbes array([ 0., 2.5, 5., 7.5, 10.]) >>> np.logspace(1, 2, 4) # 4 points entre 10**1 et 10**2 array([ 10., 21.5443469, 46.41588834, 100.]) >>> np.logspace(1, 2, 4, base=2) # 4 points entre 2**1 et 2**2 array([ 2. , 2.5198421, 3.1748021, 4.]) Calcul scientifique Array: accès à un élément • Même indexage que les listes ! >>> M=np.array([[2,4,5,11],[4,5,0,1]]) >>> M array([[ 2, 4, 5, 11], [ 4, 5, 0, 1]]) >>> M[1,1] 5 >>>N=np.array([1,3,6,3,4,8]) >>> N array([1, 3, 6, 3, 4, 8]) >>> N[-1] 8 >>> N[2]=5 # affectation >>> N array([1, 3, 5, 3, 4, 8]) 88 Calcul scientifique Array, slicing • Il est possible de sélectionner une sous matrice, en ne gardant que quelques lignes consécutives et/ou certaines colonnes consécutives • Si M est une matrice • M[:,:] : une copie intégrale de M avec nouvelle référence • M[:a,:b] : sous matrice les lignes du début jusqu’à < a > exclu, colonne de début jusqu’à <b> exclu. • M[:,b] : colonne b +1 • M[a,:] : ligne a +1 89 Calcul scientifique Algèbre linéaire avec numpy.linalg • np.dot(M,N): multiplication matricielle ou scalaire si N=a • np.inner (M,scalaire) : produit scalaire • np.diag ([liste_elt]) : création matrice diagonale • np.transpose (M): matrice transposée • np.linalg.det(M): déterminant de la matrice • np.linalg.inv(M) : inverse de la matrice • np.linalg.solve(A,B) : résolution du système linéaire A x = B • np.linalg.eig(M): valeurs propres, vecteurs propres • np.linalg.eigvals(M) :valeurs propres 90 Graphique Module Matplotlib • Un module très riche pour le traçage de courbes et de graphiques. 91 Graphique 92 Exemples • Dans l’exemple suivant, nous commençons par tracer quelques courbes, en variant leur représentation: le troisième argument permet de préciser la couleur et le type de trace. Le premier caractère désigne la couleur (r pour rouge, b pour bleu, k pour noir, g pour vert, c pour cyan, m pour magenta, y pour jaune, w pour blanc), les suivants précise le type du trace (- pour des segments de droite, . pour des points isoles, o pour des ≪ gros points ≫ isoles, o- pour des gros points relies par des segments, etc.), et on peut ajouter des arguments optionnels pour préciser son intention, comme par exemple la largeur des traits avec linewidth Graphique 93