Académique Documents
Professionnel Documents
Culture Documents
programmation
en Python
IUT Réseaux &
Télécommunications
1reannée
Éric Würbel
Copyright © 2019–2023 Éric Würbel
Cette oeuvre, création, site ou texte est sous licence Creative Commons Attribution - Pas d’Utili-
sation Commerciale - Partage dans les Mêmes Conditions 4.0 International. Pour accéder à une
copie de cette licence, merci de vous rendre à l’adresse suivante http://creativecommons.org/
licenses/by-nc-sa/4.0/ ou envoyez un courrier à Creative Commons, 444 Castro Street, Suite
900, Mountain View, California, 94041, USA.
Table des matières
I Généralités
1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.1 Programmation 11
1.2 Le langage Python 13
1.2.1 Historique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.2.2 Un langage de programmation multi-paradigmes . . . . . . . . . . . . . . . . . . . . . . 13
1.2.3 Usages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2 Objectifs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.1 Objectifs thématiques 15
2.2 Objectifs pédagogiques 15
2.3 Objectifs comportementaux 16
II Le langage Python
3 Instructions de base . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.1 Introduction 19
3.2 Variables & Affectation 19
3.2.1 Qu’est-ce qu’une variable ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.2.2 Type d’une variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.2.3 Attribuer une valeur : l’affectation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.2.4 Conversions de type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
3.3 Expressions 24
3.3.1 Définitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
3.3.2 Constantes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
3.3.3 Expressions simples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
3.3.4 Expressions unaires . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
3.3.5 Expressions multiplicatives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
3.3.6 Expressions additives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
3.3.7 Expressions de décalage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
3.3.8 Expression booléennes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
3.3.9 Exercices sur les expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3.4 Affectation composée 35
3.5 Entrées et sorties simples 36
3.5.1 Sorties à l’écran . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
3.5.2 Entrées au clavier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
3.6 Modules, fonctions et méthodes 38
3.6.1 Présentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
3.6.2 Caractéristiques et appel d’une fonction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
3.6.3 Méthodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
3.7 Annexes 41
3.7.1 Solutions des exercices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
4 Structures alternatives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
4.1 Alternative simple : si. . . alors. . . sinon. . . 45
4.2 Condition simple : si. . . 47
4.3 Alternatives multiples : si. . . sinon si. . . sinon. . . 48
4.4 Structures alternatives : bilan 50
4.5 Annexes 51
4.5.1 Solutions des exercices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
5 Structures répétitives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
5.1 Principes généraux 53
5.2 Itération conditionnelle : la boucle while 53
5.3 La boucle for 55
5.3.1 Le compteur d’itérations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
5.3.2 Répétition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
5.3.3 Répétition utilisant le compteur de boucle . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
5.3.4 Valeur initiale du compteur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
5.3.5 Incrément du compteur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
5.4 Équivalence entre boucle for et boucle while 59
5.5 Boucles et structures alternatives 60
5.6 Boucles avec variables d’accumulation 60
5.6.1 Principe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
5.6.2 Accumulation additive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
5.6.3 Accumulation multiplicative . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
5.7 Imbrication de boucles 63
5.8 Exercices supplémentaires sur les boucles 63
5.9 Annexes 64
5.9.1 Solutions des exercices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
6 Procédures et fonctions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
6.1 Définition 69
6.2 Déclaration d’une fonction 69
6.3 Fonctions à plusieurs points de retour 72
6.4 Portée des variables 74
6.4.1 Notion de portée . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
6.4.2 Contexte local d’une fonction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
6.4.3 Contexte d’une fonction avec paramètres . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
6.5 Chaînage de fonctions 76
7 Listes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
7.1 Les listes 77
7.2 Accès aux éléments 78
7.2.1 Éléments et indices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
7.2.2 L’opérateur in . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
7.3 Fonctions et méthodes pour l’objet list 80
7.3.1 Méthodes modifiant les éléments d’une liste . . . . . . . . . . . . . . . . . . . . . . . . . . 80
7.3.2 Méthodes utilisant les éléments d’une liste . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
7.3.3 Fonctions sur les listes numériques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
7.3.4 Autres méthodes sur les listes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
7.4 Parcours de listes 82
7.4.1 Notion d’itérable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
7.4.2 Parcours itératif de tous les éléments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
7.4.3 Parcours d’une partie des éléments avec une boucle while . . . . . . . . . . . . . . 85
7.5 Construire une liste 85
7.5.1 utilisation de append . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
7.5.2 Opérateurs sur les listes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
7.5.3 Fonction range . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
7.5.4 Liste en intention . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
7.6 Listes et fonctions 87
7.7 Listes en deux dimensions 88
7.8 Exercices supplémentaires 88
7.9 Annexes 89
7.9.1 Solutions des exercices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
8 Chaînes de caractères . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
8.1 Le type str 99
8.2 Accès aux caractères 99
8.2.1 Caractères et indices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
8.2.2 L’opérateur in . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
8.3 Manipulation de chaînes de caractères 101
8.3.1 rappel : manipulations élémentaires . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
8.3.2 Méthodes de la classe str . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
8.4 Parcours de chaînes de caractères 103
8.4.1 Parcours itératif avec une boucle for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
8.4.2 Parcours itératif avec une boucle while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
8.5 Construction itérative d’une chaîne 105
8.6 Constantes du module string 106
Cet ouvrage est un manuel d’apprentissage du langage de programmation Python destiné aux
étudiants de 1re année de BUT Réseaux & Télécommunications de l’IUT d’Aix-Marseille Université.
Il couvre les apprentissages à acquérir dans la ressource R107 Fondamentaux de la programmation.
Ce module est consacré à l’apprentissage de l’algorithmique et du langage de programmation
Python. Du fait du nombre d’heures consacrées à cette ressource, il ne saurait être question de
faire d’abord de l’algorithmique sans langage de programmation, puis d’étudier la traduction des
algorithmes dans un langage de programmation. Aussi l’apprentissage de l’algorithmique se fera
directement en s’appuyant sur le langage Python.
Les contenus suivants seront traités :
— Notions d’algorithmique :
— Variables, types de base : nombres, chaînes, booléens, et un unique type structuré : les
listes ;
— Structures de contrôle : structures alternatives et structures itératives ;
— Fonctions & procédures ;
— Portée des variables.
— Structures de données : chaînes de caractères, listes, piles et files.
— Tests de correction d’un programme (tests unitaires, tests d’intégration) (vu en TP).
— Prise en main d’un environnement de programmation (éditeur, environnement de développe-
ment) (vu en TP).
— Prise en main de bibliothèques, modules, d’objets existants (appels de méthodes).
— Manipulation de fichiers texte.
— Interaction avec le système d’exploitation et la ligne de commande : arguments, lancement
de commandes (vu en TP).
Le contenu de ce manuel s’inspire énormément des supports suivants :
— Le cours d’initialition à la l’algorithmique de l’école nationale d’ingénieurs de Brest ;
— les supports de cours des collègues du département Réseaux & Télécommunications de l’IUT
de Grenoble.
Il s’inspire aussi de l’ancienne version de ce manuel traitant de l’ancien module M1207.
I
Généralités
1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 11
2 Objectifs . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
1. Introduction
1.1 Programmation
Un algorithme exprime la structure logique d’un programme, et est donc indépendant du
langage de programmation utilisé. En revanche, la traduction de l’algorithme vers un langage de
programmation particulier dépend du langage choisi, et la mise en œuvre dépend de la plateforme
d’exécution.
La programmation consiste à « expliquer » en détail à l’ordinateur ce qu’il a à faire, sachant qu’il
ne « comprend » pas le langage humain, mais peut uniquement effectuer un traitement automatique
sur des séquences de 0 et de 1. Un programme n’est rien d’autre qu’une suite d’instructions, codées
en respectant scrupuleusement un ensemble de conventions fixées à l’avance 1 par un langage de
programmation. La machine décode alors ces instructions en associant à chaque « mot » du langage
de programmation une action précise. Le programme écrit dans le langage de programmation (à
l’aide d’un éditeur, sorte de traitement de texte spécialisé) est appelé programme source (ou code
source).
Le seul langage que l’ordinateur « comprenne » vraiment est très éloigné de ce que nous
comprenons nous même : c’est une longue suite de 0 et de 1 (les bits, binary digit), traités par
groupes de 8 (les octets, ou byte en anglais), 16, 32 ou même 64. Ce langage composé d’informations
binaires est appelé langage machine.
Définition 1.1.1 — bit. Un bit est un chiffre binaire (0 ou 1). C’est l’unité élémentaire d’infor-
mation.
Définition 1.1.2 — octet. Un octet est une unité d’information composée de 8 bits.
Pour se faire comprendre d’un ordinateur, il faudra donc faire appel à un système de traduction
automatique, capable de convertir en nombres binaires les suites de caractères formant le code
source d’un programme. Il existe deux grands types de systèmes de traduction (figure 1.1) :
1. L’ensemble de ces règles est appelé syntaxe du langage de programmation. On peut comparer la syntaxe d’un
langage de programmation à la grammaire d’une langue naturelle.
12 Chapitre 1. Introduction
Définition 1.1.4 — interpréteur. Un interpréteur est un programme ayant pour tâche d’analyser
et d’exécuter un programme écrit dans un langage source.
compilateur compilateur
exécuteur interpréteur
Le code source subit alors une transformation (dans le cas du compilateur) ou une évaluation
(dans le cas de l’interpréteur) dans une forme exploitable par la machine, ce qui permet d’obtenir
un programme. Les langages de programmation permettent de faire abstraction des mécanismes de
bas niveau de la machine, de sorte que le code source soit lisible et compréhensible par un humain.
Définition 1.1.6 — programmation. La programmation est l’activité de rédaction du code
source d’un programme.
instructions en langage machine, qui sont directement exécutées au fur et à mesure (au fil
de l’eau). Aucun programme objet n’est généré. L’interpréteur doit être utilisé à chaque fois
qu’on veut exécuter le programme. Les langages L ISP et P ROLOG sont des exemples de
langages de programmation interprétés 2 . Les langages du W EB PHP et Javascript sont aussi
des langages interprétés.
L’interprétation est idéale lorsqu’on est en phase d’apprentissage du langage, ou en cours
d’expérimentation sur un projet. Elle permet de tester immédiatement une modification
apportée au programme source, sans passer par une phase de compilation qui peut prendre du
temps. En revanche, lorsqu’un programme atteint un certain degré de complexité, et qu’il doit
s’exécuter rapidement, la compilation est plus efficace : un programme compilé s’exécutera
toujours plus vite qu’un programme interprété, puisque l’ordinateur ne perd pas de temps à
refaire la traduction de chaque instruction exécutée.
Semi-compilation : Certains langages utilisent les deux techniques précédentes pour tenter d’en
tirer le meilleur parti. C’est le cas de P YTHON et JAVA par exemple. De tels langages
commencent par compiler le code source pour produire un code intermédiaire, similaire à
un langage machine, mais pour une machine virtuelle, qu’on appelle bytecode. Ce bytecode
sera alors transmis à un interpréteur (qu’on appelle machine virtuelle dans ce cas) à chaque
exécution. Du point de vue de l’ordinateur, le bytecode est très simple à interpréter en langage
machine.
Le fait de disposer en permanence d’un interpréteur permet de tester n’importe quel petit
morceau de programme. On pourra donc vérifier le bon fonctionnement de chaque composant
d’une application au fur et à mesure de son développement. L’interprétation du bytecode
compilé n’est pas aussi rapide que l’exécution directe de code machine, mais elle est très
satisfaisante pour de nombreux programmes. De plus, les machines virtuelles font des
progrès constants qui tendent à rapprocher les performances d’interprététion du bytecode de
l’exécution native de code machine.
Interprétation, compilation, semi-compilation, toutes ces techniques s’occupent toutes du même
problème : traduire en instructions compréhensibles par l’ordinateur des instructions écrites dans
un autre langage.
que tous les types de données de Python sont des objets. Cette notion sera précisée lorsque nous
étudierons quelques unes des nombreuses bibliothèques fournies par Python.
Python emprunte aussi certaines constructions à la programmation fonctionnelle, dans laquelle
la structuration des traitements et des données s’appuie sur la notion de fonction. Nous y reviendrons
aussi.
1.2.3 Usages
Le langage Python est polyvalent et ses usages sont multiples : cela va de l’application de
bureau à l’utilitaire système, en passant par des applications scientifiques. C’est un très bon langage
de scripting, c’est à dire qu’il peut être très utile à l’administrateur système : il est plus simple que
le shell et mieux structuré. Aujourd’hui, Python est souvent choisi comme langage de scripting
pour les équipements réseaux comme les routeurs, d’où son importance pour vous.
2. Objectifs
Pour décrire la situation des différentes activités de ce module par rapport aux outils pédago-
giques associés, je reprendrai la métaphore musicale utilisée dans l’excellent cours d’algorithmique
de l’ENIB .
Pédagogie par objectifs : Le solfège est l’étude des principes élémentaires de la musique et de
sa notation et chaque exercice a un objectif précis pour évaluer l’apprentissage du langage
musical. Il en va de même pour l’informaticien débutant confronté à l’apprentissage d’un
langage de programmation.
Pédagogie par l’exemple : L’apprentissage de pièces de musique permet au musicien de s’appro-
prier les bases du solfège en les appliquant à ces partitions et en les (re)jouant lui-même.
L’informaticien débutant, en (re)codant lui-même des algorithmes bien connus, se constituera
ainsi une base de réflexes de programmation en « imitant » ces algorithmes.
Pédagogie de l’erreur : Les bogues (bugs) sont à l’informaticien ce que les fausses notes sont aux
musiciens : des erreurs. Ces erreurs sont nécessaires dans l’acquisition de la connaissance.
Un élève a progressé si, après s’être trompé, il peut reconnaître qu’il s’est trompé, dire où et
pourquoi il s’est trompé, et comment il recommencerait sans produire les mêmes erreurs.
Pédagogie par problèmes : Connaissant ses classiques et les bases du solfège, le musicien de-
venu plus autonome peut envisager sereinement la création de ses propres morceaux. Le
développement d’un projet informatique ambitieux sera « mis en musique » au semestre S2.
16 Chapitre 2. Objectifs
Un être humain peut parfaitrement passer outre l’absence de caractère ':'. Cela ne l’empêche
pas de comprendre le sens. La machine elle se sait pas faire cela. Elle ne se contente pas d’à
peu près, elle exige un strict respect des règles d’écriture (de la grammaire) du langage.
Persévérance Devant les messages d’erreur d’un compilateur, le débutant est souvent tenté de
« passer à autre chose », d’autant qu’il a parfois du mal à comprendre le sens des messages
d’erreur. Ce comportement ne mène à rien de bon, et il est important de prendre l’habitude
de ne pas laisser de problème en suspens. Il faut donc que le débutant apprenne à aller au
fond des choses et à traiter complètement un problème lorsqu’il se présente.
Autonomie Programmer les algorithmes qu’on a développé, mais aussi faire la trace (même
manuelle) de ces algorithmes pour en comprendre tout le sens est la meilleure école d’ap-
prentissage. Elle nécessite de se prendre en charge, d’apprendre à identifier ses erreur et à
trouver des solutions pour les corriger. Cela nécessite une grande autonomie dans son travail.
II
Le langage Python
3 Instructions de base . . . . . . . . . . . . . . . . . 19
4 Structures alternatives . . . . . . . . . . . . . . . 45
5 Structures répétitives . . . . . . . . . . . . . . . . . 53
6 Procédures et fonctions . . . . . . . . . . . . . . 69
7 Listes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
8 Chaînes de caractères . . . . . . . . . . . . . . 99
3.1 Introduction
Comme il a été dit dans le chapitre introductif, un algorithme est une suite ordonnée d’instruc-
tions qui indique la démarche à suivre pour résoudre un ensemble de problèmes équivalents. Quand
on définit un algorithme, les instructions le composant doivent être compréhensible par l’ordinateur.
Dans ce chapitre, nous nous intéresserons aux instructions (statements) de base de l’algo-
rithmique telles qu’elles existent dans un langage de haut niveau comme Python. Il s’agit de
l’affectation (assignment), des appels de fontions (function call), des expressions utilisables dans le
contexte de ces instructions de base et d’autres instructions que nous verrons par la suite, et des
instructions d’entrée au clavier (keyboard input)et de sortie à la console (console output).
Pour effectuer la conversion Farenheit → Celsius, nous commençons par donner un nom à la
température en degrés Farenheit, par exemple tF , ainsi qu’à la température en degrés Celsius, par
exemple tC . Puis nous exprimons la relation liant ces deux températures : tC = 59 (tF − 32). Nous
pouvons appliquer cette relation à un cas particulier, par exemple tF = 70 : tC = 59 (70 − 32) ≈ 21.
En informatique, l’essentiel du travail effectué par un programme consiste à manipuler des
données stockées dans la mémoire centrale (voir le cours d’architecture des ordinateurs). Ces
données peuvent être très diverses (par exemple des températures), et il est pratique de nommer ces
données plutôt que de connaître directement leurs adresses en mémoire.
Ainsi, les données sont désignées par un nom de variable (par exemple tC ou tF : on dit que
la variable désigne (ou dénote) une valeur. Pour la machine, il s’agit d’une référence désignant
20 Chapitre 3. Instructions de base
une adresse mémoire, c’est à dire un emplacement précis dans la mémoire vive où est stockée une
valeur.
Précisons ce qu’est une variable au sens de Python.
Définition 3.2.1 — variable. Une variable désigne un objet informatique dans une zone
mémoire. Elle :
1. est désignée par un identificateur, appelé aussi nom, lié à une référence (donc un espace
mémoire)
2. mémorise une valeur, évoluant avec le flot d’instructions mais unique à un instant donné
3. présente un type, précisant la nature de la valeur qu’elle mémorise
hidentificateuri : :=-
- hlettrei -
hchiffrei
hlettrei
‘_’
haffectationi : :=-
- hidentificateuri ‘=’ hexpressioni -
1 a = 5 # variable entière
2 b = 10 # variable entière
3 c = 7 # variable entière
4 reste = b % a # variable entière
5 quotient = b / a # variable entière
6 delta = b*b-4*a*c # variable entière
7 racine = (-b-math.sqrt(delta))/(2*a) # variable réelle
8 est_positif = delta > 0 # variable booléenne.
Que se passe-t-il lors de la première affectation d’une variable ? Rappelons qu’en python, la
première affectation d’une variable correspond à sa déclaration. Prenons par exemple l’affectation
x=2. Lorsque Python exécute cette instruction (cf. figure 3.1 ), il :
1. crée une zone mémoire permettant de ranger l’objet de type entier 2 (class int),
2. cherche si x existe dans le contexte de nommage 2 . Ne le trouvant pas, une entrée x est ajoutée
à ce contexte,
3. finalise l’affectation en associant x à 2.
Contexte Mémoire
x 2
Exemple 3.4 — autres exemples d’affectation. Référez vous à la figure 3.2 pour visualiser le
contexte et la mémoire.
— val = 3.14 crée la valeur flottante 3.14 (type float) en mémoire, déclare la variable val
dans le contexte, les associe.
— chaine = "Eggs" crée la chaîne de caractères "Eggs" (de type str), déclare la variable
chaine dans le contexte et les associe.
Y Attention à bien distinguer le nombre 3.14 (type float) de la chaîne de caractères "3.14"
(type str). On peut faire des calculs sur la valeur 3.14 ; en revanche, on ne peut pas faire de
calculs sur la chaîne de caractères "3.14".
2. La notion de contexte de nommage sera précisée ultérieurement. Pour l’instant, comprenez : l’ensemble des noms
manipulés par un programme.
3.2 Variables & Affectation 23
Contexte Mémoire
x 2
val 3.14
chaine "Eggs"
i = i + 1
Dans cet exemple, on évalue d’abord l’expression de droite (i+1), puis on attribue la valeur
obtenue à la variable située à gauche (i). Ainsi, à la fin de cette affectation, la valeur de i
aura été augmentée de 1 : on dit que i a été incrémentée de 1.
Exercice 3.1 Quelles sont les valeurs et les types des différentes variables après l’exécution
des affectations suivantes ?
1 nom = "Dupont"
2 coef_a = 4.0
3 coef_b = 2
4 compteur1 = 0
5 compteur2 = 0.0
6 compteur1 = compteur1 + 2
7 compteur2 = 100
8 coef_c = coef_a + 50.0
fonction traitement
int(valeur) troncature de la valeur à l’entier le plus proche de zéro
float(valeur) conversion de la valeur en flottant
str(valeur) conversion de la valeur numérique en chaîne
Y int parmet aussi des conversions dans une base donnée en utilisant son paramètre base.
Ainsi, int('FF', base=16) donne la valeur 255.
24 Chapitre 3. Instructions de base
3.3 Expressions
3.3.1 Définitions
Nous avons vu dans la section 3.2 que la partie droite d’une affectation pouvait être une
expression, nous n’avons pas défini précisément ce qu’est une expression. Nous allons examiner
de que peut être une expression, en partant des expressions les plus simples (les constantes), et en
enrichissant au fur et à mesure.
Définition 3.3.1 — Expression & opérateurs. Une expression est une série de calculs ayant
pour résultat une valeur d’un certain type.
Une expression utilise des opérateurs (+, -, *, .. . . ) agissant sur des opérandes qui peuvent
être des valeurs, des variables ou d’autres expressions.
Les expressions exploitent l’espace mémoire : la valeur d’une expression, si elle doit être
réutilisée dans la suite d’un programme, devra être stockée dans (affectée à) une variable.
3.3.2 Constantes
Il y a autant de types de constantes qu’il y a de types, aussi décrirons nous les constantes
entières (qui peuvent s’exprimer dans différentes bases), les constantes réelles et les constantes
chaînes de caractères.
Constantes entières
Les constantes entières peuvent s’exprimer en base 10, mais aussi en base 2, 8 ou 16. Il existe
donc quatre types de constantes entières :
hconstante_entièrei : :=-
- hconstante_entière_décimalei -
hconstante_entière_octalei
hconstante_entière_hexadécimalei
hconstante_entière_décimalei : :=-
- ‘0’ -
hchiffre_sauf_zéroi
hchiffrei
hconstante_entière_octalei : :=-
- ‘0’ ‘o’ hchiffre_octali -
‘O’
Constantes réelles
Les constantes flottantes de type float doivent respecter les règles suivantes :
hconstante_réellei : :=-
- hchiffresi ‘.’ -
hchiffresi hexposanti
hexposanti : :=-
- ‘e’ hchiffresi -
‘E’ ‘+’
‘-’
hchiffresi : :=-
- hchiffrei -
Exemple 3.11 — constantes flottantes bien formées : 0.22, 12., 3.665e12, 0.615e-4
— constantes flottantes mal formées : 23 (c’est une constante entière décimale)
hconstante_chaînei : :=-
- hchaîne_courtei -
hchaîne_longuei
hcaractèrei
hchaîne_courtei : :=-
- ‘"’ ‘"’ -
hcaractèrei
‘’’ ‘’’
hcaractèrei
hchaine_longuei : :=-
- ‘"""’ ‘"""’ -
hcaractèrei
‘’’’’ ‘’’’’
Un hcaractèrei est n’importe quel caractère, sauf le délimiteur utilisé ou « \ ». Ce peut être
aussi une séquence d’échappement permettent de définir des caractères spéciaux. Les séquences
d’échappement sont résumées table 3.3.
Le différence entre une chaîne courte et une chaîne longue est la suivante :
26 Chapitre 3. Instructions de base
— Dans une chaîne courte, vous ne pouvez pas passer à la ligne à l’intérieur de la chaîne
dans votre code source. Pour déclencher des passages à la ligne, il faut insérer un caractère
d’échappement \n.
— Dans une chaîne longue, vous pouvez passer à la ligne à l’intérieur de la chaîne. Ce passage
à la ligne fera partie de la chaîne de caractères.
Exemple 3.12 — constantes chaîne de caractère. — "spam and eggs", ou 'spam and
eggs' représente :
spam and eggs
— "c'est une chaîne de caractères" ou 'c\'est une chaîne de caractères'
représente :
c'est une chaîne de caractères
— "spam\nand eggs" ou 'spam\nand eggs' ou
"""spam
and eggs
"""
ou
'''spam
and eggs
'''
représente la chaîne :
spam
and eggs
Constantes booléennes
Il n’y a que deux constantes booléennes :
hconstante_booléennei : :=-
- ‘True’ -
‘False’
3.3 Expressions 27
Constante None
Cette constante particulière est utilisée pour signifier l’absence de valeur dans de nombreuses
situations. LA Constant None est du type None. Sa valeur de vérité est faux.
hexpression-simplei : :=-
- hidentificateuri -
happel_de_fonctioni
‘(’ hexpressioni ‘)’
hconstantei
hacces-tableaui
Le cas des constantes a déja été traité. Par hidentificateuri, on comprend identificateur de
variable. Les accès à un tableau seront traités dans le chapitre 7.
appel de fonction
Un appel de fonction consiste à utiliser pour le besoin d’un calcul une fonction, soit prédéfinie
par le langage, soit définie dans un module externe (cf. section 3.6), soit écrite par nous même
ailleurs dans le programme (cf. chapitre 6).
Nous avons déjà rencontré des appels de fonction sans définir précisément leur syntaxe. Celle-ci
est la suivante :
happel_de_fonctioni : :=-
- hidentificateuri ‘(’ ‘)’ -
‘,’
hexpressioni
Exemple 3.14 Python fournit une fonction prédéfinie len, qui renvoie la longueur d’une chaîne
de caractères (entre autres choses, nous reviendrons plus tard sur cette fonction qui a d’autres
usages).
hexpression_unairei : :=-
- hexpression_simplei -
‘+’ hexpression_unairei
‘-’
‘~’
a = 3
b = true
c = -a % c contient la valeur -3
d = ~a % d contient la valeur -4
00000011
0 3
11111100
F C
Le type int représente les valeurs négatives en complément à deux : toutes les valeurs dont le
bit le plus significatif est à 1 sont des valeurs négatives représentées en complément à deux. Pour
retrouver la « vraie » valeur, il faut donc effectuer l’opération de complément à deux, c’est-à-dire
ajouter 1, puis inverser les bits :
ajout de 1 :
11111101
F D
inversion :
00000010
0 4
Donc l’inversion des bits de a produit la valeur 0xFFFFFFFC qui représente l’entier -4.
hexpression_multiplicativei : :=-
- -
- hexpression_unairei -
hexpression_multiplicativei ‘*’ hexpression_unairei
‘/’
‘//’
‘%’
opérandes numériques
Une règle importante lors de l’usage des opérateurs arithmétiques binaires est celle régissant
la conversion des types. En effet, il est important de savoir ce qui se passe lorsqu’une opération
arithmétique met en jeu des opérandes de types différents. Le type du résultat en fonction du type
des opérandes et de l’opérateur considéré est déterminé par la table 3.4.
10 * 3 # la valeur entière 30
10.0 * 3 # la valeur flottante 30.0
3 / 4 # la valeur flottante 0.75
10 // 3 # la valeur entière 3
10 // 3.0 # la valeur flottante 3.0
10 % 3 # la valeur entière 1
10.0 % 3 # la valeur flottante 1.0
chaînes de caractères
Lorsqu’une des deux opérandes est une chaîne de caractères (str) et l’autre un entier (int), la
chaine de caractère est répétée autant de fois que spécifié par la valeur entière.
Exemple 3.17 — répétition de chaîne de caractères.
30 Chapitre 3. Instructions de base
hexpression_additivei : :=-
- -
- hexpression_multiplicativei -
hexpression_additivei ‘+’ hexpression_multiplicativei
‘-’
opérandes numériques
Le type du résultat est une valeur entière (int) si les deux opérandes sont entières. Si au moins
une des deux opérandes est de type float, le résultat est une valeur de type float.
L’opérateur + effectue une addition, et l’opérateur - une soustraction.
chaînes de caractères
L’opérateur + peut s’appliquer aux chaînes de caractère. Il réalise alors une concaténation, c’est
à dire qui « colle » les deux chaînes bout à bout en créant une nouvelle chaîne.
Exemple 3.18 — concaténation.
a = "spam"
b = "and"
c = "eggs"
! La présentation de ces opérateurs ne fera pas l’objet d’un cours, d’un TD ou d’un TP par
manque de ressource horaire. Toutefois, vous pouvez être amenés à utiliser ces expressions
agissant sur la représentation binaire des nombres dans d’autres contextes (autre module
d’enseignement ou projet).
Les expressions de décalage sont celles utilisant les opérateurs de décalage de bits. Elles doivent
respecter la règle suivante :
hexpression_de_décalagei : :=-
- -
- hexpression_additivei -
hexpression_de_décalagei ‘<<’ hexpression_additivei
hexpression_de_décalagei ‘>>’ hexpression_additivei
1 x = 5 << 2 # 20
2 x = 5 >> 2 # 1
3 x = 5 >> 3 # 0
4 x = -5 >> 2; # -2
5 x = -5 << 2; # -20
Quelques explications :
ligne 1 La représentation binaire de 5 sur 8 bits est :
00000101
00010100
00000001
11111011
On décale de deux positions vers la droite avec extension du signe, c’est à dire que les
positions de gauche libérées par le décalage sont remplies avec des 1 :
11111110
C’est un nombre négatif. Pour savoir lequel on calcule le complément à deux pour obtenir sa
valeur absolue :
00000010
11101100
Le bit de signe est à un, le résultat est donc un nombre négatif. Pour savoir lequel, on calcule
son complément à deux pour trouver sa valeur absolue :
11101101
00010010
Définition 3.3.2 — type booléen. Une variable de type booléen (bool), peut prendre unique-
ment deux valeurs :
— True, correspondant à vrai ou à la valeur binaire 1 ;
— False, correspondant à faux ou à la valeur booléenne 0.
Y Toute valeur peut être transtypée en valeur booléenne à l’aide de la fonction bool(valeur) :
— toute valeur égale à 0 (ou None) est considérée comme False
— toute autre valeur est considérée comme True
Par défaut, bool() utilisée sans paramètres renvoie la valeur False.
Expressions booléennes
Opérateurs de comparaison
Les expressions booléennes mettent en œuvre des opérateurs de comparaison qui comparent
deux données du même type (numérique, chaîne. . . ), et produisent une valeur booléenne. Les
principaux opérateurs de comparaison son décrits dans la table 3.5.
Y
— la syntaxe b < x < B est propre à python. Il vaut mieux éviter de l’utiliser, ou alors
rester bien conscient que cette syntaxe n’existe généralement pas dans les autres
langages de programmation. Généralement on préfèrera écrire : x > b and x
< B. and est un opérateur booléen. Voir les opérateurs booléens ci-après.
— L’opérateur in sera abordé lorsque nous étudierons les listes au chapitre 7.
Concernant les opérateurs de comparaison usuels (==, !=, >= <=, > <), les deux opérandes
doivent être d’un type compatible. On peut comparer :
— Deux nombres : int ou float
— Deux chaînes de caractères (type str)
La comparaison de deux chaînes des caractères se fait selon l’ordre lexicographique (c’est à
dire, en simplifiant un peu, l’ordre du dictionnaire). Voir les exemples ci-dessous.
Exemple 3.20 — comparaison de chaînes de caractères.
Expression Valeur Remarques
"avant" < "avarie" True car « avant » est sité avant « avarie » dans le dictionnaire
"avant" == "avant" True chaînes identiques
"Avant" == "avant" False voir les remarques ci-dessous
Dans un ordinateur, Les caractères sont représentés par une valeur numérique. La représentation
des caractères vous garantit que "A" < . . . < "Z" < . . . < "a" < . . . < "z". La table codant l’ordre
des caractères est la table UTF8. Cet ordre explique notamment que l’expression "Avant" <
"avant" est vraie.
3.3 Expressions 33
Par conséquent, si on souhaite comparer deux chaînes, le mieux est de les convertir au préalable,
soit entièrement en majuscules, soit entièrement en minuscules. Cela tombe bien, le type str
fournit une méthode (voir la section 3.6.3 pour une définition de ce qu’est une méthode) permettant
de transformer une chaine en son équivalent minuscule. C’est la méthode str.casefold(). Ainsi,
en utilisant cette méthode, l’expression "Avant".casefold() == "avant".casefold() vaut
True.
Exemple 3.21 — expressions booléennes avec opérateurs de comparaison.
Condition Expression Python
la variable prog1 est-elle égale à 10 ? prog1 == 10
la variable prog2 est-elle comprise entre 10 et 20 ? 10 < prog2 < 20
la moyenne des notes prog1 et prog2 est-elle (prog1 + prog2)/2 > 10
supérieure à 10 ?
La note prog1 est-elle divisible par 3 ? prog1 % 3 == 0
x est-il différent de "a", "b" et "c" ? x not in ["a", "b", "c"]
x est-il du type int ? isinstance(x, int)
Y La valeur d’une expression booléenne peut bienentendu être affectée à une variable. Par
exemple, l’instruction reponse = (x == 5) affecte à la variable reponse le résultat de la
comparaison « x est-il égal à 5 ? ».
Opérateurs booléens
Les expressions booléennes peuvent également mettre en œuvre des opérateurs booléens qui
combinent des valeurs booléennes entre elles. Les principaux opérateurs booléens sont décrits dans
la table 3.6. Les valeurs de vérités des opérateurs logiques sont rappelés dans la table 3.7.
Y L’évaluation des expressions booléenne s’arrête dès que le résultat est sûr : par exemple, dans
l’expression x and y, si x est évalué à False, alors l’expression est False quelque soit la
valeur de y, qui n’est donc pas évalué. De même, pour x or y, si x est évalué à True, alors
l’expression est True, quelque soit la valeur de y, qui n’est pas évaluée.
1 a = 19
2 b = 6
3 q = 0
4 r = a
5 r = r - b
6 q = q + 1
7 r = r - b
8 q = q + 1
9 r = r - b
10 q = q + 1
1 a = "spam "
2 a = a*3
3 a = a + "and eggs "
4 b = "and spam "
5 a = a + b + "spam "*2
1 a = True
2 b = False
3 c = (a or b)
4 d = (a and b)
5 e = (a and c)
6 f = not (c or d)
7 g = not c and not d
Exercice 3.5 — Séquences d’affectations et expressions entières. Quelles sont les valeurs
des variables c, d, e, f et g après l’exécution de la séquence d’affectations suivante ?
3.4 Affectation composée 35
1 a = 0o37
2 b = Ox40
3 c = 0b11010
4 d = a + b
5 e = d + c
6 f = ~b
7 g = c >> 2
haffectation_composéei : :=-
- hidentificateuri ‘+=’ -
‘-=’
‘*=’
‘/=’
‘%=’
‘//=’
‘**=’
une affectation composée du type variable op= expression est équivalente à l’affectation
variable = variable op expression.
Exemple 3.23 — affectations composées. Les instructions suivantes :
1 a = 4
2 a += 1
3 a *= 2
4 a **= 2
5 a /= 2
1 a = 4
2 a = a + 1
3 a = a * 2
4 a = a ** 2
5 a = a / 2
ligne a
1 4
2 5
3 10
4 100
5 50
Exercice 3.6 — Affectation composée. Quelles sont les valeurs des variables après la
séquence d’affectations suivante ?
1 a = 'spam '
2 b = "and eggs "
3 a *= 3
4 a += b
5 a += "and " + "spam "*3
msg = "Bonjour"
valeur = 3.14
print(msg)
print(valeur)
print("fin")
print( "Bonjour" )
print( 3.14 )
print( "fin" )
produisent l’affichage
Bonjour
3.14
fin
Variantes de print
1. print(donnee1, donnee2, ...) affiche, sur une même ligne, et séparées par un espace,
toutes les données passées en paramètre.
3.5 Entrées et sorties simples 37
msg = "Bonjour"
valeur = 3.14
print(msg, valeur)
print("fin")
print("Bonjour", 3.14)
print("fin")
1 msg = "Bonjour"
2 valeur = 3.14
3 print( msg, valeur, sep="--" )
4 print( "et" )
5 print( msg, valeur, end=">>" )
6 print( "fin" )
Si vous souhaitez que la saisie de l’utilisateur soit d’un certain type, c’est à vous de réaliser un
transtypage en utilisant les fonctions de conversion de type vues dans la section 3.2.4.
Exemple 3.28 — input avec transtypage. Les instructions :
Définition 3.6.1 — Caractéristiques d’une fonction. En plus d’un nom et d’un éventuel
module, les fonctions peuvent :
— dépendre de paramètres
— produire un résultat, appelé aussi valeur de retour (return value).
Définition 3.6.2 — Appel d’une fonction. Pour appeler une fonction, c’est-à-dire évaluer son
résultat pour des valeurs des paramètres données (appelés arguments), il faut :
— importer son module (si nécessaire) avec l’instruction import module (une seule fois
dans le programme)
— appeler la fonction avec la syntaxe :
— fonction si la fonction est déclarée dans le contexte courant ;
— module.fonction si la fonction appartient à un module importé.
suivi de parenthèses
— indiquer dans les parenthèses les arguments : chaque argument donne une valeur à chaque
paramètre de la fonction, dans le même ordre que celui de la déclaration des paramètres.
Cet appel se termine en renvoyant un résultat (une valeur), qui peut être affecté à une variable.
happel_de_fonctioni : :=-
- hnom_fonctioni ‘(’ -
hnom_modulei ‘.’
- ‘)’ -
‘,’
hargumenti
import math
res = math.sqrt(3)
print(res)
La fonction sqrt(x) est alors évaluée, son paramètre x recevant l’argument 3. Le résultat
est stocké dans la variable res, qui est ensuite affichée sur la console :
1.7320508075688772
— La fonction max(a, b) est prédéfinie, elle n’appartient à aucun module. Les instructions :
évaluent la fonction max(a, b) lorsque son paramètre a reçoit l’argument 1 et son paramètre
b reçoit l’argument b reçoit l’argument 10, stocke le résultat dans res, puis l’affiche sur la
console :
10
— La fonction getlogin() se trouve dans le module os, il faut donc importer le module :
import os
On peut alors appeler la fonction, qui ne prend pas de paramètres, ce qui n’empêche pas qu’il
faille indiquer les parenthèses :
log = os.getlogin()
print(log)
Ces instructions évaluent la fonction getlogin(), stockent le résultat dans log, puis l’af-
fichent sur la console :
wurbel.e
3.6.3 Méthodes
Certaines fonctions proposées dans les bibliothèques fournies par Python s’appliquent à des
objets d’un type particulier. Plus précisément, ils décrivent certains comportements ou certaines
propriétés des objets de cette classe (ce type).
Définition 3.6.3 — Méthode. Une méthode est une fonction décrivant un comportement d’un
objet d’une certaine classe.
Pour appeler une methode sur un objet, on utilise la syntaxe :
a = 2/3
b = 5.0
print(a.is_integer())
print(b.is_integer())
3.7 Annexes
3.7.1 Solutions des exercices
Solution de l’exercice 3.1 Pour répontre à la question, le plus simple est de réaliser une trace
du programme. La trace d’un programme décrit l’évolution de la valeur des variables au fur
et à mesure de l’exécution du programme. Ici, nous complèteronts cette trace en y ajoutant
l’information concernant le type de la valeur désignée par chaque variable.
ligne nom coef_a coef_b compteur1 compteur2 coef_c
valeur type valeur type valeur type valeur type valeur type valeur type
1 "Dupont" str — — — — — — — — — —
2 "Dupont" str 4.0 float — — — — — — — —
3 "Dupont" str 4.0 float 2 int — — — — — —
4 "Dupont" str 4.0 float 2 int 0 int — — — —
5 "Dupont" str 4.0 float 2 int 0 int 0.0 float — —
6 "Dupont" str 4.0 float 2 int 2 int 0.0 float — —
7 "Dupont" str 4.0 float 2 int 2 int 100 int — —
8 "Dupont" str 4.0 float 2 int 2 int 100 int 54.0 float
Quelques commentaires :
1. Après l’exécution de cette ligne, la variable nom désigne une valeur de type chaîne de
caractères (str).
2. Le fait d’utiliser une constante contenant le point décimal fait que la valeur désignée par
cette variable sera du type float.
3. Ici la constante numérique ne contient pas de point décimal, il s’agit donc d’une valeur de
type entier (int).
4. Là encore, la constante 0 ne contient pas de point décimal, il s’agit donc d’une valeur
entière (int).
5. La constante litérale 0.0 comprend un point décimal. Il s’agit donc d’une valeur à virgule
flottante (float), qui est différente du zéro de type entier à la ligne précédente.
6. On commence par effectuer l’expression située à droite du signe =. La valeur actuelle de
compteur1 est 0, donc la valeur de l’expression est 2 (de type int). On affecte ce résultat
à la variable compteur1 qui désigne donc maintenant la valeur 2.
7. On affecte à la variable compteur2 une nouvelle valeur. Celle-ci est de type entier (int)
puisque 100 ne contient pas de point décimal. La nouvelle valeur de compteur2 est donc
100, et le type de la variable est int. On a donc changé le type de cette variable.
8. Le résultat de l’expression à droite du signe d’affectation est 54.0. Il résulte de l’addition
de deux valeurs de type float : la valeur désignée par la variable coef_a (de type float)
et la valeur 50.0 (de type float elle aussi). Le résultat est dont logiquement de type
float.
42 Chapitre 3. Instructions de base
Solution de l’exercice 3.5 La trace du programme est la suivante. Toutes les valeurs sont
données en base 10.
3.7 Annexes 43
ligne a b c d e f g
1 31 — — — — — —
2 31 64 — — — — —
3 31 64 26 — — — —
4 31 64 26 95 — — —
5 31 64 26 95 121 — —
6 31 64 26 95 121 -65 —
7 31 64 26 95 121 -65 6
Explications complémentaires sur la ligne 6 : La variable b contient la valeur décimale 64,
soit 0x40 en hexadécimal, ou encore 0b01000000 en binaire (la valeur est réprésentable sur un
octet). L’inversion de tous les bits de cette valeur donne donc 0b10111111. Il s’agit donc d’une
valeur négative (bit le plus significatif à 1) représentée en complément à deux. Pour trouver la
valeur absolue correspondante, on calcule le complément à deux (inversion de tous les bits suivit
d’un ajout de 1) :
1 0 1 1 1 1 1 1
--------------- inversion
0 1 0 0 0 0 0 0
+ 1
---------------
0 1 0 0 0 0 0 1
La syntaxe générale d’une alternative simple est présentée dans la figure 4.2. Le fonctionnement
de cette construction est rappelé dans la figure 4.3.
if condition_booleenne:
# instructions si la condition est vraie
instruction
instruction
else:
# instructions si la condition est fausse
instruction
instruction
# fin du si/sinon
suite_du_programme
if condition_booleenne:
# instructions si la condition est vraie
instruction
uniquement si condition est True
instruction
else:
# instructions si la condition est fausse
instruction
uniquement si condition est False
instruction
# fin du si/sinon
suite_du_programme suite du déroulement séquentiel
! En python, c’est l’indentation qui délimite les blocs d’instructions. Une mauvaise indentation
conduira imanquablement à une mauvaise exécution.
if condition_booleenne:
# instructions si la condition est vraie
instruction
instruction
else:
# instructions si la condition est fausse
instruction
instruction
# fin du si/sinon
suite_du_programme
else:
# instructions si la condition est fausse
print("non :", entier, "est inférieur ou égal à 4")
# fin du si/sinon et suite du programme
print("fin")
donnent à l’exécution :
Cas 1 :
Saisissez un entier : 32
oui : 32 est supérieur à 4
fin
Cas 2 :
Saisissez un entier : 3
non : 3 est inférieur ou égal à 4
fin
Exercice 4.1 — Maximum. Écrire un programme python qui détermine le maximum de deux
nombres.
Exemple 4.2 — Fonction « porte ». On considère la fonction « porte » f dont le graphe est
chaine_x = input("x=") y
x = float(chaine_x)
2
if (x < -1) or (x > 2):
y = 0
else: x
-1 0 2
y = 2
Exercice 4.2 — fonction « porte ». Proposer une autre alternative simple pour calculer la
fonction « porte » de l’exemple 4.2.
if condition_booleenne:
# instructions si la condition est vraie
instruction
instruction
# fin de la condition
suite_du_programme
if condition_booleenne:
# instructions si la condition est vraie
omis si
instruction la condition
uniquement si condition est True
instruction est False
# fin de la condition
suite_du_programme suite du déroulement séquentiel
donnent à l’exécution :
Cas 1 :
Saisissez un nombre : 5
Sa valeur absolue est 5
fin
Cas 2 :
Saisissez un nombre : -2
Sa valeur absolue est 2
fin
syntaxe de l’alternative multiple en Python est présentée dans la figure 4.6. Son fonctionnement est
rappelé dans la figure 4.7.
if condition_booleenne_1:
instruction
instruction
elif condition_booleenne_2:
instruction
instruction
else:
instruction
instruction
suite_du_programme
if condition_booleenne_1:
instruction s’exécute si lacondition 1 est True
instruction
elif condition_booleenne_2: s’exécute si la condition 2 est False
instruction et la condition 2 est True
instruction
else: s’exécute si les conditions 1 & 2
instruction sont False
instruction
suite_du_programme suite du déroulement séquentiel
donnent à l’exécution :
Cas 1 :
Saisissez un nombre : 5
5 est positif
fin
Cas 2 :
Saisissez un nombre : -2
-2 est négatif
fin
Cas 3 :
Saisissez un nombre : 0
0 est nul
fin
Exercice 4.3 — Température de l’eau. À pression ambiante, l’eau est sous forme de glace si
la température est inférieure à 0°C, sous forme de liquide si la température est comprise entre
0°C et 100°C et sous forme de vapeur au-delà de 100°C.
Écrivez un programme Python utilisant une alternative multiple qui demande à l’utilisateur
de saisir une température, et affiche l’état de l’eau correspondant.
Exercice 4.4 Écrivez un programme Python utilisant une alternative multiple qui détermine la
catégorie sportive d’un enfant en fonction de son âge :
— Poussin de 6 à 7 ans,
— Pupille de 8 à 9 ans,
— Minime de 10 à 11 ans,
— Cadet de 12 à 14 ans.
hstructure_alternativei : :=-
- ‘if’ hexpression_booléennei ‘:’ hbloci -
- -
‘else’ ’ :’ hbloci
‘elif’ hcondition_booléennei ‘:’ hbloci
Pour finir, voici un exemple faisant le bilan sur les structures alternatives.
Exemple 4.5 Une UE contient deux modules M1 et M2.
— L’UE est validée si les notes aux deux modules sont supérieures à 10.
— il y a rattrapage si un seul des modules a une note supérieure à 10.
— si les deux notes sont inférieures à 10, l’UE n’est pas validée.
Les variables m1 et m2 représentent les notes obtenues à chaque module.
Les trois solutions suivantes sont équivalentes.
4.5 Annexes 51
if m1 >= 10:
if m2 >= 10:
print("validé")
else:
print("rattrapage")
else:
if m2 >= 10:
print("rattrapage")
else:
print("refusé")
4.5 Annexes
4.5.1 Solutions des exercices
Solution de l’exercice 4.2 Voici une autre façon d’écrire la fonction porte de l’exemple 4.2
avec une alternative simple :
x = float(chaine_x)
if (x >= -1) and (x <= 2):
y = 2
else:
y = 0
Solution de l’exercice 4.3 Voici un programme Python utilisant une alternative multiple qui
demande à l’utilisateur de saisir une température, et affiche l’état correspondant.
Ces boucles sont utiles lorsque le nombre d’itérations n’est pas connu à l’avance, par exemple
lorsque ce nombre dépend d’une action de l’utilisateur, ou du résultat d’une calcul réalisé dans la
boucle.
Exemple 5.1 — vérification d’une saisie clavier. Les fragments de programme suivants
imposent à l’utilisateur de saisir au clavier soit la lettre 'O', soit la lettre 'N'.
Pour construire la condition de la boucle, on utilise la variable rep qui contient la saisie de
l’utilisateur, et que l’on compare aux valeurs attendues.
Les deux variantes du programme se distinguent par leur étape d’initialisation de la condition :
1. rep = input("Tapez O/N : "). Dans ce cas, une saisie est réalisée avant le test. Il est
donc possible qu’on ne « rentre » jamais dans la boucle (si l’utilisateur a saisi soit 'O', soit
'N').
2. rep = "" qui affecte une valeur garantissant l’entrée dans la boucle.
Variante 1
Variante 2
Ces deux variantes donnent à l’exécution, pour les mêmes saisies utilisateur :
Variante 1 (2 passages dans la Variante 2 (3 passages dans la
boucle). boucle).
Tapez O/N : i Tapez O/N : i
O/N svp; recommencez : p Tapez O/N : p
O/N svp; recommencez : O Tapez O/N : O
fin fin
Exemple 5.2 — pgcd. Le plus grand commun diviseur de deux entiers a et b peut se calculer en
appliquant la relation de récurrence pgcd(a, b) = pgcd(b, a%b) si b 6= 0, jusqu’à ce que le reste de
(a%b) soit nul (pgcd(d, 0) = d si d 6= 0).
Par exemple, pour calculer le pgcd de a = 12 et b = 18, on applique trois fois cette relation de
récurrence : pgcd(12, 18) = pgcd(18, 12) = pgcd(12, 6) = pgcd(6, 0) = 6
Une façon de considérer la relation pgcd(a, b) = pgcd(b, a%b) est de remarquer qu’elle nous
demande de remplacer a par b et b par a%b tant que le reste n’est pas nul, auquel cas pgcd(a, 0) = a.
Cela conduit à l’algorithme suivant, et a sa traduction en Python (notez que dans la version
python,nous donnons les valeurs de a et b. Pour l’instant on ne sait pas définir en Python de
traitement réutilisable, de fonction) :
5.3 La boucle for 55
algorithme P GCD
entrées :
a : entier
b : entier
sorties :
1 a = 12
pgcd : entier
2 b = 18
variables :
3 while b != 0:
r : entier
4 r = a % b
début
5 a = b
tant que b 6= 0 faire
6 b = r
r ← a%b
7 pgcd = a
a←b
b←r
fin tant que
pgcd ← a
fin algorithme
La trace de l’exécution de ce programme est donnée dans la table .
5.3.2 Répétition
Exemple 5.3 — boucle itérant le même affichage trois fois. Les instructions suivantes :
1 for i in range(3):
2 print("*", end=" ")
3 print("fin")
Y Le compteur de boucle est une variable comme une autre. Il peut être utilisé dans les
instructions de la boucle pour faire varier leeurs résultats d’une itération à une autre.
Exemple 5.4 — affichage des nombres de 2 jusqu’à 6 (exclu). Les instructions suivantes :
1 for i in range(4):
2 print(i+2, end=" ")
3 print("fin")
5.3 La boucle for 57
! Le compteur de boucle ne doit pas être modifié dans les instructions de la boucle !. Quoi
qu’il en soit, l’ensemble des valeurs que doit prendre le compteur de boucle est précalculé
au premier passage dans la boucle. Quelles que soient les modifications faites au compteur,
chaque nouvelle itération donne au compteur la prochaine valeur attendue.
Ce comportement est spécifique à Python. Tous les langages de programmation ne se com-
portent pas comme ça.
1 for i in range(2):
2 print(i, end=" ")
3 i = 0
4 print("fin")
Exemple 5.6 — affichage des nombres de 2 à 5 (exclu). Les instructions suivantes affichent
les nombres de 2 à 4 :
1 for i in range(2,5):
2 print(i, end=" ")
3 print(fin)
initialise le compteur à la valeur val_ini, puis, à chaque itération, ajoute au compteur la valeur
de increment jusqu’à ce qu’il égale ou dépasse val_fin_exclue.
Exemple 5.7 — affichage des nombres pairs de 2 à 8 (exclu). Les instructions suivantes :
Exercice 5.1 — Dessin d’étoiles. Écrivez un programme qui affiche les n lignes suivantes
(l’exemple est donné pour n = 6) :
******
*****
****
***
**
*
On rappelle qu’en Python, l’expression 5*'r' a pour résultat 'rrrrr' et que l’expression
2*'to' a pour résultat 'toto'.
Exemple 5.8 — affichage des nombres impairs de 1 à 20. Avec une boucle for :
print("fin")
i = 1
while i < 20:
print(i, end=" ")
i += 2
print("fin")
Exercice 5.2 — Dessin d’étoiles. Réécrivez l’exercice 5.1 en utilisant une boucle while.
for i in range(20):
if (i % 2) != 0:
print(i, end=" ")
else:
print("-", end=" ")
print("fin")
solde = 0 # initialisation
for mois in range(1, 4 * 12):
solde = solde + 50
print("solde final :", solde)
print("fin")
Y On perd les valeurs intermédiaires du solde. Nous verrons comment conserver ces valeurs si
nécessaire lors de l’étude des listes (chapitre 7).
Exemple 5.11 — Quand pourrais-avoir un iPhone ?. Partant d’un livret contenant 50 euros,
sur lequel est viré 200 euros chaque année, avec 0.75% d’intérêt, combien d’années faut-t-il à son
titulaire pour acheter un iPhone ?
— Variable d’accumulation : le solde avec ajout des intérêts et du versement à chaque itération.
— La boucle sera une boucle while avec un compteur d’années (on ne sait pas a priori combien
d’années seront nécessaires).
solde = 50
annee = 0
while solde < 700:
solde = solde * (1 + 0.75/100) + 200
annee = annee + 1
print("nombre d'années :", annees)
print("Solde :", solde)
Exemple 5.12 — somme des entiers de 1 à 36. Le programme suivant calcule la somme des
entiers de 1 à 36 inclus :
somme = 0 # initialisation
for i in range(1, 36 + 1):
somme = somme + i
print("somme finale :", somme)
L’affichage est :
62 Chapitre 5. Structures répétitives
xn = x| × .{z
. . × }x,
n fois
TABLE 5.7 – Trace du programme de l’exemple 5.13, en supposant que x=2 et n=4. La trace
démarre de ce fait ligne 5.
5.7 Imbrication de boucles 63
1 n = 2
2 while n <= 3:
3 i = 1
4 while i <= 9:
5 print(i, "*", n, "=", i * n)
6 i += 1
7 n += 1
8 print("fin")
******
* *
* *
* *
* *
******
Exercice 5.4 — Dessiner un losange. Toujours dans la même série (ces exercices permettent
de bien acquérir les mécanismes de manipulation de variable de contrôle d’une boucle for),
écrivez un programme permettant d’afficher un losange (ou plutôt un carré pivoté de 45°, à partir
de la longueur de son côté saisie par l’utilisateur.
Par exemple, pour un côté de longueur 5 on obtiendrait :
*
* *
* *
* *
* *
* *
* *
* *
*
La longueur minimale acceptée sera de 2.
5.9 Annexes
5.9.1 Solutions des exercices
Solution de l’exercice 5.1 Le dessin peut être produit par le programme suivant :
n = 6
for i in range(n):
print((n-i)*'*')
Autre solution :
n = 6
for i in range(n,0,-1):
print(i*'*')
Solution de l’exercice 5.2 Voici une façon de réécrire le programme de dessin d’étoiles en
utilisant une boucle while au lieu d’une boucle for :
5.9 Annexes 65
n = 6
i = 0
while i < n:
print((n-i)*'*')
i += 1
Ou encore :
n = 6
i = n
while i > 0:
print(i*'*')
i -= 1
Solution de l’exercice 5.3 Voici une solutoion possible pour le dessin de carrés.
1 """
2 Affichage de carrés.
3 """
4
5
6 def main():
7 """programme principal"""
8 longueur = int(input("Saisissez la longueur d'un côté du carré : "))
9 while longueur < 2:
10 longueur = int(input("Saisissez la longueur d'un côté du carré : "))
11
12 for i in range(longueur):
13 if i == 0 or i == (longueur - 1):
14 # première et dernière ligne : pleine
15 print("*"*longueur)
16 else:
17 # autres lignes : "creuses"
18 print("*", " " * (longueur-2), "*", sep='')
19
20
21 if __name__ == "__main__":
22 main()
Quelques remarques :
— Remarquez la façon dont on repère la première et la dernière ligne en utilisant l’indice de
la boucle (ligne 13).
— Notez que le cas où longueur égale 1 se traite très bien. On fera une seule itération de la
boucle for (avec i valant zéro), et la condition de la ligne 13 sera vraie. On affichera au
final une seule étoile.
— Notez l’utilisation de l’argument sep='' pour éviter que print n’affiche un espace entre
66 Chapitre 5. Structures répétitives
chaque argument.
Voici une trace du programme, en supposant que l’exécution commence à la ligne 12 avec
longueur ayant pour valeur 5 :
ligne i affichage commentaire
12 0 1re itération
13 0 condition vraie (car i == 0)
15 0 *****
12 1 2e itération
13 1 condition fausse (i6= 0 et i6=longueur-1)
18 1 *␣␣␣*
12 2 3e itération
13 2 condition fausse (i6= 0 et i6=longueur-1)
18 2 *␣␣␣*
12 3 4e itération
13 3 condition fausse (i6= 0 et i6=longueur-1)
18 3 *␣␣␣*
12 4 5e itération
13 4 condition vraie (car i == longueur-1)
15 4 *****
1 """
2 Affichage d'un losage de la longueur saisie.
3 """
4
5
6 def main():
7 """Programme Principal."""
8 longueur = int(input("Saisissez la longueur d'un côté : "))
9 while longueur < 2:
10 longueur = int(input("Saisissez la longueur d'un côté : "))
11
12 # partie croissante
13 for i in range(longueur):
14 # espaces en début de ligne
15 print(" "*(longueur - 1 - i), end="")
16 if i == 0:
17 # première ligne : une seule étoile
18 print("*")
19 else:
20 # autre ligne
21 print("*", " "*(2 * i - 1), "*", sep='')
22
23 # partie décroissante
24 for i in range(longueur-1, 0, -1):
25 # espaces en début de ligne
26 print(" "*(longueur - i), end="")
27 if i == 1:
28 # dernière ligne : une seule étoile
29 print("*")
30 else:
31 # autre ligne
32 print("*", " "*(2 * (i - 1) - 1), "*", sep="")
33
34
35 if __name__ == '__main__':
36 main()
Quelques commentaires :
— La première boucle for va afficher la moitié supérieure du losange (de la pointe jusqu’à
la ligne où il est le plus large). La seconde boucle for va afficher la partie qui va en se
rétrécissant, jusqu’à la pointe du bas.
— La première boucle fait varier l’indice i de façon croissante, de 0 jusqu’à longueur-1
— La seconde boucle fait varier l’indice i de façon décroissante, de longueur-1 jusqu’à 1
(rappelez vous que l’indice de fin d’un range est toujours exclu).
— Notez l’utilisation de l’argument end="" de la fonction préféfinie print pour éviter le
passage à la ligne en fin d’affichage.
— Notez l’utilisation de l’argument sep='' pour éviter que print n’affiche un espace entre
chaque argument.
68 Chapitre 5. Structures répétitives
— Notez que les print des lignes 15 et 26 ne passent pas à la ligne après l’affichage,
puisqu’ils servent à afficher les espaces en début de ligne.
Voici une trace du programme, en supposant qu’on comment l’exécution à la ligne 13, avec
une valeur de 4 pour la variable longueur.
ligne i affichage commentaire
13 0 1re itération première boucle
15 0 ␣␣␣ (4 − 1 − 0) espaces
16 0 condition vraie
18 0 *\n \n : passage à la ligne effectué par le print
13 1 2e itération
15 1 ␣␣ (4 − 1 − 1) espaces
16 1 condition fausse
21 1 *␣*\n (2 × 1) − 1 espaces
13 2 3e itération
15 2 ␣ (4 − 1 − 2) espaces
16 2 condition fausse
21 2 *␣␣␣*\n (2 × 2) − 1 espaces
13 3 4e itération
15 3 (4 − 1 − 3) = 0 espaces !
16 3 condition fausse
21 3 *␣␣␣␣␣*\n (2 × 3) − 1 espaces
24 3 1re itération seconde boucle
26 3 ␣ 4 − 3 espaces
27 3 condition fausse
32 3 *␣␣␣*\n (2 × (3 − 1) − 1 espaces
24 2 2e itération
26 2 ␣␣ 4 − 2 espaces
27 2 condition fausse
32 2 *␣*\n (2 × (2 − 1) − 1 espaces
24 1 3e itération
26 1 ␣␣␣ 4 − 1 espaces
27 1 condition vraie
29 1 *\n
6. Procédures et fonctions
6.1 Définition
Définition 6.1.1 — Fonction. Une fonction est un bloc, une suite d’instructions, autonome
décrivant un calcul ou une tâche dans le but de structurer le programme en tâches simples. Elle :
— possède un nom ;
— possède éventuellement des paramètres d’entrée servant à faire varier les calculs ; ces
paramètres sont identifiés par un nom et un ordre ;
— renvoie une unique valeur (dépendant ou non de ses paramètres) représentant le résultat
de la fonction.
Elle se décrit par une signature de la forme nom_de_fonction(param1, param2, ...,
paramN).
instruction # code
instruction
...
return [valeur] # renvoie la valeur de retour
# et sort de la fonction
# fin de la fonction
Y
— L’indentation définit le bloc de la fonction.
— L’exécution de return stoppe le flux d’instructions et force la sortie de la fonction.
— Si return n’est suivi d’aucune valeur, la fonction renvoie None.
res = factorielle(4)
print("4! =", res)
res = factorielle(3)
print("3! =", res)
Pour aller plus loin : Notez que dans le commentaire décrivant la fonction, on précise
que n doit être un entier positif, mais on ne le vérifie pas dans la fonction. Que se passe-t-il si on
ne respecte pas ces conditions ? Par exemple, si on appelle la fonction avec une valeur flottante ?
Essayons directement à partir de ’interpréteur Python :
>>> factorielle(4.5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
6.2 Déclaration d’une fonction 71
Notez l’erreur de type signalée : l’interpréteur nous indique qu’il ne peut pas interpréter une valeur
flottante en tant qu’entier. On obtient donc une erreur signalée par le langage.
Essayons maintenant d’utiliser un entier négatif, ce qui n’a pas de sens.
>>> factorielle(-4)
1
Surprenant ! On obtient un résultat, mais celui-ci n’a aucun sens puisque la factorielle n’est définie
que pour des entiers positifs.
Idéalement, il faudrait se prémunir contre ces mauvais usages de la fonction factorielle,
c’est à dire vérifier que la valeur du paramètre n :
— est un entier,
— est positive.
On peut ajouter deux préconditions pour cela :
1 def factorielle(n):
2 """Calcule et renvoie la factorielle du nombre entier positif n, valant n!"""
3 assert type(n) is int
4 assert n > 0
5
6 res = 1
7 for i in range(1, n+1):
8 res *= i
9 return res # valeur de retour
La première précondition à la ligne 3 vérifie que la valeur passée au paramètre n est bien un entier.
La seconde précondition vérifie que cette valeur est positive. En cas de non respect d’une de ces
contitions, l’exécution est immédiatement interrompue :
>>> factorielle(4.5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/wurbel/src/python/ExemplesCours/factorielle.py", line 3, in factorielle
assert type(n) is int
AssertionError
>>> factorielle(-4)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/wurbel/src/python/ExemplesCours/factorielle.py", line 4, in factorielle
assert n > 0
AssertionError
On remarque que :
— lorsqu’on essaie de passer une valeur flottante, c’est la première précondition qui n’est pas
respectée ;
— lorsqu’on essaie de passer un entier négatif, c’est la seconde précondition qui n’est pas
respectée.
Les préconditions sont un moyen puissant de se prémunir contre les erreurs dans les programmes.
N’hésitez pas à vous en servir.
Exemple 6.3 — Fonction à deux paramètres. La fonction somme2, possédant deux paramètres
a et b, est déclarée de la façon suivante :
72 Chapitre 6. Procédures et fonctions
res = somme2(10, 2)
print("10+2 vaut :", res)
res = somme2('a', 'b')
print("a+b vaut :", res)
Y : Cette fonction est un exemple de généricité : elle peut être utilisée avec n’importe
quel type d’objet, pourvu que l’addition + soit définie.
Exemples d’appels :
res = strctmax(1, 2)
print("strctmax de 1 et 2 :", res)
6.3 Fonctions à plusieurs points de retour 73
res = strctmax(3, 1)
print("strctmax de 3 et 1 :", res)
res = strctmax(4, 4)
print("strctmax de 4 et 4 :", res)
Il est souvent plus prudent, et généralement sans incidence sur l’efficité de l’algorithme, de n’avoir
qu’une seule instruction return, située à la fin de la fonction. Ainsi, on peut réécrire la fonction
strctmax de la façon suivante :
def puissance():
nbr = 3
puiss = 2
res = nbr ** puiss
return res
nbr = 1
res = puissance()
appelée ainsi :
6.4 Portée des variables 75
Appel : puissance()
Contexte Contexte
principal Mémoire
local
nbr 1
3 nbr
2 puiss
res 9 res
return res
a = 1
b = 2
res = somme(a, b)
mais = a + b
Appel : somme(a, b)
Contexte Contexte
principal Mémoire
local
3
a 1 % a
b 2 b
res 5 res
mais 3
return res
— Lors de l’appel à la fonction somme (cf. figure 6.2), les paramètres a et b (n’existant que dans
le contexte local) référencent les mêmes objets que a et b.
— Toute modification des paramètres (ou plus précisément, toute réaffectation des objets
désignés par les paramètres) dans la fonction n’aura d’impact que dans a fonction, pas dans
le programme principal, puisque a et a ne désignent plus les mêmes objets à la fin de la
fonction.
76 Chapitre 6. Procédures et fonctions
Exemple d’appels :
res = somme4(1, 2, 3, 4)
print("1+2+3+4 :", res)
res = somme4('a', 'b', 'c', 'd')
print("a+b+c+d :", res)
La variable liste référence alors les éléments elem0, elem1, ..., elemN_1 en mé-
moire, en leur attribuant un ordre : elem0 est le premier élément, elem1 le second. . . et elemN_1
le dernier. La figure 7.1 illustre cette situation.
prenoms = ["Éric","Hugo","Sarah"]
print("longueur =", len(prenoms))
produit l’affichage :
longueur = 3
78 Chapitre 7. Listes
Contexte
principal Mémoire
Définition 7.2.2 — Accès aux éléments d’une liste. Pour un indice i donné, la syntaxe
liste[i] accède à l’élément d’indice i de la liste, en lecture comme en écriture.
! Si l’indice n’est pas compris entre 0 et len(liste)-1, l’expression liste[i] peut provo-
quer une erreur de type IndexError: list index out of range.
Contexte
principal Mémoire
Exercice 7.1 — Accès aux éléments d’une liste. Soit la liste fruits = ['pomme', 'poire',
'banane', 'orange']. Indiquez quel est le résultat affiché par les instructions print sui-
vantes :
print(fruits[0])
print(fruits[2])
print(fruits[4])
Exercice 7.2 — Modification des éléments d’une liste. Soit la liste mesures_temp =
[13.4, 13.0, 9.5, 13.0, 14.3]. Quel est l’état de la liste après chacune des affectations
suivantes :
mesures_temp[1] = 13.2
mesures_temp[4] = 14.8
mesures_temp[5] = 17.2
7.2.2 L’opérateur in
Définition 7.2.3 — Opérateur in. L’opérateur in permet de tester l’appartenance d’une valeur
à une liste.
— Pour tester si une valeur est égale à l’un des éléments d’une liste, on utilise l’expression
valeur in liste.
— Pour tester si une valeur est différente de tous les éléments d’une liste, on utilise l’expres-
sion valeur not in liste.
Exemple 7.3 — opérateur in. Le programme
Exercice 7.4 — Saisie et tri de liste. Écrivez un programme qui demande à l’utilisateur de
saisir un entier qui est ajouté dans une liste. La saisie se termine lorsque l’utilisateur saisit la
valeur 0.
Le programme trie ensuite cette liste et l’affiche.
liste = [5, 4, 3, 2, 1]
val_min = min(liste)
print("val_min=", val_min)
82 Chapitre 7. Listes
val_max = max(liste)
print("val_max=", val_max)
s = sum(liste)
print("somme=", s)
for i in range(len(liste)):
# instruction manipulant liste[i]
# ...
# suite du programme
Définition 7.4.3 — Parcours d’une liste par le biais des éléments. La structure de boucle
suivante permet d’itérer sur tous les éléments d’une liste :
À chaque itération, elt prend pour valeur un des élements de la liste (du premier au dernier
dans l’ordre des indices), et exécute les instructions.
Le parcours via les indices et les parcours via les éléments sont équivalents, elt valant
liste[i].
Exemple 7.8 — Affichage de liste. Pour une même liste liste = [1, 2, 3, 4] :
1. Parcours par indice :
for i in range(len(liste)):
print(liste[i], '/', end="")
print("fin")
1 /2 /3 /4 /fin
Y Le parcours par les indices est à privilégier si on a besoin de l’indice dans les traitements
effectués dans la boucle. Dans le cas contraire, le parcours par éléments est plus efficace.
Exemple 7.9 — affichage des éléments précédés de leur indice. Pour une même liste
liste = ['a', 1, 'b'] :
84 Chapitre 7. Listes
for i in range(len(liste)):
print(i, ':', liste[i], '/', end="")
print("fin")
0 : a /1 : 1 /2 : b /fin
Y Dans une boucle itérable de type for elm in liste, les éléments à parcourir sont évalués
à l’entrée dans la boucle for ; ils ne changeront pas au cours des itérations, même si la liste
évolue. Par exemple,
liste = [1, 2]
for elt in liste:
liste.append(elt + 1)
boucle deux fois, (parcours des éléments 1 et 2) et se termine avec liste valant [1, 2, 2,
3].
Exercice 7.5 — Affichage des éléments d’indice impair. Écrivez un programme qui affiche
les éléments d’indice impair d’une liste. Testez avec la liste [1, 35, -10, 100, 2, 5, 21].
Avec la liste de test, l’affichage produit sera
35 100 5
Exercice 7.6 — Affichage des éléments impairs. Écrivez un programme qui affiche les
éléments impairs d’une liste d’entiers. Testez avec la liste [1, 35, -10, 100, 2, 5, 21].
Avec la liste de test, l’affichage sera :
1 35 5 21
7.5 Construire une liste 85
7.4.3 Parcours d’une partie des éléments avec une boucle while
Lorque l’on souhaite ne parcourir qu’une partie des éléments d’une liste, par exemple tant
qu’une condition_booleenne n’est pas vérifiée, on utilise une boucle while :
i = 0 # compteur d'indice
while i < len(liste) and condition_booleenne:
# instruction portant sur liste[i]
# ...
# suite_du_programme
Y La condition booleenne doit être précédée d’un test vérifiant que la fin de la liste n’est
pas atteinte.
liste = list()
for i in range(10):
liste.append(0)
print(liste)
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
86 Chapitre 7. Listes
liste1 = [0]*5
liste2 = [1]*5
liste = liste1 + liste2
print liste
[0, 0, 0, 0, 0, 1, 1, 1, 1, 1]
! Ce procédé de construction ne doit être utilisé que pour des listes numériques ! Nous verrons
plus loin pourquoi (problématique des références associées à des objets mutables)
— en transformant chaque élément elt par une expression simple utilisant elt
— optionnellement en filtrant une sous-partie de la collection, sur la base d’une condition
sur l’élément condition_sur_elm.
Syntaxe :
Exemple 7.14 — liste en intention des 5 premiers cubes parfaits. La liste en intention
liste_cubes = []
for elmt in range(5):
liste_cubes.append(elmt ** 3)
La liste obtenue dans les deux cas est [0, 1, 8, 27, 64].
Exemple 7.15 — liste en intention des entiers inférieurs à 10 et non divisibles par 3. La
liste en intention
est équivalente à
liste_ndiv3 = []
for elmt in range(10):
if elmt % 3 != 0:
liste_ndiv3.append(elmt)
! Si vous passez une liste en paramètre à une fonction et que dans cette fonction vous modifiez
les éléments de la liste, les modifications seront visible du contexte appelant.
Exemple 7.16 — les listes dans les fonctions. La fonction suivante prend une liste en paramètre
et renvoie une nouvelle liste.
def ajoute_un(liste):
"""
Construit une liste res, dont les éléments sont ceux
du paramètre liste, chacun ayant été incrémenté de 1.
"""
res = []
for elmt in liste:
88 Chapitre 7. Listes
res.append(elmt + 1)
return res
L’appel suivant :
liste = [1, 2, 3]
nouvelle_liste = ajoute_un(liste)
print(nouvelle_liste)
[2, 3, 4]
liste = [ [1, 2, 3 ],
['a', 'b', 'c'],
[1.1, 2.2, 3.3] ]
l = [1, 2, 3]
insere(l, 1, 10)
print(l)
insere(l, 4, 100)
print(l)
insere(l, 10, 111)
print(l)
insere(l, 0, 333)
print(l)
Affichage produit :
[1, 10, 2, 3]
[1, 10, 2, 3, 100]
[1, 10, 2, 3, 100, 111]
[333, 1, 10, 2, 3, 100, 111]
7.9 Annexes
7.9.1 Solutions des exercices
La ligne 1 de l’affichage correspond à la ligne 1 des instructions à exécuter. 'pomme' est bien
l’élément d’indice 0 de la liste fruits.
La ligne 2 de l’affichage correspond à la ligne 2 des instructions à exécuter. 'banane' est
bien l’élément d’indice 2 de la liste fruits.
Les lignes 3, 4, 5 et 6 de l’affichage correspondent à l’instruction print(fruits[4]). Il
s’agit d’une erreur de type IndexError. Le message indique list index out of range, ce
qui signifie que l’indice demandé (4), n’existe pas dans la liste fruits.
Les trois premières instructions se déroulent correctement. En particulier, les lignes 2 et 3, qui
mettent à jour respectivement des éléments d’indice 1 et 4 de la liste mesure_temp s’exécutent
sans problème.
Après l’exécution de la ligne 2, l’état de la liste est [13.4, 13.2, 9.5, 13.0, 14.3]
(l’élément d’indice 1 a été modifié).
Après l’exécution de la ligne 3, l’état de la liste est [13.4, 13.2, 9.5, 13.0, 14.8]
(l’élément d’indice 4 a été modifié).
En revanche, l’exécution de la ligne 4 déclenche une erreur (lignes 1, 2, 3 et 4 de l’affichage).
L’erreur est de type IndexError, et le message précise que c’est l’indice de la liste assignée
qui pose problème. En effet, cette liste possède 5 éléments, les indices des éléments vont dont
de 0 à 4.
Le programme principal :
7.9 Annexes 91
8 def main():
9 """Programme principal. Recherche d'articles dans une liste
10 d'articles. La recherche est réitérée tant que l'utilisateur ne
11 veut pas terminer.
12
13 """
14 # la liste d'articles
15 articles = ["écran", "souris", "ssd 1To", "ssd 2To"]
16
17 encore = True
18 while encore:
19 # recherche et affichage du résultat
20 recherche = input("article à rechercher : ")
21 print("l'article", recherche, end=" ")
22 if cherche_article(recherche, articles):
23 print("a été trouvé")
24 else:
25 print("n'a pas été trouvé")
26
27 # question sur la poursuite
28 rep = ""
29 # on essaie d'etre tolérant sur la réponse !
30 while rep not in ["o", "O", "oui", "OUI", "Oui",
31 "n", "N", "non", "NON", "Non"]:
32 rep = input("Voulez-vous continuer ? ")
33 encore = rep in ["o", "O", "oui", "OUI", "Oui"]
34
35 print("Au revoir")
36
37 if __name__ == '__main__':
38 main()
Solution de l’exercice 7.5 Le programme suivant réalise l’affichage des éléments de la liste [1,
35, -10, 100, 2, 5, 21] d’indice impair. Notez qu’on est obligés d’utiliser un parcours
par les indices car on a besoin de tester la parité de l’indice à la ligne 8.
Solution de l’exercice 7.6 Le programme suivant réalise l’affichage des éléments impair de
la liste [1, 35, -10, 100, 2, 5, 21]. Notez qu’ici, contrairement à l’exercice 7.5, on peut
se servir d’un parcours par éléments, car on a pas besoin de l’indice.
7.9 Annexes 93
La traduction du test de la ligne 10 et de l’action à réaliser à la ligne 11 quand le test est vrai
(ajout en fin de liste) ne posent pas de problème particulier non plus :
3 if i > len(l) - 1:
4 l.append(x)
5 else:
6 l.append(l[len[l]-1])
— la boucle réalisant le décalage vers la droite des éléments (la différence de notation en
Python vient du fait que dans la fonction range, la borne d’arrivée est exclue. Dans
l’algorithme, cette borne d’arrivée est i + 1 :
9 l[i] = x
Les chaînes de caractères sont des objets non mutables, c’est à dire qu’on ne peut pas modifier
en mémoire les caractères de la chaîne, il faut en créer une nouvelle.
Définition 8.1.2 — Déclaration d’une chaîne de caractères. Une chaîne se déclare par
des guillemets ou apostrophes entourant la suite de caractères qu’elle contient : chaine
="c0 c1 c2 . . . cN−1 ". Chaque caractère est ordonné, et donc indiçable, dans le sens de la lec-
ture (de gauche à droite pour les langues européennes).
Contexte Mémoire
chaine c0 c1 c2 · · · cN−1
[0] [1] [2] · · · [N − 1]
Définition 8.2.2 — Accès aux éléments d’une chaîne en lecture. Pour un indice i donné,
la syntaxe chaine[i] permet d’accéder en lecture au caractère d’indice i de la chaine.
! Il n’est pas possible de modifier ce caractère à l’aide d’une affectation comme chaine[i] =
carac, car une chaîne de caractères est un objet non mutable.
Y L’instruction chaine[0] = 'L' tentant de modifier le 1er caractère de la chaîne produit une
erreur de type
TypeError: ’str’ object does not support item assignment
car une chaîne de caractères n’est pas un objet mutable.
8.2.2 L’opérateur in
L’opérateur in fonctionne de façon similaire aux listes.
Définition 8.2.3 — Opérateur in. L’opérateur in permet de tester l’appartenance d’un caractère
(ou d’une sous-chaîne) à une chaîne de caractères.
— Pour tester si un caractère (ou une sous-chaîne) est présent dans une chaîne, on utilise
l’expression caractere in chaine (ou sous_chaine in chaine).
— Pour tester si un caractère (ou une sous-chaîne) n’est pas présent dans une chaîne, on
utilise l’expression caractere not in chaine (ou sous_chaine not in chaine).
chaine = "abcd..."
test1 = ('a' in chaine)
8.3 Manipulation de chaînes de caractères 101
è Nous avons déjà rencontrés les opérateurs de manipulation chaînes de caractère suivants :
— chaine1 + chaine2 : concaténation
— chaine * n : n répétitions (avec concaténation)
Exemple 8.4 — illustration des méthodes de test sur les chaînes. La séquence d’instructions
chaine = "hello"
print('La chaine "hello" :')
test_deb = chaine.startswith("hel")
print("débute par hel ?", test_deb)
test_fin = chaine.endswith("mo")
print("finie par mo ?", test_fin)
chaine = "hello"
nbrel = chaine.count('l')
print("nbre de l=", nbrel)
nbrell = chaine.count('ll')
print("nbre de ll=", nbrell)
il = chaine.find('l')
print("indice du 1er l=", il)
iO = chaine.find('O')
print("indice du 1er O=", iO)
— liste = chaine.split(sep) : renvoie une liste dont les éléments sont des chaînes
obtenues en coupant la chaine suivant le séparateur sep.
— fusion = motif.join(liste) : renvoie la chaîne fusion dans laquelle tous les éle-
ments de liste sont concaténés en les séparant par la chaîne motif. La liste ne doit
comporter que des éléments de type str.
— res = chaine.replace(old, new) : renvoie la chaîne res, copie de chaine dans
laquelle toutes les occurrences de la chaîne old sont remplacées par la chaîne new.
Exemple 8.6 — illustration des méthodes renvoyant des chaînes. La séquence d’instructions
chaine = "pain"
res1 = chaine.replace('n', 'x')
print("res1=", res1)
res2 = res1.replace('a', 'o')
print("res2=", res2)
chaine = "QwertY"
majus = chaine.upper()
print("majus=", majus)
minus = chaine.lower()
print("minus=", minus)
ip = "192.168.0.1"
liste = ip.split('.')
print("liste=", liste)
fusion = '-'.join(liste)
print("fusion=", fusion)
Définition 8.4.2 — Parcours d’une chaîne par le biais des caractères. La structure de
boucle suivante permet d’itérer sur tous les caractères d’une chaîne de caractères chaine :
À chaque itération, car prend pour valeur un des caractères de la chaine (du 1erau dernier) et
exécute les instructions.
è Les instructions contenues dans les boucles des définitions précédentes ne peuvent pas
modifier la chaîne de caractère, puisque les chaînes de caractères sont non mutables.
Exemple 8.7 — parcours de chaînes. Pour une même chaîne de caractères chaine =
"bonjour", les boucles suivantes affichent les caractères de la chaîne séparés par des '*' :
1. Parcours par indices
for i in range(len(chaine)):
print(chaine[i] + "*", end="")
print(" fin")
i = 0 # Compteur d’indice
while i < len(chaine) and condition_boolenne:
# instruction portant sur chaine[i]
# ...
i = i + 1 # Incrémentation de l’indice
# suite_du_programme
La condition_booéenne doit être précédée d’un test s’assurant qu’on ne dépasse pas le dernier
caractère de la chaîne.
Exemple 8.8 — indice de la première occurrence de 'j'. Pour une même chaîne acquise
Variante 1. i = 0
while i < len(chaine) and chaine[i] != "j":
i = i + 1
if i == len(chaine):
print("'j' ne fait pas partie de " + chaine)
else:
print("'j' est à l'indice " + str(i))
produit l’affichage
Le président : **.**.**.**.**
Définition 8.6.2 — Constantes du module string. Le module string propose les constantes
suivantes :
— string.digits : la chaîne '0123456789'. ;
— string.ascii_lowercase : la chaîne contenant tous les caractères minuscules non
accentués : 'abcdefghijklmnopqrstuvwxyz'.
— string.ascii_uppercase : la chaîne contenant tous les caractères majuscules non
accentués : 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.
— string.ascii_letters : la chaîne contenant tous les caractères non accentués, minus-
cules et majuscules.
Y Le module string propose d’autres constantes qui peuvent être utiles. Consultez la docu-
mentation officielle.
9.1 Définitions
Définition 9.1.1 — Fichiers. Un fichier est un objet du système d’exploitation servant à stocker
de façon permanente des données.
Les fichiers peuvent être organisés en :
fichiers texte stockent des données sous forme de lignes successives. Les lignes (enregistre-
ments) sont séparées les unes des autres par une caractère de fin de ligne ('\n').
fichiers binaires ne présentent pas d’organisation apparente. Ce sont des données brutes, sous
forme numérique. Un fichier binaire est a priori illisible sans le programme conçu pour
l’exploiter (exemple : wav, mp3. . . ).
Les fichiers texte optent souvent pour une structuration tombant dans l’une des catégories
suivantes :
1. Structure avec délimitation. On rencontre beaucoup ce type de structuration dans les fichiers
de configuration système, sous Linux en particulier.
Harvey;Keitel;Mr White
Tim;Roth;Mr Orange
Michael;Madsen;Mr Blonde
Steve;Buscemi;Mr Pink
Le délimiteur est un caractère spécial (';', ':', '\t',. . . ) présent entre deux champs d’un
enregistrement (une ligne).
2. Structure à champs de largeur fixe.
Harvey Keitel Mr White
Tim Roth Mr Orange
MichaelMadsen Mr Blonde
Steve BuscemiMr Pink
Ce type de fichier occupe généralement plus d’espace mais est plus rapide d’accès.
108 Chapitre 9. Entrées-sorties sur des fichiers
Mode Signification
'r' lecture
'w' écriture avec création du fichier ou écrasement s’il existait
'a' ajout en fin de fichier
Exemple 9.1 — Ouverture et fermeture d’un fichier existant. Pour un fichier cr.txt dans
situé dans le même répertoire que le script Python :
9.4 Gestionnaire de contexte 109
Y Fichiers binaires Les fichiers binaires fonctionnent de façon similaire, il suffit
d’ajouter le caractère 'b' à la chaîne de caractère décrivant le mode.
L’accès au fichier n’est possible que dans ce bloc. Le fichier est automatiquement fermé lors de la
sortie du bloc.
Y Cette syntaxe, ainsi que a spécification explicite de l’encodage des caractères, est très
fortement recommandée.
fd = open("exemple.txt", 'r')
p = fd.tell()
print("p=", p, "car=", fd.read(1))
fd.seek(10, 0)
p = fd.tell()
print("p=", p, "car=", fd.read(1))
fd.seek(15, 0)
p = fd.tell()
print("p=", p, "car=", fd.read(1))
fd.close()
avec exemple.txt :
Harvey;Keitel;Mr White
Tim;Roth;Mr Orange
Michael;Madsen;Mr Blonde
Steve;Buscemi;Mr Pink