Structure du langage Python
L’interpréteur Python
1. Terminologie
Si vous lisez ce livre, c’est que vous avez un objectif : découvrir la programmation, créer un jeu, apprendre le langage Python, créer une petite application, faire des exercices ou acquérir des connaissances supplémentaires !
Tous ces objectifs vont passer par l’écriture de lignes de code constituant le code source de votre programme. Ces lignes de code sont stockées dans des fichiers texte ayant l’extension py. Ces fichiers sont modifiables dans un éditeur de texte, comme Notepad ou WordPad sous Windows ou encore TextEdit sous Mac.
Le code source au format texte n’est pas directement exécutable par l’ordinateur, il doit passer à travers une étape de conversion effectuée par l’interpréteur Python, qui a la tâche de lire le code source et de l’exécuter.
Le langage Python dispose de sa propre grammaire interne avec ses règles et ses usages. Par exemple, le langage définit une liste de mots-clés réservés qui ne peuvent être choisis par le programmeur pour créer des noms de variables ou des noms de fonctions. Vous connaissez par exemples les mots-clés correspondant aux instructions for, if, then et else. Il existe aussi d’autres mots-clés comme ceux associés aux opérateurs logiques or, and et not ou ceux correspondant aux constantes comme True et False.
Les curieux peuvent consulter la liste des mots-clés dans la documentation officielle du langage Python à l’adresse : https://docs.python.org/fr/3/reference/lexical_analysis.html
Lorsque l’interpréteur Python parcourt le code source, il catégorise chaque élément rencontré en utilisant les règles grammaticales du langage. Pour vous aider à saisir comment l’interpréteur se comporte, voici quelques exemples :
-
Si l’interpréteur rencontre le signe #, il considère que le texte placé après ce caractère représente un commentaire du programmeur.
-
La présence d’un guillemet lui permet de détecter le début d’une chaîne de caractères comme dans l’écriture "Bonjour".
-
Si l’interpréteur rencontre un groupe de caractères commençant par une lettre, il va en premier lieu vérifier si ce terme appartient à la liste des mots-clés du langage (for, and, if...) et, dans ce cas, l’interpréteur en déduit son rôle : une boucle, un test, une condition... Si le terme identifié n’est pas un mot-clé, l’interpréteur sait alors qu’il s’agit d’un nom de variable ou d’un nom de fonction créé par le programmeur.
-
Si l’interpréteur rencontre un groupe de caractères commençant par un chiffre, il en déduit que ce groupe correspond à un nombre comme par exemple 123 pour un entier, 0.23 pour un flottant, 0b010011 pour un nombre binaire ou encore 0xF1A2 pour un nombre hexadécimal.
2. Les éléments du langage
Une fois que l’interpréteur a analysé l’ensemble du code source, chaque élément...
Les variables
1. Usage
Une variable sert à représenter une valeur par un nom. Vous retrouvez ici un concept assez proche de ce que vous connaissez en mathématiques ou en physique. Cependant, il y a quelques différences :
-
En informatique, une variable est toujours connue, car elle est associée à une case mémoire qui contient sa valeur. Le concept d’inconnue n’existe pas !
-
En informatique, une variable évolue : sa valeur change au cours du temps suivant les actions effectuées durant l’exécution du programme. Lorsque l’on modifie une variable, la nouvelle valeur écrase la précédente et l’ancienne valeur est oubliée. En mathématiques et en physique, les inconnues ont une unique valeur !
Un nom de variable doit respecter certaines règles :
1. Un nom ne doit pas commencer par un chiffre.
2. Un nom ne doit pas contenir de caractères spéciaux : ! % @ # [ + = \ ( ) [ ] = & : . , ; $..., exception faite de l’underscore _ présent sur la touche [8] du clavier.
Aujourd’hui, un projet informatique peut être mené par des personnes de nationalités différentes à travers le monde. Par conséquent, l’usage veut que l’on utilise les 26 lettres standards et que l’on évite les caractères spéciaux issus de sa propre langue comme é, à ou ç pour le français. Cependant, sachez que l’interpréteur Python accepte ces caractères si vous vouliez les utiliser.
2. Conseil 1 : choisir des noms explicites
Cependant, l’homo informaticus a connu une autre évolution : il écrit des programmes contenant des millions de lignes. Cette fois, la priorité devient tout autre : lisibilité et structuration. Ce sont les deux maîtres mots de l’informaticien. Il doit à tout prix structurer sa pensée pour organiser son code et le rendre le plus lisible possible. Prenons l’exemple d’une formule écrite de deux manières différentes : en utilisant seulement une lettre pour chaque variable puis en choisissant un nom explicite pour chaque variable :
v = a * (1+t)
ou
PrixTTC = PrixHT * (1+TVA)
Il semble évident que la seconde formulation se comprend aisément et rapidement et qu’il faudrait écrire tout morceau de code ainsi. Cependant, vous serez sûrement tenté par le côté obscur (la première option), et ceci pour les raisons suivantes :
-
Trouver des noms explicites aux variables n’est pas toujours évident.
-
Vous pensez ne pas avoir à revenir vers votre code plus...
Les types numériques
Dans la mémoire de l’ordinateur, on stocke l’information dans des cases appelées octets. Chaque octet correspond à un paquet de 8 bits pouvant chacun valoir 0 ou 1. Ainsi, pour stocker chaque type d’information (du texte, des nombres entiers, des nombres à virgule, des dates…), il faut encoder chaque donnée sous forme de 0 et de 1 suivant une règle choisie. Ainsi, lorsque l’interpréteur Python lit une information en mémoire, il ne trouve qu’une série de 0 et de 1. S’il peut reconstruire à partir de ces bits un prix, une date ou une image, c’est parce qu’il a noté en mémoire que cette information représentait un certain type de donnée, il n’y a pas de magie !
Pour coder les informations en mémoire, il y a des normes. Pour les nombres à virgule, on utilise la norme IEEE 754. Pour le texte, on utilise le standard Unicode lié à la norme ISO/CEI 10646. Pour la représentation des couleurs à l’écran, on utilise le standard sRGB défini par la norme CIE 61966. Vous l’aurez compris : il y a une norme pour tout !
1. Typage automatique
Lorsque l’interpréteur Python parcourt le code du programme, il détermine automatiquement le type d’une valeur d’après son écriture. La fonction native type() permet de connaître le type associé à un littéral. Voici quelques exemples effectués en mode interactif :
>>> type(10)
<class 'int'>
>>> type(1.0)
<class 'float'>
>>> type("Bonjour")
<class 'str'>
Le nombre 10 a été écrit sans chiffres après la virgule. La convention veut qu’il soit associé au type entier (integer en anglais ou int en abrégé). La valeur 1.0 désigne cette fois un nombre à virgule. Automatiquement, l’interpréteur Python choisit le type flottant dénommé float pour stocker cette valeur en mémoire. Une chaîne de caractères est associée au type str.
Type ou classe ? Ces deux termes sont similaires dans le langage Python.
Si l’on peut utiliser des nombres à virgule, on peut se passer des nombres entiers ! Attention, cette affirmation est inexacte. En effet, les nombres flottants utilisés par l’ordinateur sont imprécis. Ainsi, en écrivant le littéral 12, il se peut que la valeur représentée en mémoire soit plutôt 12.000000001, et ce petit détail est important. Ainsi, pour représenter des compteurs ou des positions dans une liste, il faut travailler avec des nombres entiers qui nous garantissent des résultats exacts.
Opérateurs arithmétiques : +, -, *
Le type du résultat de l’opération correspond au type des nombres traités. Ainsi, l’addition de deux entiers donne un nombre entier. Lorsqu’une opération a lieu entre un nombre entier et un nombre flottant, le résultat sera de type flottant. Voici quelques exemples :...
Les chaînes de caractères
À noter que pour délimiter une chaîne de caractères, on peut utiliser soit une paire de guillemets "Total" (touche [3] du clavier) ou une paire d’apostrophes ’Total’ (touche [4] du clavier) de manière équivalente.
1. Opérations sur les chaînes de caractères
Concaténation
L’opérateur + permet d’accoler deux chaînes en une.
>>> a = 'Bonjour '
>>> b = 'toi'
>>> c = a + ' ' + b
Bonjour toi
Pour concaténer des numériques avec des chaînes de caractères, il faut d’abord convertir les nombres en chaînes grâce à la fonction str().
Longueur d’une chaîne
La fonction native len() retourne la longueur d’une chaîne et donc son nombre de caractères :
>>>A = "Bonjour"
>>>len(A)
7
Transformer en majuscules/minuscules
Les fonctions upper() et lower() retournent une chaîne composée respectivement uniquement de majuscules ou de minuscules. On accède à ces fonctions à travers une variable de type chaîne en utilisant la syntaxe LaChaine.upper().
>>> A = "Salut !!"
>>> A.upper()
SALUT !!
>>> A.lower()
salut !!
Cela peut vous dérouter : la fonction len(A) prend une chaîne en paramètre alors que les fonctions lower() et upper() utilisent la syntaxe avec le A.upper().
Notez que les fonctions upper() et lower() ne modifient pas la chaîne en cours, elles retournent une nouvelle chaîne. Si vous voulez modifier la variable courante, il faut écrire : A = A.upper().
Le standard Unicode
Le standard Unicode contient plus de 100 000 caractères et autres symboles de diverses écritures. Ainsi, chaque caractère est associé à un numéro unique : la valeur 32 correspond au caractère espace, la plage de valeurs 48 à 57 correspond aux chiffres de 0 à 9, la plage 65 à 90 code les lettres majuscules de A à Z et la plage 97 à 122 correspond aux lettres minuscules. Deux fonctions chr()et ord() permettent de convertir un code en caractère, et inversement :
>>> ord("A")
65
>>> ord("B")
66
>>> chr(67)
"C"
Pour vous amuser, consultez la page https://fr.wikipedia.org/wiki/Table_des_caractères_Unicode/U1F600 codant divers émoticônes.
>>> chr(0x1F600)
>>> chr(0x1F63B)
Chaque caractère Unicode est décrit dans la norme Unicode mais le dessin associé peut être légèrement différent entre votre ordinateur ou votre téléphone.
2. Sous-chaîne
On peut accéder à un caractère d’une chaîne en écrivant son indice entouré d’une paire de crochets. L’indice 0 est associé au premier caractère en partant de la gauche et l’indice 1 désigne le deuxième caractère. Pour désigner le dernier caractère, on peut écrire...
Les branchements conditionnels
1. Écriture d’une condition
Une condition correspond à une expression utilisant généralement des opérateurs booléens (<, >, ==) et dont le résultat peut prendre la valeur : False pour désigner un résultat faux ou True pour désigner un résultat vrai.
Dans le langage Python, nous trouvons différents opérateurs de comparaison :
-
Égalité : ==
-
Différent : != ou <>
-
Supérieur strict : >
-
Supérieur ou égal : >=
-
Inférieur strict : <
-
Inférieur ou égal : <=
Voici quelques exemples d’une condition exprimée en langage naturel suivie de sa version informatique :
-
La collision a lieu si l’abscisse x est supérieure ou égale à 100 : x >= 100
-
La réduction s’applique pour les 60 ans et plus : age >= 60
-
Les deux frères ont le même âge : ageFrere1 == ageFrere2
-
Si la distance est inférieure (stricte) à deux fois le rayon : distance < 2 * rayon
Le résultat d’une condition peut être stocké dans une variable :
partieFinie = pointsDeVie <= 0
Il est possible d’effectuer grâce à l’opérateur not une inversion (ou négation) d’une valeur booléenne. Cet opérateur logique retourne vrai lorsque la valeur qu’il reçoit est fausse, et inversement. Par exemple, pour savoir si la partie continue, nous pouvons écrire la condition suivante :
not partieFinie
Les comparaisons fonctionnent aussi avec des chaînes de caractères et respectent l’ordre lexicographique utilisé dans un dictionnaire. Voici quelques exemples :
>>> "TATA" < "TONTON"
True
>>> "ZOE" < "ZERO"
False
>>> "TATI" == "TA" + "TI"
True
L’inversion/négation est un des rares opérateurs du langage prenant un seul paramètre en entrée, il est dit unaire. La plupart des opérateurs (ET/OU, +, -, *, /) s’appliquent sur deux valeurs, ce sont des opérateurs binaires. L’expression opérateur binaire est aussi utilisée pour parler des opérateurs bit à bit comme l’opérateur OU binaire, 0b01 | 0b11 donnant 0b11.
2. Branchement if
Un branchement permet de déclencher l’exécution d’une partie du code lorsque le résultat d’une condition est vrai. La syntaxe est la suivante :
if condition :
Dans le langage Python, contrairement à la plupart des langages informatiques, il n’est pas nécessaire d’englober la condition avec une paire de parenthèses. Pour définir le bloc de code devant être exécuté si la condition est vraie, on indente les lignes correspondantes en les décalant vers la droite. Si la condition est fausse, le fil d’exécution ignore les lignes contenues dans le bloc et passe directement à la première ligne de code dont l’indentation est la même que l’instruction if :
if note >= 10 :
print("Tu...
La boucle for avec indice
1. Principe de fonctionnement
Une boucle for permet d’exécuter plusieurs fois un bloc de code. Ce bloc, appelé corps de boucle, commence à la ligne suivant l’instruction for. Il doit avoir une indentation plus importante, et lorsque l’indentation revient au même niveau que celle de l’instruction for, cela signifie que le corps de boucle s’est achevé. En résumé, nous identifions le corps de boucle ainsi :
...
for ... : # Démarrage de la boucle for
... # || Corps de boucle
... # ||
... # ||
... # \/ Fin du corps de boucle
...
La boucle for permet de définir une variable servant d’indice ainsi que la plage de valeurs que cet indice va parcourir. Pour cela, on utilise la fonction native range(k) définissant une plage de valeurs allant de 0 à k-1. Ainsi, en écrivant for i in range(3), la variable i lors de la première exécution du corps de boucle vaut 0. Ensuite, l’interpréteur exécute à nouveau le même bloc, mais cette fois la variable i vaut 1. Puis, pour terminer, l’interpréteur exécute une dernière fois le corps de boucle avec 2 comme valeur pour l’indice i. Après cela, la boucle est terminée.
Mettons nos connaissances en application sur l’exemple suivant :
print("Avant la boucle for")
for i in range(3) : # Mise en place de la boucle
print(" Début du corps de boucle") # || Corps
print(" i =",i) # ||
print(" Fin du corps de boucle") # \/
print("Après la fin de la boucle for ")
Essayez de deviner les affichages produits par ce code. L’indice de boucle i va démarrer à la valeur 0 et sa dernière valeur sera 2. Voici le résultat obtenu :
>> Avant la boucle for
>> Début du corps de boucle
>> i = 0
>> Fin du corps de boucle
>> Début du corps de boucle
>> i = 1
>> Fin du corps de boucle
>> Début du corps de boucle
>> i = 2
>> Fin...
Exercices d’entraînement
Dans les exercices d’application précédents, vous deviez comprendre le fonctionnement d’un morceau de code. Maintenant, nous allons pour chaque exercice décrire les objectifs devant être remplis par votre programme. C’est à vous que revient la lourde tâche d’organiser le code. Génial ! Vous avez enfin les mains sur le volant. Attention, pensez à retirer le frein à main !
La correction de cet exercice est disponible en téléchargement depuis l’onglet Compléments. Demandez à l’utilisateur d’entrer un mot au clavier. Ensuite, écrivez-le à l’envers, c’est-à-dire de droite à gauche. Voici quelques conseils :
-
Utilisez une boucle for avec indice, le nombre de lettres correspond aux nombres d’itérations.
-
L’écriture mot[i] parcourt les caractères de gauche à droite. Ce n’est pas ce que nous voulons. Calculez à partir de la valeur de l’indice, et éventuellement de la longueur du mot, un autre indice partant de la droite et se déplaçant vers la gauche. Deux approches sont possibles, en utilisant une valeur d’indice positive ou négative.
-
Affichez les caractères un à un en utilisant la fonction print(...,end=’’’’) pour éviter les retours à la ligne.
-
Pensez à faire des tests.
La correction de cet exercice est disponible en téléchargement depuis l’onglet Compléments. Demandez à l’utilisateur d’entrer un nombre quelconque. Attention, cela peut être un nombre à virgule. Calculez la valeur du polynôme et affichez-la. Redemandez deux autres valeurs et affichez les résultats.
-
Utilisez la fonction input() pour lire au clavier.
-
Pensez à convertir la chaîne de caractères retournée en nombre à virgule.
-
Une boucle for peut vous éviter un copié-collé maladroit.
La correction de cet exercice est disponible en téléchargement depuis l’onglet Compléments. L’utilisateur entre un nombre n au clavier. Vous devez calculer la somme des n premiers entiers : 1+ … + n, et l’afficher :
-
Utilisez la fonction input() pour lire au clavier.
-
Pensez à convertir la chaîne de caractères retournée en nombre entier.
-
Utilisez une boucle for avec indice, son range dépend de la variable n.
-
Créez une variable pour additionner les différentes valeurs. Pensez à l’initialiser correctement.
-
Attention, un petit piège se cache sur la valeur de range, pensez à vérifier vos résultats.
La correction de cet exercice est disponible en téléchargement depuis l’onglet Compléments. Vous allez diviser successivement par 2 la valeur 1, ceci 50 fois. À chaque fois, affichez le résultat sous la forme d’un nombre ayant 50 chiffres après la virgule. Pour valider votre résultat, affichez au démarrage la chaîne : "XX0123456789023456789012345678901234567890123456789"....
Projets
Les projets sont des exercices longs. Pour éviter un énoncé complexe, nous prenons des exemples amusants de la vie courante que vous devriez déjà connaître. L’organisation du programme devient un peu plus difficile. Vous devrez peut-être utiliser des fonctions hors programme ou des astuces. Mais dans ce cas, toutes les informations vous seront données dans l’énoncé. L’objectif est d’arriver à un programme fonctionnel, amusant et de qualité.
La correction de ce projet est disponible en téléchargement depuis l’onglet Compléments. Le jeu du pendu consiste à trouver un mot en devinant les lettres qui le composent. Nous vous proposons de mettre en place une version simplifiée, mais relativement complète. Pour rendre le code plus simple, vous ne traiterez que des mots avec des lettres différentes. Cela permet d’éviter la gestion des doublons.
Voici vos objectifs :
-
Au démarrage du jeu, affichez : "Jeu du pendu !!".
-
Demandez au joueur d’entrer une lettre suivie d’un appui sur la touche [Entrée].
-
L’utilisateur doit faire six propositions de lettre, ni plus, ni moins.
-
Si la lettre n’est pas présente dans le mot, affichez "#˽# ... #˽#" avec autant de symboles # que de lettres à deviner.
-
Si la lettre est présente dans le mot, il faut indiquer sa position. Par exemple, s’il s’agit de la "X" à la troisième position en partant de la gauche pour un mot de six lettres, l’affichage sera "#˽#˽X˽#˽#˽#".
-
Une fois les six essais effectués, demandez au joueur de proposer un mot. Comparez la proposition du joueur avec le mot recherché. S’il a trouvé, écrivez "GAGNE", sinon "PERDU".
Voici quelques conseils :
-
Transformez le caractère en caractère majuscule pour que votre recherche fonctionne.
-
Si la lettre n’est pas trouvée, pour éviter une boucle for, vous pouvez utiliser une syntaxe permettant de répéter n fois une chaîne comme : "#˽" * n.
-
Si la lettre est trouvée, calculez le nombre de fois où la séquence "#˽" est présente à gauche et à droite de la lettre trouvée. Connaissant la longueur du mot et la position de la lettre, vous pouvez par un calcul trouver ces deux valeurs. Utilisez ensuite l’astuce du "#˽" * k pour répéter plusieurs fois l’écriture de la chaîne "# " sans utiliser de boucle for. Pour éviter un retour à la ligne suite à l’appel de la fonction print(), utilisez son paramètre optionnel : end="".
-
Nous vous conseillons de transformer la réponse de l’utilisateur en majuscules.
-
Utilisez l’opérateur == pour comparer deux chaînes.
Voici un exemple de déroulement de partie :
Jeu du pendu !!
Entrez une lettre suivie d'un appui sur la touche Entrée
A
# # # # A #
C
C # # # # #
L
# # # # # L
V
# # # V # #
T
# # # # # # ...