TD01 td1

Télécharger au format pdf ou txt
Télécharger au format pdf ou txt
Vous êtes sur la page 1sur 62

P i ee ai de P h

INF TC1

Ve i e

2020-2021
o

o
Introduction #4

III Introduction
• Python est un langage de programmation à la fois impératif, fonctionnel et objet avec un typage dynamique. Dans
Python, toute est expression et toute expression représente une valeur (que l’on peut stocker / affecter / écrire / ...
ou pas).
• Penser à utiliser la fonction help pour connaitre les détails d’une fonction : par exemple help(’print’) ou
print? (ou encore print??)
• Si vous travaillez sans un IDE (éditeur avec interprète de Python intégré), préférez IPython à l’interprète de base
de Python. IPython fournit des outils supplémentaires ainsi qu’un accès au système hôte (Windows, Linux, MacOS,
etc).

III-1 Commentaires en Python


• Deux manières pour écrire un commentaire en Python :
# En Python , un commentaire c o u r t commence par un # e t se l i m i t e à l a f i n de l a l i g n e

"""
On peut a u s s i c r é e r un commentaire l o n g = une zone de
commentaires s u r p l u s i e u r s l i g n e s p l a c ées
e n t r e une p a i r e de t r i p l e g u i l l e m e n t s dont l e second s u i t :
"""

+ Remarques :
• Un ’ ;’ à la fin d’une ligne rend la ligne muette (pas d’affichage des résultats). Il permet également de placer plusieurs
expressions sur la même ligne.

• Si vous placez un commentaire immédiatement après la signature d’une fonction (ou une méthode, une classe, etc.)
entre un couple de """, votre commentaire (appelé docstring) devient accessible avec help :

• Python est un langage à indentation : un bloc est une zone contigüe de lignes d’expressions avec la même inden-
tation. Un tel bloc peut en contenir d’autres.
Ÿ Essayer d’utiliser la même indentation partout (espaces ou tabulation). Une mauvaise indentation qui ne provoque
pas d’erreur de syntaxe est un piège parfois difficile à détecter.
Exemples et exercices simples #5

IV Exemples et exercices simples


IV-1 Exemple 1 : moyenne
• Calcul de la moyenne de deux entiers
a= i n p u t ( ’ Donner l a v a l e u r de a : ’ )
b= i n p u t ( ’ Donner l a v a l e u r de b : ’ )
p r i n t ( ’ l a moyenne = ’ , ( i n t ( a ) + i n t ( b ) ) / 2 ) # i n t ( a ) : c o n v e r s i o n de ’ a ’ en e n t i e r

• Une seconde méthode : on convertit en lisant les valeurs en int


a= i n t ( i n p u t ( ’ Donner l a v a l e u r de a : ’))
b= i n t ( i n p u t ( ’ Donner l a v a l e u r de b : ’))
p r i n t ( ’ l a moyenne = ’ , ( a+b ) / 2 )

Points Python :
input
Conversion en int.
print
Affectation (=)

+ Remarque : que se passe-t-il si au lieu de donner un entier, on donne une lettre ?


Ÿ Voir plus loin les exceptions section XVI page 30

IV-2 Exemple 2 : racines carrées


• Lire les coefficients a, b, c et calculer et afficher les racines de l’équation quadratique ax2 + bx + c = 0
i m p o r t math ;

a= i n t ( i n p u t ( ’ Donner l e c o e f f i c i e n t a : ’))
b= i n t ( i n p u t ( ’ Donner l e c o e f f i c i e n t b : ’))
c= i n t ( i n p u t ( ’ Donner l e c o e f f i c i e n t c : ’))

i f ( a == 0 ) :
i f ( b != 0) :
p r i n t ( " Pas q u a d r a t i q u e : r a c i n e s i m p l e x = " , c / b )
else :
p r i n t ( " une blague ! " )
else :
d e l t a =b * b 4*a * c #ou b * * 2
i f ( d e l t a < 0) :
p r i n t ( " pas de r a c i n e s r e e l l e s " )
else :
assert ( a != 0) # Dé j à vé r i f i é mais pour montrer l ’ i n t é r ê t de " a s s e r t " .
i f ( d e l t a >0) :
x1 = ( b+math . s q r t ( d e l t a ) ) / ( 2 * a )
x2 = ( b math . s q r t ( d e l t a ) ) / ( 2 * a )
p r i n t ( " x1 = " , x1 )
p r i n t ( " x2 = " , x2 )
else :
x1 = x2 = b / ( 2 * a )
p r i n t ( " r a c i n e double x1 = x2 = " , x1 )

• Après un ’ :’ (d’ouverture d’un block), si vous passez à la ligne, n’oubliez pas l’indentation.

Points Python :
import
structures conditionnelles if-else, if-elif-else, assert
indentation (préférez des espaces à la tabulation) : espaces ou tabulation, utilisez la même chose dans un bloc !
test et comparaisons (==, !=, < , >, >=, <=, ...)
math.sqrt()

+ Remarques :
• Contrairement aux versions antérieures à Python 3, le résultat de l’opérateur ’/’ est un réel. Pour récupérer la
partie entière d’une division, utiliser ’//’ (ou convertir le quotient en un entier).
• La notation math.sqrt(delta) : pour éviter de mentionner math, remplacer
import math; par
from math import sqrt; (voir aussi plus loin à propos des modules)
Introduction aux fonctions #6

IV-3 Exercice : pair/impair


• Lire un entier au clavier et décider (et afficher) s’il est pair ou impair.

V Introduction aux fonctions


• Une fonction est définie par def nom_fonction(paramètres formels) :
|-indent-| Corps de la fonction
Cette fonction sera appelée par nom_fonction(arguments d’appel)

V-1 Exemple : moyenne de deux entiers


• Calcul de la moyenne de deux entiers par une fonction (de signature entier ⇥ entier ! reel)
d e f moyenne ( a , b ) :
r e t u r n ( a+b ) / 2 # indentation obligatoire si vous passez à la ligne après ’ :’

# Partie Principale
a= i n p u t ( ’ Donner l a v a l e u r de a : ’ )
b= i n p u t ( ’ Donner l a v a l e u r de b : ’ )
p r i n t ( ’ l a moyenne = ’ , moyenne ( i n t ( a ) , i n t ( b ) ) )

Ÿ Et pour la signature moyenne : entier ⇥ entier ! entier ?

V-2 Exercice : Racines d’une quadratique avec une fonction


• Reprendre l’exemple du calcul des racines d’une équation de seconde degré et placer les calculs dans la fonction
quadratique(a, b, c) qui reçoit en paramètre les coefficients a,b et c et renvoie les racines de cette équation.

+ Remarques :
• Une fonction Python peut renvoyer différents types de données : il n’y a pas de contrôle (n’en déplaise aux
Camliens !).
• Dans le cas présent, on décide de renvoyer un string (au lieu de float ou string).
• Savoir quel type de donnée une fonction doit renvoyer
Z est davantage nécessaire si ce résultat doit participer à
X
une expressions (P. ex. une expression effectuant ou sur la fonction quadratique).
• Pour répondre à de telles situations en Python, le mécanisme d’exception permet de définir des fonctions partielles
(comme quadratique) qui s’appliquent sous certaines conditions, voir la section XVI page 30.

V-3 Exercice : Moyenne et écart type


• Dans cet exercice, on utilisera des fonctions travaillant avec une liste remplie par un tirage Gaussien.
Pour ce faire, on écrira (pour le moment et avant d’en voir les détails) :
import random
echantillon=[random.gauss(16,2) for n in range(100)]
qui crée une liste de 100 nombres de la distribution N (16, 2).

• Écrire la fonction moyenne comme ci-dessus et utiliser cette fonction pour calculer l’écart type via la variance =
moyenne((xi µ)2 ) d’une suite de nombres telle que la liste echantillon ci-dessus.
Ÿ Vous devez donc appeler moyenne avec une liste qui contient les (xi µ)2 , xi 2 echantillon.

+ Naturellement, vos résultats doivent (plus ou moins) s’accorder avec N (16, 2).

• Voir les tirages aléatoires en section XVII, page 33 et les listes en compréhension en section XXIV, page 52.
Créer un script Python indépendant #7

V-4 Variante : Exercice (suite écart type)


• Il y a une seconde manière de calculer l’écart type (qui est adaptée à un calcul de la moyenne et de la variance
partielles, par exemple, lorsque les xi se présentent au fur et à mesure) :
N N N N
! N N
! N
!
1 X 1 X X X 1 X X 1 X
var = (xi µ)2 = x2i + µ 2
2.xi µ = x2i + Nµ 2
2µ xi = x2i + Nµ 2
2µ.N.µ
N 1 N 1 1 1
N 1 1
N 1
N
1 X 2
Et donc var = | (x ) µ2 |. 1
N 1 i

€ Il faut donc construire une liste contenant les x2i , xi 2 echantillon.

• Écrire le code Python nécessaire pour calculer l’écart type de cette seconde manière (réutilisez moyenne() ci-
dessus) et vérifier bien que le résultat correspond au calcul précédent.

VI Créer un script Python indépendant


• Supposons que nous souhaitons créer une version exécutable du calcul des racines d’une équation quadratique (vu
ci-dessus) et de pouvoir utiliser cette fonction dans un programme indépendant (on veut un script Python).
Ÿ Cela nous évitera de lancer pyzo/spyder/... pour utiliser notre fonction.

Pour commencer, on place le code vu ci-dessus dans le fichier racines.py. Pour les besoins de l’exemple, on sim-
plifie le code en prenant moins de précautions au niveau des coefficients (car on maîtrise les arguments d’appel).

On n’oublie pas de tester cette fonction pour s’assurer qu’elle fonctionne !


from math i m p o r t s q r t ;
# r é s o l u t i o n équation quadratique
def trinome ( a , b , c ) :
delta = b**2 4*a * c
i f delta > 0.0:
assert ( a != 0)
racine_delta = sqrt ( delta )
r e t u r n ( 2 , ( b r a c i n e _ d e l t a ) / ( 2 * a ) , ( b+ r a c i n e _ d e l t a ) / ( 2 * a ) )
e l i f delta < 0.0: return (0 ,)
else :
assert ( a != 0)
return (1 , ( b / ( 2 * a) ) )

# Partie Principale
print ( trinome ( 1 . 0 , 3.0 , 2 . 0 ) )
print ( trinome ( 1 . 0 , 2.0 , 1 . 0 ) )
print ( trinome ( 1 . 0 , 1.0 , 1.0) )

" " " On o b t i e n t


(2 , 1.0 , 2.0)
(1 , 1.0)
(0 ,) """

VI-1 Une façon simple


• Placer ce code dans un fichier racines.py.
• D’emblée, vous pouvez prendre une fenêtre "terminal" sur votre machine et taper la commande
$ python racines.py (ou c:\> python.exe racines.py sous Windows)
Ÿ La partie "principale" de votre code s’exécute et utilisera la fonction que vous avez définie.

• Si vous souhaitez éviter de taper python au début de la commande, vous pouvez :

Sous linux : Ajouter au tout début de ce fichier la ligne (dite shebang)


#!/usr/bin/python ou (mieux) #!/usr/bin/env python
Puis rendez ce code exécutable par la commande Linux chmod u+x racines.py
Puis exécuter ce programme en tapant simplement dans une console $ ./racines.py

Sous Windows : exécuter votre code dans une fenêtre de commande par python.exe racines.py
Windows ne semble pas avoir le mécanisme shebang (à moins d’avoir installé cygwin)

• Complétons en nous donnant les moyens d’importer nos propres fonctions pour les utiliser dans d’autres codes.
1. Valeur absolue : la variance et l’écart type sont toujours 0. Dans leur formulation usuelle, ce problème n’apparaît pas grâce à (xi µ)2
Créer un script Python indépendant #8

VI-2 Une solution plus élaborée


• Il arrive que l’on ait besoin d’utiliser les fonctions qu’on a définies dans un autre programme Python (à l’aide de
import).
• On crée le fichier utiliser_racines.py avec le contenu suivant (placer les deux fichiers ".py" dans le même
répertoire) :
from r a c i n e s i m p o r t t r i n o m e ;
p r i n t ( trinome ( 2 . 0 , 4.0 , 2 . 0 ) )

• Puis exécuter ce dernier et obtenir (un peu trop de réponses) :


(2, 1.0, 2.0) Qu’est-ce que c’est ?
(1, 1.0) Et ça
(0,) ;-)

(1 , 1.0) # I l nous f a u t j u s t e c e c i

• Le problème est que la partie principale de racines.py s’exécute aussi ! Et ce n’est pas ce que l’on veut.

• Résumons :
Nous voulons être capables de tester nos fonctions placées dans racines.py,
Nous voulons pouvoir lancer ce fichier comme un programme exécutable indépendant,
Nous voulons également réutiliser les dites fonctions dans d’autres programmes Python (comme nous l’avons
fait dans utiliser_racines.py

• La solution est de faire précéder la partie "programme principal" de racines.py par :


if __name__ == "__main__":

Puis placer le contenu de la partie principale en dessous (avec indentation !)

• Cela donne ("assert" oubliés car on sait comment on appelle cette fonction depuis "main" ) :
from math i m p o r t s q r t ;

# fonction
def trinome ( a , b , c ) :
delta = b**2 4*a * c
i f delta > 0.0:
racine_delta = sqrt ( delta )
r e t u r n ( 2 , ( b r a c i n e _ d e l t a ) / ( 2 * a ) , ( b+ r a c i n e _ d e l t a ) / ( 2 * a ) )
e l i f delta < 0.0: return (0 ,)
else : return (1 , ( b / ( 2 * a ) ) )

i f __name__ == " __main__ " :


p r i n t ( trinome ( 1 . 0 , 3.0 , 2 . 0 ) )
p r i n t ( trinome ( 1 . 0 , 2.0 , 1 . 0 ) )
p r i n t ( trinome ( 1 . 0 , 1.0 , 1.0) )

• Pour exécuter ce programme, dans une fenêtre de console, taper" :


r a c i n e s . py

OU (sous Windows) :
python r a c i n e s . py

• On peut maintenant importer notre fonction dans utiliser_racines.py ci-après sans que la partie principale
de racines.py ne s’exécute :
from r a c i n e s i m p o r t t r i n o m e ;
p r i n t ( trinome ( 2 . 0 , 4.0 , 2 . 0 ) )

Puis exécuter ce programme (par les moyens expliqués ci-dessus) et obtenir :


(1 , 1.0)

• Noter que racines.py reste indépendant et exécutable si on le souhaite.


Types principaux en Python #9

VII Types principaux en Python


• Les types principaux de Python :
• int : sur 4 octets
• file : fichier
• long : sur 4 (ou 8 octets)
• none : vide (équivalent à void)
• float : réel
• exception : exception
• str : chaîne de caractères (et conversion unicode)
• function : fonction
• bool : booléen
• module : module
• tuple : comme (1,2,"ECL", 3.14)
• object : objet
• list : liste
• slice : objet extensible
• set : ensemble
• basestring : str + Unicode
• range : liste de valeurs à générer (xrange() en Python 2)
+ les caractères en Python 3 sont
• dict : dictionnaire comme {’small’ : 1, ’large’ : 2}
par défaut en Unicode.
• complex : nombre complexe (ex : 1j est une des racine de -1)

+ La lettre ’j’ ou ’J’ est utilisée pour la partie imaginaire d’un nombre complexe. Pourquoi pas ’i’ ou ’I’ ? : les concep-
teurs de Python ont suivi les symboles utilisés en Ingénierie où ’I’ est déjà utilisé comme symbole du courant.

+ Voir ci-après pour les conversions entre ces types.

VII-1 Exemples
i f t y p e ( 1 ) i s n o t i n t : p r i n t ( ’ oups ’ )

i f type ( ’ 1 ’ ) i s not i n t : p r i n t ( 1 )

type ( 3 . 1 4 )
# float

t y p e ( None )
# NoneType

f = lambda c : c i f t y p e ( c ) i s s t r and c . isalpha ( ) else ’ ? ’


type ( f )
# function

# U t i l i s a t i o n de f ( v o i r p l u s l o i n l e s " lambda e x p r e s s i o n s " ) :


f ( ’ a ’ ) # donne ’ a ’ c a r ’ a ’ e s t alphab é t i q u e
f ( ’ 1 ’ ) # donne ’ ? ’ c a r ’ 1 ’ n ’ e s t pas alphab é t i q u e
f (1) # donne ’ ? ’ c a r 1 n ’ e s t pas une chaine

• Pour connaître les détails des types et leurs limites (les tailles sont en byte = 2 octets en Python) :
i m p o r t sys ;

p r i n t ( sys . i n t _ i n f o )
# sys . i n t _ i n f o ( b i t s _ p e r _ d i g i t =30 , s i z e o f _ d i g i t =4)

p r i n t ( sys . f l o a t _ i n f o )
# sys . f l o a t _ i n f o ( max=1.7976931348623157e+308 , max_exp=1024 , max_10_exp=308 , min =2.2250738585072014e 308,
min_exp= 1021, min_10_exp= 307, d i g =15 , mant_dig =53 , e p s i l o n =2.220446049250313e 16, r a d i x =2 , rounds =1)

p r i n t ( sys . g e t s i z e o f ( f l o a t ) ) # La t a i l l e de la classe f l o a t
# 400
p r i n t ( sys . g e t s i z e o f ( f l o a t ( ) ) ) # La t a i l l e d ’ un f l o a t
# 24 # Ce que coute en o c t e s un r é e l ( v a l e u r + i n f o s supplémentaires )

VIII Conversions de types


• Quelques conversions entre les types de données :
int(val) : convertir en entier (la partie entière).
long(val) : transforme une valeur en long.
float(val) : transformation en flottant.
complex(re,im) : transformation en nombre complexe.
str(val) : transforme la plupart des variables en chaînes de caractères.
Conversions de types #10

repr(val) : similaire à str.


eval(str) : évalue le contenu de son argument comme si c’était du code Python (déconseillé).
unicode(val) : convertit en Unicode comme dans u"aà eéèê" # donne le code de la chaîne

VIII-1 Exemples de conversion de types


• caractères en string : liste de caractères entiers en string :
l i s t 1 = [ ’1 ’ , ’2 ’ , ’3 ’ ]
str1 = ’ ’ . join ( l i s t 1 )

str1
# ’123 ’

Ici, la fonction join() va accoler les éléments de son paramètre et les mettre à la que leu-leu. La chaîne vide (”) placée
à gauche de join() sera le séparateur à placer entre les éléments accolés (ici rien).

• entiers en string : liste d’entiers en string : on convertie chaque entier en caractère (car join() s’applique aux
strings) puis

list1 = [ 1, 2, 3]
str1 = ’ ’ . join ( str (e) for e in l i s t 1 ) # ou avec " " à l a p l a c e de ’ ’

str1
# ’123 ’

• string en entier : pour convertir un string S composé de chiffres en un entier, int(S) suffit. Par contre, si on n’est
pas certain que les caractères de S sont des chiffres, un contrôle est nécessaire (voir exercice ci-dessous).

• string en réel : pour convertir un string S composé de chiffres en un réel, float(S) suffit. Cependant, la même
précaution que pour les entiers ci-dessus s’applique.
a = " 545.2222 "
float (a)
# 545.2222 s u i v a n t l e s y s t ème, on peut a v o i r des ’ 0 ’ apr ès l e s ’ 2 ’

int ( float (a) )


# 545

Ou en passant par une petite fonction (de même pour un entier) :


def i s _ f l o a t ( value ) :
try :
f l o a t ( value )
r e t u r n True
except :
r e t u r n False

Pour les exceptions, voir la section XVI en page 30.

VIII-2 Exercice
• Écrire la fonction convertir(S) qui convertit son paramètre (un string) en un entier. Pour que la conversion soit
possible, le paramètre S doit être être composé de chiffres éventuellement précédé d’un signe.
Noter qu’on peut accéder à S[i] (i commence à 0)
+ Si un string S ne contient que des chiffres : S.isdigit() est vrai.

VIII-3 Exercice
• Écrire la fonction convertir2r(S) qui convertit son paramètre (un string) en un réel (loat). Pour que la conversion
soit possible, le paramètre S doit être être éventuellement précédé d’un signe, puis composé de chiffres suivis d’un
’.’ puis une série de chiffres. La présence d’un ’.’ est obligatoire, et qui est forcément suivi d’au moins un chiffre.
+ On peut réutiliser la fonction définie ci-dessus.
Modules Python #11

IX Modules Python
• Format général :
import tel_module
t e l _ m o d u le . f o n c ( . . ) # appel de l a f o n c t i o n f o n c du module

• Mieux conseillé :
i m p o r t t e l _ m o d u l e as mod1
i m p o r t un_module as mod2
mod1 . f o n c ( . . ) # appel de l a f o n c t i o n f o n c du t e l _ m o d u l e
mod2 . f o n c ( . . ) # appel de l a f o n c t i o n homonyme du un_module

Ÿ Cette écriture permet d’éviter les conflits de noms (cf. fonc()).

• On peut adapter un nom de fonction dans notre code :


import tel_module

d e f ma_fonction ( ) :
localname = t e l _ m o d u l e . f o n c
f o o = localname ( bar )

• Si on veut importer une fonction d’un module de façon plus précise :


from t e l_ m o d u l e i m p o r t f o n c
fonc ( . . ) # appel de l a f o n c t i o n f o n c du module

• Déconseillé : on risque de créer des conflits de noms :


from t e l_ m o d u l e i m p o r t *
fonc ( . . ) # appel de l a f o n c t i o n f o n c du module

• Sachant qu’un module peut importer d’autres modules, préférez :


i m p o r t s c i p y . s t a t s as s t
s t . nanmean ( )

à cette autre manière équivalente :


import scipy . stats
s c i p y . s t a t s . nanmean ( )

• On privilégie la parcimonie (importer seulement ce qui est nécessaire) :


from s c i p y . s t a t i m p o r t nanmean , nanstd
nanmean ( . . )
nanstd ( )

• Un compromis intéressant : on peut renommer les fonctions importées pour éviter les conflits de noms :
from sys i m p o r t argv as sys_argv

X La fonction range
• Format de la fonction range() :
range([début], fin, [incrément])
Ÿ Le début et l’incrément sont optionnels (mis entre []).
Ÿ Si on donne deux arguments à range(), ce seront alors le début et la fin de l’intervalle (et l’incrément=1).

Exemple : utilisez la fonction range() pour afficher une liste contenant


- les entiers de 0 à 3 ;
- les entiers de 4 à 7 ;
- les entiers de 2 à 8 par pas de 2
p r i n t ( " range ( 4 ) = " , l i s t ( range ( 4 ) )
p r i n t ( " range ( 4 , 8 ) = " , l i s t ( range ( 4 , 8 ) ) )
p r i n t ( " range ( 2 , 9 , 2 ) = " , l i s t ( range ( 2 , 9 , 2 ) ) , " \ n " )
La fonction range #12

+ Remarques : Python 3.4 "oblige" à écrire print(list(range(4))) au lieu de print(range(4)) car


range(4) ne représente pas l’intervalle souhaité sous forme de 0..3 (on dit qu’elle représente l’intervalle par in-
tension ou compréhension alors que 0..3 est l’intervalle par extension obtenu via la fonction list)
R=range ( 4 )
t y p e (R)
# range

l i s t (R)
# [ 0, 1, 2, 3]

X-1 Deux ou trois trucs pratiques sur range


1- Valeurs pour une séquence de variables :
a , b , c , d , e , f , g , h = range ( 8 )

Permet d’assigner les valeurs 0..7 à la séquence a, b, c, d, e, f, g, h.

2- Valeurs d’un range() à l’envers :


range ( 4 ) [ :: 1 ] # r e p r é sente l ’ i n t e r v a l l à l ’ envers
l i s t ( range ( 4 ) [ :: 1]) # à l ’ envers
# [ 3, 2, 1, 0]

On obtient le même effet en explicitant l’intervalle [3 .. -1[ et un incrément = -1 :


l i s t ( range (3 , 1 , 1) ) # Noter l e s bornes
# [ 3, 2, 1, 0]

3- Interroger les valeurs potentielles d’un range :


R=range ( 4 ) # R e s t du t y p e range

R . count ( 0 ) # Combien de ’ 0 ’ dans R


# 1

R. index ( 2 ) # L ’ i n d i c e de ’ 2 ’ dans R
# 2

4- Dans range(debut, fin), on a en général debut < f in tandis qu’avec debut f in, on désigne un intervalle
vide (et non une erreur).
l i s t ( range ( 1 , 1 ) )
# []

X-2 Bonus : sommes


• Écrire le code Python en utilisant range() pour montrer les équivalences suivantes.
X X
• En Python, x*sum(S) == sum(x*y for y in S) représente x. y= x.y
y2S y2S
n
X
• f (i) donne en Python sum(f(i) for i in range(m, n+1)) qui est équivalent à :
i=m
s = 0
f o r i i n range (m, n +1) :
s += f ( i )

• Les constantes multiplicatifs peuvent être insérées ou être sortie des sommes :
Xn n
X
c. f (i) = c.f (i) car c(f (m) + · · · + f (n)) = c.f (m) + · · · + c.f (n).
i=m i=m
n
X n
X n
X
• Associativité : sachant que f (i) + g(i) = (f (i) + g(i)), on peut écrire en Python :
i=m i=m i=m
sum(f(i) for i in S) + sum(g(i) for i in S)
qui est la même chose que sum(f(i) + g(i) for i in S).

Ÿ Notons que ces équivalences ne tiennent que si les fonctions en questions n’ont pas d’effet de bord (ne modifient
pas la mémoire).

• De même pour la soustraction.


Les listes #13

XI Les listes
• Une introduction par des exemples de quelques fonctions sur les listes.
• Le premier élément d’une liste L est à l’indice 0,
le dernier à l’indice len(L)-1 ou à l’indice -1 et L[-2] = L[len(L)-2]).

• Quelques fonctions (pour une liste L), voir les autres fonctions plus loin :

L[:] toute la liste L (référence explicite aux éléments de L, cf. la copie d’une liste)
L[k:p] (k+1)ème et pème éléments (le premier élément à l’indice 0)
L[:k] du début jusqu’au kème
L[-1] dernier élément
L[:-1] L amputée du dernier élément
L[:len(L)-1] Idem : L amputée du dernier élément
L[0] premier élément
L[i]=val remplace L[i] par val (si L[i] existe, sinon exception IndexError).
L=list(itérable) crée une liste à partir d’un itérable (comme range()), une liste est elle-même itérable.
len(L) nombre d’éléments de L
L.append(val) ajout d’un élément (à la fin, L est modifiée)
L.remove(val) suppression de la première occurrence de val (L est modifiée)
L.reverse() renverse L (L est modifiée)
L.index(val) renvoie l’indice de la 1ère occurrence de val dans L, erreur si val pas dans L.
L.copy() copie le contenu de L
L.count(val) compte le nombre d’occurrence de val dans L
L.extend(itérable) ajoute à L les éléments donnés par itérable, équivalent à L[len(L):] = liste ...
del(L[i]) ou del D[i] effacement de l’élément d’indice i d’une liste (L est modifiée)
L.clear() efface le contenu de L. Équivalent à del L[:]
L.insert(i, x) insertion de x avant l’indexe i
L.insert(0, x) insère x au début de L et L.insert(len(L), x) est équivalent à L.append(x).
L.pop() supprime et renvoie le dernier élément.
L.pop(i) supprime l’élément en position i et renvoie cet élément (i=-1 ’ le dernier)

+ Pour une liste L, L[::-1] représente la liste L inversée :


L=[1,3,6,2]
L[::-1]
# Donne [2, 6, 3, 1]

• Deux fonctions pour le tri d’une liste :

L.sort() trie la liste L (L est modifiée)


sortd(L) trie la liste L (voir exemples plus loin)
Les listes #14

+ Remarques et rappels sur Indices et Listes


• Dans une liste, les indices négatifs commencent par la fin :
-1 : le dernier, -2 : l’avant dernier ...

• L[0:5] est la même chose que L[:5] : du 1er au 5e inclus ([0..5[)

• Plus généralement : du k_ème au p_ème élément s’écrira L[k-1:p] (le premier à l’indice 0)
Si L=[0,1,2,3,4,5,6,7,8,9], pour avoir du 3ème au 5ème, on écrit L[2:5]

+ Si L=[0,1,2,3,4,5,6,7,8,9], L à l’envers : L[::-1] = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0].

+ pour L[0:10] ! [0,1,2,3,4,5,6,7,8,9], les indices d’une tranche (slice) peuvent être négatifs
x[-5:-2] ! [5,6,7]
x[-1] ! 9

+ Une tranche (slice) : une_liste[début : fin : incrément]


R=range(10) # R vaut (par intention) ! [0,1,2,3,4,5,6,7,8,9]
list(R[1:7:2]) # la tranche [1..7[ d’incrément 2
# ! [1, 3, 5]

+ Tranche avec incrément : pour L[0:10] ! [0,1,2,3,4,5,6,7,8,9]


x[0:10:2] ! [0,2,4,6,8] l’incrément est à la fin (par opp. à Matlab : au milieu)
Et à l’envers : L[8:0:-2] ! [8,6,4,2]

+ Si l’intervalle est limité par un bord, on peut l’omettre : pour L[0:10] ! [0,1,2,3,4,5,6,7,8,9]
L[:] ! [0,1,2,3,4,5,6,7,8,9]
L[::2] ! [0,2,4,6,8]
L[-5:] ! [5,6,7,8,9]
L[8::-2] ! [8,6,4,2,0]
• Exemple d’affectation par tranches
L = [ 1, 2, 3, 4, 5]
L [ 2:3 ] = [ 0 , 0 ] # p l a c e ’ 0 ’ à l ’ i n d i c e 2 e t a j o u t e t o u t l e r e s t e à l a s u i t e de c e l u i ci .

L
# [ 1, 2, 0, 0, 4, 5]

L [ 1:1 ] = [ 8 , 9 ] # Idem
L
# [ 1, 8, 9, 2, 0, 0, 4, 5]

L [ 1: 1 ] = [ ] # é l ément d ’ i n d i c e 1 au d e r n i e r ( mais l e d e r n i e r e x c l u ) d e v i e n n e t " v i d e "


L
# [ 1, 5]

XI-1 Un exemple sur les listes


• Définir la liste liste =[17, 38, 10, 25, 72], puis effectuez les actions suivantes :
triez et affichez la liste ;
ajoutez l’élément 12 à la liste et affichez la liste ;
renversez et affichez la liste ;
affichez l’indice de l’élément 17 ;
enlevez l’élément 38 et affichez la liste ;
affichez la sous-liste du 2eau 3e élément ;
affichez la sous-liste du début au 2e élément ;
affichez la sous-liste du 3e élément à la fin de la liste ;
affichez la sous-liste complète de la liste ;
affichez le dernier élément en utilisant un indiçage négatif.
affichez l’avant-dernier élément en utilisant un indiçage négatif.
puis définir L comme une liste des entiers de 0 à 5 et testez l’appartenance des éléments 3 et 6 à L.
Les listes #15

+ Bien remarquer que certaines méthodes de liste ne retournent rien.


nombres = [ 17 , 38 , 10 , 25 , 72 ]
p r i n t ( " L i s t e i n i t i a l e " . center (50 , ’ ’ ) )
p r i n t ( nombres , ’ \ n ’ )

p r i n t ( " T r i " . center (50 , ’ ’ ) )


nombres . s o r t ( ) # TRI s u r p l a c e ( l a l i s t e e s t m o d i f i ée )
p r i n t ( nombres , ’ \ n ’ )

p r i n t ( " A j o u t d ’ un element " . c e n t e r ( 5 0 , ’ ’ ) )


nombres . append ( 1 2 )
p r i n t ( nombres , ’ \ n ’ )

p r i n t ( " Retournement " . c e n t e r ( 5 0 , ’ ’ ) )


nombres . r e v e r s e ( )
p r i n t ( nombres , ’ \ n ’ )

p r i n t ( " I n d i c e d ’ un element " . c e n t e r ( 5 0 , ’ ’ ) )


p r i n t ( nombres . i n d e x ( 1 7 ) , ’ \ n ’ )

p r i n t ( " R e t r a i t d ’ un element " . c e n t e r ( 5 0 , ’ ’ ) )


nombres . remove ( 3 8 )
p r i n t ( nombres , ’ \ n ’ )

print ( " Indicage " . center (50 , ’ ’ ) )


print ( " nombres [ 1 : 3 ] = " , nombres [ 1 : 3 ] )
print ( " nombres [ : 2 ] = " , nombres [ : 2 ] )
print ( " nombres [ 2 : ] = " , nombres [ 2 : ] )
print ( " nombres [ : ] = " , nombres [ : ] )
print ( " nombres [ 1] = " , nombres [ 1] )
print ( " nombres [ 2] = " , nombres [ 2] )

L = l i s t ( range ( 6 ) ) # range(6) représente 0..5 qu’on transforme en une liste


p r i n t ( " La l i s t e = " , L )
p r i n t ( " Test d ’ appartenance de l ’ element 3 : " , 3 i n L )
p r i n t ( " Test d ’ appartenance de l ’ element 6 : " , 6 i n L )

XI-2 Autres exemples de fonctions sur les listes


• Retrait du dernier élément (fonction partielle) avec pop() :
L= [ 1 ,3 ,2 ]
L
# [ 1 ,3 ,2 ]
L . pop ( )
# 2
L
# [ 1 ,3 ]
L . pop ( ) ; L . pop ( )
# 1
L
# []
L . pop ( )
# I n d e x E r r o r : pop from empty l i s t

+ L.pop(i) enlève et renvoie l’élément d’indice i (à partir de 0) de la liste L.


Si i > l.len()-1, on aura une exception IndexError: pop index out of range.

• Copie de liste :
L= [ 1 ,2 ,3 ]
L1=L #L1 e s t homonyme de L ; ce n ’ e s t pas une c o p i e ( l a l i s t e a maintenant deux noms ! )
L [ 0 ] =6
L
# [ 6, 2, 3]
L1
# [ 6, 2, 3]

#Pour c o p i e r une l i s t e , i l f a u t ê t r e p l u s e x p l i c i t e :
L2=L [ : ] # c o p i e r v r a i e m e n t L dans L2
L [ 1 ] =7
L
# [ 6 ,7 , 3 ]
L1
# [ 6 ,7 , 3 ]
L2
# [ 6 ,2 , 3 ]

Ÿ L’équivalent de cette copie : L2=L.copy()

+ On dit qu’en Python, une variable est avant tout son contenu et le nom n’est qu’un attribut de la variable. C’est
pour cette raison qu’on doit copier le contenu. Cette différence reflète le comportement des copie-constructeurs.
Les listes #16

Ÿ N’oublions pas que ce comportement (deux noms font référence au même objet) s’applique aux objets mutables
(List, Dict, Set, etc.) 2 , pas aux non mutables (comme les entiers, constantes strings , tuples, None).
Pour éviter cette confusion, les fonctions de la librairie std de Python rendent None lorsqu’elles modifient un objet
mutable (cf, append, sort). Notons aussi que cette confusion n’arrive pas en cas de création d’un nouvel objet tel que
y=y+[10] (où y : un entier) ou sorted(liste).
Il y a une exception à cette règle : l’opérateur +=. Dans liste += [1,2,3], on applique en fait la fonction
liste.extend([1,2,3]) à l’objet mutable liste tandis que entier_y +=1 ou tuple1 += (1,2,3) créent de
nouvelles variables car les entiers et les tuples ne sont pas mutables.

Enfin, pour savoir si deux variables font référence à un même objet , utiliser is ou la fonction id().

• sorted() et sort() (Python 3.4, noter le trie à l’ envers :


sorted ( [ 5 , 2 , 3 , 1 , 4 ] ) # Crée une n o u v e l l e l i s t e
# [ 1, 2, 3, 4, 5]

s o r t e d ( [ 5 , 2 , 3 , 1 , 4 ] , r e v e r s e =True ) # Crée une n o u v e l l e l i s t e . On trie à l’envers


# [ 5, 4, 3, 2, 1]

a = [ 5, 2, 3, 1, 4]
a . s o r t ( ) # T r i s u r p l a c e ( l a l i s t e e s t m o d i f i ée )
a
# [ 1, 2, 3, 4, 5]

s o r t e d ( { 1 : ’D ’ , 2 : ’B ’ , 3 : ’B ’ , 4 : ’E ’ , 5 : ’A ’ } )
# [ 1, 2, 3, 4, 5]

+ Remarques : sort() ne s’applique qu’aux listes alors que sorted() s’applique à tout ce qui "itérable" (y
compris les Dicos).
• sorted() et sort() acceptent un paramètre key qu’on peut utiliser pour préparer chaque élément avant le
tri.
#Dans c e t exemple , on demande ( par s p l i t ( ) ) à i s o l e r l e s mots p u i s à t r i e r l e u r frome minuscule

s o r t e d ( " Ceci e s t une Chaine de c a r a c t è r s Debase ! " . s p l i t ( ) , key= s t r . l o w e r ) ) # passer d ’ abord en minuscules
# [ ’ c a r a c t è r s ’ , ’ Ceci ’ , ’ Chaine ’ , ’ de ’ , ’ Debase ! ’ , ’ e s t ’ , ’ une ’ ]

# Nom, Note e t Age des é t u d i a n t s


student_tuples = [
( ’ j o h n ’ , ’A ’ , 25) ,
( ’ pasSa ’ , ’B ’ , 22) ,
( ’ t r o n c h e ’ , ’B ’ , 20) ,
]

s o r t e d ( s t u d e n t _ t u p l e s , key=lambda s t u d e n t : s t u d e n t [ 2 ] ) # sort suivant l ’ Age


# [ ( ’ t r o n c h e ’ , ’B ’ , 20) , ( ’ pasSa ’ , ’B ’ , 22) , ( ’ j o h n ’ , ’A ’ , 25) ]

+ Remarques : la liste student_tuples contient des tuples (ici des triplets). Voir plus loin pour les tuples la section
XIII page 20.
Ici, on peut aussi utiliser sort().

XI-3 Itération à l’envers


f o r x i n r e v e r s e d ( sequence ) :
. . . # do something w i t h x . . .

• Par exemple :
S= [ 1 , 2 , 3 , 4 ]
f o r x i n reversed (S) :
print (x)
"""
4
3
2
1
"""

• Ou par :
S= [ 1 , 2 , 3 , 4 ]
f o r x i n S [ :: 1] :
print (x)
"""
4

2. Pour faire court, un objet mutable est celui dont la valeur peut changer. Par opposition aux objets non-mutables. Cette propriété découle
du type de l’objet en question.
Les listes #17

3
2
1
"""

XI-4 Itération sur une liste avec enumerate


• Si on doit écrire les éléments d’une liste avec le rang de chacun :
strings = [ ’a ’ , ’b ’ , ’c ’ , ’d ’ , ’e ’ ]
f o r index , s t r i n g i n enumerate ( s t r i n g s ) :
p r i n t ( index , s t r i n g )

"""
0 a
1 b
2 c
3 d
4 e """

• On peut réaliser le même effet avec un accès aux éléments par indice :
S = [ ’a ’ , ’b ’ , ’c ’ , ’d ’ , ’e ’ ]
f o r i n d e x i n range ( l e n ( S ) ) :
p r i n t ( index , S[ index ] )

"""
0 a
1 b
2 c
3 d
4 e """

XI-5 Exemple : Pile


• Implantez une pile LIFO (Last in First out, comme une pile d’assiettes) avec une liste.
+ Remarques : dans une spécification formelle (appelée TDA : type de données abstrait) des piles, on utilise
une notation algébrique pour spécifier le type Pile. On précise d’abord la signature des opérateurs. Deux autres
parties préconditions et axiomes viennent compléter la définitions d’un TDA.
• Ce qui est important est que chaque fonction renvoie une et une seule valeur et que les fonctions partielles
(celles avec le symbole 9) ne s’appliquent que sous conditions (exprimées dans la partie préconditions).
• Par exemple, pour une pile, on aura :
type : pile ce que ce TDA définit
utilise : Bool, Data, Nat les types que ce TDA utilise (une sorte de "import")
Signature :
vide : ! pile la pile vide (une constante = fonction 0-aire=sans argument)
empile : pile ⇥ Data ! pile ajout d’un élément
depile : pile 9 pile fonction partielle (non définie si pile vide). Noter qu’on ne renvoie pas un Data
top : pile 9 Data consultation du 1er élément. Fonction partielle (non définie si la pile est vide)
est_vide : pile ! Bool test de vacuité
len : pile ! Nat nbr d’éléments

Préconditions :
ici, on précise les conditions d’applications des fonctions partielles
Par exemple : depile(p) : not(est_vide(p)) ....

Axiomes (les propriétés des fonctions) :


Par exemple : pour e :data, p : pile
est_vide(vide)=True
est_vide(empiler(p,e))=False
depile(empiler(p,e))=p
top(empiler(p,e))=e
....
• Noter que le concept de classes convient parfaitement aux objets Piles (voir en TC2).

• Une implantation partielle à titre d’exemple :


Les listes #18

d e f empile ( p , a ) :
p . append ( a )

def d e p i l e ( p ) :
try :
p . pop ( )
return p
except :
p r i n t ( " La p i l e e s t v i d e ! " )
r e t u r n None

def top ( p ) :
try :
return p[0]
except :
p r i n t ( " La p i l e e s t v i d e ! " )
r e t u r n None

d e f e s t _ v i d e ( p ) : r e t u r n p== [ ]

d e f i n i t ( * args ) : # On prend t o u t ce q u i e s t donné en paramè t r e e f f e c t i f


p = []
i f n o t args : return p # On nous a r i e n donné !
f o r elem i n args : p . append ( elem )
return l i s t (p)

# Tests
p r i n t ( " P il e i n i t i a l e " . center (50 , ’ ’ ) )
l i f o = i n i t (5 , 8 , 9)
print ( " lifo : " , lifo )
i n p u t ( ’ E n t r ée pour c o n t i n u e r . . . ’ )
p r i n t ( " Empilage " . c e n t e r ( 5 0 , ’ ’ ) )
empile ( l i f o , 11)
print ( " lifo : " , lifo )
i n p u t ( ’ E n t r ée pour c o n t i n u e r . . . ’ )
p r i n t ( " Depilages " . c e n t e r ( 5 0 , ’ ’ ) )
f o r i i n range ( 5 ) :
depile ( l i f o )
print ( " lifo : " , lifo )

• Traces :

" " " TRACE


Pile i n i t i a l e
lifo : [ 5, 8, 9]
E n t r ée pour c o n t i n u e r . . . >?
Empilage
l i f o : [ 5 , 8 , 9 , 11 ]
E n t r ée pour c o n t i n u e r . . . >?
Depilages
lifo : [ 5, 8, 9]
lifo : [ 5, 8]
lifo : [5]
lifo : [ ]
La p i l e e s t v i d e !
lifo : [ ]
"""

XI-6 Bonus : TDA Queue


• De la même manière, implémentez une queue FIFO (First in First out, comme une file devant un guichet) avec une
liste.

XI-7 Exercice : liste des moyennes


• Écrire une fonction moyennes(V1) qui reçoit une liste (vecteur) V1 en paramètre et produit une liste V2 telle que
X i
V1 [j]
j=0
V2 [i] = i+1 , i = 0..|V1 | 1. Autrement dit, V2 [i] contient la moyenne des éléments V1 [0..i].

XI-8 Exercice : méthode EM de base


• Soit une liste de nombres L 3 . Certaines valeurs de cette liste sont connues et on voudrait estimer les autres par la
méthode suivante :
1) On fixe une moyenne µ0 = 0, = 1 et les valeurs manquantes = µ0 ; i = 1
2) Estimer les valeurs inconnues à l’aide de µi sur L : elles seront égales à µi
3. Pour la méthode EM, voir par exemple http ://ai.stanford.edu/⇠chuongdo/papers/em_tutorial.pdf
Les listes #19

3) Les éléments manquants étant estimés, calculer µi+1 ; poser les éléments manquants de départ =µi ; i = i + 1 et aller à 2)
4) Stopper les itérations si µk+1 ' µk

• Exemple : soit L=[4,10, ?, ?]


1) µ0 = 0; = 1; i = 1
2) L = [4, 10, 0, 0]
3) µ1 = 144 = 3.5 € L = [4, 10, 3.5, 3.5]
4) µ2 = 5.25 € L = [4, 10, 5.25, 5.25]
5) µ3 = 6.125 € L = [4, 10, 6.125, 6.125]
6...) µ4 = 6.5625 . . . µ5 = 6.125 . . . µ3 = 6.7825 . . . µ6 = 6.89062525 . . .
...X) µk = 7 € L = [4, 10, 7, 7]

XI-9 Exercice : enlever les doublons d’une liste


• Supprimer les éléments répétés dans une liste sans changer l’ordre des éléments.
• Notons qu’en Python, pour une liste L=[5,1,2,8,1,5], le même résultat est obtenu par set(L) qui transforme L en
un ensemble. Par contre, l’ensemble obtenu sera ordonné. C’est ce que l’on veut éviter ici.

XI-10 Bonus : Scinder une liste


• Échantillonner une liste L d’entiers de taille N > 10 au hasard (entre 2..N ⇤ 4) puis scinder cette liste en L1 , L2 :
L1 contiendra les sous-séquences ascendantes de L de longueur d’au moins 2, L2 les autres.
• Exemple-1 : si L = [27, 6, 32, 13, 28, 12, 34, 37, 2, 30] alors L1 = [6, 32, 13, 28, 12, 34, 37, 2, 30], L2 = [27]
• Exemple-2 : Si L = [18, 17, 27, 18, 40, 22, 30, 30, 22, 15], on aurait L1 = [17, 27, 18, 40, 22, 30, 30], L2 = [18, 22, 15]
Copie de listes (important) #20

XII Copie de listes (important)


+ La copie d’une liste même de dimension 1 avec L1=L2 créé une synonymie.
+ La copie d’une liste de dimension 1 avec L1=L2[:] fonctionne mais si L1 est de dimension > 1 (liste de listes), les
sous-listes ne sont pas copiées (synonymie).
+ Pour copier véritablement une liste de n’importe quelle dimension, on utilise deepcopy() :
M= [ [ 1 , 2 , 3 ] , [ 4 , 10 , 6 ] , [ 7 , 8 , 9 ] ]

M5=M # Synonymie

# Copions autrement
M3=M[ : ]
M3
# [ [ 1, 2, 3] , [ 4, 5, 6] , [ 7, 8, 9] ]

# On m o d i f i e M3
M3[ 1 ] [ 1 ] =10

M
# [ [ 1 , 2 , 3 ] , [ 4 , 10 , 6 ] , [ 7 , 8 , 9 ] ] # M e s t également m o d i f i ée

# La bonne f a çon :
i m p o r t copy
M4=copy . deepcopy (M)

M4
# [ [ 1 , 2 , 3 ] , [ 4 , 10 , 6 ] , [ 7 , 8 , 9 ] ]

# On m o d i f i e M
M[ 2 ] [ 2 ] =20
M
# [ [ 1 , 2 , 3 ] , [ 4 , 10 , 6 ] , [ 7 , 8 , 20 ] ] # M a b i e n changé

M4
# [ [ 1 , 2 , 3 ] , [ 4 , 10 , 6 ] , [ 7 , 8 , 9 ] ] # Mais pas M4

XIII Tuples
• Le tuple vide se note : ()
• On accède au range d’un élément d’un tuple par la fonction index.
• On teste l’appartenance d’un élément à un tuple par in.
• Si les (éléments des) tuples sont des objets non mutables, on ne peut pas les modifier.
• Exemple :
a_tuple = (1 , 2)
a _ t u p l e += ( 3 , 4 )
a_tuple
# (1 , 2 , 3 , 4)

# a _ t u p l e [ 0 ] += 3 : e r r e u r : a f f e c t a t i o n / m o d i f i c a t i o n i n t e r d i t e s

a_tuple [ 3 ]
# 4

• Tentative de modification des éléments non mutables du tuple :


a _ t u p l e [ 4 ] =5 # > erreur affectation / modification i n t e r d i t e s
a _ t u p l e += ( 5 ) # > e r r e u r can o n l y concatenate t u p l e ( n o t " i n t " ) t o t u p l e

Ÿ Remarquer les 2 erreurs.

• Mais si un élément du tuple est mutable (ici une liste), alors les modifications sont possibles :
a _ t u p l e += ( [ ’ H e l l o ’ ] , ’ P a r i s ’ )
a_tuple
# (1 , 2 , 3 , 4 , [ ’ Hello ’ ] , ’ Paris ’ )

a_tuple . index ( [ ’ Hello ’ ] )


# 4

# a _ t u p l e [ 4 ] = [ ’ GoodBye ’ ] : erreur affectation / modification interdites

Ÿ Le tuple est allergique à l’opérateur d’affectation.

• Par contre, on peut modifier le contenu de la liste [’Hello’]


a _ t u p l e [ 4 ] . append ( ’ World ’ )
a_tuple
# ( 1 , 2 , 3 , 4 , [ ’ H e l l o ’ , ’ World ’ ] , ’ P a r i s ’ )
Tuples #21

• Modifions la liste dans le tuple d’une autre manière (devrait être autorisée) :

a _ t u p l e [ 4 ] += [ ’ o f L i o n s ’ ] # Etrangement , i l y a une e r r e u r MAIS l ’ a j o u t se f a i t ( bug ? )


a_tuple
# ( 1 , 2 , 3 , 4 , [ ’ H e l l o ’ , ’ World ’ , ’ o f L i o n s ’ ] , ’ P a r i s ’ )

+ Préférez utiliser "append" (ici utilisé en l’état), voir aussi l’ajout de ’Good Luck’ (ci-dessous) :
a _ t u p l e [ 4 ] . append ( ’ I n ’ )
a_tuple
# ( 1 , 2 , 3 , 4 , [ ’ H e l l o ’ , ’ World ’ , ’ o f L i o n s ’ , ’ I n ’ ] , ’ P a r i s ’ )

• On peut également modifier un élément de la liste [’Hello’, ’World’, ...]


a _ t u p l e [ 4 ] [ 0 ] = ’ Good Luck ’ # On remplace ’ H e l l o ’
a_tuple
# ( 1 , 2 , 3 , 4 , [ ’ Good Luck ’ , ’ World ’ , ’ o f L i o n s ’ , ’ I n ’ ] , ’ P a r i s ’ )

• On peut ajouter des doublets ou plus à un tuple. On va ajouter un couple puis un triplet :
a _ t u p l e += ( 5 , ’ t o t o ’ )
a_tuple
# ( 1 , 2 , 3 , 4 , [ ’ Good Luck ’ , ’ World ’ , ’ o f L i o n s ’ , ’ I n ’ ] , ’ P a r i s ’ , 5 , ’ t o t o ’ )

a _ t u p l e += ( 1 0 , 2 0 , 3 0 )
a_tuple
# ( 1 , 2 , 3 , 4 , [ ’ Good Luck ’ , ’ World ’ , ’ o f L i o n s ’ , ’ I n ’ ] , ’ P a r i s ’ , 5 , ’ t o t o ’ , 10 , 20 , 30)

XIII-1 Accès aux éléments d’un tuple


• Comme pour les liste, on peut avoir accès aux éléments du tuple par indice négatif et par tranches. Exemple :
t = ( " a " , " b " , " c " , " z " , " example " )
t
# ( ’ a ’ , ’ b ’ , ’ c ’ , ’ z ’ , ’ example ’ )

t [0]
# ’a ’

t [ 1]
# ’ example ’

t [ 1:3 ]
# ( ’b ’ , ’c ’)

z in t
# True

• On peut associer des variables aux membres d’un tuple :


v = ( ’ a ’ , ’ b ’ , ’ e ’ ) # v e s t un t u p l e
(x , y , z) = v
x
# ’a ’

y
# ’b ’

z
# ’e ’

• Association d’un rang (à partir de 0) aux éléments d’un tuple.


l i s t ( range ( 7 ) ) # ’ l i s t ’ né c e s s a i r e en Python 3
#[ 0, 1, 2, 3, 4, 5, 6]

( v e r t u , genie , t r a v a i l , o p i n i o n , recompenses , r e v o l u t i o n , s a n c u l o t t i d e s ) = range ( 7 )


vertu
# 0

sanculottides
# 6

• Mais aussi, il est possible d’associer un range 6= 0 au premier élément. Noter la fonction len :

l e n ( ( v e r t u , genie , t r a v a i l , o p i n i o n , recompenses , r e v o l u t i o n , s a n c u l o t t i d e s ) )
#7

( v e r t u , genie , t r a v a i l , o p i n i o n , recompenses , r e v o l u t i o n , s a n c u l o t t i d e s ) = range ( 3 , 10)


vertu
# 3
Introduction à la mise en page #22

% a_tuple
% # ( 1 , 2 , 3 , 4 , [ ’ God Luck ’ , ’ World ’ , ’ o f L i o n s ’ ] , ’ P a r i s ’ , 10 , 20 , 30)
%
% p r i n t ( * a_tuple )
% # 1 2 3 4 [ ’ God Luck ’ , ’ World ’ , ’ o f L i o n s ’ ] P a r i s 10 20 30
%

XIV Introduction à la mise en page


• Écrire des choses avec print :
q = 459
p = 0.098
print (q, p, p * q)
# Donne > 459 0.098 44.982

p r i n t ( q , p , p * q , sep= " , " )


# Donne > 459 ,0.098 ,44.982

p r i n t ( q , p , p * q , sep= " : ) " )


# Donne > 459 : ) 0.098 : ) 44.982

+ print renvoie None (au cas où vous vous laisseriez aller à la programmation fonctionnelle !).
print ( print (1) )
# 1
# None

• On peut créer des strings et les écrire


p r i n t ( s t r ( q ) + " >> " + s t r ( p ) + " << " + s t r ( p * q ) )
# Donne > 459 >> 0.098 << 44.982

• Le format : opérateur "%" (hérité du langage C)


x=5
’%d ’ % x
# Donne > ’5 ’

’ (%d ) ’ % x
# Donne > ’(5) ’

’ Je connais un mouton à %d p a t t e s . ’ % x
# Donne > ’ Je connais un mouton à 5 p a t t e s . ’

y=2
’ Je connais %d moutons à %d p a t t e s . ’ % ( y , x )
# Donne > ’ Je connais 2 moutons à 5 p a t t e s . ’

+ Remarques : dans ces exemples, "%" sépare le string exprimant le format (e.g. "%d") de la valeur à écrire
(e.g. "x").

• On peut maitriser les longueurs des champs (e.g. pour justifier des colonnes) :
Ÿ La syntaxe à suivre est %[flag][longueur][.precision] variable
r =2
p r i n t ( " La s u r f a c e pour un rayon <%3d> sera <%8.3 f > " % ( r , r * r * p i ) )
# Donne > La s u r f a c e pour un rayon < 2> sera < 12.566 >

Ici, %3d demande à écrire r sur 3 positions (on écrit entre <> pour plus de clarté). Pour la surface, %8.3f demande
une longueur totale de 8 places (le ’.’ compris) dont 3 chiffres après la virgule. En cas d’erreur de notre part pour la
totalité de la longueur, par exemple si on demande <%1.3f>, Python outrepasse l’erreur et utilise ce qui est juste (ici
3 chiffres après la virgule), sinon le minimum de longueur requise.
Par exemple, si on demande %4.2f pour la surface, les 2 chiffres après la virgule demandés plus une place nécessaire
pour le ’.’ feront que le total de 4 places ne suffiront pas (il faut au moins 2 places pour 12). Au final, on écrira
<12.57>.
Noter que %3d est équivalent à %3i.
Quelques informations supplémentaires (extrait de la doc) :
Introduction à la mise en page #23

Symbole de conversion (suit %) Signification


d entier décimal signé.
i entier décimal signé.
o octal Non signé .
u décimal Non signé .
x hexadécimal non signé (minuscule).
X hexadécimal non signé (majuscule).
e exponentiel au format virgule flottante (minuscule).
E exponentiel au format virgule flottante (majuscule).
f décimal au format virgule flottante.
F décimal au format virgule flottante.
g Comme "e" si exposant > 4 ou < à la précision, "f" sinon.
G Comme "E" si exposant > 4 ou < à la précision, "F" sinon.
c Un caractère (ou un entier ou un string mono caractère).
r String (convertit tout objet Python à l’aide de repr()).
s String (convertit tout objet Python à l’aide de str()).
% Pas de conversion, produit le caractère "%".
Introduction à la mise en page #24

Quelques exemples :
p r i n t ( " %10.3e "% ( 35 6 . 0 8 97 7 ) )
#Donne > 3.561 e+02
p r i n t ( " %10.3E"% ( 35 6 . 0 8 97 7 ) )
#Donne > 3.561E+02
p r i n t ( "%10o "% ( 2 5 ) )
#Donne > 31
p r i n t ( " %10.3o "% ( 2 5 ) )
#Donne > 031
p r i n t ( " %10.5o "% ( 2 5 ) )
#Donne > 00031
p r i n t ( "%5x "% ( 4 7 ) )
#Donne > 2f
p r i n t ( " %5.4x "% ( 4 7 ) )
#Donne > 002 f
p r i n t ( " %5.4X"% ( 4 7 ) )
#Donne > 002F
p r i n t ( " Only one percentage s i g n : %% " % ( ) )
#Donne > Only one percentage s i g n : %
p r i n t ( ’%d ’ % 0x12 )
#Donne > 18

XIV-1 La fonction format


• La section ci-dessus (avec "%") est un héritage du langage C. Ce mécanisme peut être insuffisant dans certain cas,
par exemple pour écrire une liste (à moins de l’écrire élément par élément ou de la transformer par repr()).
• On peut utiliser un formatage (à la Python) à l’aide de la fonction format. Dans :
r =2
" La s u r f a c e pour un rayon { 0 : 3 d } sera { 1 : 8 . 3 f } " . f o r m a t ( r , r * r * p i )
# Donne > ’ La s u r f a c e pour un rayon 2 sera 12.566 ’

Le {0:3d} précise le format de la première colonne (commence à 0) et {1:8.3f} celui de la 2e colonne.


Noter la position de la fonction format. N’oubliez pas que ’%’ est absent dans l’expression de format (ne pas écrire
1:%8.3f)

• D’autres exemples :
" F i r s t argument : { 0 } , second one : { 1 } " . f o r m a t ( 4 7 , 1 1 )
# Donne >’ F i r s t argument : 47 , second one : 11 ’
" Second argument : { 1 } , f i r s t one : { 0 } " . f o r m a t ( 4 7 , 1 1 )
# Donne >’Second argument : 11 , f i r s t one : 47 ’
" Second argument : { 1 : 3 d } , f i r s t one : { 0 : 7 . 2 f } " . f o r m a t ( 4 7 . 4 2 , 1 1 )
# Donne >’Second argument : 11 , f i r s t one : 47.42 ’
" F i r s t argument : { } , second one : { } " . f o r m a t ( 4 7 , 1 1 )
# Donne >’ F i r s t argument : 47 , second one : 11 ’
# arguments can be used more than once :
...
" various precions : { 0:6.2 f } or { 0:6.3 f } " . format (1.4148)
# Donne >’ v a r i o u s p r e c i o n s : 1.41 o r 1 . 4 1 5 ’

• Aussi, on peut remplacer la numérotation des colonnes et renommer les argument. Dans l’exemple ci-dessous, le
rayon représente r et la surface la superficie.
r =2
" La s u r f a c e pour un rayon { rayon : 3 d } sera { s u r f a c e : 8 . 3 f } " . f o r m a t ( s u r f a c e = r * r * p i , rayon= r )
# Donne > ’ La s u r f a c e pour un rayon 2 sera 12.566 ’

• D’autres exemples (noter les longueurs des champs utilisées pour les strings).
• N.B. : le symbole ’<’ impose une justification à gauche (avec ajoute d’espaces si nécessaires) et ’>’ une justification
à droite.
p r i n t ( ’ %(language ) s has %(number ) 03d quote t y p e s . ’ % { " language " : " Python " , " number " : 2 } )
# Python has 002 quote t y p e s .

" { 0: <20 s } { 1 : 6 . 2 f } " . f o r m a t ( ’Spam & Eggs : ’ , 6 . 9 9 )


# Donne >’Spam & Eggs :
6.99 ’
" { 0: >20 s } { 1 : 6 . 2 f } " . f o r m a t ( ’Spam & Eggs : ’ , 6 . 9 9 )
# Donne >’ Spam & Eggs : 6.99 ’

" { 0: >20 s } { 1 : 6 . 2 f } " . f o r m a t ( ’Spam & Ham: ’ , 7 . 9 9 )


# Donne >’ Spam & Ham: 7.99 ’

" { 0: <20 s } { 1 : 6 . 2 f } " . f o r m a t ( ’Spam & Ham: ’ , 7 . 9 9 )


# Donne > ’Spam & Ham: 7.99 ’

" { 0: <20 } { 1 : 6 . 2 f } " . f o r m a t ( ’Spam & Ham: ’ , 7 . 9 9 )


# Donne > ’Spam & Ham: 7.99 ’

" { 0: >20 } { 1 : 6 . 2 f } " . f o r m a t ( ’Spam & Ham: ’ , 7 . 9 9 )


# Donne >’ Spam & Ham: 7.99 ’
Itérations : While, for #25

• Un exemple de mise en colonne de valeurs : afficher en colonnes de x, x2 , x3 avec x 2 1..10


f o r x i n range ( 1 , 11) :
p r i n t ( ’ { 0:2d } { 1:3d } { 2:4d } ’ . format ( x , x * x , x * x * x ) )

1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
6 36 216
7 49 343
8 64 512
9 81 729
10 100 1000

# On peut a u s s i ne r i e n é c r i r e e n t r e l e s { } :
x , y= ’ choux ’ ,1
p r i n t ( " I l n ’ y a que { } f a çon de p l a n t e r des { } chez { } " . f o r m a t ( y , x , ’ nous ’ ) )
# Donne > I l n ’ y a que 1 f a çon de p l a n t e r des choux chez nous .

XIV-2 Exercice : table de x, x*x, sqrt(x)


p
• Écrire un programme qui affichage en colonnes la table contenants les colonnes x, x2 et x pour x 2 1..N . Lire au
préalable la valeur de N (ou supposer N = 20).

XV Itérations : While, for


• Il est difficile d’éviter de rencontrer les itérations (en particulier avec for) en Python et ce assez rapidement. Voyons
quelques exemples moins triviaux.

XV-1 While : Celcius-Farenheit


• Programmer une table de conversion Celcius-Frenheit et écrire les valeurs en colonnes.
• On utilisera les différentes formes d’itérations.
p r i n t ( " Table de c o n v e r s i o n f a h r e n h e i t > celsius " )
p r i n t ( " " *60)
i n f , sup , pas =0 ,100 ,20;

# Premiè r e mé thode : avec w h i l e e t sans vé r i t a b l e mise en page


fahr= i n f ;
w h i l e ( f a h r <=sup ) :
c e l s i u s = ( 5 . 0 / 9 . 0 ) * ( f a h r 32.0) ;
p r i n t ( " En f a h r e n h e i t : " , f a h r , " En c e l s i u s : " , c e l s i u s )
f a h r = f a h r + pas

" " " TRACES


Table de c o n v e r s i o n f a h r e n h e i t > celsius

En fahrenheit : 0 En c e l s i u s : 17.77777777777778
En fahrenheit : 20 En c e l s i u s : 6.666666666666667
En fahrenheit : 40 En c e l s i u s : 4.444444444444445
En fahrenheit : 60 En c e l s i u s : 15.555555555555557
En fahrenheit : 80 En c e l s i u s : 26.666666666666668
En fahrenheit : 100 En c e l s i u s : 37.77777777777778
"""

# Une v a r i a n t e de l a premi è r e mé thode : avec w h i l e + break


fahr= i n f ;
w h i l e True :
c e l s i u s = ( 5 . 0 / 9 . 0 ) * ( f a h r 32.0) ;
# Premiè r e f a çon de f o r m a t e r
p r i n t ( " En f a h r e n h e i t : " , r e p r ( f a h r ) . r j u s t ( 5 ) ,
" En c e l s i u s : %8.3 f " % c e l s i u s )
f a h r = f a h r + pas
i f ( f a h r >sup ) :
break

" " " TRACE


En f a h r e n h e i t : 0 En c e l s i u s : 17.778
En f a h r e n h e i t : 20 En c e l s i u s : 6.667
En f a h r e n h e i t : 40 En c e l s i u s : 4.444
En f a h r e n h e i t : 60 En c e l s i u s : 15.556
En f a h r e n h e i t : 80 En c e l s i u s : 26.667
En f a h r e n h e i t : 100 En c e l s i u s : 37.778
"""
%\usepackage { setspace , l i s t i n g s } % setspace i m p o r t a n t
% on peut donner \ begin { l s t l i s t i n g } [ c a p t i o n = . . , l a b e l = . . . ]
Itérations : While, for #26

XV-2 For : Celcius-Farenheit


• La même question avec for :
# Deuxième mé thode : avec f o r
f o r f a h r i n range ( i n f , sup+pas , pas ) :
# Deuxième f a çon de f o r m a t e r ( pour l e s r é e l s )
c e l s i u s = ( 5 . 0 / 9 . 0 ) * ( f a h r 32.0) ;
p r i n t ( " En f a h r e n h e i t : " , r e p r ( f a h r ) . r j u s t ( 5 ) , " En c e l s i u s : %8.3 f " % c e l s i u s )

""" TRACE
En fahrenheit : 0 En celsius : 17.778
En fahrenheit : 20 En celsius : 6.667
En fahrenheit : 40 En celsius : 4.444
En fahrenheit : 60 En celsius : 15.556
En fahrenheit : 80 En celsius : 26.667
En fahrenheit : 100 En celsius : 37.778
"""

# V a r i a n t e de f o r avec une a u t r e mis en page


i n f , sup , pas =0 ,100 ,20;
p r i n t ( " Fahre
n h e i t " . c e n t e r ( 1 0 ) , " c e l s i u s " . c e n t e r ( 1 0 ) , sep= ’ ’)
p r i n t ( " " *60)
fahr= i n f ;
nb_pas=sup / / pas # l e nbr de pas

f o r i n d i c e i n range ( 0 , nb_pas +1) :


c e l s i u s = ( 5 . 0 / 9 . 0 ) * ( i n d i c e * pas+ f a h r 32.0) ;

# 0 : xx e t 1 : yyy f o n t r é f é rences aux numé r o s des colonnes dans f o r m a t


# 0 : xx f a i t r é f é rence au champ No 0 = 1è r e colonne
p r i n t ( ’ { 0:7d } { 1 : 4 . 1 f } ’ . f o r m a t ( i n d i c e * pas+ f a h r , c e l s i u s ) )

"""
Fahrenheit celsius
0 17.8
20 6.7
40 4.4
60 15.6
80 26.7
100 37.8
"""

Ÿ Noter que dans for i in range(5) : ..., la valeur de i à la sortie de ce for est 4 (et non 5 comme on
pourrait le penser).
Itérations : While, for #27

+ Remarques : le format de for :


for iteration_for in intervalle :
corps_for
else : else_expression

Noter que intervalle est évalué une seule fois et donne lieu à un itérateur dont les valeurs sont assignées une
par une à iteration_for (donc, c doit pouvoir recevoir une valeur, ou être une lvalue, ce qui exclue par exemple
un appel de fonction).
for peut provoquer une exception "StopIteration".
else_expression est exécutée à la fin des itérations ou suite à l’exception "StopIteration".
corps_for peut contenir break.
Si break est exécuté, on abandonne l’itération sans exécuter else_expression.
corps_for peut contenir continue. S’il est exécuté, on passe à l’itération suivante (mais s’il n’y aucune autre
itération possible, else_expression sera exécutée avant de terminer).
Les variables de iteration_for reçoivent des valeurs qui écrasent leur éventuelle ancienne valeur :

# Observer i

i =12
f o r i i n range ( 5 ) :
p r i n t ( i , end= ’ ’ )
i =42
print ( i )
# Donne > : 0 1 2 3 4 42

• On constate que i=12 ni les i=42 n’ont aucun effet sur i de iteration_for. Cependant, la valeur finale de i=42
(fait à la toute dernière itération).

• On aura le même résultat avec (noter else) :


# Observer i

i =12
f o r i i n range ( 5 ) :
p r i n t ( i , end= ’ ’ )
e l s e : i =42

print ( i )
# Donne > : 0 1 2 3 4 42

Les variables de iteration_for existeront après les itérations. Elles auront leur valeur finale de la dernière
itération.
Éviter de modifier intervalle dans corps_for sous peine de surprises.

+ Le schéma while dispose également d’une clause else : ... dont le comportement est identique à celle
présente dans for. Idem pour continue et break dans le schéma while.

XV-3 Exercice : valeur de e


Xn
1
• Écrire un programme qui estime la valeur de la constante mathématique e en utilisant la formule : e =
0
i!
Pour ce faire, définissez la fonction factorielle puis, dans votre programme principal, lire au clavier l’ordre n et affichez
l’approximation correspondante de e.
+ Remarques : la fonction math.factorial(.) existe.
Itérations : While, for #28

XV-4 Exercice : nombre premier


• On appelle nombre premier tout entier naturel supérieur à 1 qui possède exactement deux diviseurs, lui-même et
l’unité ;
• On dira donc que l’entier positif N est premier si N = 1 ou N = 2 ou alors N remplit les conditions suivantes :
N %2 6= 0
p
N2/N
p p
@k, (k 2 3 . . . d N e ^ k|N ) c-à-d. : N n’est multiple d’aucun des entiers k 2 3.. N + 1

• Lire un entier et tester s’il s’agit d’un nombre premier.

XV-5 Bonus : Nombre Premier par diviseurs propres


• Une autre méthode : on appelle diviseur propre de de l’entier naturel N , un diviseur quelconque de N (N exclu) ;
• Lire N et compter le nombre de diviseurs propres du nombre N . S’il n’y a pas de tel diviseur alors N est premier.
Sinon, on afficher ses diviseurs ainsi que leur nombre.

XV-6 Bonus : Diviseurs des nombres Parfaits et Premiers


• Un entier naturel est dit parfait s’il est égal à la somme de tous ses diviseurs propres ;
• Les nombres a tels que : (a + n + n2 ) est premier pour tout n tel que 0 < n < (a 1), sont appelés nombres chanceux.
• Écrire un script Python définissant quatre fonctions : somDiv, estParfait, estPremier, estChanceux.
la fonction somDiv retourne la somme des diviseurs propres de son argument ;
les trois autres fonctions vérifient la propriété donnée par leur définition retournant un booléen. Plus précisé-
ment, si par exemple la fonction estPremier vérifie que son argument est premier, elle retourne True, sinon elle
retourne False.

• Écrire et tester ces fonctions, par exemple avec les valeurs somDiv(12), estParfait(6), estPremier(31) et
estChanceux(11).

XV-7 Bonus (suite) : Importer vos fonctions


• Transformer le module précédent en le nommant parfait_chanceux_m.py définissant les quatre fonctions : somDiv,
estParfait, estPremier, estChanceux.
• Penser à la partie principale (voir la section VI, page 7) : pour transformer ce module en un script indépendant (et
importer les fonctions qui y sont définies), vous devez ajouter avant la partie principale :
if __name__==’__main__’:

• Écrire le programme principal parfait_chanceux.py qui comporte :


- l’initialisation de deux listes : parfaits et chanceux ;
- une boucle de parcours de l’intervalle [2, 1000] incluant les tests nécessaires pour remplir ces listes ;

XV-8 Exemple : compter les lettres


• On lit un texte terminé par un ’.’. Compter le nombre de chiffres et de lettres.
ph= i n p u t ( " Donner une phrase s u r une l i g n e t e r m i n ée par un p o i n t " )

n b _ c h i f f r e s = n b _ l e t t r e s =0
f o r c a r i n ph :
i f c a r == ’ . ’ :
break
i f car . isalpha ( ) :
n b _ l e t t r e s +=1
i f car . i s d i g i t ( ) :
n b _ c h i f f r e s +=1

p r i n t ( " Dans l a phrase %s , i l y a %d l e t t r e s e t %d c h i f f r e s " % ( ph , n b _ l e t t r e s , n b _ c h i f f r e s ) )


Itérations : While, for #29

• On pourrait utiliser liste_caracters=list(ph).

+ Dans le version ci-dessus, la présence de ’.’ n’est pas contrôlée lors de la lecture de la phrase. Même si on teste
cette présence dans le code !
• Dans la version suivante, on va s’assurer de la lecture du ’.’ final tout en lisant la phrase sur plusieurs lignes.
stock= ’ ’
w h i l e True : # l i r e j u s q u ’ au ’ . ’
ph= i n p u t ( " Donner une ( s u i t e de ) phrase t e r m i n ée par un p o i n t " )
s t o c k +=ph # stock contiendra toutes les lignes
i f ph [ 1] == ’ . ’ :
break

n b _ c h i f f r e s = n b _ l e t t r e s =0
f o r car i n stock :
i f c a r == ’ . ’ :
break
i f car . isalpha ( ) :
n b _ l e t t r e s +=1
i f car . i s d i g i t ( ) :
n b _ c h i f f r e s +=1
p r i n t ( " Dans l a phrase %s , i l y a %d l e t t r e s e t %d c h i f f r e s " % ( stock , n b _ l e t t r e s , n b _ c h i f f r e s ) )

XV-9 Exercice : compter les voyelles et consonnes


• On lit un texte terminé par EOF. Ce texte pouvant être composé de plusieurs phrases. Le programme doit déter-
miner le nombre de voyelles, le nombre de consonnes, le nombre de chiffres, le nombre d’autres caractères
+ Remarques : on peut créer un dictionnaire Python (une MAP) indexé sur les voyelles init 0 :
nb_voyelles = {i:0 for i in ’aeiouAEIOU’}
Le résultat est nb_voyelles ={’a’ : 0, ’e’ : 0, ’i’ : 0, ’o’ : 0, ’u’ : 0, ’A’ : 0, ’E’ : 0, ’I’ : 0, ’O’ : 0, ’U’ : 0}
On peut alors compter le nombre d’occurrence de chaque voyelle dans la chaîne ch1 :
ch1= " Une n u i t , un h o t e l a p r i s f e u e t l e s gens o n t couru dehors en h a b i t s de n u i t . Deux hommes o b s e r v a i e n t . "
n b _ v o y e l l e s = { i : 0 f o r i i n ’ aeiouAEIOU ’ }
f o r l e t t r e i n ch1 :
i f l e t t r e i n ’ aeiouAEIOU ’ : n b _ v o y e l l e s [ l e t t r e ] += 1
p r i n t ( nb_voyelles )
{ ’O ’ : 0 , ’ i ’ : 5 , ’E ’ : 0 , ’ e ’ : 13 , ’A ’ : 0 , ’ u ’ : 7 , ’ a ’ : 3 , ’U ’ : 1 , ’ I ’ : 0 , ’ o ’ : 6 }

• Pour compter la somme de toutes les voyelles dans un string ch2 (converti à la volée en minuscule) :
ch2 = " L ’ un a d i t : puisque l e s gens ne f o n t pas a t t e n t i o n à l e u r s biens , j e me s u i s s e r v i en s o r t a n t ! "
v o y e l l e s = " aeiou " ; t o t a l _ v o y e l l e s =0 # On ne prend que l e s v o y e l l e s minuscules
for v in voyelles : # On compte l e nombre d ’ occurrence de chaque v o y e l l e dans
t o t a l _ v o y e l l e s += ch2 . l o w e r ( ) . count ( v ) # ch2
# 29

Ÿ Remarquer le ’ ;’ qui permet de placer plusieurs expressions sur la même ligne a .

a. La suite de l’histoire que les chaînes de caractères de cet exemple racontent :


ch3="L’autre a répliqué : ’savez-vous que je suis de la Police ?’ Le premier a répondu : ’savez-vous qu’écrivain, j’invente des histoires ?’ !’"

XV-10 Exercices Bonus : lancers de dés


1. L’utilisateur donne un entier n entre 2 et 12, le programme donne le nombre de façons de faire n en lançant
deux dés.
2. Même problème que le précédent mais avec n entre 3 et 18 et trois dés.
3. Généralisation des deux questions précédentes. L’utilisateur saisit deux entrées, d’une part le nombre de dés,
nbd (limité à 10), et d’autre part la somme s comprise entre nbd et 6*nbd.
Le programme calcule et affiche le nombre de façons de faire s avec les nbd dés.

XV-11 Bonus : Tri sélection


• Dans cette méthode de tri d’un vecteur V[0..k] éléments comparables (méthode de complexité O(N 2 )), on trouve
l’indice du minimum du V[0..k] qu’on permute avec V[0], puis on recommence avec V[1..k] ... et on termine avec
V[k..k].
• Écrire la méthode.
Les exceptions #30

+ Remarques :
Noter iMin = t.index(min(t[i:])) : on veut l’indice du minimum de la liste t à partir du ième élément.

XVI Les exceptions


• Python bénéficie du mécanisme d’exception (venant des langages Modula et ADA). Le schéma simplifié d’un bloc
avec exception est le suivant :
try :
expression1
except :
expression2

En cas d’exception dans expression1, on exécute expression2.


Si la clause except est absente pour un try, on passe au niveau supérieur (englobant) et ainsi de suite.
Ce mécanisme est important, en particulier dans le cas des fonctions partielles (cf. TDA).
Une exception peut être prédéfinie (voir ci-dessous) ou définie (à l’aide des classes) et levée par raise). Voir un
exemple plus bas.

XVI-1 Exemple 1
• Pour l’exercice pair-impair, on peut contrôler la lecture d’un entier au clavier.
a= i n p u t ( " Donner l e c o e f f i c i e n t a : " )
try :
a= i n t ( a )
i f ( a%2 ==1) :
p r i n t (a , " est impair " )
else :
p r i n t (a , " est pair " )
except V a l u e E r r o r : # On v i e n t i c i s i a= i n t ( a ) provoque une e x c e p t i o n .
p r i n t ( " pas un nbr " )

Qu’est-ce passe-t-il si au lieu de donner un entier, on donne une lettre ?

Si la valeur rentrée au clavier n’est pas un entier, la conversion a=int(a) provoque une exception prédéfinie. De
ce fait, la ligne suivante cette erreur n’est pas exécutée et Python cherche une clause except ValueError : qui va
de paire avec try et exécute ce qui y est prévu.

• Et si on tient à lire un entier à tout prix :


# Tant qu’un entier n’est pas donné, insistez !
w h i l e True :
a= i n p u t ( " Donner un e n t i e r : " )
try :
a= i n t ( a )
i f ( a%2 ==1) :
p r i n t (a , " est impair " )
else :
p r i n t (a , " est pair " )
break
except V a l u e E r r o r as e : # On v i e n t i c i s i a= i n t ( a ) provoque une e x c e p t i o n .
p r i n t ( e . args [ 0 ] . s p l i t ( " : " ) [ 1 ] + " n ’ pas un e n t i e r , recommencer ! " )

# I c i , on e s t s u r que a c o n t i e n t un e n t i e r

+ Remarques : ici, l’exception prend un nom locale (e) pour être traitée / détaillé.
• Dans cet exemple, l’exception e contient la chaîne "invalid literal for int() with base 10:
’a’", l’expression e.args[0].split(": ") sépare cette chaîne de part et d’autre de ": " et donne une
liste à 2 éléments contenant les deux chaînes [’invalid literal for int() with base 10’, ’a’]
et finalement l’indice [1] représente ’a’ (le 2e élément).

XVI-2 Exemple : Min/Max d’une séquence à la volée


• Dans cet exemple, on utilise l’exception EOFError pour détecter ctrl-D (ou ctrl-Z sous Windows) qui mettra
fin aux lectures d’entiers.
• Cet exemple doit être exécuté sous Python et dans une fenêtre "terminal" car spyder se bloque à cause de l’exception
EOFError provoquée par ctrl-D (ou ctrl-Z sous Windows).
Les exceptions #31

• Cependant, sous spyder, on peut demander l’exécution dans le menu Exécution/Configurer une fenêtre "terminal" :
Sous spyder, on peut associer à chaque fichier Python son type de console d’exécution (dans le menu Exécution/-
Configurer, choisir OK au lieu d’exécuter immédiatement). A partir de ce moment, l’exécution de ce code (placé
dans un fichier .py) aura lieu sous la console précisée.

+ Noter que si la fenêtre ferme immédiatement, c’est qu’il y a une erreur dans le code ! Il faut d’abord la corriger !
min=max=0
v a l = i n p u t ( " donner l e p r e m i e r e n t i e r " )
try :
val= i n t ( val )
min=max= v a l

except V a l u e E r r o r : #On v i e n t i c i s i on n ’ a pas donné un e n t i e r


p r i n t ( " F a l l a i t donner un e n t i e r " )
i n p u t ( " Taper s u r e n t r ée pour f e r m e r l a f e n e t r e e t q u i t t e r . " )
exit (0)

# I c i , on a l u un e n t i e r e t i n i t i a l i s é min e t max
w h i l e True :
try :
v a l = i n p u t ( " donner un e n t i e r " )
val= i n t ( val )
i f ( v a l < min ) :
min= v a l
i f v a l > max :
max= v a l

except V a l u e E r r o r : #On v i e n t i c i s i on n ’ a pas donné un e n t i e r


p r i n t ( " I l f a u t donner des e n t i e r s " )
exit (0)

except EOFError : #On v i e n t i c i s i on a f a i t CTRL D ( ou CTRL Z ) DANS un " t e r m i n a l "


p r i n t ( " c ’ e s t f i n i : min = " , min , " max = " , max )
break
i n p u t ( " pour ne pas f e r m e r l a f e n e t r e de s u i t e . . " )

+ Rappel : pour pouvoir terminer les lectures avec ctrl-D (ctrl-Z), exécutez ce code dans une fenêtre
"terminal". Sous votre IDE, cela ne marchera pas.

• Si on veut continuer toutes les lectures après une erreur :


min=max=0

w h i l e True :
try :
v a l = i n t ( i n p u t ( " donner l e p r e m i e r e n t i e r " ) )
min=max= v a l
break
except V a l u e E r r o r : #On v i e n t i c i s i on n ’ a pas donné un e n t i e r
continue

# I c i , on a l u un e n t i e r e t i n i t i a l i s é min e t max
w h i l e True :
try :
v a l = i n t ( i n p u t ( " donner un e n t i e r " ) )
i f ( v a l < min ) : min= v a l
i f v a l > max : max= v a l

except V a l u e E r r o r : #On v i e n t i c i s i on n ’ a pas donné un e n t i e r


p r i n t ( " F a l l a i t donner des e n t i e r s , on recommence " )
continue

except EOFError : #On v i e n t i c i s i on a f a i t CTRL D ( ou CTRL Z )


p r i n t ( " c ’ e s t f i n i : min = " , min , " max = " , max )
break

i n p u t ( " pour ne pas f e r m e r l a f e n e t r e de s u i t e . . " )

XVI-3 raise : deux exemples


• On utilise raise pour lever des exceptions, y compris celle que l’on juge opportunes.
Exemple 1 : si vous avez une fonction qui n’accepte qu’un entier n > 0 (par exemple, n est un nombre d’itérations),
procédez comme suit :
d e f ma_fonction ( n ) :
i f n < 1 : raise ValueError
else : # la s u i t e . . . . .

Ÿ l’exception ValueError sera levée si on appelle cette fonction avec n < 1.


L’utilisateur de ma_fonction() prendra ses précautions.
Les exceptions #32

Exemple 2 : Supposons que l’on veuille trouver le plus grand réel (à 1% près) de Python. L’exemple suivant multiplie
un nombre (initialisé à 1000000) par un facteur de 1,01 jusqu’à ce que cette multiplication ne soit plus possible faute
de capacité ! Dans ce dernier cas, le nombre devient infini (inf de Python) et on lève, par raise, une exception
prédéfinie ValueError dont le traitement affiche la plus grande valeur de facteur atteinte avant de devenir inf
= float(’inf’).
f a c t e u r = 1000000
w h i l e True :
try :
i f 1/ facteur :
save = f a c t e u r
f a c t e u r * = 1.01 # l’opération qui provoquera une exception
p r i n t ( ’ nombre grand a c t u e l : ’ , save )
else :
raise ValueError # on lève une exception prédéfinie

except V a l u e E r r o r :
p r i n t ( ’ l i m i t e : ’ , save )
break

p r i n t ( " Passer à l a s u i t e .... ")

" " " TRACE des d e r n i e r s nombres a f f i c h és :


.....
nombre grand a c t u e l : 1.7600504054160286e+308
nombre grand a c t u e l : 1.7776509094701888e+308
nombre grand a c t u e l : 1.7954274185648906e+308
l i m i t e : 1.7954274185648906e+308 # le plus grand réel (à 1% près)

Passer à l a s u i t e ....

XVI-4 Exercice : moyenne et fonction


• On reprend un exemple vu plus haut.
• Lire et constituer une liste d’entiers puis calculer la moyenne et la variance de ces valeurs.
• Protéger la lecture des entiers par une exception.

XVI-5 Expression Pass


• pass ne fait rien. C’est donc un bouche-trou à placer là où il faut quelque chose. On peut l’utiliser (entre autres) dans
les exceptions.
try :
vaZy_Plante ( )

except :
pass

• Ici, l’exception est captée et ignorée.

• D’autres exemples de pass :


w h i l e True :
pass # A t t e n t e a c t i v e , par exemple pour un C t r l +C

d e f f o n c t i o n _ a _ e c r i r e ( params ) :
pass # La f o n c t i o n e x i s t e . Pensez à l a complé t e r .

• pass est également utilisé pour créer des classes vides qui doivent exister ! Voir Inf-TC2. On l’utilise aussi dans les
exceptions si on veut les ignorer.
Génération de nombres aléatoires #33

XVII Génération de nombres aléatoires


• Des exemples (tirage uniforme) :
% i m p o r t random ;
random . random ( ) # Random f l o a t x , 0 . 0 <= x < 1 . 0
#Donne > 0.37444887175646646

random . u n i f o r m ( 1 , 10) # Random f l o a t x , 1 . 0 <= x < 10.0


#Donne > 1.1800146073117523

random . r a n d i n t ( 1 , 10) # E n t i e r s de 1 à 10 ( bornes i n c l u s e s )


#Donne > 7

random . randrange ( 0 , 101 , 2 ) # E n t i e r s p a i r s de 0 à 100


#Donne > 26

random . c h o i c e ( ’ a b c d e f g h i j ’ ) # Choix a l é a t o i r e
#Donne > ’c ’

items = [ 1 , 2 , 3 , 4 , 5 , 6 , 7 ]
random . s h u f f l e ( i t e m s )
items
#Donne > [ 7, 3, 2, 5, 6, 4, 1]

random . sample ( [ 1 , 2 , 3 , 4 , 5 ] , 3) # é c h a n t i l l o n n e r 3 é l éments


#Donne > [ 4, 1, 5]

• Une manière simple de générer une liste d’entiers aléatoires :


a , b , n = 3 , 20 , 5
[ r a n d i n t ( a , b ) f o r i i n range ( n ) ]

# Donne par exemple : [ 16 , 9 , 16 , 14 , 8 ]

+ Remarques : noter la définition a, b, n = 3, 20, 5.


• [randint(a, b) for i in range(n)] est appelé liste en compréhensions à voir en section XXIV page
52.

XVII-1 Exemple : indice du minimum d’une liste aléatoire d’entiers


from random i m p o r t seed , r a n d i n t

# fonctions
def l i s t A l e a t o i r e I n t ( n , a , b ) :
" " " Retourne une l i s t e de <n> e n t i e r s a l e a t o i r e s dans [ <a> . . <b> ] . " " "
r e t u r n [ r a n d i n t ( a , b ) f o r i i n range ( n ) ]

# programme p r i n c i p a l
seed ( ) # i n i t i a l i s e l e g e n e r a t e u r de nombres a l e a t o i r e s
t = l i s t A l e a t o i r e I n t ( 1 0 0 , 2 , 125) # c o n s t r u c t i o n de l a l i s t e

## c a l c u l de l ’ i n d i c e du minimum de l a l i s t e
i M i n = t . i n d e x ( min ( t ) )

## A f f i c h a g e s
p r i n t ( " { } t [ iMin ] = { } " . format ( " Indice : " , t [ iMin ] ) ) # V o i r p l u s l o i n pour l a f o n c t i o n f o r m a t

+ Remarques :
Noter les deux {} : la première est pour "Indice : " et la seconde pour t[iMin].
Ÿ voir section XIV page 22

XVII-2 Exemple : amplitude et la moyenne d’une liste aléatoire de réels


• On échantillonne une liste de réels dont on affiche l’amplitude et la moyenne.
# imports
from random i m p o r t seed , random

# fonctions
def l i s t A l e a t o i r e F l o a t ( n ) :
" " " Retourne une l i s t e de <n> f l o t t a n t s a l e a t o i r e s . " " "
r e t u r n [ random ( ) f o r i i n range ( n ) ]

# programme p r i n c i p a l
n = i n t ( i n p u t ( " E n t r e z un e n t i e r [ 2 . . 100 ] : " ) )
w h i l e n o t ( 2 <= n <= 100) : # s a i s i e f i l t r e e
n = i n t ( i n p u t ( " E n t r e z un e n t i e r [ 2 . . 100 ] , s . v . p . : " ) )

seed ( ) # i n i t i a l i s e l e g e n e r a t e u r de nombres a l e a t o i r e s
t = l i s t A l e a t o i r e F l o a t ( n ) # c o n s t r u c t i o n de l a l i s t e
Génération de nombres aléatoires #34

print ( " Liste : " , t )


p r i n t ( " Amplitude : { : . 2 f } " . f o r m a t ( max ( t ) min ( t ) ) )
p r i n t ( " Moyenne : { : . 2 f } " . f o r m a t ( sum ( t ) / n ) )

• Pour le formatage des écritures, voir la section XIV page 22.

XVII-3 Échantillonnage : Normale et Uniforme


+ Remarques :
• La fonction seed([n]) (avec un paramètre optionnel n) permet d’initialiser une séquence aléatoire.
Si le paramètre n n’est pas fourni (ou si on fournit None), Python initialise la séquence avec le temps système.
Ce même temps système est utilisé à la première importation du module random.

• Pour générer une séquence de distribution Normale, utiliser


from numpy.random import normal
N = normal(0, 1) # centré réduit N (0, 1)
N = normal() # la même chose (paramètre par défaut : N (0, 1))
N # Donne p.ex -0.11692213582578123
N = normal(10, 5) # N (10, 5)
normal(size= (2, 2)) # renvoie une matrice 2 ⇥ 2 de N (0, 1)
...

+ A propos de randn() du module numpy (scipy)


from scipy import randn
N = randn() # alternative à N = normal(0, 1)
N = randn(3,2) # renvoie une matrice 3 ⇥ 2 dont les nombres viennent de N (0, 1)
N = randn(2,2,2) # renvoie une cube 2 ⇥ 2 ⇥ 2 dont les nombres viennent de N (0, 1)

+ Donc :
⇤ randn(d1 , ..., dn ) + µ est équivalent à normal(µ, , d1 , ..., dn ) di : taille de la ième dimension

• A noter ( random ) :
import random
random.randint(a, b) : Échantillonnage Uniforme : renvoie un entier a  N  b
random.random() renvoie un réel dans [0 .. 1[.
random.gauss(µ, ) renvoie un réel de N (µ, )
random.choice(seq) renvoie un élément aléatoire de la séquence seq
random.randrange[début], fin, [pas]) équivalent à choice(range([début], fin, [pas])).
P. Ex. : random.randrange(0, 101, 2) renvoie un entier pair dans 0..100
random.shuffle(seq[, random]) "mélange" la séquence X sur place et seq devient égale à l’une
de ses propres permutations.
Le 2e argument est par défaut la fonction random() qui renvoie un réel N dans [0 .. 1[.
Si le 2e argument est présent, il doit être le nom d’une fonction sans argument.
Par exemple, si on définit
def f() : return 0 et L=[7, 2, 10, 7, 7, 18, 7, 7, 15, 11], alors
random.shuffle(L,f) place dans L la permutation [2, 10, 7, 7, 18, 7, 7, 15, 11, 7].
Puis à la répétition de ce même appel, le 1er élément de L est placé à la fin le le 2e devient le premier, ...

random.sample(seq, k) renvoie une liste de taille k des éléments sans remise de seq.

+ Consulter la doc du module random pour d’autres distributions.


Génération de nombres aléatoires #35

XVII-4 Complément : Tirage avec remise


• Exemple de tirage aléatoire avec remise (celui de Python est biaisé) et il est fortement préconisé d’utiliser les généra-
teurs de numpy dans une application sensible à ce type de tirage.

• Pour une distribution Uniforme :


from math i m p o r t *
from random i m p o r t *

# S i m u l a t i o n d ’ un t i r a g e avec remise de k o b j e t s parmi n

def tirage_uniforme_k_of_n_avec_remise ( n , k ) :
if k > n :
r a i s e V a l u e E r r o r ( " k (%d ) d o i t ê t r e =< que n (%d ) " % ( k , n ) )
T= [ x f o r x i n range ( 1 , n +1 ,1) ] # On c o n s t i t u e une urne avec p o b j e t s

f o r i i n range ( k ) : # T i r a g e de k numé r o s
d= r a n d i n t ( 1 , n )
# On permute l e d ème é l ément de l ’ urne e t l a d e r n i e r e
temp=T [ d 1]
T [ d 1] =T [ n 1]
T [ n 1] =temp
n=n 1
r e t u r n T [ n : n+k+1 ]

n= i n t ( i n p u t ( " La v a l e u r de n ? " ) )
k= i n t ( i n p u t ( " La v a l e u r de k ( parmi n ) ? " ) )
try :
p r i n t ( " Le t i r a g e : " , t i r a g e _ u n i f o r m e _ k _ o f _ n _ a v e c _ r e m i s e ( n , k ) )
except V a l u e E r r o r as e r r :
p r i n t ( " Error : { 0 } " . format ( e r r ) )

• Pour une distribution Normale :


from math i m p o r t *
from random i m p o r t *

def tirage_gauss_centre_reduit ( ) :
x= u n i f o r m ( 0 , 1 )
y= s q r t ( 2 * l o g ( u n i f o r m ( 0 , 1 ) ) )
y = y * cos ( x * 2 * p i )
return y

try :
n= i n t ( i n p u t ( " combien de v a l e u r s : " ) )
f o r i i n range ( n ) :
p r i n t ( " Le t i r a g e : " , t i r a g e _ g a u s s _ c e n t r e _ r e d u i t ( ) )
except V a l u e E r r o r as e r r :
p r i n t ( " Error : { 0 } " . format ( e r r ) )

" " " TRACE :


combien de v a l e u r s : 5
Le t i r a g e : 0.1675459650607427
Le t i r a g e : 0.8810297798592189
Le t i r a g e : 0.4764601603767129
Le t i r a g e : 1.8446292482050937
Le t i r a g e : 0.35483078367598453
"""

• Rappel : on peut faire un tel tirage à l’aide de numpy.


i m p o r t numpy as np
mu, sigma = 0 , 1 # Moyenne e t l ’ é c a r t t y p e
s = np . random . normal (mu, sigma , 5 )
s
# a r r a y ( [ 0.82484502 , 0.31461483 , 0.67549573 , 0.21602054 , 0.13565971 ] )

+ Il faudra un tirage d’un grand nombre de valeurs pour que la moyenne et l’écart type correspondent !
Ÿ Pour nos 5 valeurs, les choses sont mal engagées ! Vérifions :
np . mean ( s )
# 0.40500364849867287

np . s t d ( s , ddof =1)
# 0.80987532417316277
Génération de nombres aléatoires #36

XVII-5 Exemple : Tirage de cartes


• A partir d’un jeu de 52 cartes, donner la probabilité d’avoir un as de pique (10000 essais).
• Dans cet exemple, on utilise la fonction choice() qui choisit un élément d’un range aléatoire dans une séquence.
• La variables toutes_cartes représente tous les 52 cartes sous forme de strings, à l’aide d’une liste en compréhen-
sion (lire ci-après).
v a l e u r s = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 1 0 , ’ V a l e t ’ , ’Dame ’ , ’ Roi ’ }
c o u l e u r s = { ’ c a r r e a u ’ , ’ coeur ’ , ’ pique ’ , ’ t r e f l e ’ }
t o u t e s _ c a r t e s = [ s t r ( v ) + ’ ’ +c f o r v i n v a l e u r s f o r c i n c o u l e u r s ]

from random i m p o r t *

somme=0
f o r n i n range ( 1 0 0 0 ) :
i f c h o i c e ( t o u t e s _ c a r t e s ) == " 1 pique " :
somme+=1

p r i n t ( " proba ( f r équence ) obtenue : " ,somme/ 1 0 0 0 0 )


p r i n t ( " proba d ’ une c a r t e parmi 52 : " , 1 / 5 2 )

# > 0.002
# 0.019230769230769232

• Noter que la liste en compréhension utilisée équivaut tout simplement à :


toutes_cartes= [ ]
for v in valeurs :
f o r c in couleurs :
t o u t e s _ c a r t e s . append ( s t r ( v ) + ’ ’ +c )

Ÿ Voir la section XXIV page 52 pour plus de détails sur les listes en compréhension.

XVII-6 Exercice : Tirage de cartes


• Donner la probabilité d’avoir au moins 3 cartes de la même couleur dans une main de 4 cartes (10000 essais)

XVII-7 Bonus : Tirage de cartes (bis)


• Donner la probabilité d’avoir au moins 3 As dans une main de 5 cartes (10000 essais).

XVII-8 Bonus : Fréquences de dés


• Lancer 10000 fois un dé et donner la fréquence de chaque face.
Quelques fonctions sur les chaînes #37

XVIII Quelques fonctions sur les chaînes


• Une bonne partie de ces fonctions sont celles applicables aux listes.

• str.center(n) : centrage dans un champ de taille n, voir plus haut.


• str.ljust(n) : justification, voir plus haut.
• str.rjust(n) : justification, voir plus haut.
• str.count(ele) : compte le nombre d’occurrences de ele dans str.
• str.lower() : transformation en minuscules
• str.upper() : transformation en majuscules
• str.find(ele) : renvoie l’indice de la première occurrence de ele dans str.
• str.split(caractère) : découpage de str suivant charactère

• Exemples :
my_name
# ’ David ’
my_name . upper ( )
# ’ DAVID ’
my_name . c e n t e r ( 1 0 )
# ’ David ’
my_name . f i n d ( ’ v ’ )
# 2
my_name . s p l i t ( ’ v ’ )
# [ ’ Da ’ , ’ i d ’ ]

+ Rappel : une constante string est un objet non mutable :


my_name [ 0 ] = ’ d ’
# TypeError : ’ s t r ’ o b j e c t does n o t s u p p o r t i t e m assignment

+ Remarque : comme pour les listes, les tuples, on peut multiplier un string par un entier n pour répéter son contenu
n fois :
my_name
# ’ David ’

my_name * 3
# ’ DavidDavidDavid ’

+ Rappel : Par contre, parmi les listes, tuples et constantes strings, seules les listes sont mutables (on peut modifier
la valeur d’un de ses éléments).
Imbrication de fonctions #38

XIX Imbrication de fonctions


• Sous Python, la définition d’une fonction peut contenir la définition d’autres fonctions.
def f1 ( x ) :
x=1
d e f g1 ( x ) :
x += 10
g1 ( x )
print (x)

# main ( )
f1 (2) # donne 1
g1 ( 2 ) # donne une e r r e u r : g1 ( ) e s t incnnue

• Remarquez que la fonction g1() n’est visible qu’à l’intérieur de la définition de la fonctions f1(). On ne peut donc
pas l’appeler à partir du niveau 0.
• Noter que dans def g1(x) : , le paramètre formel x devient une variable locale à g1(.) ; elle reçoit sa valeur initiale
(1) par copie et n’aura plus de lien avec x de f1(). Voir section XX, page 42 sur la portée des variables.

XIX-1 Quelques règles utiles


• Les règles (sur la visibilité des variables) sont développées en section XX, page 42.
Dans une fonction Python : toute variable définie (par exemple par x=1) et tout paramètre (initialisé par le
passage de paramètre par valeur) est locale à la fonction.
def fonc ( x ) :
x += 15 # x est l o c a l e ’ fonc ’

x=12
fonc ( x ) ; x
#12 > x n ’ a pas changé de v a l e u r

Les variables du main (niveau global) sont accessibles dans une fonction via le mot clé global. Si elles existent
au préalable et au niveau global, elles sont ainsi référencées. Si elles n’existent pas, elles sont créées au niveau
global. On peut ainsi créer une variable (globale) pour le compte du niveau global dans une fonction.
d e f machin ( ) :
global bidule
b i d u l e = 50

machin ( ) ; b i d u l e
# 50

Ÿ Il y eu donc une création. Par contre, s’il s’agit d’une modification, ça ne passera pas :
def t r u c ( ) :
g l o b a l muche
muche += 50

truc ()
# NameError : name ’ muche ’ i s n o t d e f i n e d

Ÿ Cette fois, on a essayé de modifier muche. Dans ce cas, muche doit avoir existé avant l’appel de truc()
puisqu’on ajoute 50 à son ancienne valeur :
def t r u c ( ) :
g l o b a l muche
muche += 50

muche=10
t r u c ( ) ; muche
# 60

Supposons qu’une fonction définisse d’autres fonctions (par exemple, f() définit g() qui définit u()). Pour accéder
à la variable x de f(), les fonctions g() et u() utilisent le mot clé nonlocal x. La variable x doit exister dans f() et y
avoir déjà reçu une valeur. De même, pour accéder à la variable z de g(), u() utilisera nonlocal z.
Imbrication de fonctions #39

def f ( ) :
x = 1
def g ( ) :
nonlocal x
x+=10
p r i n t ( ’ x dans g ( ) : ’ , x )
def u ( ) :
nonlocal x
x+=100
p r i n t ( ’ x dans u ( ) : ’ , x )
# On e s t dans g ( )
u()
# On e s t dans f ( )
g()
x += 1000
p r i n t ( ’ x dans f ( ) : ’ , x )
f ()
# x dans g ( ) : 11
# x dans u ( ) : 111
# x dans f ( ) : 1111

Les 3 fonctions écriront global k pour utiliser une variable k du niveau 0 si k est définie avant l’appel de f().
Si k n’existe pas au niveau global avant cet appel, elle existera désormais (voir le premier exemple ci-dessous).
Le mot clé nonlocal exprime le besoin d’utiliser d’autres variables que les locales. Ce mot clés ne définit pas
de variable et ne change pas le statut d’une variable. Il fait seulement référence à une variable existante des
niveaux englobants.
Un paramètre formel d’une fonction est une variable locale à la fonction, il peut donc être référencé par nonlocal.

• Un premier exemple : global


def f ( ) :
def g ( ) :
g l o b a l val_g # " v a l _ g " n ’ e x i s t e pas encore . La v o i c i c r éée .
v a l _ g =300
g()
g l o b a l val_g # " v a l _ g " e x i s t e par l ’ appel à g ( ) . E l l e e s t r é f é renc ée .
v a l _ g += 100
v a l _ l = 200 # " v a l _ l " e s t i c i l o c a l . On ne v e r r a pas son e f f e t à l ’ e x t é r i e u r .

val_l = 0
f ()
val_l
val_g

# On o b t i e n t
# 0
# 400

Ÿ Il est important qu’ici, global val_g soit citée au moins 2 fois ! Faute de quoi on n’aura pas affaire
à une variable globale.

• Un exemple qui mélange nonlocal et global :


def f ( x , y ) :
x=1
y=2
def g ( x ) :
x += 10 # x e s t maintenant l o c a l e à g ( )
p r i n t ( ’ x dans g ( ) : ’ , x ) # 11 : on a r e çu 1 p u i s +10
nonlocal y # y d o i t e x i s t e r dans l a f o n c t i o n englobante
y += 20 # Ca f a i t +20 s u r l e y de f ( )
p r i n t ( ’ l e n o n l o c a l y dans g ( ) : ’ , y )
global k # K devient globale
k+=30 # Ca f a i t +30 s u r l e k de main
p r i n t ( ’ l e g l o b a l k dans g ( ) : ’ , k )
g(x)
p r i n t ( ’ r e t o u r de g ( ) : x dans f ( ) : ’ , x , ’ y dans f ( ) : ’ , y )
global z
z += 50
p r i n t ( ’ l e g l o b a l z dans f ( ) : ’ , z )

# main ( ) :
z = 3
k = 4
f (z ,k)
p r i n t ( ’ r e t o u r de f ( ) : z dans main ( ) : ’ , z, ’ k dans main ( ) : ’ , k)

" " " donne


x dans g ( ) : 11
l e n o n l o c a l y dans g ( ) : 22
l e g l o b a l k dans g ( ) : 34
r e t o u r de g ( ) : x dans f ( ) : 1 y dans f ( ) : 22
l e g l o b a l z dans f ( ) : 53
"""
Imbrication de fonctions #40

Un dernière chose : sous Python, on a des paramètres nommés. Ce mécanisme permet une certaine souplesse
lors des appels dans la mesure où en nommant les arguments, on n’est pas obligé de respecter l’ordre des
paramètres formels donné dans la signature de la fonction.
Dans l’exemple suivant, remarquer l’ordre des arguments d’appel et celui des paramètres formels :

d e f f ( p e t i t , moyen , grand ) :
p r i n t ( p e t i t , ’ <= ’ , moyen , ’ <= ’ , grand )

f ( grand =12 , p e t i t = 5 , moyen = 9 )

# 5 <= 9 <= 12

XIX-2 Bonus : Tri par insertion


• L’idée de cette méthode de tri s’explique plus facilement de manière récursive, quitte à écrire ensuite une solution
itérative.
• Pour trier une séquence T [0..n] : supposons que T [1..n] est trié. Il ne nous reste qu’à insérer T [0] à sa place dans
T [0..n]. Appelons cette fonction insere_a_sa_place(liste, val).
• Et comment faire pour trier T [1..n] ? Il faut trier T [2..n] puis insérer T [1] à sa place dans T [1..n].
Noter bien que pour insérer T [1] à sa place dans T [1..n], on sait que T [2..n] est déjà trié et il faut ’injecter’ T [1] à sa
place dans T [1..n], en poussant des éléments si nécessaire. C’est le rôle de insere_a_sa_place(liste, val).

• Cet enchaînement nous conduit à un état de base (d’induction) : on finira par arriver à l’état où pour trier une
tranche du tableau à 2 éléments T [n 1..n], il faudra trier T [n] (il est déjà trié car c’est un singleton). Donc, la première
élément à être inséré à sa placer sera T [n 1] à insérer dans T [n 1..n] par insere_a_sa_place(liste, val).
• Ainsi, T [n 1..n] devient trié et l’insertion suivante va insérer T [n 2] à sa place dans T [n 2..n].... et enfin, on
finira par insérer T [0] à sa place dans T [0..n].
• Un exemple : soit T = [5, 2, 3, 9, 1, 6]. On doit
! trier T = [2, 3, 9, 1, 6] (qui doit donner T [1, 2, 3, 6, 9]) puis y insérer 5 à sa place.
!trier T = [3, 9, 1, 6] (qui doit donner T [1, 3, 6, 9]) puis y insérer 2 à sa place.
! ....
! trier T = [6] (il l’est déjà) puis y insérer 1 à sa place.
insérer 1 dans T = [6] donne [1, 6]
...
insérer 2 dans T [1, 3, 6, 9] donne T [1, 2, 3, 6, 9]
insérer 5 dans T [1, 2, 3, 6, 9] donne T [1, 2, 3, 5, 6, 9]

• Une autre illustration de cette méthode sur le string "INSERTIONSORT" :

• Écrire la méthode de Tri par insertion. Utiliser une fonction imbriquée pour l’insertion des éléments à leur place
dans la partie triée. Quelle est la complexité de cette méthode de tri ?
Imbrication de fonctions #41

XIX-3 Bonus : Tri split-merge


• Tri d’une liste par la méthode split-merge (proche de merge-sort) :
Pour une liste L à trier, on cherche dans L une sous-séquence ordonnée et on la met dans la sous liste L1
Ensuite, la sous-séquence ordonnée suivante de L est mis dans L2 , ...
Et ainsi de suite alternativement, une séquence dans L1 , la suivante dans L2 jusqu’à l’épuisement de L.

• Exemple : L = [4, 5, 2, 3, 1, 9, 6, 0, 7], la fonction my_split donne (split correspond à une fonction prédéfinie de
Python) :
L1 : 4,5 puis 1,9 puis 0,7 ! L1 = [4, 5, 1, 9, 0, 7]
L2 : 2,3 puis 6 , ! L2 = [2, 3, 6]

• Ensuite, on fusionne L1 et L2 (un peu comme merge-sort en mettant toujours le plus petit élément d’abord) :
La fusion donne : L : 2,3 (de L2 car 2 et 3 sont plus petits que 4) puis 4,5,1 (de L1 car ils sont plus petits que
6),6,9,0,7. Donc, le résultat de cette fusion est L = [2, 3, 4, 5, 1, 6, 9, 0, 7].

• Mais la liste L résultante de cette fusion n’est pas encore triée. On recommence avec my_split sur L :
L1 : [2,3,4,5 puis 0,7]
L2 : [1,6,9]

Ÿ On fusionne : L = [1, 2, 3, 4, 5, 0, 6, 7, 9]
• On re scinde L :
L1 : [1,2,3,4,5]
L2 : [0,6,7,9]
Ÿ On re fusionne : L = [0, 1, 2, 3, 4, 5, 6, 7, 9]

• Un dernier appel à my_split produit L1 = L et L2 = []


Ÿ terminé.

• La condition d’arrêt de cet algorithme est que la liste L2 renvoyée par my_split soit vide.
Complément sur la Visibilité des variables #42

XX Complément sur la Visibilité des variables


• On étudie plus en détails la question de la portée (visibilité, champ, contexte) des variables.
• En matière de fonctions Python, on peut se poser la question de la portée des variables.
• A l’intérieur d’une fonction, toute variable est local à la fonction.
def fonc ( x ) :
x = x+1
print (x)

x=15
fonc ( x )
print (x)

# Donne
16 # é c r i t par f o n c
15 # au r e t o u r de fonc , x n ’ a pas changé de v a l e u r

XX-1 Variables locales


• Observe les exemples ci-dessous :
a=1
def f ( ) :
print (a)

f ()
# Donne 1

Ÿ Dans cet exemple, print(a) affichera la valeur de la variable a.


def g ( ) :
x=1
def f f ( ) :
print (x)
ff ()
g()
# Donne 1

Ÿ Ici aussi, x de g() est visible dans ff().

+ Par contre :
a=1
def f ( ) :
a += 1

f ()
# Erreur

Ÿ Dans cet exemple, a += 1 provoque une erreur d’accès à a : la variable locale a référencée avant de recevoir
une valeur. Ce qui veut dire qu’il faut d’abord écrire a=.. et à partir de ce moment, les deux a seront différentes.
def g ( ) :
x=1
def f f ( ) :
x += 1
ff ()
g()
# Erreur

Ÿ Ici aussi, x += 1 provoque une erreur d’accès à x.

+ Règle : une fonction a accès en lecture aux variables définies dans son contexte ainsi que dans le contexte
englobant (cf : print(a) et print(x) ci-dessus).
Ÿ Si la variable accédée est non mutable (int, constante string, tuple, etc), toute modification de celle-ci
provoque une erreur.
Ÿ Par contre, pour une variable mutable (List, Dict, Set, etc.), la modification est possible.

Exemple :
L= [ ]
def f ( ) :
L . append ( 1 )

f ()
print (L)

# Donne [ 1 ]
Complément sur la Visibilité des variables #43

Ÿ La liste étant mutable, L peut être modifiée.

• Les mots clés global et nonlocal permettent de modifier ce comportement.

XX-2 global
• Un exemple :
d e f method ( ) :
# On change l e s t a t u t de " v a l u e " : e l l e sera g l o b a l e .
# Sans " g l o b a l " , l ’ a f f e c t a t i o n sera " l o c a l "
g l o b a l value
v a l u e = 100

value = 0
method ( )
value
# Donne 100

• Ici, globale value fait référence à la variable value du niveau global.


• Mais observez cet exemple :
d e f method ( ) :
# On change l e s t a t u t de " value1 " : e l l e sera g l o b a l e .
# Sans " g l o b a l " , l ’ a f f e c t a t i o n sera " l o c a l "
g l o b a l value1
value1 = 100
v a l u e = 200

value = 0
method ( )
value
value1
# Donne
# 0
# 100

• Ici, global value1 (value1 n’existe pas encore) définit et affecte une valeur à value1.
+ Remarques : global var définit var si elle n’existe pas et la rend accessible à l’extérieur de toute fonction.
Si var existe déjà (à un niveau global), ce sera cette var qui sera référencée.

XX-3 nonlocal
• nonlocal a un comportement similaire à global mais pour des fonctions imbriquées. nonlocal veut dire ni global, ni
local. Une variable nonlocal fait référence à un niveau englobant.
d e f method ( ) :
d e f method2 ( ) :
# dans c e t t e f o n c t i o n i m b r i q u ée , ’ v a l u e ’ f a i t r e f e r e n c e à une v a r i a b l e ’ n o n l o c a l ’ .
nonlocal value
v a l u e = 100

# Set l o c a l .
v a l u e = 10
method2 ( )

# La v a r i a b l e l o c a l e s t a f f e c t ée par un changement NON LOCAL .


p r i n t ( value )

# essai
method ( )

# Donne 100

• nonlocal rend pratique l’échange de variables entre les fonctions imbriquées. Sans nonlocal, on risque de provoquer
des conflits de noms entre un fonction imbriquée et le niveau englobant là où global ne rentre pas dans ce niveau de
détail.
• Il est communément admis que la plupart des fonctions Python n’ont besoin de ce mécanisme qui rend le code
Python obtenu plus complexe. Néanmoins, global et nonlocal peuvent convenir dans certains situations pour éviter
les conflits de noms.
Complément sur la Visibilité des variables #44

XX-4 Un exemple récapitulatif


• A l’intérieur d’une fonction, l’expression global x précise que x existe (sinon, existera) globalement et en de-
hors de la fonction et doit être réaffectée en dehors de son champ (cf. spam dans les commentaires # (glob) de
l’exemple).
• Une variable nonlocal indique que cette variable existera dans un champ interne (englobé) et doit être réaffectée
dans ce contexte là (cf. spam).

• Un exemple récapitulatif :
def scope_test ( ) :
def do_local ( ) :
spam = " l o c a l spam "
d e f d o _ n o nl o c a l ( ) :
n o n l o c a l spam
p r i n t ( " Dans d o_ n on l oc a l ( ) : " , spam )
spam = " n o n l o c a l spam "
def do_global ( ) :
g l o b a l spam # ( glob ) se superpose à l a dé f i n i t i o n ’ spam = " t e s t spam " ’
# p r i n t ( " Dans d o _ g l o b a l ( ) " , spam ) Provoquera une erreur : spam non défini.
spam = " g l o b a l spam " # ( glob ) le ’spam’ du niveau 0, pas celle de scope_test.

spam = " t e s t spam " # ( glob ) , né c e s s a i r e pour ’ g l o b a l spam ’ c i dessus


do_local ( )
p r i n t ( " Après l ’ a f f e c t i o n l o c a l d a n s d o _ l o c a l ( ) : " , spam )
do_nonlocal ( )
p r i n t ( " Après a f f e c t a t i o n n o n l o c a l dans d o _n o nl o c a l ( ) : " , spam )
do_global ( )
p r i n t ( " Après a f f e c t a t i o n g l o b a l e dans d o _ g l o b a l ( ) : " , spam )

scope_test ( )
p r i n t ( " Dans l a p o r t ée g l o b a l ( hors l e s f o n c t i o n s ) : " , spam )

" " " Donne


Après l ’ a f f e c t i o n l o c a l dans d o _ l o c a l ( ) : t e s t spam
Dans d o _ no n lo c al ( ) : t e s t spam
Après a f f e c t a t i o n n o n l o c a l dans d o_ n on l oc a l ( ) : n o n l o c a l spam
Après a f f e c t a t i o n g l o b a l e dans d o _ g l o b a l ( ) : n o n l o c a l spam
Dans l a p o r t ée g l o b a l ( hors l e s f o n c t i o n s ) : g l o b a l spam

"""

• On note que :
do_local n’a pas changé la valeur de spam de scope_test. Ce que do_local a fait à spam n’est pas visible
à l’extérieur. Si on tente d’écrire spam au début de do_local, on provoque une erreur de définition.
Dans do_nonlocal, la référence à spam concerne spam de scope_test. L’affectation fait dans
do_nonlocal modifie donc spam de scope_test.
Dans do_global, on déclare global spam (une variable globale va exister !). Une tentative d’écriture (par
print) de ce spam provoque une erreur : la nouvelle occurrence de spam n’a pas encore de valeur ! Noter bien
qu’au retour de l’appel à do_global, spam vaut toujours nonlocal spam. Noter également que global
spam fera exister spam au niveau global (et affichée à la fin de la partie principale).
La fonction scope_test écrit ensuite la valeur de spam définie dans do_global.
+ Si on écrivait (sous Python) la valeur de spam, on obtiendrait global spam.
Complément sur la Visibilité des variables #45

XX-5 ZZ-Vars globales et les fonctions


# Exemples de m a n i p u l a t i o n des v a r i a b l e s g l o b a l e s
# dé f i n i e dans une f o n c t i o n ( main ( ) ) , m o d i f i ée dans f ( )
"""
I n [ 5 ] : main ( )
avant f ( ) 1
apr ès f ( ) 2

Et e n s u i t e , au console , v a r _ g l o b1 e s t accé s s i b l e ( e l l e l ’ e s t devenue pour TOUS ? )


V o i r a u s s i p l u s bas pour __main__
"""

d e f main ( ) :
g l o b a l v a r _g l o b 1
v a r _ g l o b 1 =1
p r i n t ( " v a r _ g l ob 1 avant appel de f ( ) " , v a r _ g l o b 1 )
f ()
p r i n t ( " v a r _ g l ob 1 apr ès l ’ appel de f ( ) " , v a r _ g l o b 1 )

def f ( ) :
g l o b a l v a r _g l o b 1
v a r _ g l o b 1 +=1

def g ( ) :
g l o b a l v a r _g l o b 2
v a r _ g l o b 2 +=10

# ZZ : l a f o n c t i o n p r i n c i p a l e __main__ DOIT e t r e en d e r n i e r !
# Tests f a i t . Plac ée avant g ( ) , e r r e u r de mé connaissance de g ( ) ! !
# mm s i on charge t o u t !
# Parce que dès que __main__ e s t r e n c o t r ée , e l l e e s t exé c u t ée !

i f __name__ == " __main__ " :


g l o b a l v a r _g l o b 2
v a r _ g l o b 2 =10
p r i n t ( " v a r _ g l ob 2 avant appel de g ( ) " , v a r _ g l o b 2 )
g()
p r i n t ( " v a r _ g l ob 2 apr ès l ’ appel de g ( ) " , v a r _ g l o b 2 )
Introduction à la récursivité #46

XXI Introduction à la récursivité


• Récursivité et Induction Mathématique (et lien directe avec la preuve)
• Récursivité directe et indirecte.

XXI-1 Exemple : Tri bulle récursive


• Pour trier une liste (ou tableau) L, le principe de cette méthode est le suivant :
i=0
visiter les éléments de L[i+1:] et si l’un est < L[i] alors permuter L[0] et cet élément
Ÿ à la fin de cette action, L[0] contient le minimum de L
recommencer en faisant +1 sur i (jusqu’à i == len(L)-1)
• Soit la version itérative de l’algorithme du Tri Bulle :
def t r i _ b u l l e _ i t e r a t i f ( l s t ) :
t a i l l e = len ( l s t )
f o r i i n range ( t a i l l e 1) :
f o r j i n range ( i +1 , taille ) :
if lst [ i ] > lst [ j ] :
lst [ i ] , lst [ j ] = lst [ j ] , lst [ i ] # permutaion
return l s t

l i s t e = [ 1 ,3 ,13 ,4 ,7 ,2 ,9 ,2 ,18 ]
print ( tri_bulle_iteratif ( liste ) )
# [ 1 , 2 , 2 , 3 , 4 , 7 , 9 , 13 , 18 ]

• On reprend la méthode tri bulle pour donner sa version récursive.


• Récursivité directe : la fonction tri_bulle() s’appelle (dans le texte).
from random i m p o r t seed , r a n d i n t

# proc é dure r é c u r s i v e ( q u i m o d i f i e son argument L e t ne r e n v o i e r i e n )


d e f tri_bulle(L,from_) :
i f from_ < l e n ( L ) 1 :
i M i n = t . i n d e x ( min ( L [ from_ : ] ) )
t [ from_ ] , t [ i M i n ] = t [ i M i n ] , t [ from_ ]
tri_bulle(L,from_+1)

# programme p r i n c i p a l
seed ( ) # i n i t i a l i s e l e g e n e r a t e u r de nombres a l e a t o i r e s
N=10
t = [ r a n d i n t ( 2 , 125) f o r i i n range (N) ]
p r i n t ( " Avant l e t r i , l i s t e = { } " . f o r m a t ( t ) )
tri_bulle ( t ,0)

p r i n t ( " Après l e t r i , l i s t e = { } " . f o r m a t ( t ) )

# Avant l e t r i , l i s t e = [ 125 , 78 , 77 , 24 , 2 , 22 , 26 , 120 , 111 , 84 ]


# Après l e t r i , l i s t e = [ 2 , 22 , 24 , 26 , 77 , 78 , 84 , 111 , 120 , 125 ]

XXI-2 Un exemple de récursivité indirecte


• Calcul simple de sinus et cosinus.
• Dans cette forme de la récursivité, la fonction my_sin(x) appelle my_cos(x) qui à son tour appelle my_sin(x).
Noter que cet exemple contient également la récursivité directe.
i m p o r t math ;
d e f my_sin ( x ) :
i f abs ( x ) < 1e 6 : s i n e =x
e l s e : s i n e = 2 * my_sin ( x / 2 ) * my_cos ( x / 2 )
return sine

d e f my_cos ( x ) :
i f abs ( x ) < 1e 6 : c o s i n e =1
e l s e : c o s i n e = pow ( my_cos ( x / 2 ) , 2 ) pow ( my_sin ( x / 2 ) , 2 )
r e t u r n cosine

angle = math . p i / 3
p r i n t ( " avec n o t r e mé thode : { 0 : 8 . 6 f } " . f o r m a t ( my_sin ( angle ) +my_cos ( angle ) ) )
p r i n t ( " avec l a mé thode c l a s s i q u e : { 0 : 8 . 6 f } " . f o r m a t ( math . s i n ( angle ) +math . cos ( angle ) ) )

" " " TRACE


avec n o t r e mé thode : 1.366026
avec l a mé thode c l a s s i q u e : 1.366025
"""
Introduction à la récursivité #47

XXI-3 Exercice : recherche Dichotomique dans une liste triée


• Méthode : pour chercher val dans une liste triée de taille N L[0:N],
On examine le milieu de la liste : L[N//2]
Si val==L[N//2] alors on a trouvé ; renvoyer vrai
Si val > L[N//2] alors il faut chercher val à droite dans la tranche L[N//2+1:]
Si val < L[N//2] alors il faut chercher val à gauche dans la tranche L[:N//2]
On constate que la taille de la liste est divisée par 2 à chaque appel récursif.
Continuer ainsi soit jusqu’à L==[] : renvoyer faux
• Écrire la recherche Dichotomique d’un élément dans une liste triée.

XXI-4 Variante : recherche Dichotomique et la place


• Dans cette variante de la recherche dichotomique, on souhaite obtenir l’indice d’insertion (la place) si l’élément
recherché n’est pas dans la liste.

XXI-5 Bonus : Tri par insertion


• Pour réaliser cet exercice en bonus, vous devez avoir réalisé le tri par insertion itératif vu (en bonus) plus haut.
• La version itérative de l’algorithme de tri par insertion a été vue plus haut. Écrire la version récursive de cette même
méthode.

XXI-6 Bonus : Tri par insertion utilisant la recherche dichotomique


• L’algorithme itératif du tri par insertion précédent est O(N 2 ) car la fonction inserer_a_sa_place() est O(N )
et celle-ci est appelée N fois.
• Reprendre l’algorithme de recherche dichotomie() ci-dessus (qui est O(log(N )) et modifiez le pour qu’il renvoie
la place d’insertion d’un élément dans un tableau trié. Puis utiliser cet algorithme dans le tri par insertion.
Ÿ Pour l’ajout concret de l’élément à insérer, on pourra utiliser L.insert(Place, val).
• Quelle est la complexité de ce nouvel algorithme ?

XXI-7 Bonus : lancers de dés


• L’utilisateur donne deux valeurs : le nombre de dés nbd (limité à 8), et la somme s à réaliser avec les dés (s comprise
entre nbd et 6*nbd). Le programme calcule récursivement et affiche le nombre de façons de faire la somme s avec les
nbd dés.
• La solution suivante utilise un argument niveau (niv) qui permet de faire un affichage décalé de niv*’ ’ pour
faciliter la lecture de la trace.
’ Les traces débutant cas-3: ... cumulent les sous calculs du dessus et qui sont décalés plus à droite.

+ Remarques : il est important d’avoir à l’esprit que Python limite le nombre d’appels récursifs à une fonction
à 1000 fois. C’est une limitation de l’implantation du langage.
Par ailleurs, Python ne traite et ne supprime pas la récursivité terminale (pas encore !).
Un appel à gc pourrait éventuellement améliorer l’état de la mémoire.
Introduction à la récursivité #48

XXI-8 Exercice : Médiane


Calculer la médiane M dans une suite d’entiers S de taille N (on note |S| = N) telle que la moitié des nombres de S
soient plus petits que M et l’autre moitié plus grande.

Méthode 1 - Pour calculer la médiane, il suffit de trier S puis de choisir l’élément du milieu.
€ Complexité : celle de l’algorithme de tri (au mieux O(N.Log(N))).

Méthode 2 - pour S de taille |S|, on peut trouver le kième plus petit élément (ici k = b |S|
2 c).
€ Le point fort de cette méthode est de ne trier que la plus petite sous séquence de S contenant le kième plus petit
élément. On étudiera cette méthode ci-dessous.

Méthode 3 - Construire un TAS (de complexité O(N), voir + loin) puis retirer k fois l’élément minimal (k= b|S|2c ).
€ Complexité : O(N.log2 N ) pour N 4

Détail de la Méthode 2 : un algorithme Diviser-régner


• Soit la séquence S. On généralise pour k = 1..|S| et pour la médiane : k |S|
2

Pour une valeur v appartenant à S, on peut scinder S en 3 sous tableaux :


Sg : contenant les éléments plus petits que v
Sv : contenant les éléments = v (et v lui-même)
Sd : contenant les éléments de S plus grands que v

Exemple : S = < 2, 36, 5, 21, 8, 13, 11, 20, 5, 4, 1 > et v = 5 :


€ Sg=< 2, 4, 1 >, Sv = < 5, 5 >, Sd=< 36, 21, 8, 13, 11, 20 >

Pour trouver le kième plus petit élément de S, il suffit de repérer le sous tableau susceptible de contenir cet élément
et de traiter celui-ci. Par exemple : si k=8, on sait que le 8e plus petit élément de S ne peut être que dans Sd car la
somme |Sg| + |Sv| = 5 < 8. Ce qui permet d’écrire : selection(S,8) = selection(Sd,8-5) = selection(Sd,3).

Généralisation : selection(S,k) = selection(Sg , k) si k  |Sg|


=v si |Sg| < k  |Sg| + |Sv|
= selection(Sr, k-|Sg| + |Sv|) si k > |Sg| + |Sv|
On répétera ce traitement (récursif) sur le sous-tableau concerné jusqu’à arriver au résultat recherché.
+ Le découpage déséquilibré des Sd et Sg peut donner une complexité défavorable, quoique O(N ).
V 2 S peut être choisi aléatoirement mais on préfère prendre la première valeur de S.

N.B. : [Aho & al] montre qu’en moyenne, 2 divisions suffisent pour trouver la médiane. Voir [Aho & al] ou [Wirth]
pour 2 algorithmes de complexité O(n) pour obtenir le kième plus petit élément de S.

Déroulement d’un exemple : calcul de la médiane de S=< 2, 36, 5, 21, 8, 13, 11, 20, 5, 4, 1 > avec |S| = 11 et donc
k = 6.
selection(S,6) :
V1=2, Sg1=< 1 >, Sv1=< 2 > , Sd1=< 36, 5, 21, 8, 13, 11, 20, 5, 4 >
€ k > |Sg1| + |Sv1| ’ selection(Sd1, 6 - |Sg1| + |Sv1|) = selection(Sd1, 4)
selection(Sd1,4) : V2=36, Sg2=< 5, 21, 8, 13, 11, 20, 5, 4 >, Sv2=< 36 >, Sd2=<>
€ k < |Sg2| ’ selection(Sg2, 4)
selection(Sg2,4) : V3=5, Sg3=< 4 > , Sv3=< 5, 5 > , Sd3=< 21, 8, 13, 11, 20 >
€ k > |Sg3| + |Sv3| ’ selection(Sd3, 4 - |Sg3| + |Sv3|) = selection(Sd3, 1)
selection(Sd3,1) : V4=21, Sg4=< 8, 13, 11, 20 > , Sv4=< 21 > , Sd4=<>
€ k < |Sg4| ’ selection(Sg4, 1)
selection(Sg4,1) : V5=8, Sg5=<> , Sv5=< 8 > , Sd5=< 13, 11, 20 >
€ |Sg5| < k  |Sg5| + |Sv5| car 0 < 1  1
€ le résultat est = V5 = 8
€ Il y a bien 5 éléments < 8 et 5 éléments 8
Paramètre formel à valeur par défaut des fonctions #49

XXII Paramètre formel à valeur par défaut des fonctions


• Si vous demandez un café dans un bistrot en France, on vous apporte un café noir (court, ni allongé ni double) avec
sucre et sans lait (et on ne vous apporte pas de lait). Si vous souhaitez un café décaféiné, ou avec du lait, ..., il faudra
demander explicitement (et payer pour le lait !).
• Par contre, en Allemagne (par exemple), on vous apporte du lait systématiquement.
• On pourrait alors proposer une fonction :
d e f s e r v i r _ c a f e ( deca=False , t a i l l e = ’ c o u r t ’ , l a i t = False ) :
# c o u l e u r : ’ n o i r ’ ou déca
# t a i l l e : double , a l l o n g é , . . .
p r i n t ( ’On s e r t un c a f é ’ , end= ’ ’ )
p r i n t ( ’ dé c a f é i n é ’ , end= ’ ’ ) i f deca e l s e p r i n t ( ’ n o i r ’ , end= ’ ’ )
i f t a i l l e ! = ’ c o u r t ’ : p r i n t ( t a i l l e , end= ’ ’ )
i f l a i t : p r i n t ( ’ avec du l a i t ’ )
else : p r i n t ( )

servir_cafe ()
# On s e r t un c a f é noir

s e r v i r _ c a f e ( t a i l l e = ’ double ’ )
# On s e r t un c a f é n o i r double

s e r v i r _ c a f e ( True , ’ a l l o n g é ’ ) # sans u t i l i s e r l e s noms : r e s p e c t e r l ’ o r d r e des paramè t r e s .


# On s e r t un c a f é dé c a f é i n é a l l o n g é

• Notez qu’on ne peut pas écrire :


servir_cafe(True, lait=True, ’allongé’)
sous peine de provoquer une erreur : SyntaxError: non-keyword arg after keyword arg
De même, servir_cafe(deca=True, ’allongé’) provoque la même erreur.
• On ne peut donc pas revenir aux positions (de gauche à droite sans les nommer) si on a commencé par les nommer.
Mais on peut appeler la fonction en nommant les paramètres après avoir utilisé les positions :
servir_cafe(True, ’allongé’, lait=True) qui donne
On sert un café décaféiné allongé avec du lait

• Sous Python, les paramètres (formels) à valeur par défaut sont nommés. Ces noms permettent de passer les argu-
ments dans un ordre quelconque (on a vu un exemple plus haut).
• En Python, la combinaison des valeur par défaut et le nom pour un paramètre permettent d’appeler les fonctions
avec plus de souplesse, sans que l’utilisation des noms soit une obligation.

Un autre exemple :
d e f l o g ( message=None ) :
i f message :
p r i n t ( " { 0 } " . f o r m a t ( message ) )

• On peut appeler cette fonction avec un argument (qui peut être None).
l o g ( " F i c h i e r ferm é " )

# F i c h i e r ferm é

l o g ( None )
#

• Mais on peut l’appeler sans argument auquel cas, la valeur par défaut joue son rôle (ici None) :
log ( )
#

XXII-1 Attention aux paramètres mutables


d e f f u n c t i o n ( item , s t u f f = [ ] ) :
s t u f f . append ( i t e m )
print ( stuff )

function (1)
# Donne 1

function (2)
# Donne 1 ,2 ]
# !!!
Nombre variable de paramètres d’une fonction #50

Ÿ La 2e valeur affichée semble étrange.

+ Remarques sur la valeur de la liste stuff et son comportement étrange :


• L’argument à valeur par défaut stuff est évaluée une seule fois et ce lors de la définition de la fonction.
Ensuite, toute modification de stuff se répercute sur l’emplacement initialement allouée à [] ! !
• Python ne vérifie pas si cette valeur par défaut (en fait la case mémoire associée à initialisée à []) a changé et
continue de l’affecter à stuff. C’est pourquoi au 2e appel, stuff = [1].
• Puisque nous affectons des valeurs différentes à stuff, vous changeons à chaque fois sa valeur par défaut.
Et lorsque nous rappelons cette fonction, nous récupérons la valeur par défaut modifiée.
• Pour éviter cette situation étrange, il est conseillé de NE PAS UTILISER un objet mutable comme argument
à valeur par défaut.

• Il est néanmoins possible de corriger ce comportement :


d e f f u n c t i o n ( item , s t u f f = None ) :
i f s t u f f i s None :
stuff = [ ]
s t u f f . append ( i t e m )
print ( stuff )

function (1)
# prints ’ [1] ’

function (2)
# p r i n t s ’ [ 2 ] ’ , as expected

+ Ce comportement semble bizarre car normalement, stuff contient [1] après le 1er appel. Pourtant, le test sur
stuff fait au début est pour savoir si on a appelé la fonction sans donner ce paramètre (et None n’est pas mutable).
Donc, le test (if stuff is None) réussit et nous permet de savoir si le 2e paramètre a été fourni ou non.

XXIII Nombre variable de paramètres d’une fonction


• Un exemple :
d e f do_something ( a , b , c , * args ) :
p r i n t ( a , b , c , args )

do_something ( 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 )
# Donne ’ 1 , 2 , 3 , ( 4 , 5 , 6 , 7 , 8 , 9 ) ’

• On peut également avoir une nombre quelconque de clé-valeur (voir les Dicts) comme paramètre. Une fois
qu’on aura défini tous les autres paramètres, on utilise une variable précédée de ’**’ : soit **V. Python utilisera tout
le reste des paramètres clé-valeurs et les place dans une dict et l’affecte à V.
d e f do_something_else ( a , b , c , * args , * * kwargs ) :
p r i n t ( a , b , c , args , kwargs )

do_something_else ( 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , t i m e o u t = 1 . 5 )
# Donne ’ 1 , 2 , 3 , ( 4 , 5 , 6 , 7 , 8 , 9 ) , { " t i m e o u t " : 1 . 5 } ’

• Un problème se pose dans les paramètres par défaut et paramètres nommés. On définit une fonction et des
paramètres nommés.
d e f do_something ( a , b , c , a f f i c h e r = True , * args ) :
i f afficher :
p r i n t ( a , b , c , args )

do_something ( 1 , 2 , 3 , 4 , 5 , a f f i c h e r = True )
# ERREUR : TypeError : do_something ( ) g o t m u l t i p l e v a l u e s f o r paramè t r e ’ afficher ’

do_something ( 1 , 2 , 3 , a f f i c h e r = True , 4 , 5 , 6 )
# ERREUR S y n t a x E r r o r : non keyword arg a f t e r keyword arg

• Le problème : il n’y a pas de moyen pour spécifier afficher comme un paramètre clé-valeur tout en four-
nissant des paramètres autres.
Ÿ La seule solution pour passer afficher ici est d’utiliser un paramètre non clé-valeur.
do_something ( 1 , 2 , 3 , True , 4 , 5 , 6 )
# Ré s u l t a t : 1 , 2 , 3 , ( 4 , 5 , 6 )
Nombre variable de paramètres d’une fonction #51

XXIII-1 Un autre exemple


d e f Test1 ( * args , * * kwargs ) :
p r i n t ( ’ Test1 ’ )
f o r arg i n args :
p r i n t ( arg )
f o r k , v i n kwargs . i t e m s ( ) :
p r i n t (k , ’= ’ , v )
print ()

"""
Test1 ( 1 , 2 , 3 )
Test1
1
2
3

Test1 ( 1 , b =3)
Test1
1
b = 3

Test1 ( a=1 ,b =3)


Test1
b = 3
a = 1

Test1 ( a=4 , 1 , b =3)


F i l e "< ipython input 137 f14bd18d0943 > " , l i n e 1
Test1 ( a=4 , 1 , b =3)

S y n t a x E r r o r : non keyword arg a f t e r keyword arg

Test1 ( 1 , a=4 , b =3)


Test1
1
b = 3
a = 4
"""

XXIII-2 Passer des paramètres par défaut d’une fonction à une autre
• Un exemple :
d e f f u n c ( foo , bar=None , * * kwargs ) :
pass # On dé f i n i r a c e t t e f o n c t i o n p l u s t a r d !

....

#Appel :
desVars =1 ,2 ,3
f u n c ( 4 2 , bar =314 , e x t r a =desVars ) # e x t r a e s t un mot r é s e r v é

• Un autre exemple : on réceptionne les paramètres en utilisant * et ** dans les paramètres de la fonction. On peut
passer ces paramètres comme des paramètres d’appel d’une autre fonction.
d e f f ( x , * args , * * kwargs ) :
...
kwargs [ ’ w i d t h ’ ] = ’ 14.3 c ’
...
g ( x , * args , * * kwargs )
Listes en Compréhension #52

XXIV Listes en Compréhension


• On lit parfois (par erreur) la compréhension de liste. Notons que lorsqu’on construit une liste élément par élément
(via append() ou une liste donnée explicitement comme [a,b,c,...]), on appellera cela une liste par extension. Intension
et Compréhension ont le même sens.

• La liste en compréhension souligne l’aspect fonctionnel de Python, en particulier avec map, filter et reduce 4 et le
expressions-lambda.
• Ce mécanisme procure un moyen rapide et compacte pour créer des listes. La liste en compréhension est davantage
préconisée en Python 3.4 à cause des modifications sur map et filter (qui sont devenus des générateurs).
• La liste en compréhension permet une traduction quasi directe des intensions. Soit :
S = {x2 : x 2 {0...9}}
V = (1, 2, 4, 8, ..., 212 )
M = {x|x 2 S ^ even(x)} avec even(x) : x = 2k, k 2 N

Qu’on écrite en Python :


S = [ x * * 2 f o r x i n range ( 1 0 ) ]
V = [ 2 * * i f o r i i n range ( 1 3 ) ]
M = [ x f o r x i n S i f x % 2 == 0 ]

p r i n t ( S) ; p r i n t ( V ) ; p r i n t (M)
# [ 0 , 1 , 4 , 9 , 16 , 25 , 36 , 49 , 64 , 81 ]
# [ 1 , 2 , 4 , 8 , 16 , 32 , 64 , 128 , 256 , 512 , 1024 , 2048 , 4096 ]
# [ 0 , 4 , 16 , 36 , 64 ]

+ On a demandé les résultats sous forme de listes. En utilisant des () à la place des [], on obtiendrait ici un générateur
(mais ce ne sera plus une liste en compréhension !). Notons également que {} sont utilisées pour les Sets et les Dicts
et les ’()’ également pour les tuples.

• On peut mieux comprendre les listes en compréhension à travers leurs fonctions équivalentes :
S = []
f o r i i n range ( 1 0 ) :
S . append ( i * 2 )

# Et
S = [ i * 2 f o r i i n range ( 1 0 ) ]

S
# [ 0 , 2 , 4 , 6 , 8 , 10 , 12 , 14 , 16 , 18 ]

• Ou encore
M = []
f o r i i n range ( 1 0 ) :
i f ( i % 2 == 0 ) :
M. append ( i )

# Et
M = [ i f o r i i n range ( 1 0 ) i f i % 2 == 0 ]

M
# [ 0, 2, 4, 6, 8]

XXIV-1 Exemple : Nombres premiers


• Pour construire la liste des nombres premiers dans l’intervalle 1..50, on construit une liste de nombres non premiers
puis on utilise son complément pour obtenir des nombres premiers :
noprimes = [ j f o r i i n range ( 2 , 8 ) f o r j i n range ( i * 2 , 50 , i ) ]
primes = [ x f o r x i n range ( 2 , 50) i f x n o t i n noprimes ]
p r i n t ( primes )
# [ 2 , 3 , 5 , 7 , 11 , 13 , 17 , 19 , 23 , 29 , 31 , 37 , 41 , 43 , 47 ]

p
Ÿ La valeur 8 correspond à int( 50) + 1.

4. Utiliser, comme dans l’exemple, functools.reduce(). Il est fortement conseillé d’utiliser une boucle for à la place.
Listes en Compréhension #53

XXIV-2 Exemple : Manipulation de caractères


• Manipulation de listes de caractères :
[ c f o r c in " foobar " ]

# Donne [ ’ f ’ , ’ o ’ , ’ o ’ , ’ b ’ , ’ a ’ , ’ r ’ ]

Ÿ L’expression [c for c in "foobar"] est, du fait de la présence des ’[]’, équivalente à list("foobar").
• Une autre liste en compréhension pour construire une liste des caractères :
t e x t e = " La m e i l l e u r e f a çon de marcher . . . "
[ t e x t e [ i ] f o r i i n range ( l e n ( t e x t e ) ) ]

# Donne : [ ’ L ’ , ’ a ’ , ’ ’ , ’m ’ , ’ e ’ , ’ i ’ , ’ l ’ , ’ l ’ , ’ e ’ , ’ u ’ , ’ r ’ , ’ e ’ , ’ ’ , ’ f ’ , ’a ’ , ’ç ’ , ’o ’ , ’n ’ , ’ ’ , ’d
’ , ’ e ’ , ’ ’ , ’m ’ , ’ a ’ , ’ r ’ , ’ c ’ , ’ h ’ , ’ e ’ , ’ r ’ , . . . ]

D’autres exemples :
liste_origine = [ 0, 1, 2, 3, 4, 5]
[ nb * nb f o r nb i n l i s t e _ o r i g i n e ]
#==> [ 0 , 1 , 4 , 9 , 16 , 25 ]

# L i r e 10 f o i s l e c l a v i e r e t f a i r e un e l i s t e :
L= [ i n p u t ( " une chose " ) f o r i i n range ( 1 0 ) ]

# Copie d ’ une l i s t e
l l = [ 1 ,2 ,3 ]
i n v = [ l l [ i ] f o r i i n range ( 3 ) ]

• L’expression de la liste en compréhension peut contenir des filtres (tests, appels de fonctions, etc) :
l i s t e _ o r i g i n e = [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ]
[ nb f o r nb i n l i s t e _ o r i g i n e i f nb % 2 == 0 ]
# ==> [ 2 , 4 , 6 , 8 , 10 ]
#

d e f pa s_ mu l ti p l e _d e_6 ( x ) : r e t u r n x % 2 ! = 0 and x % 3 ! = 0
[ i f o r i i n range ( 2 , 25) i f pas _m ul t i p l e_ de _6 ( i ) ]
# Donne : [ 5 , 7 , 11 , 13 , 17 , 19 , 23 ]
#
d e f cube ( x ) : r e t u r n x * x * x

[ cube ( i ) f o r i i n range ( 1 , 11) ]


#Donne : [ 1 , 8 , 27 , 64 , 125 , 216 , 343 , 512 , 729 , 1000 ]

• En Python 3, la liste en compréhension vient remplacer map et filter (voir plus loin).

XXIV-3 Exercice Simple


• Dans cet exercice, on étudie les deux formes de construction des listes.
• Utilisez une construction classique puis une liste en compréhension pour
I) ajouter 3 à chaque élément d’une liste d’entiers de 0 à 5.
II) ajouter 3 à chaque élément d’une liste d’entiers de 0 à 5, mais seulement si l’élément 2.
III) obtenir la liste [’ad’, ’ae’, ’bd’, ’be’, ’cd’, ’ce’] à partir des chaînes "abc" et "de".
IV) calculer la somme d’une liste d’entiers de 0 à 9.
Ÿ Indication : utilisez deux boucles for imbriquées.

XXIV-4 Exercice : Mots en Majuscule


• Soit la chaîne mots = ’Le petit chien jaune et noir mange la soupe chaude’
Extraire les mots de cette phrase (utiliser la fonction str.split()) et transformez et afficher ces mots en majus-
cule et donner leur taille. Pour obtenir un mot M en majuscule / minuscule, vous pouvez utiliser M.upper() /
M.lower().

XXIV-5 Exercice : anagramme


• Écrire le code qui vérifie si deux strings sont des anagrammes.
Manipulation de fichiers #54

XXIV-6 Bonus : tousDiff


• Créer une liste d’entiers avec un tirage aléatoire (de valeurs entre 0 et 3N , N = 10 par exemple) puis tester si les
éléments de cette liste sont deux à deux différents.

XXV Manipulation de fichiers


XXV-1 Exemple
• Pour simplement ouvrir un fichier avec contrôle :
i m p o r t os
os . c h d i r ( " / home / a l e x / Telechargement / Apprendre Python 3" )
try :
f = open ( ’ f i c t e s t . t x t ’ )
except OSError as e r r :
p r i n t ( "OS e r r o r : { 0 } " . f o r m a t ( e r r ) )
raise # Pour ne pas c o n t i n u e r c i dessous .
# U t i l i s e r c e l a au l i e u de ’ e x i t ( ) ’ q u i a r r ê t e l ’ i n t e r p r ê t e Python .

# S i l e f i c h i e r n ’ e x i s t e pas , on a l ’ e r r e u r ( e x c e p t i o n ) :
# OS e r r o r : [ Errno 2 ] No such f i l e o r d i r e c t o r y : ’ f i c t e s t 1 . t x t ’

# Et ’ r a i s e ’ c e l a donnera
# F i l e N o t F o u n d E r r o r : [ Errno 2 ] No such f i l e o r d i r e c t o r y : ’ fic tes1t . t x t ’

• Un autre exemple : avec lecture d’entiers


i m p o r t sys

try :
f = open ( ’ m y f i l e . t x t ’ )
s = f . readline ()
i = int (s. strip () )

except OSError as e r r :
p r i n t ( "OS e r r o r : { 0 } " . f o r m a t ( e r r ) )
except V a l u e E r r o r : # Pour l ’ e r r e u r de c o n v e r s i o n
p r i n t ( " Conversion en e n t i e r i m p o s s i b l e . " )
except : # Autre e r r e u r
p r i n t ( " E r r e u r ? : " , sys . e x c _ i n f o ( ) [ 0 ] )
raise # On r e l ève l ’ e x c e p t i o n pou r l e niveau e ng l o b an t .

XXV-2 Rappel sur la fonction split()


• Cette fonction sépare une chaîne de caractères en liste de mots. Elle utilise comme séparateur par défaut les carac-
tères blancs (espace ou tabulation). Elle supprime tous les séparateurs contigus. Le nombre de séparation maximum
est indiqué par un deuxième paramètre optionnel.
Exemples :
# split()
a= " C e t t e phrase , d e v i e n t , , une \ t l i s t e "
b=a . s p l i t ( )
print (b)
# [ ’ C e t t e ’ , ’ phrase , ’ , ’ d e v i e n t , , ’ , ’ une ’ , ’ l i s t e ’ ]
# ’ \ t ’ symbolise une t a b u l a t i o n .

# split(sep)
a= " C e t t e phrase , d e v i e n t , , une \ t l i s t e "
b=a . s p l i t ( " , " )
print (b)
# [ ’ C e t t e phrase ’ , ’ d e v i e n t ’ , ’ une \ t l i s t e ’ ]

# split(chaîne-sep) avec une chaîne comme séparateur


# s p l i t ( ) avec une cha î ne comme sé p a r a t e u r
a= " C e t t e phrase , d e v i e n t , , une \ t l i s t e "
b=a . s p l i t ( " , , " )
print (b)
# [ ’ C e t t e phrase , d e v i e n t ’ , ’ une \ t l i s t e ’ ]

# split() avec maximum de séparations


a= " C e t t e phrase , d e v i e n t , , une \ t l i s t e "
b=a . s p l i t ( None , 2 )
print (b)
# [ ’ C e t t e ’ , ’ phrase , ’ , ’ d e v i e n t , , une \ t l i s t e ’ ]

• splitlines() sépare un texte en liste de lignes. Un exemple :


Manipulation de fichiers #55

a= " Ligne1 a b c d e f \ nLigne2 a b c \ n \ nLigne4 a b c d"


b=a . s p l i t l i n e s ( )
print (b)

# [ ’ Ligne1 a b c d e ’ , ’ Ligne2 a b c’, ’’, ’ Ligne4 a b c d’ ]

+ Un truc :
Si vous voulez lire une série d’entiers sur une ligne :
s e r i e = map( i n t , i n p u t ( ) . s t r i p ( ) . s p l i t ( " " ) )

XXV-3 Un exemple avec with


• Exemple (vu plus haut dans la partie système ?, chercher "with")
f = open ( " f i c t e s t . t x t " )
f
#< _ i o . TextIOWrapper name= ’ f i c t e s t . t x t ’ mode= ’ r ’ encoding = ’UTF 8’>

f . __enter__ ( ) # La mé thode de l a c l a s s e
#< _ i o . TextIOWrapper name= ’ f i c t e s t . t x t ’ mode= ’ r ’ encoding = ’UTF 8’>

f . read ( 1 ) # L i r e un c a r a c t è r e
# ’E ’

f . _ _ e x i t _ _ ( None , None , None )


f . read ( 1 )
# V a l u e E r r o r : I /O o p e r a t i o n on c l o s e d f i l e

Avec with, c’est plus simple : pour ouvrir le fichier, traiter son contenu (ça, c’est nous qui le faisons !) et de le
fermer à la fin.
w i t h open ( " f i c t e s t . t x t " ) as f :
data = f . read ( )
# t r a i t e r l e s données , par exemple :
p r i n t ( data )

• Créer avec with : hello.txt va exister (ou écrasé s’il existait)


w i t h open ( " h e l l o . t x t " , "w" ) as f :
f . w r i t e ( " H e l l o World " )

• with et split() :
w i t h open ( ’ data . t x t ’ , ’ r ’ ) as f :
data = f . r e a d l i n e s ( )

f o r l i n e i n data :
words = l i n e . s p l i t ( )
p r i n t ( words )
# Et s i vous v o u l e z chaque c a r a c t è r e de ’ words ’ , f a i t e s comme pour l e s l i s t e s .

XXV-4 Un exemple utilisant les générateurs et les listes en compréhension


• Dans cet exemple, le fichier ’fic-test.txt’ contient :
E x e r c i c e 25 : c e t e x e r c i c e concerne l e s f i c h i e r s .
L i r e un f i c h i e r c o n t en a n t des nombres e t des l i g n e s v i d e s e t e x t r a i r e :
Les l i g n e s
Les mots de chaque l i g n e

Les l e t t r e s de chaque mot


E x t r a i r e l e s nombres
Compter l e nombre de phrases ( t e r m i n ées avec ’ . ’ )
etc .

V o i r e a u s s i l ’ e x e r c i c e 561.

• On fera attention aux générateurs qui sont des ressources épuisables.


Manipulation de fichiers #56

f = open ( ’ f i c test . txt ’ )

# Un ggéné r a t e u r
lignes_non_vides = ( l i n e f o r l i n e in f i f line . strip () )
mot = " E x t r a i r e "

# Un géné r a t e u r
l i g n e s _ q u i _ c o n t i e n n e n t _ m o t = ( l f o r l i n l i g n e s _ n o n _ v i d e s i f mot i n l )
p r i n t ( lignes_qui_contiennent_mot )
# < g e n e r a t o r o b j e c t <genexpr > a t 0x7f291d512ee8 >

# Un géné r a t e u r
l i g n e s _ q u i _ n e _ f i n i s s e n t _ p a s _ p a r _ u n _ p o i n t = ( l f o r l i n l i g n e s _ q u i _ c o n t i e n n e n t _ m o t i f n o t l . endswith ( ’ . ’ ) )

# On r écupè r e l a l i s t e a s s o c i ée à un géné r a t e u r
lignes_numerotees = l i s t ( enumerate ( l i g n e s _ q u i _ n e _ f i n i s s e n t _ p a s _ p a r _ u n _ p o i n t ) )
p r i n t ( lignes_numerotees )

# [ (0 , ’ E x t r a i r e l e s nombres \ n ’ ) ]

f . close ( )

XXV-5 Création d’un fichier


• Un exemple simple :
file = open ( " n e w f i l e . t x t " , "w" )
file . w r i t e ( " h e l l o w o r l d i n t h e new f i l e \ n " )
file . w r i t e ( " and a n o t h e r l i n e \ n " )
file . close ( )

+ Remarques :
• Noter bien que readline renvoie la chaîne vide ” après EOF, pas d’exception.
• On peut essayer en testant vs ” ou utiliser strip() pour déceler les lignes vides : ligne.strip() réussit si ligne
n’est pas vide.
• Noter que ligne=readline() conserve ’\n’.
• Pour trouver un ’.’ à la fin de ligne (qui contient ’\n’), on peut tester if ligne.endswith(’.\n’).

XXV-6 Exercice
• Lire un fichier et extraire :
La fréquence des mots
La fréquence des lettres
Le nombre de phrases (terminant avec un ’.’)
Les nombres

• Le contenu du fichier (test_fic.txt) a été donné ci-dessus.


% E x e r c i c e 25 : c e t e x e r c i c e concerne l e s f i c h i e r s .
% L i r e un f i c h i e r c o n t e na n t des nombres e t des l i g n e s v i d e s e t e x t r a i r e :
% Les l i g n e s
% Les mots de chaque l i g n e
%
% Les l e t t r e s de chaque mot
% E x t r a i r e l e s nombres
% Compter l e nombre de phrases ( t e r m i n ées avec ’ . ’ )
% etc .
%
% V o i r e a u s s i l ’ e x e r c i c e 561.
%
Compléments sur la mise en page #57

XXVI Compléments sur la mise en page


XXVI-1 format pour les conversions
• Conversion de string en binaire (voir la fonction format() en section XIV-1 page 24. L’exemple suivant a été vu
plus haut.
s t = " h e l l o Debase "
’ ’ . j o i n ( f o r m a t ( ord ( x ) , ’ b ’ ) f o r x i n s t )
# ’1101000 1100101 1101100 1101100 1101111 100000 1000100 1100101 1100010 1100001 1110011 1100101 ’

Ÿ Le passage par la fonction ord(x) est ici obligatoire. ord(x) renvoie un entier pour un caractère contenant un
chiffre.
Si on doit nommer le range du champ à formater (ici 0:...) :
s t = " h e l l o Debase "
p r i n t ( ’ ’ . j o i n ( [ " { 0 : b } " . f o r m a t ( ord ( x ) ) f o r x i n s t ] ) )
# 1101000 1100101 1101100 1101100 1101111 100000 1000100 1100101 1100010 1100001 1110011 1100101

• Conversion de string en hexadécimal :


s= ’ H e l l o Debase o f E c l ’
’ ’ . j o i n ( f o r m a t ( ord ( x ) , ’ x ’ ) f o r x i n s )
# ’48 65 6c 6c 6 f 20 44 65 62 61 73 65 20 6 f 66 20 45 63 6c ’

XXVI-2 Justification avec rjust, ljust et center, bourrage avec zfill


• Justification des strings à droite ou à gauche, centrage ou remplissages par des zéros :
s = " Python "
s . center (10) # centrer sur 10 positions
# Donne >’ Python ’

s . center (10 , " * " ) # centrer sur 10 positions en complétant par des ’*’
# Donne >’** Python * * ’

s = " Training "


s . l j u s t (12) # justifier à gauche sur 12 positions
# Donne >’ T r a i n i n g ’

s . l j u s t (12 , " : " )


# Donne >’ T r a i n i n g : : : : ’

s = " Programming "


s . r j u s t (15)
# Donne >’ Programming ’
s . r j u s t (15 , "~" )
# Donne >’~~~~Programming ’

account_number = " 43447879 "


account_number . z f i l l ( 1 2 )
# Donne >’000043447879’

# Même chose avec r j u s t :


account_number . r j u s t ( 1 2 , " 0 " )
# Donne >’000043447879’

+ En fait, str.ljust(n) construit une nouvelle chaîne de taille n à partir de str en plaçant str à gauche de cette nouvelle
chaîne. De même pour str.rjust(n) et str.center(n).
Compléments sur la mise en page #58

XXVI-3 str() et repr()


• str() permet d’obtenir un string lisible (par l’humain) alors que repr() permet d’obtenir une représentation
lisible par l’humain et par l’analyseur de Python.
• La plupart du temps, ces deux fonctions donnent le même résultat. Cependant, repr() s’applique dans les situa-
tions (objets, construction complexes) ou str() pourrait ne pas suffire (voir ci-dessous).

• Exemples :
s = ’ Hello , world . ’
str (s)
# Donne >’H e l l o , w o r l d . ’

repr ( s )
# Donne > " ’ Hello , world . ’ "
str (1/7)
# Donne > ’0.14285714285714285 ’

x = 10 * 3.25
y = 200 * 200
s = ’ The v a l u e o f x i s ’ + r e p r ( x ) + ’ , and y i s ’ + r e p r ( y ) + ’ . . . ’
print (s)
# Donne > The v a l u e o f x i s 3 2 . 5 , and y i s 4 0 0 0 0 . . .

# Le r e p r ( ) d ’ un s t r i n g a j o u t e des quotes e t backslashes :


h e l l o = ’ hello , world \ n ’
str ( hello )
# Donne > ’ h e l l o world \ n ’
repr ( hello )
# Donne > ’ h e l l o , w o r l d \ \ n ’ noter le double slash

# L ’ argument d ’ appel de r e p r ( ) peut ê t r e n ’ i m p o r t e q u e l o b j e t Python :


r e p r ( ( x , y , ( ’ spam ’ , ’ eggs ’ ) ) )
# Donne >"(32.5, 40000 , ( ’ spam ’ , ’ eggs ’ ) ) "

• Un exemple de mise en colonne de valeurs : afficher en colonnes x, x2 , x3 , x 2 1..10


f o r x i n range ( 1 , 11) :
p r i n t ( repr ( x ) . r j u s t (2) , repr ( x*x ) . r j u s t (3) , repr ( x*x*x ) . r j u s t (4) )
# Donne >
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
6 36 216
7 49 343
8 64 512
9 81 729
10 100 1000

+ Remarques : Si vous souhaitez terminer chaque écriture par autre chose qu’un retour charriot, utilisez l’ar-
gument end=... dans l’appel de print. Par défaut, end=’\n’.
Par exemple :

f o r x i n range ( 1 , 6 ) :
p r i n t ( r e p r ( x ) . r j u s t ( 2 ) , end= ’ # ’ * x+ ’ \ n ’ ) on ajoute x fois # + \n à la fin de chaque ligne

# Donne >
1#
2##
3###
4####
5#####

• L’intérêt de end=... se trouve souvent dans les cas où on a deux ordres print et on voudrait que le deuxième
soit à la suite du premier.
p r i n t ( 1 , 2 , end= ’ ’ ) # Ne pas passer à l a l i g n e pour que . . .
x= f o n c t i o n _ q u i _ c a l c u l e ( 3 ) # . . . la
print (x) # . . . v a l e u r de x s ’ a f f i c h e à l a s u i t e s u r l a même l i g n e
Gestion du temps #59

XXVI-4 Un truc sur print


• Si on doit répéter un format d’écriture (par exemple %2d) pour k valeurs, on peut répéter ce format par "%2d"*8.
Par exemple :
# Cré a t i o n de 8 v a l e u r s
a , b , c , d , e , f , g , h = range ( 8 ) # assigner 0 .. 7 à a , b , c , d , e , f , g , h
X= ( a , b , c , d , e , f , g , h )

p r i n t ( "%2d " * 8 % X )
# 0 1 2 3 4 5 6 7

• Remarquer qu’on aurait pu, dans ce cas précis, écrire :


a , b , c , d , e , f , g , h = range ( 8 ) # assigner 0 .. 7 à a , b , c , d , e , f , g , h
X = (a, b, c , d, e, f , g, h)

[ p r i n t ( "%2d " % i ) f o r i i n X ]

XXVII Gestion du temps


import t i m e i t
timeit . timeit ( "x = 2 + 2" )
#.0188..............
t i m e i t . t i m e i t ( " x = sum ( range ( 1 0 ) ) " )
#.589.........

• Pour une exécution en ligne de commande d’une fonction my_fonction() que l’on aurait définie dans le module
my_module et mesurer le temps, on peut écrire :
$ python3 . 4 m timeit s "import my_module as my_mo_sa" "my_mo_sa.my_fonction()"

• On peut également utiliser la fonction time.time() pour mesurer le temps d’exécution d’une fonction :
from t i m e i m p o r t t i m e

d e f count ( ) :
deb = t i m e ( )
[ x f o r x i n range (10000000) i f x%4 == 1 ]
f i n = time ( )
p r i n t ( f i n deb )

count ( )
# 1.213

Ÿ Il est conseillé d’utiliser timeit (exemple ci-dessus) à la place de time car timeit est plus juste et tient compte du
ramassage des miettes (gc : garbage collector).
Gestion du temps #60

Table des Matières

I. Modalités des travaux à rendre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1


II. Objectifs de ce BE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
II-1. Principe de ce BE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
II-2. Documentation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
II-3. A savoir . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
III. Introduction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
III-1. Commentaires en Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
IV. Exemples et exercices simples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
IV-1. Exemple 1 : moyenne. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
IV-2. Exemple 2 : racines carrées . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
IV-3. Exercice : pair/impair . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
V. Introduction aux fonctions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
V-1. Exemple : moyenne de deux entiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
V-2. Exercice : Racines d’une quadratique avec une fonction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
V-3. Exercice : Moyenne et écart type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
V-4. Variante : Exercice (suite écart type) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
VI. Créer un script Python indépendant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
VI-1. Une façon simple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
VI-2. Une solution plus élaborée . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
VII. Types principaux en Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
VII-1. Exemples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
VIII. Conversions de types. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
VIII-1. Exemples de conversion de types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
VIII-2. Exercice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
VIII-3. Exercice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
IX. Modules Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
X. La fonction range . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
X-1. Deux ou trois trucs pratiques sur range . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
X-2. Bonus : sommes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
XI. Les listes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
XI-1. Un exemple sur les listes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
XI-2. Autres exemples de fonctions sur les listes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
XI-3. Itération à l’envers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
XI-4. Itération sur une liste avec enumerate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
XI-5. Exemple : Pile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
XI-6. Bonus : TDA Queue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
XI-7. Exercice : liste des moyennes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
XI-8. Exercice : méthode EM de base . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
XI-9. Exercice : enlever les doublons d’une liste . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
XI-10. Bonus : Scinder une liste. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
XII. Copie de listes (important) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
XIII. Tuples. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
XIII-1. Accès aux éléments d’un tuple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
XIV. Introduction à la mise en page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
XIV-1. La fonction format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
XIV-2. Exercice : table de x, x*x, sqrt(x) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
XV. Itérations : While, for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
XV-1. While : Celcius-Farenheit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
XV-2. For : Celcius-Farenheit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
XV-3. Exercice : valeur de e . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
XV-4. Exercice : nombre premier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
XV-5. Bonus : Nombre Premier par diviseurs propres. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
XV-6. Bonus : Diviseurs des nombres Parfaits et Premiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
XV-7. Bonus (suite) : Importer vos fonctions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
XV-8. Exemple : compter les lettres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
XV-9. Exercice : compter les voyelles et consonnes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
XV-10. Exercices Bonus : lancers de dés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
XV-11. Bonus : Tri sélection. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
XVI. Les exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
XVI-1. Exemple 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
XVI-2. Exemple : Min/Max d’une séquence à la volée . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
XVI-3. raise : deux exemples. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
XVI-4. Exercice : moyenne et fonction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
XVI-5. Expression Pass . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
XVII. Génération de nombres aléatoires. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
XVII-1. Exemple : indice du minimum d’une liste aléatoire d’entiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
XVII-2. Exemple : amplitude et la moyenne d’une liste aléatoire de réels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
XVII-3. Échantillonnage : Normale et Uniforme. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
XVII-4. Complément : Tirage avec remise. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
XVII-5. Exemple : Tirage de cartes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
XVII-6. Exercice : Tirage de cartes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
XVII-7. Bonus : Tirage de cartes (bis) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
XVII-8. Bonus : Fréquences de dés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Gestion du temps #61

XVIII. Quelques fonctions sur les chaînes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37


XIX. Imbrication de fonctions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
XIX-1. Quelques règles utiles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
XIX-2. Bonus : Tri par insertion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
XIX-3. Bonus : Tri split-merge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
XX. Complément sur la Visibilité des variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
XX-1. Variables locales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
XX-2. global . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
XX-3. nonlocal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
XX-4. Un exemple récapitulatif . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
XX-5. ZZ-Vars globales et les fonctions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
XXI. Introduction à la récursivité . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
XXI-1. Exemple : Tri bulle récursive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
XXI-2. Un exemple de récursivité indirecte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
XXI-3. Exercice : recherche Dichotomique dans une liste triée . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
XXI-4. Variante : recherche Dichotomique et la place . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
XXI-5. Bonus : Tri par insertion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
XXI-6. Bonus : Tri par insertion utilisant la recherche dichotomique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
XXI-7. Bonus : lancers de dés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
XXI-8. Exercice : Médiane . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
XXII. Paramètre formel à valeur par défaut des fonctions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
XXII-1. Attention aux paramètres mutables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
XXIII. Nombre variable de paramètres d’une fonction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
XXIII-1. Un autre exemple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
XXIII-2. Passer des paramètres par défaut d’une fonction à une autre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
XXIV. Listes en Compréhension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
XXIV-1. Exemple : Nombres premiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
XXIV-2. Exemple : Manipulation de caractères . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
XXIV-3. Exercice Simple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
XXIV-4. Exercice : Mots en Majuscule . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
XXIV-5. Exercice : anagramme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
XXIV-6. Bonus : tousDiff . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
XXV. Manipulation de fichiers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
XXV-1. Exemple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
XXV-2. Rappel sur la fonction split() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
XXV-3. Un exemple avec with . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
XXV-4. Un exemple utilisant les générateurs et les listes en compréhension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
XXV-5. Création d’un fichier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
XXV-6. Exercice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
XXVI. Compléments sur la mise en page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
XXVI-1. format pour les conversions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
XXVI-2. Justification avec rjust, ljust et center, bourrage avec zfill . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
XXVI-3. str() et repr() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
XXVI-4. Un truc sur print. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
XXVII. Gestion du temps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

Vous aimerez peut-être aussi