Apprendre A Coder Avec Python Session 5
Apprendre A Coder Avec Python Session 5
Thierry Massart
Jean Olgiati
Isabelle Poirier
Septembre 2021
Conditions d’utilisation du contenu du cours
CC-BY-SA : Sébastien Hoarau - Thierry Massart - Jean Olgiati - Isabelle Poirier
Attribution - Partage dans les Mêmes Conditions
Les contenus peuvent être partagés et adaptés, y compris dans un but commercial, sous réserve de créditer l’oeuvre originale et de
partager l’oeuvre modifiée dans les mêmes conditions.
Table des matières
Avant Propos I
CC BY-SA 3.0 - 2021 - Sébastien Hoarau - Thierry Massart - Jean Olgiati - Isabelle Poirier i
2.2.3 Tester l’arithmétique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
2.3 Python comme machine de traitement de texte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
2.3.1 Les expressions chaînes de caractères . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
2.3.2 À vous de tester les chaînes de caractères . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
2.4 Les variables pour changer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
2.4.1 Les variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
2.4.2 Code avec variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
2.5 PyCharm en mode script, entrées et sorties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
2.5.1 Manipuler des scripts avec PyCharm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
2.5.2 Python Tutor et les diagrammes d’état . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
2.5.3 Commentons notre programme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
2.5.4 Réalisation des exercices UpyLaB du module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
2.5.5 Exercice UpyLaB 2.1 - Parcours Vert, Bleu et Rouge . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
2.5.6 Exercice UpyLaB 2.2 - Parcours Vert, Bleu et Rouge . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
2.5.7 Exercice UpyLaB 2.3 - Parcours Vert, Bleu et Rouge . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
2.6 Quelques fonctions prédéfinies, les modules math et turtle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
2.6.1 Exemples d’utilisations de fonctions prédéfinies, et des modules math et turtle . . . . . . . . . . . . . . . 53
2.6.2 Quelques fonctions prédéfinies et fonctions turtle très utilisées . . . . . . . . . . . . . . . . . . . . . . . 56
2.6.3 Pavé hexagonale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
2.6.4 Exercice UpyLaB 2.4 - Non noté - Parcours Bleu et Rouge . . . . . . . . . . . . . . . . . . . . . . . . . 61
2.7 Pour terminer ce module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
2.7.1 Stockage des valeurs et caractères d’échappement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
2.7.2 Les opérateurs d’assignation et de mise à jour . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
2.7.3 On passe à la pratique autonome ! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
2.7.4 Exercice UpyLaB 2.5 - Parcours Vert, Bleu et Rouge . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
2.7.5 Exercice UpyLaB 2.6 - Parcours Vert, Bleu et Rouge . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
2.7.6 Exercice UpyLaB 2.7 - Parcours Bleu et Rouge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
2.8 Quiz de fin et bilan du module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
2.8.1 Quiz de fin de module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
ii CC BY-SA 3.0 - 2021 - Sébastien Hoarau - Thierry Massart - Jean Olgiati - Isabelle Poirier
3.4.5 Des programmes qui bouclent indéfiniment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
3.4.6 L’instruction for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
3.4.7 Syntaxe du for, carrés, étoiles et autres polygones réguliers . . . . . . . . . . . . . . . . . . . . . . . . . 102
3.4.8 Quiz sur while et for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
3.5 Code avec while et for dans la pratique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
3.5.1 La suite de Fibonacci . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
3.5.2 Un pavé hexagonal avec des for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
3.5.3 Mise en pratique autonome : exercices UpyLaB 3.9 et suivants . . . . . . . . . . . . . . . . . . . . . . . 108
3.5.4 Exercice UpyLaB 3.10 (parcours vert, bleu et rouge) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
3.5.5 Note sur la fonction print . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
3.5.6 Exercice UpyLaB 3.11 (Parcours Vert, Bleu et Rouge) . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
3.5.7 Exercice UpyLaB 3.12 (Parcours Bleu et Rouge) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
3.5.8 Exercice UpyLaB 3.13 (Parcours Bleu et Rouge) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
3.5.9 Exercice UpyLaB 3.14 (Parcours Rouge) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
3.5.10 Exercice UpyLaB 3.15 (Parcours Rouge) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
3.5.11 range(debut, fin, pas) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
3.5.12 Exercice UpyLaB 3.16 (Parcours Rouge) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
3.5.13 Exercice UpyLaB 3.17 (Parcours Rouge) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
3.5.14 Exercice UpyLaB 3.18 (Parcours Rouge) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
3.6 L’instruction pass et quiz de fin de module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
3.6.1 L’instruction pass . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
3.6.2 Quiz de fin de module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
3.7 Bilan du module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
3.7.1 Qu’avons-nous vu dans ce module ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
CC BY-SA 3.0 - 2021 - Sébastien Hoarau - Thierry Massart - Jean Olgiati - Isabelle Poirier iii
4.5.9 Exercice UpyLaB 4.8 (Parcours Bleu et Rouge) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
4.5.10 Exercice UpyLaB 4.9 (Parcours Bleu et Rouge) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172
4.5.11 Exercice UpyLaB 4.10 (Parcours Bleu et Rouge) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174
4.6 Bilan du module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
4.6.1 Qu’avons-nous vu dans ce module ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
iv CC BY-SA 3.0 - 2021 - Sébastien Hoarau - Thierry Massart - Jean Olgiati - Isabelle Poirier
5.8.4 Des exemples de manipulation de fichiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
5.8.5 Les traitements de fichiers avec UpyLaB 5.19 et suivants . . . . . . . . . . . . . . . . . . . . . . . . . . 236
5.8.6 Exercice UpyLaB 5.20 (Parcours Vert, Bleu et Rouge) . . . . . . . . . . . . . . . . . . . . . . . . . . . 237
5.8.7 Exercice UpyLaB 5.21 (Parcours Bleu et Rouge) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238
5.8.8 Exercice upylab 5.22 (parcours rouge) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
5.9 Manipulons les matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
5.9.1 Remarque importante sur l’initialisation des tableaux . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
5.9.2 À présent exerçons-nous sur les matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240
5.9.3 Passons à la mise en pratique sur les matrices avec les exercices UpyLaB 5.26 et suivants . . . . . . . . . 243
5.9.4 Exercice UpyLaB 5.24 (Parcours Vert, Bleu et Rouge) . . . . . . . . . . . . . . . . . . . . . . . . . . . 244
5.9.5 Exercice UpyLaB 5.25 (Parcours Bleu et Rouge) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245
5.9.6 Exercice UpyLaB 5.26 (Parcours Bleu et Rouge) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246
5.9.7 Exercice UpyLaB 5.27 (Parcours Rouge) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247
5.10 Bilan du module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
5.10.1 Qu’avons-nous vu dans ce module ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
CC BY-SA 3.0 - 2021 - Sébastien Hoarau - Thierry Massart - Jean Olgiati - Isabelle Poirier v
7 Votre projet 299
7.1 Quête dans le château au sommet du Python des Neiges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299
7.1.1 Information préliminaire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299
7.1.2 Présentation du projet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
7.1.3 En pratique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303
7.2 Détails des phases du projet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306
7.2.1 Niveau 1 : construction et affichage du plan du château . . . . . . . . . . . . . . . . . . . . . . . . . . . 306
7.2.2 Niveau 2 : gestion des déplacements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 308
7.2.3 Niveau 3 : collecte d’objets dans le labyrinthe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 310
7.2.4 Niveau 4 : Le jeu escape game complet avec questions-réponses . . . . . . . . . . . . . . . . . . . . . . 311
7.2.5 Remise et évaluation du projet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311
7.3 Phase d’évaluation par les pairs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314
7.3.1 Phase d’évaluation par les pairs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314
7.4 Phase d’auto-évaluation du projet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315
7.4.1 Phase d’auto-évaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315
8 Projet donné lors des trois premières sessions du MOOC Apprendre à coder avec Python 317
8.1 Le projet Vasarely . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317
8.1.1 Énoncé du projet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317
8.1.2 En pratique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319
8.1.3 Remise et évaluation du projet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324
8.1.4 Galerie des oeuvres produites par le projet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327
9 Annexes 329
Index 329
vi CC BY-SA 3.0 - 2021 - Sébastien Hoarau - Thierry Massart - Jean Olgiati - Isabelle Poirier
Avant Propos
Bienvenue dans la session 5 (2021-2022) de notre MOOC intitulé Apprendre à coder avec Python diffusé sur la plateforme FUN.
Cette version du cours est le fruit d’un travail important que nous avons réalisé depuis la première session diffusée en 2019.
Depuis la session 4 (2020-2021), nous avons apporté les améliorations ou ajouts suivants :
Contenu
Ce cours intègre désormais :
— un manuel comme support écrit pour accompagner le MOOC ;
— des sous-titres aux vidéos (dans la version en ligne), activables lors de la visualisation (attention : ne fonctionne pas avec le
navigateur Safari) ;
— une Foire Aux Questions (FAQ) pour vous permettre de trouver une réponse aux questions fréquemment posées ;
— des résumés des vidéos du cours ;
— des énoncés de notre exerciseur UpyLaB, mieux structurés avec des exemples de ce qui est demandé ;
— un choix des exercices UpyLaB encore mieux adapté au cours ;
Par ailleurs, cette session vous propose un projet (« Quête au Château du sommet du Piton Rocheux ») où il vous sera demandé de
construire et de jouer à votre jeu d’évasion (escape game) sur ordinateur.
Horaire de diffusion
Nous avons également aménagé l’horaire de diffusion pour vous permettre de suivre ce cours soit sur un semestre (septembre-
décembre ou janvier-mai), soit sur toute l’année scolaire.
Nous vous invitons à vous inscrire dès à présent à cette nouvelle session pour bénéficier de l’ensemble des ressources.
Bon travail et bon amusement
Isabelle - Sébastien - Thierry
Septembre 2021
CC BY-SA 3.0 - 2021 - Sébastien Hoarau - Thierry Massart - Jean Olgiati - Isabelle Poirier 1
Apprendre à coder avec Python, Version - Release 3.0
Note : Voir la vidéo de la section 1.1.2 : Bienvenue dans le MOOC Apprendre à Coder avec Python
CONTENU DE LA VIDÉO
La vidéo précédente présente brievement nos motivations pour vous apprendre à coder avec le langage de programmation Python,
l’approche proposée dans ce cours et les parcours proposés.
Tout ceci sera présenté plus en détails dans la suite de ce module de cours.
CC BY-SA 3.0 - 2021 - Sébastien Hoarau - Thierry Massart - Jean Olgiati - Isabelle Poirier 3
Apprendre à coder avec Python, Version - Release 3.0
Cette version du cours est le fruit d’un travail important que nous avons réalisé depuis la première session diffusée en 2019.
Contenu
Ce cours intègre désormais :
— un manuel comme support écrit pour accompagner le MOOC ;
— des sous-titres aux vidéos, activables lors de la visualisation (attention : ne fonctionne pas avec le navigateur Safari) ;
— une Foire Aux Questions (FAQ) pour vous permettre de trouver une réponse aux questions fréquemment posées ;
— des résumés des vidéos du cours ;
— des énoncés de notre exerciseur UpyLaB, mieux structurés avec des exemples de ce qui est demandé ;
— un choix des exercices UpyLaB encore mieux adapté au cours ;
Par ailleurs, cette session vous propose un projet (« Quête au Château du sommet du Piton Rocheux ») où il vous sera demandé de
construire et de jouer à votre jeu d’évasion (escape game) sur ordinateur.
Horaire de diffusion
Nous avons également aménagé l’horaire de diffusion pour vous permettre de suivre ce cours soit sur un semestre (septembre-
décembre ou janvier-mai), soit sur toute l’année scolaire.
Modules disponibles dès l’ouverture
— Le module 1 - Bienvenue dans l’environnement Python 3 présente tout d’abord les éléments importants de ce MOOC, à la
fois ce qui va être enseigné et comment vous allez l’apprendre. La seconde partie du module 1 vous demande d’installer
l’environnement de développement Python 3 sur votre ordinateur en expliquant les procédures à suivre : c’est une étape
essentielle à votre apprentissage.
— Le Module 2 - Python comme machine à calculer et à écrire va vous apprendre comment écrire votre premier programme
Python 3 complet.
— Le Module 3 - Les instructions : tous vos désirs sont des ordres introduit les instructions de contrôle de flux Python, qui vont
nous permettre d’écrire des codes bien plus sophistiqués.
— Le Module 4 - Les fonctions : créez les outils que vous voulez présente dans un premier temps des fonctions prédéfinies
utiles. Ensuite nous allons regarder comment définir et utiliser nos propres fonctions Python. Nous discutons aussi sur la
qualité d’un code, ce que nous appelons un code « propre ».
Bon travail et surtout bon amusement dans l’apprentissage de cette nouvelle matière !
Dans la suite du module nous présentons notre outil UpyLaB que vous utiliserez de façon intégrée dans ce MOOC pour réaliser de
nombreux exercices de codage.
UpyLaB est le fruit de nombreuses années de développements d’informaticiens et étudiants de l’Université Libre de Bruxelles. Une
bonne partie des développements et la coordination ont été réalisées de main de maître par notre informaticien, Arthur Lesuisse,
que nous remercions vivement pour cela !
Ce MOOC n’aurait pas vu le jour sans les membres de l’équipe ULB-Podcast qui nous ont accompagnés durant toutes les étapes,
de sa conception à sa diffusion :
— Ariane Bachelart : accompagnement pédagogique et technique FUN
— Guillaume Gabriel : production multimédia
— Jérôme Di Egidio : production audiovisuelle
— Nathalie François : conseils pédagogiques
— Sophie Poukens : accompagnement pédagogique
Nous voulons également remercier les membres de l’équipe de la Direction des Usages du Numérique de l’Université de la Réunion
(DUN) :
— Emmanuel Pons : production audiovisuelle
— Jean-François Février : production audiovisuelle
Merci également à Jean Olgiati qui a co-conçu le nouveau projet « Quête au Château au sommet du Piton Rocheux ».
Merci aussi aux « Bêta-testeurs » de la première heure qui nous ont conseillés dans la réalisation de ce MOOC ainsi qu’aux personnes
qui ont participé aux séances de confection du « teaser » : Ali Manzer, Anne-Françoise Biet, Arnaud Decostre, Ashley Yong Ching,
Fabrice Nativel, Françoise Bols, Ludovic De Wachter, Marco Bianchin, Nicolas Pettiaux, Pierre Evrard, Priscillia Hardas, Ronico
Billy, Vincenzo Sargenti, Yishen Yu.
Merci aussi aux participants des premières sessions de ce MOOC qui, par leurs commentaires, nous ont aidés à améliorer ce cours.
Merci à tous !
NOS MOTIVATIONS
Nos premières motivations pour donner ce cours sont de vous montrer que programmer, c’est créer, et de vous transmettre le bonheur
de cette activité.
Vous allez apprendre à programmer en utilisant le langage Python 3. Contrairement à d’autres matières comme l’apprentissage
d’une langue étrangère ou des mathématiques, il s’agit probablement de quelque chose de réellement neuf pour vous.
L’apprentissage peut être comparé à l’apprentissage de la marche chez un enfant :
— L’enfant qui apprend à marcher va d’abord jouer dans son parc ou son bac à sable ; cela lui permet d’apprendre des gestes et
de réaliser des choses utiles (ou non) pour cet apprentissage spécifique.
— Ensuite, quelqu’un va peut-être lui expliquer comment faire pour se lever, avancer, . . .
— Plus tard, il va être aidé pour commencer à faire ses premiers pas.
— Et enfin, il va marcher et ensuite se lever seul et s’entrainer dur pour s’améliorer.
Nous vous invitons à faire le même type de parcours ici pour votre apprentissage du codage avec Python.
Pour réussir, il faut rigueur et persévérance et vous devez répondre oui aux questions suivantes :
1) Pourrez-vous consacrer suffisamment de temps, en respectant les échéances, pour cet apprentissage incluant visionnage des
vidéos, lecture des explications, réponses aux quiz après mûres réflexions et codage des exercices demandés (entre 50 et 150
heures de travail) ?
2) Êtes-vous prêt à apprendre une matière fort différente de ce que vous avez appris jusqu’à présent ?
3) Êtes-vous conscient que la persévérance est une clé fondamentale pour apprendre ?
Et vous, pouvez-vous résumer vos motivations à suivre ce cours ? Écrivez dans les rectangles ci-dessous au maximum quatre mots
ou phrases courtes (un par rectangle) qui représentent le mieux vos motivations et cliquez sur “enregistrer”. Vous pourrez alors voir
ce que les autres apprenants ont répondu.
Ce cours en ligne, appelé aussi MOOC, est construit sur une base d’une dizaine de semaines de travail étalées sur 15 semaines.
MOOC est l’acronyme de « Massive Open Online Course », prononcé « mouc », c’est-à-dire un cours ouvert, gratuit et massif en
ligne.
Apprendre à programmer peut être fortement chronophage : le cours complet demande donc un rythme assez soutenu. Si vous ne
pouvez ou ne voulez pas consacrer autant de temps chaque semaine à cet apprentissage, nous vous proposons un aménagement que
vous pourrez éventuellement choisir de suivre n’importe quand tout au long du cours.
A priori le cours demande environ 12 heures de travail chaque semaine sur 10 à 15 semaines. C’est une évaluation moyenne.
En réalité le temps que vous mettrez dépendra essentiellement de votre facilité à assimiler la matière et à réaliser les exercices,
principalement de notre exerciseur UpyLaB.
De toute manière, si vous ne pouvez réaliser le travail complet, nous vous proposons deux parcours alternatifs.
Le principe est simple : tous les contenus théoriques, les exercices solutionnés et les quiz sont communs à tous les parcours. Par
contre chaque exercice proposé par notre exerciseur UpyLaB a une ou plusieurs couleurs.
Un exercice dans :
— le parcours vert est un exercice de base (dans ce cas il sera aussi inclus dans les autres parcours) ;
— le parcours bleu est un exercice plus difficile (dans ce cas il sera aussi inclus dans le parcours rouge) ;
— le parcours rouge est un exercice jugé parmi les plus difficiles du cours, à faire si vous voulez suivre le parcours complet.
Libre à vous de moduler les exercices UpyLaB que vous réalisez, sachant que :
— le parcours vert propose un travail moyen d’environ 6 heures par semaine sur 15 semaines.
Dans ce cas, a priori le projet final n’est pas inclus dans le cours.
Si vous suivez précisément le parcours vert, cela vous permettra d’avoir au maximum 61% des points. La réussite de la
majorité des quiz et des exercices du parcours vert devrait donc vous permettre d’obtenir la note requise soit 50% des points ;
— le parcours bleu propose un travail moyen d’environ 9 heures par semaine sur 15 semaines y compris un projet final ainsi
qu’un travail d” « évaluation par les pairs » du projet de trois autres apprenants, et une auto-évaluation de votre projet.
Si vous suivez précisément le parcours bleu, cela vous permettra d’avoir au maximum 89% des points
— le parcours rouge comprend l’ensemble des travaux et exercices, et propose un travail moyen d’environ 12 heures par semaine
sur 15 semaines, y compris le projet final ainsi que l’évaluation du projet de trois autres apprenants et une auto-évaluation
de votre propre projet.
Notez que la notion de parcours n’est ici qu’à titre informatif. Libre à vous de faire des exercices UpyLaB en dehors de votre
parcours (par exemple des exercices du parcours bleu ou de réaliser le projet même si vous avez choisi le parcours vert).
Note : Veillez à ne pas répondre aux quiz trop rapidement, puisque nombre d’entre eux ne permettent qu’un seul essai avant
de noter votre réponse. Si votre réponse est fausse vous aurez alors définitivement perdu les points associés !
Enfin, si vous ne pouvez consacrer six heures par semaine sur 15 semaines (3 heures par semaines sur l’année scolaire), ou simple-
ment si voulez suivre le cours et faire les exercices à un autre rythme, vous pouvez choisir de réaliser le parcours de votre choix à
votre allure, sachant que vous pouvez obtenir une attestation FUN si vous avez obtenu 50% des points à la fin de ce cours, que le
matériel et les exercices restent disponibles après la fin de la session, mais que les forums ne seront animés que pendant la période
d’ouverture de la session et qu’il ne vous sera pas possible de soumettre le projet sur la plateforme ni d’obtenir l’attestation finale
de succès après la clôture du MOOC.
— Soyez régulier dans votre apprentissage, par exemple en y consacrant une ou deux heures chaque jour.
— Si vous êtes bloqué dans la réalisation d’un exercice, n’hésitez pas à bien relire l’énoncé précis, à revoir encore et encore la
matière déjà vue pour comprendre ce qui vous a échappé.
— La FAQ (Foire Aux Questions), organisée sous forme de questions d’apprenants et de réponses associées, est également une
source d’information précieuse.
— Comme disait Nicolas Boileau en 1674 dans l’Art Poétique :
— Ne vous découragez pas et si rien ne va, adressez-vous aux forums pour chercher de l’aide.
Nous allons passer du temps tous ensemble, pourquoi ne pas venir vous présenter dans le forum afin de faire connaissance ?
Venez nous raconter ce que vous faites dans la vie et pourquoi il est important pour vous de suivre ce cours.
Vous avez déjà utilisé le langage Python ou vous vous êtes déjà essayé à un langage informatique ? Partagez votre expérience avec
la communauté.
ATTENTION !
Avant d’utiliser les forums, nous vous encourageons à prendre connaissance des règles et bonnes pratiques des forums via le lien
[Link] et à les suivre scrupuleu-
sement.
En particulier, ne mettez jamais d’informations personnelles comme votre nom, email ou n° de téléphone. Votre pseudo sera suffisant
pour vous identifier.
Pour participer à la discussion :
1. Cliquez sur « Afficher la discussion » pour voir les messages déjà postés dans ce fil de discussion ;
2. Si un des fils traite du sujet dont vous voulez parler, cliquez sur « déplier la discussion » en dessous du premier message
posté ;
3. Faites défiler la page pour voir les autres messages postés et accéder à la boite de rédaction ;
4. Éventuellement cliquez sur « Nouveau message » si vous désirez créer un nouveau fil de discussion sur un nouveau sujet,
choisissez s’il s’agit d’une question ou d’une discussion et un titre pertinent,
5. Enfin rédigez votre message à l’endroit adéquat (nouveau message ou commentaire à un post existant ou dans la fenêtre
étiquetée « Post a response ») et postez-le en cliquant sur « Soumettre » ou sur « Ajouter un message » pour ajouter un
message au fil de discussion choisi ou nouvellement créé.
Note : Voir le forum Faisons connaissance dans la section 1.1.3 du cours en ligne
Dans cette section, nous donnons des informations générales sur notre MOOC (objectifs, calendrier, modalités d’évaluation), sur la
manière d’utiliser la plateforme d’apprentissage FUN ainsi que les modalités de communication entre apprenants et l’équipe.
La section est terminée par une vidéo qui fait une rapide présentation de la suite de ce présent module.
Cette section reprend ou donne accès aux informations générales du cours y compris l’horaire de diffusion des différents modules
et les échéances principales.
Fiche du cours
Elle donne la plupart des informations générales sur le cours, et est accessible via le lien que vous pouvez trouver ici (https:
//[Link]/courses/course-v1:ulb+44013+session05/about)
Attestation de suivi avec succès
Tout apprenant atteignant un taux de réussite de 50% des points recevra une attestation de suivi avec succès produite et envoyée par
la plateforme FUN.
Calendrier et échéances principales
Le calendrier et échéancier du MOOC est donné dans l’onglet Calendrier.
Vous pouvez également visualiser le calendrier en cliquant sur le lien ici ([Link]
session05/pdfbook/1/).
En particulier, vous devez impérativement respecter les trois échéances suivantes pour valider votre apprentissage :
— réalisation des quiz et exercices UpyLaB des modules 1 à 6 avant l’échéance du 22/12/2021 pour la première génération des
attestations de suivi, ou pour l’échéance finale du 18/05/2022.
Si vous décidez de faire le projet :
Deux vagues d’évaluation vous sont proposées.
— remise du projet proposé avant le 17/11/2021 pour la première vague ou avant le 20/04/2022 pour la seconde vague ;
— évaluation de projets de pairs avant le 1/12/2021 pour la première vague ou avant le 4/05/2022 pour la seconde vague ;
— auto-évaluation de votre projet amendé avant l’échéance du 22/12/2021 pour la première vague ou pour l’échéance finale du
18/05/2022.
Notez que les procédures de remise du projet et d’évaluations sont dans le module « Projet ».
Le module projet correspond au module 7 de ce support de cours.
PARCOURS
Comme expliqué précédemment, trois parcours vous sont proposés, le parcours vert, le parcours bleu ou le parcours rouge. Dans
tous les cas, pour obtenir l’attestation de réussite, 50% des points suffisent. Évidemment, même si ce pourcentage ne sera pas noté
sur votre attestation, un meilleur taux de réussite signifiera que vous avez une connaissance plus profonde de la matière.
Ainsi, la profondeur de vos connaissances sera corrélée avec votre choix de suivre le parcours vert, le parcours bleu ou le parcours
rouge.
Les parcours vert, bleu ou rouge ne sont que des indications sur la difficulté de chaque exercice proposé. Libre à vous de panacher
en faisant les exercices de votre choix.
NOTATION
Le cours comporte des évaluations de votre apprentissage tout au long des différents modules, soit sous forme de quiz soit sous
forme d’exercices de codage. Aucune évaluation finale sous forme d’un examen ou quiz de fin de cours n’est donc proposée.
L’évaluation tout au long de l’apprentissage s’effectue par un système classique de points, et votre note sera calculée sur un total de
300 points, répartis en :
— 102 points sur les quiz qui déterminent si vous avez assimilé la matière à raison de 1 point par réponse correcte. Attention
vous n’avez généralement qu’un seul essai pour obtenir la bonne réponse ;
— 150 points sur les codes UpyLaB à fournir qui valident votre autonomie dans le codage avec la matière vue jusque-là, à
raison généralement de 2 points par exercice UpyLaB noté qui passe correctement la vérification ;
— 48 points sur le projet associé au cours ; les points sont répartis en 24 points provenant des évaluations par vos pairs et 24
points provenant d’une auto évaluation du projet éventuellement amendé suite aux remarques de vos pairs.
Notez que quelques exercices UpyLaB ne sont pas notés même s’ils participent à votre apprentissage.
REMARQUES IMPORTANTES
1) Contrairement aux quiz, les exercices UpyLaB peuvent être testés autant de fois que vous le désirez.
2) Pour enregistrer votre réponse dans un exercice UpyLaB vous devez cliquer sur le bouton Valider, et cela, même si vous
savez que votre code n’est pas correct ; ce n’est pas un souci puisque le nombre de fois que vous vérifiez chaque exercice
UpyLaB n’est pas limité.
3) Attention, si, pour un exercice UpyLaB, la dernière vérification est négative, la plateforme ne retient pas si une vérification
précédente avait été positive. En clair, la plateforme ne vous accorde les points que si la dernière vérification de cet exercice
est positive.
4) Si vous décidez de ne pas faire le projet, pour obtenir votre attestation de réussite, vous devrez obtenir 150 points sur les 252
points qui restent en jeu. Libre à vous de faire le parcours vert, mais de quand même décider de faire le projet pour obtenir
des points en plus grâce à cela.
5) De même ne pas faire certains exercices UpyLaB signifie que sciemment, vous décidez de ne pas avoir de points pour ces
exercices. Vous pourrez toujours, avant l’échéance finale du cours, changer d’avis pour améliorer votre score.
Tout apprenant atteignant un taux de réussite de 50% des points avant l’échéance recevra une attestation de suivi avec succès
produite et envoyée par la plateforme FUN.
Un MOOC contient de nombreuses ressources vidéos, textuelles, des exercices à soumettre et à faire viser par la plateforme mais
aussi des forums de discussions, des tableaux montrant votre progression, etc.
Il est donc important de bien maîtriser la plateforme FUN pour être à l’aise dans ces aspects pratiques. Pour les débutants sur FUN,
un mini cours de démonstration de la plateforme FUN est proposé pour vous y familiariser.
Note : Voir le cours en ligne section 1.2.4 pour accéder au mini cours d’utilisation de la plateforme FUN.
Si nous parcourons notre MOOC « Apprendre à coder avec Python », les onglets suivants sont présents :
Cours
Il vous donne accès aux 7 modules du cours dont le module « Projet », au fur et à mesure de leur mise à disposition.
Infos du cours
L’équipe pédagogique y communique des nouvelles et informations importantes comme l’ouverture d’un module, un rappel des
échéances, ou encore des éventuelles informations sur l’état d’avancement du cours.
Discussions
Vous y trouverez les forums ou espaces de discussion du cours :
— Forum pour faire connaissance en début de cours (module 1) ;
— Forums généraux de chaque module : pour répondre aux questions sur la matière du module ou aux soucis d’accès aux pages
... ;
— Forums des exercices de codage UpyLaB : notre outil que nous présentons dans une section suivante et qui vous permettra
de vous exercer ; ces forums sont à utiliser si vous avez des soucis avec un exercice de codage UpyLaB que vous n’arrivez
pas à résoudre malgré la consultation du cours et de la FAQ (Foire Aux Questions) sur le sujet ;
— Forum sur le projet et son évaluation (réalisée au module « Projet ») ;
Les échanges entre les apprenants et l’équipe pédagogique se font majoritairement via ces forums.
Wiki
Il ne sera utilisé que pour déposer les oeuvres d’art que vous et les autres apprenants aurez produites grâce au programme réalisé en
projet.
Progression
Il contient deux parties :
1) D’abord un tableau récapitulatif des notes obtenues jusqu’à présent, comme le montre la figure « Tableau récapitulatif de la
progression » :
CONTENU DE LA VIDÉO
La vidéo précédente présente la suite du module 1 : l’installation de l’interpréteur Python 3 ainsi que de l’environnement de déve-
loppement PyCharm qui seront utilisés tout au long de ce cours.
Remarque :
Notez que pour les sessions précédentes de ce MOOC, comme présenté dans la vidéo qui suit, nous avions conseillé d’utiliser l’en-
vironnement PyCharm Community, qui permet de réaliser beaucoup d’aides aux programmeurs et est gratuit, même s’il a été conçu
par une société privée (Jetbrains). A partir de cette session, nous vous proposons d’installer Thonny : un environnement de dévelop-
pement plus simple mais qui fait parfaitement l’affaire. En effet, PyCharm est trop complexe pour un débutant en programmation
par rapport aux bénéfices qu’il va en tirer.
Dans les vidéos que nous présentons, c’est l’environnement PyCharm qui est utilisé ; si vous utilisez Thonny, la correspondance
entre PyCharm et Thonny ne devrait pas vous poser de problèmes.
La méthode la plus simple pour installer Thonny consiste à se rendre sur le site de l’application [Link] et à télécharger
la dernière version. L’installation se fait par simple clic, comme la plupart des applications.
Le principal avantage de cet IDE est qu’il embarque aussi un interprète Python. Cela signifie que vous n’avez rien d’autre à installer ;
ce qui est particulièrement intéressant pour les utilisateurs du système Windows qui ne possède pas forcément d’interprète Python
installé par défaut (contrairement aux systèmes MacOS et Linux).
Si vous avez réussi à installer Thonny et à le lancer, vous pouvez passer directement à la section suivante montrant l’utilisa-
tion de l’IDE.
Pour les autres, et notamment ceux ou celles qui travaillent avec les systèmes MacOs ou Linux, voici une autre méthode d’installation
et de lancement de cette application.
Vous avez normalement Python déjà installé sur vos machines. Pour vous en rendre compte :
— Recherchez sur votre ordinateur l’application Terminal puis exécutez-la. Vous devriez avoir l’ouverture d’une fenêtre très
basique (avec des noms différents pour la machine et l’utilisateur bien sûr) :
— Une fois lancé, l’interprète Python devrait s’afficher (vous le reconnaissez au triple symbole > ) :
— La première ligne vous renseigne sur la version de votre interprète (ici 3.7.0). Si cette version est supérieure ou égale à
3.4 alors l’utilitaire pip est installé. Vous pouvez quitter votre interprète Python3 (un simple CTRL-Z). Assurez-vous d’être
connecté à internet puis exécutez la commande : pip3 install thonny (ou pip install thonny si cela ne fonctionne pas). Pour
lancer l’IDE il suffit alors de taper la commande : thonny
Vous avez installé Thonny sur votre ordinateur. Lancez-le, vous devriez avoir une fenêtre similaire à :
Dès que vous avez cliquez sur le bouton Enregistrer, vous naviguez dans votre système de fichier de façon classique
pour l’enregistrement d’un document (en créant éventuellement un nouveau dossier).
— Pour exécuter le code il suffit de cliquer sur la flèche verte :
Ici l’exécution ne produit aucune trace puisque notre script ne comporte que la définition d’une fonction (vous verrez
en détail ces notions, ne vous inquiétez pas). Toutefois, l’indication %Run [Link] dans la partie interprète nous dit
que le code a bien été exécuté :
Les quelques exemples présentés couvrent l’utilisation de base de Thonny, utilisation suffisante dans le cadre du MOOC. Pour une
utilisation avancée, notamment du déboggueur, nous vous invitons à consulter la documentation officielle : [Link]
1.3.3 Si je veux quand même installer PyCharm plutôt que Thonny sur mon ordinateur Win-
dows
Ouvrez un navigateur Web et allez sur le site officiel de Python. Cliquez sur le menu Download -> Python3.x.x (Python 3.6.3 ou
ultérieur). Si le site ne propose pas spontanément la bonne version, vous devez sélectionner celle qui convient au système de votre
ordinateur. L’interpréteur Python 3 s’installe en cliquant sur « exécuter » du programme d’installation.
La vidéo suivante montre tout ceci plus en détails.
Note : Voir la première vidéo de la section 1.3.2 du cours en ligne : Installation de Python 3 sur un ordinateur Windows
INSTALLER PYCHARM
Note : Voir la seconde vidéo de la section 1.3.2 : Installation de l’environnement PyCharm sur un ordinateur Windows
1.3.4 Si je veux quand même installer PyCharm plutôt que Thonny sur mon ordinateur MacOs
Ouvrez un navigateur Web et allez sur le site officiel de Python. Cliquez sur le menu Download -> Python3.x.x (Python 3.6.3 ou
ultérieur). Si le site ne propose pas spontanément la bonne version, vous devez sélectionner celle qui convient au système de votre
ordinateur. L’interpréteur Python 3 s’installe en cliquant sur « exécuter » du programme d’installation.
La vidéo suivante montre tout ceci plus en détails.
Note : Voir la première vidéo de la section 1.3.3 : Installation de Python 3 sur un ordinateur MacOS
INSTALLER PYCHARM
Note : Voir la seconde vidéo de la section 1.3.3 : Installation de PyCharm sur un ordinateur MacOS
1.3.5 Si je veux quand même installer PyCharm plutôt que Thonny sur mon ordinateur
Ubuntu ou Linux
Nous allons procéder à l’installation qui vous permettra d’avoir l’interpréteur Python 3 et l’environnement PyCharm. Cette instal-
lation est décrite pour la distribution 16.04 du système d’exploitation Ubuntu ; une installation similaire peut être réalisée avec un
ordinateur fonctionnant avec un autre système Linux.
Python 3 est déjà installé dans cette distribution, excepté le module turtle qui sera utilisé lors du cours. Pour ajouter ce module
utilisez la commande :
sudo apt-get install python3-tk
Par contre PyCharm n’est pas installé.
La procédure est disponible via le site [Link] et une recherche sur le mot clé PyCharm.
Ouvrez un terminal (par exemple via Ctrl+Alt+T ou en cherchant et lançant l’application). Dans le terminal exécutez la commande :
sudo snap install pycharm-community --classic
sudo demande le mot de passe, que vous devez introduire terminé par la touche Enter. Normalement l’installation s’effectue.
La vidéo suivante montre la procédure d’installation et de mise en route de PyCharm.
Note : Voir la vidéo de la section 1.3.4 : Installation de PyCharm sur un ordinateur Linux
Soit Python 3 et IDLE ont été installés sur votre ordinateur mais ce dernier n’a pas la configuration minimale pour l’installation de
PyCharm : dans ce cas,
— soit installez Thonny : un éditeur simple mais parfaitement adapté à ce cours
— soit rabattez-vous sur l’IDE plus simple IDLE (fourni avec python3, mais pas toujours très stable)
— soit utilisez un éditeur simple pour écrire vos scripts et ensuite exécutez-les avec la commande qui invoque l’interpréteur
(python3 sur linux ou macOs ou py sur windows) ;
— ou encore exécutez vos codes via le site trinket (voir plus bas).
Soit vous n’avez pas réussi non plus à installer Python 3. Dans ce cas exécutez vos codes via le site Trinket (voir ci-dessous).
Si la configuration de votre ordinateur est a priori suffisante : essayez de voir si le sujet existe dans la FAQ ou sinon mettez à profit
l’entraide sur le forum du module, en décrivant précisément le souci et en demandant aux autres inscrits de vous aider. Si malgré
tout, cela ne fonctionne pas, utilisez IDLE ou Trinket.
Notre cours en ligne est aussi un endroit (virtuel) où l’entraide est la règle d’or. Le forum du module, en fin de module, permet
de mettre en contact les apprenants (voir règles de bonnes pratiques des forums via le lien [Link]
44013+session05+type@asset+block@[Link]).
En particulier dans l’activité précédente :
— Si vous avez rencontré des soucis dans l’installation de l’environnement Python, décrivez le plus clairement possible le
problème et précisez surtout le système d’exploitation qu’utilise votre ordinateur (exemple : Windows 10 version 1703 ou
MacOS 10.12.4. . . ) : notre équipe ou d’autres apprenants qui ont la solution pourront probablement vous aider.
— Si vous avez réussi l’installation après avoir résolu quelques soucis, merci de partager votre expérience en détaillant le
système d’exploitation utilisé par votre ordinateur, le souci rencontré et sa résolution.
— Si vous avez la solution à un problème évoqué dans le forum, aider ceux qui l’évoquent en leur fournissant une réponse leur
sera d’un grand secours et fera avancer la communauté formée par l’ensemble des participants de notre cours en ligne.
Trinket permet d’exécuter du code Python sur une plateforme distante, c’est-à-dire sans que l’interpréteur Python ou un IDE local
soit installé sur son ordinateur.
Trinket est une bonne alternative pour apprendre Python 3 même si vous n’aurez pas la flexibilité offerte par un environnement
complet comme fourni par PyCharm.
Il suffit de se connecter à l’adresse [Link] et de créer un compte en cliquant sur l’onglet Sign up et en remplissant le
formulaire (votre nom, un nom d’utilisateur, votre adresse email et un mot de passe).
Une fois votre compte créé, vous pouvez vous connecter et trouver l’interpréteur Python 3 par exemple en cliquant sur le bouton
new trinket -> Python 3.
Vous pouvez dès lors taper votre code dans la fenêtre [Link] : la première ligne du code doit toujours être la suivante :
#!/bin/python3
qui indique à Trinket que la suite est du Python 3 (avec la convention Unix).
Par exemple :
#!/bin/python3
print('Hello World')
et ensuite vous pouvez demander l’exécution du code en cliquant sur le triangle au dessus de la fenêtre [Link]
L’environnement de développement PyCharm est d’une grande aide aux codeurs. En particulier, il vérifie si ce que nous encodons
semble être du code Python cohérent. Il nous mentionne également si nous utilisons dans nos explications (nous verrons qu’elles
s’appellent commentaires) des mots corrects. Pour cela PyCharm utilise un ou des dictionnaires.
Pour nous aider, nous proposons d’installer le dictionnaire des mots français (y compris, nous verrons pourquoi, les mots dont les
accents ont été supprimés). Avant de procéder à l’installation elle-même, nous devons télécharger ces deux dictionnaires.
— Après avoir ouvert PyCharm, cliquez sur le menu File ensuite Settings (ou PyCharm ensuite Preferences suivant
le système que vous utilisez (Windows, MacOS, . . . ) (voir figure « Installation dictionnaire étape 1 ») ;
— cliquez sur le petit triangle devant l’intitulé Editor pour ouvrir ce sous-menu (voir figure « Installation dictionnaire étape
2 ») ;
— dans la sous-fenêtre Custom Dictionaries cliquez sur le bouton + (voir figure « Installation dictionnaire étape 4 ») ;
— et trouvez et sélectionnez le dictionnaire à ajouter en cliquant sur open ;
— le dictionnaire s’ajoute à la liste des dictionnaires (voyez les deux nouvelles coches) (voir figure « Installation dictionnaire
étape 5 ») :
UTILISER PYCHARM
Vous avez installé PyCharm. Lancez-le et créez un nouveau projet. Voyons comment créer et exécuter un script.
Un projet peut contenir plusieurs scripts bien sûr. Soit qui sont liés (c’est le cas dans les gros projets réels) soit qui sont indépendants
mais appartiennent à une même famille. . . C’est le cas par exemple si je décide de faire un projet par Module de mon MOOC :
je mettrai dans le projet Module_1 tous mes exercices du Module 1, etc. On peut aussi faire un gros projet MOOC_Python et y
mettre tous ses scripts sans distinction de module.
Cette organisation est bien sûr question de goût, d’habitude de travail et donc propre à chacun.
Lorsque votre projet est créé, pour y ajouter un nouveau script vous pouvez utiliser un clic droit sur le nom du projet, dans la colonne
de gauche, et faire New > Python File. Vous donnez un nom à ce script qui vient se rajouter aux autres. Dans la colonne de
gauche vous avez l’ensemble des scripts. Ainsi, les deux captures suivantes montrent comment j’ai créé un nouveau script nommé
test_2.py (voir les deux figures « Création d’un nouveau script dans PyCharm »).
n’apparaît pas dans mon Projet (qu’on voit à gauche). Mais si je fais apparaître le menu contextuel en cliquant-droit sur le nom
scratch_2.py, je vois que j’ai un Run scratch_2 et je peux donc l’exécuter (voir figure « Exécution d’un script dans un
fichier scratch dans PyCharm »).
UPYLAB
Dans ce cours, en plus de l’interpréteur Python 3 et de l’environnement de développement PyCharm, nous utilisons deux « outils » :
UpyLaB et Python Tutor. Présentons d’abord UpyLaB.
UpyLaB est notre plateforme d’apprentissage en ligne. Elle propose des exercices de codage et demande aux étudiants de produire
le code Python correspondant ; ensuite UpyLaB, qui est exécuté sur un serveur extérieur à la plateforme FUN, teste si la solution
proposée est correcte. Nous avons intégré l’utilisation d’UpyLaB au cours en ligne, comme le montre le premier exercice UpyLaB
proposé à la page suivante.
MODE D’EMPLOI
L’exercice UpyLaB 1.1 ci-après vous permet de tester l’utilisation d’UpyLaB dans le cours.
Le principe consiste à lire l’énoncé de l’exercice concerné puis à résoudre le problème votre environnement de développement
(PyCharm ou Thonny par exemple). Une fois que vous vous êtes assuré que votre script répond aux exigences de l’énoncé, il faut
le recopier dans la partie de fenêtre UpyLaB servant à cet effet (mini-fenêtre vide au départ, sinon qui contient votre dernière
proposition de solution) pour le soumettre à évaluation en cliquant sur le bouton « Valider ».
Quand l’utilisateur a cliqué sur le bouton « Valider », UpyLaB va demander à l’interpréteur Python 3 d’exécuter le code fourni. Il
va ensuite comparer le résultat obtenu avec ce qui est attendu et le valider si les deux coïncident.
UpyLaB effectue un ou plusieurs tests selon les exercices, et ensuite, en fonction des résultats de ces tests, vous indique si le code
soumis lui semble correct ou non par rapport à ce qui vous est demandé.
Comme pour l’installation de Python 3, en cas de besoin, nous vous proposons d’utiliser la FAQ et si vos soucis ne sont pas résolus,
le forum UpyLaB du présent module afin de vous mettre en contact avec les autres apprenants et l’animateur des forum.
En particulier, si vous rencontrez des soucis pour réaliser l’exercice 1.1 d’UpyLaB, décrivez le plus clairement possible le problème :
notre équipe ou d’autres apprenants plus expérimentés pourront probablement vous aider.
Les seuls buts de cet exercice sont de vérifier que vous avez accès à notre exerciseur UpyLaB et de vous donner un premier contact
avec cet outil.
Écrire un programme qui affiche « Bonjour UpyLaB ! » grâce à l’instruction :
Veillez à ne pas ajouter d’espace au début de la ligne et à parfaitement respecter les espaces, minuscules et les majuscules (ici
pourquoi ne pas simplement faire une copier/coller de l’instruction dans la fenêtre UpyLaB)
Pour tous les exercices UpyLaB, vous devez écrire le code Python qui solutionne le problème (c’est-à-dire votre programme
Python) dans la sous-fenêtre intitulée « Entrez votre solution ».
Exemple
Bonjour UpyLaB !
Note : en cas de besoin, la section PROCÉDURE POUR UTILISER UPYLAB ci-dessous peut solutionner vos problèmes ou répondre
à plusieurs de vos questions.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Vous obtenez une erreur de syntaxe ? : Vérifiez que vous avez bien copié l’instruction demandée, sans ajouter d’espace
devant, et sans oublier parenthèses ou guillemets fermants.
— Pas d’erreur de syntaxe, mais UpyLaB refuse de valider votre code ? : L’affichage doit être exactement identique à celui
attendu. Veillez en particulier à respecter majuscules / minuscules, à ne pas ajouter ou ôter des espaces (en particulier à la
fin de la phrase), à ne pas oublier la ponctuation.
— Un conseil pour avoir un message identique est de le copier depuis l’énoncé pour le coller dans votre code. Ici, vous pouvez
même copier toute l’instruction :
Comme expliqué, chaque fenêtre UpyLaB donne un exercice à résoudre sous forme de code Python. Une procédure d’identification
est mise en place entre les pages FUN et UpyLaB. Voici la procédure précise qui inclut une procédure pour rafraîchir la page web si
un certain délai est passé après cette identification.
Procédure :
1) Après avoir développé dans votre IDE (PyCharm ou Thonny par exemple) le code demandé,
2) copiez ce code pour le coller dans la sous-fenêtre UpyLaB correspondante ;
3) cliquez sur le bouton « Valider ».
4) Si le code passe les tests, félicitations vous obtenez les points correspondants.
5) Si les tests ne sont pas concluants, vous devez corriger votre code et recommencer la procédure.
6) Si par contre un message d’erreur apparaît (Erreur serveur : session expirée ou non-trouvée. Veuillez rafraîchir la page dans
le navigateur),
— cliquez sur le bouton Rafraîchir la page si demandé par UpyLaB avant de vérifier à
nouveau
— et ensuite cliquez à nouveau sur le bouton Valider
— et reprenez la procédure au point 4.
La fenêtre UpyLaB reste bloquée sur Connexion en cours . . .
Pour certains navigateurs Web et certaines configurations, des problèmes d’accès à notre outil UpyLaB peuvent survenir. Typique-
ment, la fenêtre reste bloquée avec un message Connexion en cours ...
Si cela se produit, cliquez simplement sur le bouton Rafraîchir la page si demandé par UpyLaB avant de
vérifier à nouveau situé en dessous de l’exercice (même si ce n’est pas demandé explicitement :-) ).
Si le souci perdure, une des causes les plus courantes est l’utilisation de code anti « pop-up » ou anti-mouchard (en particulier avec
Firefox). Si c’est le cas, il est possible que vous deviez autoriser l’accès à [Link] (l’adresse d’accès à notre outil
UpyLaB).
Donc si une telle erreur se produit, allez voir dans la FAQ (Foire Aux Questions) (onglet FAQ) ou cliquez sur l’onglet Discussion
et trouvez le fil de discussion Problèmes d'accès à UpyLaB où un résumé des soucis constatés et des solutions précises
proposées y a été déposé.
Un point essentiel à fixer pour bien apprendre lors de ce cours est la façon de réaliser les exercices UpyLaB. Pour chaque exercice
UpyLaB, l’énoncé est fourni.
UpyLaB n’est pas un environnement de développement. Il permet juste de tester si votre code lui semble correct.
Ainsi, après avoir bien compris l’énoncé de l’exercice, il est important de développer une solution en utilisant l’IDE PyCharm (ou si
PyCharm n’est pas disponible, IDLE ou Trinket) ou, pour voir de façon détaillée comment votre code s’exécute, l’outil Python Tutor
que nous présentons à la section suivante. Ce n’est que quand votre solution sera complète et que vous l’aurez validée en testant
le code que vous pourrez copier et coller ce code dans la fenêtre UpyLaB de l’exercice pour lancer la validation. Tester son code
signifie exécuter le programme plusieurs fois et, si possible, sur des exemples différents, pour être convaincu qu’il donne toujours
une réponse correcte.
Si UpyLaB ne le valide pas - j’ai par exemple mis l’instruction :
print("Bonsoir UpyLaB !")
ou même
print("Bonjour UpyLaB ! ")
avec une espace en trop après le point d’exclamation,
à la place de :
print("Bonjour UpyLaB !")
vous devez le corriger avant de soumettre une solution modifiée.
Attention : Le nombre de vérifications que vous pouvez faire avec UpyLaB n’est pas limité. Malgré tout, il est préférable de
réussir l’exercice avec un nombre de clics « Valider » le plus petit possible.
Nous insistons sur le fait qu’UpyLaB est un exerciseur avec un environnement de tests et non un environnement de développement.
Prenez donc l’habitude de développer chacun de vos codes dans un environnement de développement comme PyCharm, et ensuite,
quand vous le jugez correct et complet, de faire un copier-coller dans la fenêtre UpyLaB qui doit recevoir le code qui solutionne le
problème, pour ensuite cliquer sur le bouton « Valider » afin de réaliser les tests.
PYTHON TUTOR
Python Tutor est un outil en ligne créé et maintenu par Philip Guo ([Link] de l’Université de San Diego. Comme
tout ce que nous utilisons pour ce cours, son utilisation est totalement libre et gratuite.
Python Tutor permet d’exécuter pas à pas des petits scripts Python en visualisant l’effet de chaque instruction Python exécutée,
comme le montre le petit exemple ci-dessous. Dans notre cours, nous utiliserons cet outil de façon intégrée à nos pages.
Exemple Python Tutor du code Python qui affiche les trois lignes suivantes avant de se terminer
Hello World
Bonjour le Monde !
J'apprends Python 3
Python Tutor va nous permettre de détailler, instruction par instruction, comment Python fonctionne en cliquant sur les boutons
« Next » (et « Prev » pour revenir en arrière) ou en actionnant le curseur.
N’hésitez pas à animer l’exemple ci-dessous en cliquant sur ces boutons et curseur !
Exemple Python Tutor intégré
print('Hello World')
print('Bonjour le Monde !')
print("J'apprends Python 3")
Note : Voir animation du code avec Python Tutor dans le cours en ligne
DOCUMENTATION OFFICIELLE
Dans le cadre de ce cours, vous n’aurez normalement pas besoin de consulter la documentation « officielle » Python. En effet la
documentation officielle d’un langage de programmation est souvent un peu rédhibitoire pour des débutants. Malheureusement,
parfois, c’est le seul endroit où l’on trouve ce que l’on cherche.
L’accès à cette documentation se fait via le site officiel de Python ([Link] qui contient un menu « documentation » :
cliquez sur le bouton « Python 3.x Docs » qui vous propose toute la documentation officielle Python 3, y compris une possibilité en
haut à droite de faire une recherche rapide. Essayez cette recherche, et vous verrez qu’au début vous serez probablement noyé dans
l’abondance d’information. Ne vous en faites pas pour cela !
Il est important pour tout un chacun de connaître quelques mots de « jargon » et quelques définitions dans le domaine. Cela permet
de mieux comprendre et connaître les informaticiens et leur travail, mais aussi de comprendre leur façon de s’exprimer par exemple
lorsqu’ils décrivent un problème à résoudre.
Commençons par brièvement parler de l’informatique. Le but de l’informatique est d’effectuer du traitement automatisé de
l’information.
L’information est un ensemble d’éléments qui ont une signification dans le contexte étudié.
Les données d’un problème sont représentées par l’ensemble des informations utilisées pour résoudre ce problème en vue d’obtenir
les résultats escomptés. Pour cela, l’informaticien peut commencer par écrire des algorithmes.
Un algorithme n’est pas conçu uniquement pour obtenir un résultat pour une donnée bien précise, mais constitue une méthode qui
permet, à partir de n’importe quelle autre donnée du même type, d’obtenir le résultat correspondant.
Un exemple simple d’algorithme est celui qui consiste, depuis l’entrée, à trouver la sortie d’un labyrinthe.
— Les données de l’algorithme sont le plan du labyrinthe avec en particulier l’endroit où se trouvent l’entrée et la sortie.
— L’algorithme va consister à entrer dans le labyrinthe et ensuite longer le côté gauche (ou le droit mais sans alterner) et
avancer tant que possible, en faisant demi-tour quand nous sommes bloqués mais en continuant à longer le côté gauche. Si le
labyrinthe n’a qu’une seule entrée et une sortie sur les côtés extérieurs de celui-ci et qu’il n’a ni pont ni tunnel, cet algorithme
permet de trouver la sortie.
— Le résultat de cet algorithme sera par exemple la séquence de mouvements à réaliser pour, depuis l’entrée, trouver la sortie.
Un algorithme peut être implémenté sur un ordinateur. Celui-ci ne possède jamais qu’une quantité limitée de mémoire de stockage
d’information dont la précision est limitée. De ce fait pour résoudre certains problèmes qui, en théorie, pourraient requérir un calcul
trop long, ou une précision ou un stockage d’information trop important, des algorithmes ne donnant qu’une valeur approchée du
résultat doivent être conçus.
Dans le contexte de ce cours, on parle de code et de programme informatique sous forme de séquence d’instructions Python 3.
Un code est un programme informatique, une partie de programme, ou une liste d’instructions ou de commandes (un “script”) pour
le système de votre ordinateur.
Un programme est un ensemble d’instructions (donc du code) qui, quand il est exécuté sur un ordinateur, réalise un traitement
défini. Un programme est donc vu comme la traduction en un code compréhensible par l’ordinateur d’un algorithme qui solutionne
un problème.
Même si on peut faire de longs débats pour savoir si un bout de code peut être défini comme un programme, et plus important, pour
savoir si quelqu’un peut être décrit comme un codeur ou un programmeur (faites par exemple une recherche sur le Web : “différence
codeur programmeur”), dans notre contexte, nous supposons que c’est presque la même chose.
Un langage de programmation comme le langage Python définit les règles nécessaires pour le code ou le programme pour qu’il soit
compréhensible et exécutable par un ordinateur.
Un programme appelé interpréteur ou compilateur « traduit » ce code source, c’est-à-dire dans le langage de programmation, en
code machine. L’interpréteur « exécute » immédiatement chaque instruction analysée, tandis que le compilateur traduit d’abord
complètement le code source en code machine qui pourra par la suite être exécuté.
Dans le contexte Python, vous pouvez voir une instruction comme un ordre que l’interpréteur Python donne à l’ordinateur qui
exécute le code.
Écrire un code ou un programme ou a fortiori développer un gros logiciel demande une démarche en plusieurs étapes, appelée
processus de développement d’un programme, qui peut être divisée en plusieurs phases (partiellement) successives.
— Analyse et spécification de ce qui est requis
— Conception
— Implémentation
— Tests et installation
— Exploitation et maintenance
Chaque phase produit des résultats écrits : spécification de ce qui est requis (cahier de charges), manuel utilisateur, description du
fonctionnement, description succincte ou détaillée de l’algorithme, programme dûment commenté, historique des modifications,
....
Le travail d’un ingénieur système est de mener ces phases ou de les superviser.
Dans ce cours nous nous concentrons sur l’implémentation, c’est-à-dire le codage qui, bien sûr, demande de travailler sur les quatre
premières phases de développement logiciel.
Tous les quiz de la formation comptent pour la note finale du cours en ligne. Attention, pour certains quiz, comme celui-ci, vous
aurez droit à plusieurs essais, mais pour la plupart, vous n’aurez droit qu’à un seul essai !
Note : Sondage sur l’installation de Python 3 et de PyCharm Community : voir en section 1.5.2 du cours en ligne
Retour d’information
— Si vos installations de Python 3 et PyCharm ont été totalement aisées : chouette on peut y aller ; merci de voir dans le forum
si vous pouvez aider un apprenant qui aurait un souci.
— Si vos installations de Python 3 et PyCharm ont été globalement aisées : nous espérons que cela ne vous a pas pris trop de
temps, on continue ; merci de voir dans le forum si vous pouvez aider un apprenant qui aurait le même type de souci que
celui que vous avez expérimenté.
— Si votre installation de Python 3 et de PyCharm ont été difficiles : nous espérons que cela ne vous a pas pris trop de temps,
on continue ; merci éventuellement de dire dans le forum comment votre souci a été résolu.
— Si vous n’êtes pas arrivé à installer Python 3 ou PyCharm : si personne de votre entourage ne peut vous aider, utilisez le
forum ; nous espérons que quelqu’un pourra y solutionner vos soucis.
RÉFÉRENCES
Dans ce module nous avons planté le décor. Vous avez installé l’environnement Python 3 avec PyCharm sur votre ordinateur et pris
connaissance d’outils qui vont nous aider tout au long du cours ; les références qui suivent complètent la panoplie d’outils.
Références :
— [Link] : accès à “Start visualizing your code now” qui vous permet de visualiser comment s’exécute pas à
pas votre code (ne pas oublier de mettre l’option python 3.6 ou ultérieur)
— Si vous désirez avoir un livre complet en plus du support de cours, le livre de Gérard Swinnen Apprendre à programmer avec
Python 3 est une excellente référence pour débuter votre apprentissage
— [Link] : site officiel de Python (téléchargements et documentations Python 3)
BILAN DU MODULE
RÉSUMÉ DE LA VIDÉO
— Vous avez installé et fait connaissance avec Python 3 ainsi que l’environnement PyCharm.
— Vous avez vu comment soumettre un exercice UpyLaB et comment manipuler une démonstration Python Tutor.
— En route vers le module 2 et l’apprentissage de la programmation ! Ce module 2 va nous montrer les bases de Python qui
peut manipuler des nombres et faire de l’arithmétique mais aussi faire du traitement de textes.
PRÉSENTATION DU MODULE 2
CC BY-SA 3.0 - 2021 - Sébastien Hoarau - Thierry Massart - Jean Olgiati - Isabelle Poirier 35
Apprendre à coder avec Python, Version - Release 3.0
CONTENU DE LA VIDÉO
La vidéo précédente présente les opérations arithmétiques de base possibles en Python sur des valeurs entières (int) ou fraction-
naires (float). Nous donnons ici les tests qui y sont réalisés sur la console Python suivis d’un résumé des explications données
s’y rapportant.
Tests réalisés sur la console dans la vidéo
>>> 3
3
>>> 3 + 5
8
>>> 9 - 5
4
>>> 3 * 4
12
>>> 3 + 4 * 5
23
>>> (3 + 4) * 5
35
>>> 8 - 5 - 2
1
>>> 8 / 4
2.0
>>> 8 / 3
2.6666666666666665
>>> type(3)
<class 'int'>
>>> type(3 + 4 * 5)
<class 'int'>
>>> type(2.66)
<class 'float'>
>>> type(4.0)
<class 'float'>
>>> type(8 / 2)
<class 'float'>
>>> 8 // 4
2
>>> 8 // 3
2
>>> 10 ** 5
100000
>>> 3.14159
3.14159
>>> 314159e-5
3.14159
>>> 0.00001
(suite sur la page suivante)
La vidéo en bref
Si nous ouvrons une console Python (dans l’environnement PyCharm), celle-ci attend une instruction de l’utilisateur. On voit les
symboles >>> qui invitent l’utilisateur à entrer quelque chose.
Dans ce mode, appelé mode interactif, la valeur de ce que l’on évalue est renvoyée. On peut ainsi voir l’effet des différentes
opérations arithmétiques et la façon de les écrire : (addition +, soustraction -, multiplication *, division en nombre flottant /,
division entière //, exponentiation **), ainsi que les types entiers (int : 3, 8, 12, . . . ) et fractionnaires appelés aussi flottants
(float : 2.0, 2.6666666666666665, 3.14159, 0.00001, 1.0e-5, . . . ).
2.2.2 L’arithmétique
TESTER L’ARITHMÉTIQUE
À vous maintenant de « tester les choses » : « tester » dans le jargon informatique signifie exécuter des petits programmes ou des
instructions pour voir comment les choses se déroulent (donc ici comment l’interpréteur fonctionne).
Dans la console de Thonny, ou de PyCharm (menu Tools -> Python Console) et expérimentez ce que donnent des calculs utilisant
les opérateurs arithmétiques sur les valeurs de type entier (int) et fractionnaire (float).
Si l’on regarde dans la documentation Python (The Python Standard Library sur le site [Link]) la liste des opérateurs arithmé-
tiques de base, on obtient (principalement)
+ L’addition
- La soustraction
* La multiplication
/ La division réelle (c’est-à-dire dont le résultat est du type float)
// La division entière tronquée (une explication sur la division est donnée ici)
** L’exponentiation (appelée également puissance ; une explication sur l’exponentiation est donnée ici)
% Le modulo (appelé aussi modulus ; pour les nombres entiers positifs, le modulo est défini comme le reste de la division
entière ; une explication du modulo est donnée ici).
Nous n’avons pas encore parlé de l’opérateur modulo écrit % en Python. Ici nous vous demandons d’être curieux pour comprendre
comment fonctionne cet opérateur. La curiosité est un outil essentiel pour bien apprendre à programmer !
De plus Python en mode interactif dans une console vous facilite souvent la vie.
Par exemple, si vous saisissez 8 % 3 dans une console, vous obtiendrez bien 2, qui correspond au reste de la division entière de 8
par 3.
L’opérateur modulo Python fonctionne également avec des nombres négatifs et même avec des nombres fractionnaires.
L’associativité et la priorité (appelée également précédence) de ces opérateurs (voir ci-dessous pour une explication), depuis le plus
prioritaire vers le moins prioritaire, sont les suivantes :
(expression)
** associatifs à droite
* / // associatifs à gauche
+- associatifs à gauche
où les opérateurs sur une même ligne ont le même niveau de priorité.
Priorité
Par exemple, la multiplication, appelée également produit, est plus prioritaire que l’addition : ainsi l’évaluation de 3 + 4 * 5
vaut 23 (on effectue d’abord la multiplication 4 * 5 et ensuite l’addition).
Notons que pour 2 ** -1 le moins est unaire (en fait il faut le voir comme le nombre -1) et donc vaut 2 ** (-1) c’est-à-dire
0.5.
Associativité
La plupart des opérateurs sont associatifs à gauche. La soustraction - est associative à gauche : ainsi, 8 - 5 - 2 est équivalent à
(8 - 5) - 2.
Par contre, l’exponentiation ** est associative à droite : ainsi 2 ** 2 ** 3 est équivalent à 2 ** (2 ** 3), c’est-à-dire 256
et non à (2 ** 2) ** 3 qui vaut 64.
Parenthèses
Des parenthèses peuvent être utilisées pour modifier l’ordre d’évaluation dans une expression ; ainsi : (3 + 4) * 5 pour réaliser
l’addition (3 + 4) avant la multiplication par 5. On évalue donc prioritairement ce qui à l’intérieur des parenthèses.
Dans le quiz suivant, nous vous demandons de nous dire, éventuellement avec l’aide d’une console Python, les résultats de différentes
expressions utilisant l’opérateur modulo ou les autres opérateurs arithmétiques.
Nous avons vu comment faire des calculs avec les différents opérateurs arithmétiques que Python nous fournit.
Avec ces opérateurs en poche, lançons-nous pour faire des calculs utiles !
Par exemple, faisons un peu de cuisine en réalisant la recette de la mousse au chocolat sur le site [Link] qui est donnée ici :
Ingrédients (pour 4 personnes)
— 3 oeufs
— 100 g chocolat (noir ou au lait)
— 1 sachet de sucre vanillé
Préparation de la recette
— Séparer les blancs des jaunes d’oeufs
— Faire ramollir le chocolat dans une casserole au bain-marie
— Hors du feu, incorporer les jaunes et le sucre
— Battre les blancs en neige ferme et les ajouter délicatement au mélange à l’aide d’une spatule
— Verser dans une terrine ou des verrines et mettre au frais 1 heure ou 2 minimum
La page mousse au chocolat du site Marmiton donne la quantité de chaque ingrédient quand on adapte le nombre de personnes qui
vont manger la recette.
On voit par exemple que pour 7 personnes, 6 oeufs, 175 g de chocolat et 1.75 sachet de sucre vanillé sont requis. Cela correspond
aux quantités d’ingrédients pour 4 personnes, divisées par 4 pour calculer les quantités requises par personne, et multipliées par 7
correspondant aux 7 personnes. Si ce calcul pour les oeufs ne tombe pas juste (c’est-à-dire s’il existe une partie fractionnaire), la
recette demande un oeuf de plus (c’est ce que l’on appelle la valeur plafond).
Mais si, pour simplifier, nous désirions calculer les ingrédients à l’unité près mais en faisant une simple troncature, c’est-à-dire en
ne gardant que la valeur entière, quels résultats aurions-nous ?
Par exemple, les troncatures de 1.3 et de 1.6 donnent tous les deux la valeur 1.
Note : Pour obtenir la valeur tronquée à l’unité, on pourra utiliser l’opérateur de division entière //, en faisant attention aux priorités
opératoires. Mais vous pouvez aussi utiliser la fonction prédéfinie int(). Par exemple int(1.6), qui reçoit comme argument la
valeur 1.6 de type fractionnaire (float), donnera la valeur entière 1.
Donc, en utilisant une console Python, pouvez-pour me dire la quantité de chaque ingrédient que je dois avoir pour faire ma recette
pour 7 personnes, en tronquant les valeurs calculées à l’unité près ?
Note : Les bons cuisiniers savent que Marmiton a raison dans ses calculs de proportions pour le nombre d’oeufs requis :-)
QUIZ
La vidéo qui suit présente les notions de base sur les textes appelés chaînes de caractères Python.
CONTENU DE LA VIDÉO
La vidéo précédente présente les chaînes de caractères Python. Nous donnons ici les tests qui y sont réalisés sur la console Python
suivis d’un résumé des explications données s’y rapportant.
Tests réalisés sur la console dans la vidéo
>>> "Bonjour"
'Bonjour'
>>> 'Bonjour'
'Bonjour'
>>> 'c'est facile'
File "<input>", line 1
'c'est facile'
^
SyntaxError: invalid syntax
>>> "c'est facile"
"c'est facile"
>>> "Bonjour " + "Michelle"
'Bonjour Michelle'
>>> "bon" * 10
'bonbonbonbonbonbonbonbonbonbon'
>>> 10 * "ha"
'hahahahahahahahahaha'
>>> len("Bonjour")
7
La vidéo en bref
"Bonjour" et 'Bonjour' entourés par des doubles ou simples apostrophes, appelés aussi doubles ou simples quotes, sont
des chaînes de caractères (textes).
type('Bonjour') exprime que le type (la classe) de la valeur 'Bonjour' est str pour string, terme anglais pour chaîne
de caractères, ou plus simplement texte.
Taper dans la console Python 'c'est facile' renvoie un message d’erreur du type SyntaxError puisque l’interpréteur
considère que la chaîne de caractères est 'c' et ne comprend plus la suite.
On peut écrire "c'est facile" entourés de double quotes pour obtenir une chaîne de caractères correcte.
Concaténation et répétition
"Bonjour " + "Michelle" renvoie "Bonjour Michelle"
La concaténation (+) est l’opération qui consiste à coller deux textes ensemble pour n’en former qu’un.
"bon" * 10 donne 'bonbonbonbonbonbonbonbonbonbon' et 10 * "ha" donne 'hahahahahahahahahaha'
C’est la concaténation de 10 fois le texte "bon" ou de 10 fois le texte "ha".
len()
La fonction prédéfinie len() donne la longueur de la séquence donnée en argument. Cela signifie que len("Bonjour")
donne la longueur du texte, c’est-à-dire ici 7 caractères (les doubles quotes étant là pour marquer le début et la fin du texte).
À vous de jouer ! Entrez à nouveau dans une console Python et expérimentez comment l’interpréteur réalise les manipulations
simples de chaînes de caractères.
Pour ce faire, nous vous proposons de regarder ce que donnent les lignes de code suivantes :
>>> "bonjour"
>>> 'bonjour'
>>> '" Bonjour "'
>>> "C’est facile"
Il est également possible d’appliquer des fonctions à des chaînes de caractères. Par exemple, la fonction prédéfinie len() donne
la longueur de la séquence passée en argument. Cela signifie que len("bonjour") donne la longueur du texte soit 7 caractères
(les doubles quotes étant là pour marquer le début et la fin du texte).
Afin de voir si vous avez compris l’utilité de la fonction len(), nous vous proposons le quiz suivant.
La vidéo qui suit présente les notions fondamentales de variables et d’assignation, appelée également affectation, en Python.
CONTENU DE LA VIDÉO
La vidéo précédente présente les variables Python. Nous donnons ici les tests qui y sont réalisés sur la console Python suivis d’un
résumé des explications données s’y rapportant.
Tests réalisés sur la console dans la vidéo
>>> x = 3
>>> x
3
>>> y = 4 * 3
>>> y
12
(suite sur la page suivante)
La vidéo en bref
Les variables permettent de retenir des valeurs ; l’instruction d’affectation, appelée également assignation, donne une valeur à
une variable.
Une assignation a la forme suivante
nom = valeur
où à gauche du symbole d’assignation =, nom est le nom de la variable, choisi par le programmeur, et à droite du symbole = est
donnée la valeur à assigner. Par exemple :
x = 3
y = 4 * 3
z = x + 5
y = y + 1
r = 8 / 3
mon_message = 'bonjour'
Après l’assignation, (par exemple x = 3), la variable assignée a une valeur et un type (ici x vaut la valeur entière 3) ;
x + 5 utilise la valeur de la variable x pour faire les calculs (ici comme x vaut 3 : 3 + 5 c’est-à-dire 8) ;
type(x) renseigne que la variable x, donnée en argument de la fonction prédéfinie type() est de type entier (son contenu est
un entier). De façon raccourcie on dit que x est un entier.
Certains noms sont des mots réservés (mots-clés) Python : ainsi if = 0 ne fonctionne pas : l’interpréteur donne une erreur de
syntaxe car if est un mot-clé Python.
Notons plus précisément qu’une valeur en Python sera un objet et une variable le nom d’un objet.
Avertissement : La variable qui reçoit la valeur d’une assignation est à gauche du symbole = (symbole d’affectation).
N’essayez pas d’écrire
3 = x
qui exprime que vous essayez d’assigner la valeur de la variable x à la valeur 3, ce qui n’est pas possible !
À VOUS DE JOUER !
L’exercice suivant vous demande d’écrire votre premier code utilisant des variables.
Pour cela, nous allons reprendre la préparation de la mousse au chocolat donnée dans l’activité 2.2.3.
Nous vous demandons de calculer à nouveau les quantités nécessaires de chaque ingrédient mais cette fois, pour un nombre quel-
conque de personnes.
Votre programme commencera donc par assigner le nombre de convives à une variable (de nom) n. Ensuite, il calculera les
quantités (en grammes ou en unités) de chaque ingrédient qu’il stockera dans trois autres variables : oeufs, chocolat et
sucre_vanille. Chacune de ces quantités sera, comme dans l’activité précédente, tronquée à l’unité près. Par souci de sim-
plification, on supposera que le nombre de personnes pour lesquelles il faut préparer la mousse au chocolat sera toujours supérieur
ou égal à 4.
Pour n valant 7, les valeurs pour oeufs, chocolat (en grammes) et sucre_vanille sont respectivement de 5, 175 et 1.
On voit que l’assignation en Python revient réellement à donner un nom à une valeur.
PROPOSITION DE SOLUTION
Vous avez du mal pour réaliser l’exercice ou vous l’avez réussi mais voulez avoir une autre solution : nous vous en proposons une.
n = 12
oeufs = 3 * n // 4
chocolat = 100 * n // 4
sucre_vanille = n // 4
À toute fin utile, voici une règle de bonne pratique qui vous permettra de rendre votre code plus lisible et souvent plus efficace : on
utilise généralement des noms de variables qui ont un sens en fonction de leur contenu. Par exemple sucre_vanille. En Python, les
noms des variables ne peuvent contenir d’accents ni de caractères non alphanumériques (un caractère alphanumérique signifie une
lettre ou un chiffre) excepté le caractère souligné « _ », et ne peuvent pas commencer par un chiffre. Par exemple sucre_vanille,
s9 ou oeufs sont des noms corrects pour des variables mais par exemple sucre_vanillé (qui contient un accent) ou 9s (qui
commence par un chiffre) ne sont pas des noms de variables valides.
Note : PyCharm analyse nos scripts pour déterminer s’ils respectent bien les « règles de bonnes pratiques » (nous en reparlerons
plus loin) : si les mots utilisés par exemple pour donner un nom aux variables ne sont pas dans ses dictionnaires, PyCharm nous
avertit qu’il y a probablement un typo (mais peut-être que vous l’avez délibérément orthographié ainsi). C’est pour cette raison que
nous avons ajouté un dictionnaire français contenant les mots avec et sans accents ce qui permet de donner dans nos codes des noms
de variables sans les accents (par exemple cafe = 5 si notre programme parle de café).
Dans un programme, on distingue les valeurs qui peuvent changer, comme la valeur des variables n, oeufs. . . , des valeurs qui
restent inchangées tout au long du programme, et que l’on appelle constantes dans le jargon informatique. Comme son nom l’indique
la valeur d’une constante n’est jamais modifiée lors de l’exécution du programme. Ainsi, de façon évidente, les valeurs 0, 1 ou 7
sont des constantes. Plus loin, on parlera de la valeur pi comme étant une constante.
SYNTAXE ET SÉMANTIQUE
Rappelons la définition de ces deux mots courants en informatique et dans notre cours en ligne.
Syntaxe : pour un programme Python, est l’ensemble des règles grammaticales que l’on doit suivre pour que le programme soit a
priori compréhensible par l’interpréteur. Parmi les règles de syntaxe à suivre, nous avons vu que l’assignation doit avoir un nom de
variable à gauche du signe « = » et une valeur ou une expression à droite.
Toute erreur syntaxique dans l’écriture de code Python sera sanctionnée par l’interpréteur, lors de l’exécution de la partie incriminée
par un message : SyntaxError avec une explication du soucis.
Sémantique : exprime le « sens », la « signification ». Parmi les erreurs sémantiques dans un code Python, on a par exemple le fait
d’utiliser un nom (identificateur) non défini.
Par exemple x = z est une instruction Python syntaxiquement correcte. Mais, si z n’a encore reçu aucune valeur, par exemple, via
l’assignation (z n’a pas encore été définie), l’interpréteur Python qui exécute cette instruction produira une erreur (NameError) :
c’est une erreur sémantique.
La capsule suivante introduit les deux fonctions input et print qui seront bien utiles pour que le code Python puisse communi-
quer avec son utilisateur. La notion de script Python est aussi introduite.
CONTENU DE LA VIDÉO
La vidéo précédente présente les scripts Python ainsi que les foncctions input et print. Son résumé est groupé avec celui de la
vidéo de l’onglet 3 de cette section, un peu plus loin dans ce cours ; cette seconde vidéo complète l’explication. Le résumé des deux
vidéos est disponible dans cet onglet 3.
Nous avons déjà présenté Python Tutor dans le module précédent. Python Tutor est un outil en ligne permettant d’exécuter pas à pas
des petits scripts Python en visualisant l’effet de chaque instruction Python.
Avant de montrer de façon plus précise comment fonctionne Python Tutor, commençons par expliquer pourquoi diable nous intro-
duisons un outil de plus dans ce cours en ligne. La réponse est double :
— d’une part Python Tutor permet d’interpréter le code Python en s’arrêtant à chaque instruction pour voir son effet,
— d’autre part, après chaque instruction, Python Tutor représente le « diagramme d’état » illustrant l’état du programme à ce
moment-là.
Comme nous allons le voir, un diagramme d’état est un schéma qui montre graphiquement comment les variables et valeurs mani-
pulées dans un script Python sont stockées en mémoire. Si au départ cette information ne vous sera pas d’une grande utilité, petit à
petit nous verrons qu’elle est essentielle pour comprendre comment nos codes fonctionnent.
Python Tutor n’est donc pas un simple interpréteur ; c’est un outil d’apprentissage de Python (et d’autres langages) principalement
pour les débutants. Python Tutor nous sera d’une grande utilité, en particulier pour visualiser les diagrammes d’état montrant l’état
de codes fournis, à chaque étape de l’exécution, ce qu’un interpréteur « normal » comme PyCharm ne fait pas. Mais Python Tutor
n’est pas un interpréteur complet de scripts en ligne comme ce qui vous est fourni via PyCharm. Ainsi, Python Tutor ne permet
l’exécution que des scripts utilisant un petit sous-ensemble d’instructions Python.
Pour bien expliquer les nouveaux concepts Python, nous inclurons fréquemment des exemples Python Tutor intégrés dans ce cours
en ligne. Mais libre à vous de mettre dans une fenêtre Python Tutor un code Python de votre choix pour visualiser son exécution
étape par étape et bien comprendre son fonctionnement grâce aux diagrammes d’état fournis par Python Tutor.
Pour vous aider à utiliser Python Tutor, la petite vidéo qui suit fait une démonstration de son utilisation. Libre à vous de la visionner
maintenant ou quand vous en aurez besoin.
PYTHON TUTOR
À VOUS DE JOUER !
Dans le but d’apprendre à manipuler Python Tutor, reprenez votre script rédigé à la section précédente qui calcule les quantités
d’ingrédients pour la préparation de la mousse au chocolat. Modifiez-le dans Python Tutor pour lire la valeur de n (input de n) et
écrire les résultats grâce à des print : la valeur des variables oeufs, chocolat et sucre_vanille .
Ensuite, visualisez comment celui-ci s’exécute pas à pas dans une fenêtre de Python Tutor.
Pour rappel, dans ce cours, nous utiliserons également Python Tutor de façon intégrée, c’est-à-dire au sein même des pages du
cours. Par exemple, voici deux animations Python Tutor intégrées de l’exemple précédent sur la mousse au chocolat avec input et
print. La première utilise l’option « render all objects on the heap », la seconde l’option « inline primitives & nested objects ».
Les deux vidéos sur les scripts Python ainsi que les fonctions input et print, présentées dans l’onglet précédent et l’onglet
courant de la présente section, sont résumées ici.
Nous donnons ici les scripts qui y sont utilisés pour la présentation suivis d’un résumé des explications données s’y rapportant.
Scripts utilisés dans les vidéos
rayon = 5.0
circ = 2 * 3.14 rayon # l’astérisque manque
aire = 3.14 * rayon ** 2
circ, aire
rayon = 5.0
circ = 2 * 3.14 * rayon
aire = 3.14 * rayon ** 2
circ, aire
rayon = 5.0
circ = 2 * 3.14 * rayon
aire = 3.14 * rayon ** 2
(suite sur la page suivante)
rayon = float(input())
circ = 2 * 3.14 * rayon
aire = 3.14 * rayon ** 2
print(circ, aire)
La vidéo en bref
Les deux fonctions input et print sont introduites. Elles sont bien utiles pour que le code Python puisse communiquer avec
son utilisateur. La notion de script Python est aussi introduite.
1) Le premier script est édité et ensuite sauvé par exemple dans le fichier [Link]. Son exécution par l’interpréteur
Python donne une erreur de syntaxe : l’interpréteur lorsqu’il désire calculer la valeur de circ ne comprend pas ce qui est
demandé. En effet cette ligne de code n’est pas correcte : il manque l’opérateur de multiplication *.
2) Après avoir corrigé mon script en ajoutant le symbole de multiplication, je redemande, avec la commande Run, à l’in-
terpréteur d’exécuter le code du script [Link] et cette fois il se termine avec un exit code 0 qui signifie que
l’exécution s’est bien déroulée. Mais nous constatons que le script n’a pas communiqué de résultats !
3) Le troisième script permet avec la fonction print d”afficher, on dit aussi imprimer, les résultats donnés en arguments
du print.
4) Le quatrième script permet de recevoir grâce à la fonction input() une donnée que l’utilisateur peut encoder. La
donnée reçue grâce à la fonction input est de type chaîne de caractères. Cette donnée est traduite dans ce script, en
valeur fractionnaire grâce à la fonction prédéfinie float(). Notez l’écriture pour réaliser la succession lecture de la
donnée qui donne une chaîne de caractères et traduction en valeur fractionnaire : float(input()).
5) Le cinquième script ci-dessus demande l’entrée de données (input()) avec un texte explicatif en argument, l’affichage
de résultats (print()) également avec un texte explicatif à chaque print.
6) Le dernier script contient des commentaires. De façon générale, pour rendre un script plus lisible pour les autres program-
meurs qui voudraient comprendre son fonctionnement, on peut rajouter des explications. Pour cela on peut, à la fin de
chaque ligne de code, mettre le caractère # (croisillon) suivi de texte explicatif. Ce texte s’appelle du commentaire et ne
sera pas utilisé par l’interpréteur. Je peux aussi, n’importe où, rajouter un commentaire multiligne entouré de 3 simples
quotes ou double quotes. Je peux mettre une explication plus complète de ce que fait le script dans un docstring initial :
— l’auteur
— la date
— le but du programme
— les données reçues (input)
— les résultats affichés (print)
Le caractère # utilisé en Python pour marquer les commentaires est le caractère croisillon ; celui-ci a deux barres obliques
parallèles coupées par deux barres horizontales. Ce caractère est souvent erronément appelé dièse (♯). Ce dernier, utilisé par
exemple dans les partitions musicales, a deux barres verticales coupées par deux barres obliques parallèles.
Nous pouvons maintenant visualiser un script complet commenté. Pour illustrer cela, donnons deux scripts complets solutionnant le
problème de la mousse au chocolat :
— une version avec assignation des résultats dans des variables
— et une version améliorée où les calculs se font directement lors des print.
Solution avec variables
Solution améliorée
Nous voici à la dernière étape d’apprentissage pour la matière de ce module : l’apprentissage autonome. Pour cela, nous vous
demandons de réaliser les exercices 2.1 à 2.3 du Module 2 qui vous sont proposés dans le cadre de cette activité.
Note : En cas de problème d’affichage, essayez de recharger la page. Il se peut que votre navigateur ne sache pas bien afficher le
code UpyLaB, et que vous deviez en utiliser un autre.
Faire les exercices UpyLaB va vous demander de développer du code Python résolvant les problèmes demandés. En général, au
début, votre code ne résoudra pas (exactement) le problème demandé : nous dirons simplement que votre code est faux ! Dans ce
cas, vous devrez le déboguer.
Déboguer son code (debug en anglais) correspond à y faire la chasse aux erreurs. La pratique de la programmation apprend comment
déboguer efficacement un programme. Nous essayerons tout au long de ce cours de vous donner certains conseils pour y arriver. En
voici quelques uns.
1) Lors du développement de chacun de vos codes, il est plus que vivement conseillé d’utiliser un environnement de dévelop-
pement comme PyCharm ou Python Tutor pour tester ou même déboguer pas par pas votre code avant de passer aux tests
UpyLaB. En effet, faire tester directement par UpyLaB un code dont vous n’avez pas une certaine confiance dans le fait qu’il
soit correct s’avère souvent être un gouffre au niveau du temps. En effet, pour valider votre code, UpyLaB ajoute du code
supplémentaire qu’il va ensuite exécuter : si votre code est erroné à une ligne donnée, il est possible qu’UpyLaB évoque un
autre numéro de ligne pour cette erreur ou renvoie un message peu explicite. Pour cette raison, il est recommandé de ne pas
utiliser UpyLaB lors des développements de vos codes, mais uniquement pour valider s’ils sont bien corrects.
La démarche la plus efficace pour développer du code en Python est donc :
— de comprendre exactement ce qui vous est demandé,
— de développer une solution dans PyCharm en la testant,
— de tester l’ensemble de votre code dans UpyLaB (en le transférant dans UpyLaB grâce au copier / coller du code depuis
PyCharm) pour faire valider votre script.
2) UpyLaB est parfois « psychorigide » dans le sens où, si votre code ne fait pas exactement ce qu’il demande, UpyLaB le
considère comme faux. En particulier dans les consignes, votre code à tester par UpyLaB :
— ne doit pas avoir d’arguments dans les appels à input.
— ne doit pas imprimer autre chose que le résultat dans les print.
Ainsi, il faut écrire :
a = float(input())
print(a)
plutôt que :
a = float(input("a = "))
print('a vaut :', a)
En effet UpyLaB teste votre programme en l’exécutant plusieurs fois. Durant ces tests, la sortie (print) du code proposé
sur différentes entrées fournies automatiquement est comparée à la sortie attendue, produite par une solution de référence.
Si votre code fait des sorties supplémentaires avec les fonctions input ou print, il sera jugé faux par UpyLaB lors
des validations ! Vous expérimenterez sûrement cela tôt ou tard. Cela vous obligera à une rigueur à laquelle les novices en
programmation sont généralement peu habitués.
Attention : Le but des exercices UpyLaB est de vous rendre autonome en programmation. C’est vous qui devez trouver la ou
une solution, en code Python, à chaque exercice demandé. Si vous ne voyez pas comment y arriver ou qu’UpyLaB ne valide
toujours pas votre code, voici quelques conseils :
1. Relire l’énoncé et les consignes associés à l’exercice ainsi que les éventuels conseils.
2. Lire la FAQ générale à propos des exercices UpyLaB.
3. Lire, si elle existe, la FAQ spécifique à l’exercice réalisé.
4. Si rien de tout cela ne fonctionne, poser votre question sur le Forum dédié aux exercices, en étant le plus précis possible,
sans mettre votre code complet ni substantiel mais en mettant des copies d’écran des résultats fournis par UpyLaB.
Le but de cet exercice est de vérifier que vous savez définir des variables, et leur affecter des valeurs des différents types rencontrés
dans le cours.
Écrire un programme qui assigne :
— la valeur entière 36 à la variable x ;
— la valeur entière résultat de 36 fois 36 à la variable produit ;
— la valeur entière résultat de la division entière de 36 par 5 à la variable div_entiere ;
— la valeur entière résultat de 15 exposant 15 à la variable expo ;
— la valeur float 3.14159 à la variable pi ;
— la valeur chaîne de caractères "Bonjour" à la variable mon_texte.
Consignes
Attention, dans cet exercice, il n’y a rien à afficher, donc vous ne ferez aucun appel à la fonction print.
Quand votre solution sera validée, cliquez sur le bouton « AFFICHER LA RÉPONSE » pour trouver des conseils de bonnes
pratiques et éventuellement améliorer votre façon de coder.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Pour tester votre code, UpyLaB va l’exécuter en ajoutant des instructions lui permettant de vérifier que les variables attendues
existent et sont bien affectées des valeurs attendues.
Si vous souhaitez tester votre code dans votre IDE (Thonny ou PyCharm par exemple), pensez à ajouter les instructions :
print("x =", x)
print("produit =", produit)
print("div_entiere =", div_entiere)
...
Le but de cet exercice est de vérifier que vous savez lire des données en entrée avec la fonction input, les affecter à des variables
et imprimer (on dit aussi afficher) une valeur grâce à la fonction print.
Écrire un programme qui imprime (donc grâce à la fonction print) la moyenne arithmétique de deux nombres de type float
lus en entrée (c’est-à-dire grâce à des appels à la fonction input) .
𝑎+𝑏
On rappelle que la moyenne arithmétique de deux nombres a et b est égale à 2
Exemple 1
2.0
3.0
2.5
Exemple 2
4.2
3.8
4.0
Consignes
Attention, nous rappelons que votre code sera évalué en fonction de ce qu’il affiche, donc veillez à n’imprimer que le résultat
attendu.
En particulier, il ne faut rien écrire à l’intérieur des appels à input (float(input()) et non float(input("Entrer un
nombre : ")) par exemple), ni ajouter du texte dans ce qui est imprimé (print(res) et non print("résultat :",
res) par exemple).
Quand votre solution sera validée, cliquez sur le bouton « AFFICHER LA RÉPONSE » pour trouver des conseils de bonnes
pratiques et éventuellement améliorer votre façon de coder.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Pour tester votre code, UpyLaB va l’exécuter plusieurs fois en lui fournissant à chaque test des nombres différents en entrée.
Il vérifiera alors que le résultat affiché par votre code correspond à ce qui est attendu. N’hésitez donc pas à tester votre code
en l’exécutant plusieurs fois dans votre IDE (Thonny ou PyCharm par exemple) avec des valeurs différentes en entrée.
— Portez attention aux règles de priorité des opérateurs arithmétiques.
— Si rien ne marche : consultez la FAQ sur UpyLaB 2.2.
Le but de cet exercice est de vous familiariser avec la lecture (input()) de données et l’impression (print()) de résultats.
𝑎 𝑐
Une méthode pour trouver le quatrième terme parmi quatre termes ayant un même rapport de proportion 𝑏 = 𝑑 lorsque trois de ces
termes sont connus repose sur l’égalité des produits en croix.
Elle utilise le fait que le produit des premier et quatrième termes est égal au produit du second et du troisième : 𝑎.𝑑 = 𝑏.𝑐 et donc
𝑑 = 𝑏.𝑐
𝑎
Exemple : si chacun mange autant de chocolat et que pour 4 personnes il en faut 100 grammes, pour 7 personnes il en faudra donc
4
𝑑 tel que 100 = 𝑑7
7.100
D’où 𝑑 = 4 grammes = 175 grammes.
𝑎
Écrire un programme qui lit des valeurs de type float pour 𝑎, 𝑏 et 𝑐 et qui affiche la valeur de 𝑑 vérifiant l’égalité 𝑏 = 𝑑𝑐 .
Exemple 1
4.0
100.0
7.0
175.0
Exemple 2
3.5
0.5
8.0
1.1428571428571428
Remarque : Du fait du manque de précision dans les calculs avec les nombres de type float, votre résultat pourra légèrement différer
de celui indiqué ci-dessus. Ce n’est pas un problème, car UpyLaB acceptera toute réponse suffisamment proche du résultat attendu,
avec une tolérance d’environ 1.0e-5.
Consignes
Attention, nous rappelons que votre code sera évalué en fonction de ce qu’il affiche, donc veillez à n’imprimer que le résultat
attendu.
En particulier, il ne faut rien écrire à l’intérieur des appels à input (int(input()) et non int(input("Entrer un nombre
: ")) par exemple), ni ajouter du texte dans ce qui est imprimé (print(res) et non print("résultat :", res) par
exemple).
Quand votre solution sera validée, cliquez sur le bouton « AFFICHER LA RÉPONSE » pour trouver des conseils de bonnes
pratiques et éventuellement améliorer votre façon de coder.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Pour tester votre code, UpyLaB va l’exécuter plusieurs fois en lui fournissant à chaque test des nombres différents en entrée.
Il vérifiera alors que le résultat affiché par votre code correspond à ce qui est attendu. N’hésitez donc pas à tester votre code
en l’exécutant plusieurs fois dans votre IDE (Thonny ou PyCharm par exemple) avec des valeurs différentes en entrée.
— Si rien ne marche : consultez la FAQ sur UpyLaB 2.3.
PRÉSENTATION
Les capsules suivantes montrent que Python fournit au programmeur des modules avec des constantes et des fonctions prédéfinies,
c’est-à-dire déjà écrites, qu’il peut utiliser à sa guise soit directement, soit en les important.
Les deux vidéos précédentes ont introduit les modules Python math et turtle.
Nous donnons ici les scripts qui y sont utilisés pour la présentation suivis d’un résumé des explications données s’y rapportant.
Scripts et consoles utilisés dans les vidéos
Le module math
#lecture du rayon :
rayon = float(input("Veuillez donner le rayon : "))
circ = 3.14 * 2 * rayon # calcul de la circonférence
(suite sur la page suivante)
pi = 3.14159
#lecture du rayon :
rayon = float(input("Veuillez donner le rayon : "))
circ = pi * 2 * rayon # calcul de la circonférence
aire = pi * rayon ** 2 # calcul de l'aire
import math
#lecture du rayon :
rayon = float(input("Veuillez donner le rayon : "))
circ = [Link] * 2 * rayon # calcul de la circonférence
aire = [Link] * rayon ** 2 # calcul de l'aire
˓→'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma',
˓→'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log',
˓→'log10', 'log1p', 'log2', 'modf', 'nan', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan',
#lecture du rayon :
rayon = float(input("Veuillez donner le rayon : "))
circ = pi * 2 * rayon # calcul de la circonférence
aire = pi * rayon ** 2 # calcul de l'aire
Le module turtle
import turtle
[Link](100)
[Link](90)
[Link](100)
[Link](90)
[Link](100)
[Link](90)
[Link](100)
[Link](90)
import turtle
[Link]()
[Link](-150,-150)
[Link]()
[Link]("blue")
turtle.begin_fill()
[Link](150,-150)
[Link](150,150)
[Link](-150,150)
[Link](-150,-150)
turtle.end_fill()
[Link]() # [Link]()
La vidéo en bref
Cette section montre que Python fournit au programmeur des modules avec des constantes et des fonctions prédéfinies, c’est-à-
dire déjà écrites, qu’il peut utiliser à sa guise soit directement, soit en les important.
Le module math
Au début du script, après le docstring initial, on peut rajouter la ligne de code
import math
Dans ce cas, pour utiliser pi, je dois spécifier que c’est l’attribut du module math en tapant [Link] qui me donne la valeur
approximative de pi (avec les 15 ou 16 premiers chiffres corrects vu la précision possible).
Si je n’ai besoin que de pi et cos du module math par exemple, je peux préciser et écrire
from math import cos, pi
Et alors cos(pi), qui appelle la fonction cos() avec pi en argument, et qui donc demande la valeur du cosinus de pi, est bien
compris par l’interpréteur Python.
Le module turtle
Le module turtle permet de dessiner des figures de façon très simple. turtle peut être vue comme une tortue qui porte une
plume. Quand elle se déplace, soit la plume est descendue, ce qui est le cas au début, et dans ce cas elle trace une ligne lors de
ses déplacements, soit la plume est relevée et dans ce cas, elle ne trace rien.
Une liste de commandes turtle, les plus communes dont nous allons nous servir avec leur explication, est donnée plus loin
dans le cours.
Pour laisser la fenêtre ouverte à la fin du programme jusqu’à ce que l’utilisateur décide de la fermer en cliquant sur le bouton
rouge de fermeture de la fenêtre où turtle a dessiné, il suffit d’ajouter comme dernière instruction du code : [Link]()
ou bien [Link]().
FONCTIONS PRÉDÉFINIES
Dans la vidéo précédente, nous avons déjà utilisé certaines fonctions prédéfinies ; en voici une liste non exhaustive qui vous sera
sûrement bien utile pour résoudre des exercices dans le cadre de ce cours ou de projets futurs :
— abs(x)
— dir(x)
— divmod(x, y)
— float(x)
— help(x)
— input()
— int(x)
— max(a, b,...)
— min(a, b,...)
— print()
— round(x, y)
— sum(a)
— type(x)
N’hésitez pas à vous les approprier en les manipulant dans une console Python avec différents arguments donnés à la fonction
appelée, à utiliser la fonction help() ou même à aller voir dans la documentation python3 pour bien comprendre ce que ces
fonctions font.
Par exemple pour comprendre comment fonctionne la fonction round(), tapez dans une console PyCharm help(round) (et si
l’anglais n’est pas votre fort, n’oubliez pas que sur internet des traducteurs automatiques en ligne peuvent vous aider).
>>> help(divmod)
pour savoir l’effet de cette fonction. L’explication utilise le mot invariant : cela signifie un fait toujours vrai.
isinstance
Si l’on veut tester si une valeur ma_variable est de type int par exemple, la fonction booléenne prédéfinie isinstance
peut être utilisée avec isinstance(ma_variable, int) plutôt que type(ma_variable) is int. La différence
entre les deux façons de faire n’est visible qu’en programmation orientée-objet (si dans une console python vous tapez
help(isinstance), il est dit que isinstance(obj, class) teste si obj est une instance d’une classe ou une sous-
classe de class). Dans le cadre de ce cours, comme la notion de sous-classe d’une classe n’a pas été vue et n’est pas utilisée, les
deux utilisations sont équivalentes.
Aide-mémoire : Pour vous aider tout au long de ce cours, nous avons confectionné un aide-mémoire, qui explique succinctement
l’effet des fonctions et méthodes prédéfinies les plus couramment utilisées.
L’aide-mémoire est disponible à l’adresse [Link]
[Link]
Nous vous conseillons même de l’imprimer, et de l’avoir sous la main quand vous programmez. Notez que jusqu’à présent nous
n’avons étudié qu’une petite partie du contenu de cet aide-mémoire. Soyez patient, la suite arrive !
Module math
Le module math est particulièrement utile pour écrire des scripts résolvant des problèmes mathématiques. Le but de ce cours n’est
sûrement pas de connaître le contenu de modules comme math par coeur. Par contre, il est important lorsque nous écrivons un
programme Python de savoir trouver de l’information complémentaire. Une première exploration du contenu d’un module, comme
le module math, consiste à ouvrir une console Python et à exécuter :
>>> help('math')
Commande Effet
reset() On efface tout et on recommence
goto(x, y) Aller à l’endroit de coordonnées x, y
forward(distance) Avancer d’une distance donnée
backward(distance) Reculer
up() Relever le crayon (pour pouvoir avancer sans dessiner)
down() Abaisser le crayon (pour recommencer à dessiner)
color(couleur) couleur peut être 'red' , 'blue', etc.
color(bord, zone) couleur du bord et de la zone
left(angle) Tourner à gauche d’un angle donné (exprimé en degrés)
right(angle) Tourner à droite
width(épaisseur) Choisir l’épaisseur du tracé
begin_fill() Début de la zone fermée à colorier
end_fill() Fin de la zone fermée à colorier
hideturtle() Cache la tortue
showturtle() Montre la tortue
write(texte) Ecrit texte
done() ou mainloop() Attend que l’utilisateur ferme la fenêtre
Nous vous invitons à ouvrir une console Python et à essayer ces commandes.
Pour bien visualiser le rôle des fonctions couramment utilisées par turtle, créez un script dans Thonny ou PyCharm qui contient le
code ci-dessous et exécutez-le (Run). Afin de vous aider à analyser l’effet de chaque instruction, nous vous suggérons de commenter
chaque ligne en expliquant ce qu’elle fait et en ayant découvert quelle figure est dessinée par ce code.
Note : Attention, surtout n’appelez pas votre script [Link] qui est le nom utilisé pour le module turtle lui même. Si vous faites
cela, l’import du module turtle ne sera pas réalisé.
import turtle
[Link]()
[Link]('turtle')
[Link](-80,0)
[Link]('blue')
[Link]()
turtle.begin_fill()
[Link](300)
[Link](144)
[Link](300)
[Link](144)
[Link](300)
[Link](144)
[Link](300)
[Link](144)
[Link](300)
[Link](144)
turtle.end_fill()
[Link]()
[Link]()
PROPOSITION DE SOLUTION
PAVÉ HEXAGONAL
Lancez-vous avec turtle : faites fonctionner votre imagination pour dessiner des figures. Vous pouvez aussi dessiner des poly-
gones réguliers à 3, 5, 7 . . . côtés.
Si vous avez besoin de vous rafraîchir la mémoire sur certaines notions de vos cours de mathématiques, une rapide recherche sur le
Web vous permettra de (re)découvrir que pour dessiner un polygone à n côtés (par exemple n = 5), l’angle de la rotation à réaliser
entre deux côtés est de 360°/n. Si n vaut 5 cela donne donc 360°/5 = 72°.
Si l’on veut dessiner des étoiles à n branches et en supposant n impair (pour n pair, c’est un peu plus délicat) au moins égal à 5,
l’angle intérieur sera de (n-1)*180°/n (par exemple 144° pour n valant 5 comme donné dans mon code précédent).
Un exemple de pavé hexagonal, est la composition de trois losanges de couleurs différentes comme ici en noir, bleu et rouge.
Visionnez la vidéo pour comprendre la séquence réalisée par le code.
Note : Voir la vidéo de la section 2.6.3 : dessin d’un pavé hexagonal avec turtle
Pourquoi ne pas essayer : dessinez avec turtle un tel pavage en partant du point (0, 0) qui est la position initiale de la tortue, avec
des lignes de longueur 100 par exemple.
— D’abord en utilisant en particulier les instructions [Link](), [Link]() et [Link]() (Un
petit conseil : utilisez des angles de 60° ou de 120° pour faire tourner votre tortue ; voir la figure « Géométrie d’un hexagone »)
— Ensuite, encore mieux, utilisez l’instruction [Link]() pour vos déplacements en calculant les abscisses et ordon-
nées des points extrémités où doit se déplacer la tortue ; voir les deux figures « Géométrie d’un hexagone » et « Rappel sur
les sinus et cosinus ». Une des figures vous rappelle comment vous pouvez calculer ces coordonnées avec les fonctions sinus
et cosinus ([Link] et [Link] après avoir importé le module math) : dans un espace à 2 dimensions, pour un cercle
de centre (0,0) et de rayon 1, les coordonnées du point sur le cercle ayant un angle alpha avec l’axe des x (le point en
rouge) est donné par (cosinus(alpha), sinus(alpha)). Dans la figure « Rappel sur les sinus et cosinus », l’angle
alpha vaut 60 degrés soit pi / 3 radians.
Avant de réaliser le pavage hexagonal nous vous demandons de réaliser l’exercice 2.4 du module 2 d’UpyLaB donné ci-après. La
réussite de cet exercice vous permettra de réaliser plus facilement le pavage demandé ci-dessus.
Comme l’exercice contient un bagage mathématique en trigonométrie qui n’est pas l’objet de ce cours, nous proposons à ceux qui
n’ont pas ou plus la connaissance des notions de sinus et cosinus d’avoir accès à une solution en bas de l’exercice UpyLaB 2.4.
Notons que de ce fait, l’exercice n’est pas noté.
Écrire un programme qui lit une longueur long de type float strictement positive, et qui affiche les valeurs x y des coordonnées
(x, y) des sommets de l’hexagone de centre (0,0) et de rayon long
Chaque couple de coordonnées sera affiché sur une ligne différente, en commençant par le point à 0°, puis par le point à 60°, puis
120° . . . jusqu’au 6ème point.
Exemple 1
100.0
100.0 0.0
50.000000000000014 86.60254037844386
-49.99999999999998 86.60254037844388
-100.0 1.2246467991473532e-14
-50.00000000000004 -86.60254037844383
50.000000000000014 -86.60254037844386
Exemple 2
5.5
5.5 0.0
2.7500000000000004 4.763139720814412
-2.7499999999999987 4.763139720814413
-5.5 6.735557395310443e-16
-2.7500000000000027 -4.7631397208144115
2.7500000000000004 -4.763139720814412
Consignes
— Pour les calculs utilisez la valeur pi et les fonctions sin et cos du module math, comme indiqué sur la figure « Coordonnées
d’un sommet de l’hexagone ».
— Notez qu’il n’est pas demandé de tester si la valeur lue est bien strictement positive ; nous vous assurons que ce sera le cas
pour les valeurs passées au programme dans les tests d’UpyLaB.
— Il ne vous est pas demandé de tracer l’hexagone, mais uniquement d’afficher des valeurs. Notez qu’UpyLaB ne supporte pas
le module turtle et donc ne l’importez pas dans votre code pour cet exercice !
— Vous constaterez que l’utilisation des fonctions sin() et cos() et les erreurs d’arrondis et de troncature durant les calculs
induiront que les résultats peuvent être un peu différents du résultat théorique ;
Pour l’exemple 1 plus haut, les résulats plus précis devraient être :
100.0 0.0
50.0 86.6025403784438
-50 86.6025403784438
-100.0 0.0
-50.0 -86.6025403784438
50.0 -86.6025403784438
√
où 86.6025403784438 est une valeur approchée de la valeur de 100. 23 .
UpyLaB laisse une certaine latitude (ici de l’ordre de 1.0𝑒 − 5).
— Attention, nous rappelons que votre code sera évalué en fonction de ce qu’il affiche, donc veillez à n’imprimer que
le résultat attendu. En particulier, il ne faut rien écrire à l’intérieur des appels à input (int(input()) et non
int(input("Entrer un nombre : ") par exemple), ni ajouter du texte dans ce qui est imprimé (print(res) et
non print("résultat :", res)) par exemple).
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Pour tester votre code, UpyLaB va l’exécuter plusieurs fois en lui fournissant à chaque test un nombre différent en entrée. Il
vérifiera alors que le résultat affiché par votre code correspond à ce qui est attendu. N’hésitez donc pas à tester votre code en
l’exécutant plusieurs fois dans votre IDE (Thonny ou PyCharm par exemple) avec des valeurs différentes.
— Veillez à ce que votre affichage corresponde bien à ce qui est attendu ; (1.0, 0.0) n’est pas la même chose que 1.0
0.0. Utilisez deux variables distinctes pour chacune des coordonnées et imprimez-les grâce à l’instruction print(x, y).
— Si rien ne marche : consultez la FAQ sur UpyLaB 2.4. Vous y trouverez en particulier quelques indices sur les calculs à
effectuer.
Vous n’arrivez pas à réaliser l’exercice. Voici une solution pour le résoudre :
long = float(input())
print(long * cos(0), long * sin(0))
print(long * cos(pi / 3), long * sin(pi / 3))
print(long * cos(pi * 2 / 3), long * sin(pi * 2 / 3))
print(-long, 0.0)
print(long * cos(4 / 3 * pi), long * sin(4 / 3 * pi))
print(long * cos(5 / 3 * pi), long * sin(5 / 3 * pi))
Dans ce cours, nous ne voulons pas vous donner d’informations inutiles pour votre apprentissage. Par exemple, il est à ce stade
inutile de trop détailler comment l’interpréteur Python réalise son travail. Il est pourtant important d’avoir certains éléments qui
vont vous permettre de mieux comprendre le pourquoi des choses, et ainsi de savoir à quoi il faut faire attention dans vos codes.
Ainsi, pourquoi Python distingue-t-il les valeurs entières et fractionnaires ?
La réponse est dans le stockage en mémoire de l’ordinateur.
Entiers (int)
Tant que l’interpréteur Python a de la place mémoire disponible, il stocke des entiers aussi grands que demandé.
Si l’on demande à l’interpréteur Python dans une console interactive
>>> 3**100
>>> 3**1000
>>> 3**10000
les calculs peuvent prendre du temps mais vous pouvez vérifier que l’interpréteur donne le résultat.
Par contre, les valeurs entières ne stockent bien évidemment pas les parties fractionnaires ; ainsi
>>> 1 // 3
ou même
>>> 1 // 3 * 3
donnent la valeur 0.
Fractionnaires (float)
Pour les valeurs float, l’interpréteur fait des calculs et encode les valeurs dans un mot mémoire généralement de 64 bits, avec
la meilleure précision qu’il peut et en retenant également le signe et une partie exposant pour pouvoir représenter des petits ou des
grands nombres (grosso modo jusqu’environ 10e-300 pour le plus petit nombre strictement positif et 10e300 pour le plus grand).
Pour comprendre comment cela se passe, un parallèle peut être fait avec la représentation décimale des nombres fractionnaires :
si on doit représenter 1/3 en nombre décimal avec un nombre fixé, par exemple 5, de chiffres après le point décimal, cela donne
0.33333 et on perd de la précision.
La représentation de nombres float en Python est similaire sauf que tout est représenté en binaire, c’est-à-dire avec comme seuls
chiffres des 0 et des 1.
Nous vous invitons à tester cela vous-même dans une console en tapant par exemple :
>>> 1.0e308
>>> 1.0e309
>>> 1.0e-323
>>> 1.0e-324
>>> 1.00000000000000001
print('\n\nBonjour\n\n')
demande d’imprimer le texte qui contient au début 2 passages à la ligne suivi du texte Bonjour et terminé par à nouveau 2 passages
à la ligne (soit 11 caractères au total qui seront imprimés sur 4 lignes).
Le tableau suivant donne quelques caractères spéciaux dénotés grâce au caractère d’échappement. Notez que de ce fait, pour spécifier
qu’un caractère antislash fait partie du texte, il faut mettre deux antislashs : la première exprimant que ce qui suit est le caractère
antislash lui-même.
print('\\')
N’hésitez pas à tester ces caractères par vous-même pour être sûr que vous les maîtrisez.
Nous avons vu qu’au début de nos scripts, il était recommandé de mettre un commentaire multiligne donnant des informations sur
ce que fait ce script, son auteur, la date de création et éventuellement de dernière modification.
Un commentaire multiligne est en fait une chaîne de caractères multiligne qui peut être manipulée comme n’importe quelle autre
chaine de caractères. Sa particularité est qu’il peut s’étaler sur plusieurs lignes ; chaque passage à la ligne correspondant au caractère
dénoté \n.
Par exemple, le code
mon_texte = '\n\nBonjour\n\n'
Bonjour
"""
Dans ce cas, faites attention à l’indentation puisque ici, tout ce qui est entre les trois doubles quotes fait partie du texte.
Pour être précis l’interpréteur Python manipule des objets contenant les valeurs et des variables qui sont des noms pour les objets.
Notons que l’instruction d”assignation multiple
x = y = 3
crée un objet de type entier contenant la valeur 3 ; x et y sont deux noms donnés à cet objet.
Si juste après, l’interpréteur exécute
x = 4
après cette instruction, la variable x aura changé de valeur et vaudra 4 (x désigne la valeur 4), tandis que y reste inchangée et a
toujours la valeur 3.
Les opérateurs de mise à jour
Python permet d’écrire de façon courte des opérations qui consistent à prendre la valeur d’une variable et de lui appliquer une
opération avec une valeur comme deuxième opérande.
L’exemple le plus courant est l”incrémentation :
supposons que x soit égal à 5 (par exemple après l’assignation x = 5)
x += 1
Le code ci-dessus assigne 5 à la variable x, ensuite évalue 5 * 7 avant d’incrémenter x du résultat. C’est donc l’équivalent de x
= x + (5 * 7).
Ce principe peut être appliqué avec tous les opérateurs arithmétiques (+=, -=, *=, /=, //=, **=, %=).
Comme déjà annoncé, on ne peut devenir un bon codeur sans la mise en pratique répétée des concepts vus.
C’est le rôle d’UpyLaB de vous obliger à réaliser cette pratique.
Nous vous demandons de réaliser l’ensemble des exercices du module 2 qu’il vous reste à faire et qui sont donnés dans les pages
suivantes de cette section.
En cas de difficultés, nous vous rappelons ces quelques conseils :
1. Relire l’énoncé et les consignes associés à l’exercice ainsi que les éventuels conseils.
2. Lire la FAQ générale à propos des exercices UpyLaB.
3. Lire, si elle existe, la FAQ spécifique à l’exercice réalisé.
4. Si rien de tout cela ne fonctionne, poser votre question sur le Forum dédié aux exercices, en étant le plus précis possible,
sans mettre votre code complet ni substantiel mais en mettant des copies d’écran des résultats fournis par UpyLaB.
Énoncé
Le but de cet exercice est de vous familiariser avec la syntaxe Python pour écrire des expressions arithmétiques simples et avec
l’instruction print qui affiche (on dit aussi imprime) des valeurs à l’écran.
Écrire un programme qui lit deux valeurs entières 𝑥 et 𝑦 strictement positives suivies de deux valeurs réelles (float) 𝑧 et 𝑡, et qui
affiche les valeurs des expressions suivantes, chacune sur une nouvelle ligne :
— 𝑥−𝑦
— 𝑥+𝑧
— 𝑧+𝑡
— 𝑥.𝑧 (produit de 𝑥 et de 𝑧)
— 𝑥2
𝑥
— 𝑦+1
— (𝑥+𝑦).𝑧
4.𝑥
1
— 𝑥− 2 (𝑥 exposant − 12 )
Exemple
2
1
3.0
3.5
1
5.0
6.5
6.0
1.0
1.0
1.125
0.7071067811865476
Consignes
— Il n’est pas demandé de tester si les valeurs de x et de y sont bien strictement positives.
— Attention, nous rappelons que votre code sera évalué en fonction de ce qu’il affiche, donc veillez à n’imprimer que
le résultat attendu. En particulier, il ne faut rien écrire à l’intérieur des appels à input (int(input()) et non
int(input("Entrer un nombre : ")) par exemple), ni ajouter du texte dans ce qui est imprimé (print(res)
et non print("résultat :", res) par exemple).
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Pour tester votre code, UpyLaB va l’exécuter plusieurs fois en lui fournissant à chaque test des nombres différents en entrée.
Il vérifiera alors que le résultat affiché par votre code correspond à ce qui est attendu. N’hésitez donc pas à tester votre code
en l’exécutant plusieurs fois dans votre IDE (Thonny ou PyCharm par exemple) avec des valeurs différentes en entrée.
— Si rien ne marche : consultez la FAQ sur UpyLaB 2.5.
Énoncé
Le but de cet exercice est de vous familiariser avec l’impression de certains caractères particuliers comme les simples et double
quotes (apostrophes), l’anti-slash » (appelée également la barre oblique inversée \), . . .
Écrire un programme affichant les quatre lignes suivantes :
Hello World
Aujourd'hui
C'est "Dommage !"
Hum \o/
Consignes
Veillez à ce que votre programme n’affiche rien de plus que ce qui est attendu : pas d’espace en fin de ligne, pas de ligne vide
supplémentaire, . . . , et faites attention aux détails : respectez la ponctuation (les simples et doubles quotes sont droites), le nombre
d’espaces entre les mots. . .
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Si votre code n’est pas accepté et qu’il semble pourtant afficher ce qui est attendu, c’est qu’il peut y avoir des espaces
superflues en fin de ligne. Attention en particulier à la fonction print, qui ajoute par défaut une espace entre ses arguments
s’il y en a plusieurs. Une solution consiste à modifier l’argument nommé sep de cette fonction, en lui attribuant par exemple
la valeur chaîne vide (sep = ""), ou encore à utiliser plusieurs appels à cette fonction.
— Si rien ne marche : consultez la FAQ sur UpyLaB 2.6.
Écrire un programme qui imprime la valeur du volume d’une sphère de rayon r, float lu en entrée.
On rappelle que le volume d’une sphère de rayon 𝑟 est donné par la formule : 43 𝜋𝑟3
Exemple 1
1.0
4.1887902047863905
Exemple 2
0.5
0.5235987755982988
Consignes
— Il n’est pas demandé de tester si la valeur lue en entrée est bien positive ou nulle.
— Attention, nous rappelons que votre code sera évalué en fonction de ce qu’il affiche, donc veillez à n’imprimer que
le résultat attendu. En particulier, il ne faut rien écrire à l’intérieur des appels à input (int(input()) et non
int(input("Entrer un nombre : ")) par exemple), ni ajouter du texte dans ce qui est imprimé (print(res)
et non print("résultat :", res) par exemple).
— Pour rappel, en Python, l’opérateur exposant est **. Ainsi, 2 ** 3 vaut 8 soit 2 * 2 * 2.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Pour tester votre code, UpyLaB va l’exécuter plusieurs fois en lui fournissant à chaque test des nombres différents en entrée.
Il vérifiera alors que le résultat affiché par votre code correspond à ce qui est attendu. N’hésitez donc pas à tester votre code
en l’exécutant plusieurs fois dans votre IDE (Thonny ou PyCharm par exemple) avec des valeurs différentes en entrée.
— Si rien ne marche : consultez la FAQ sur UpyLaB 2.7.
MINI QUIZ
BILAN EN BREF
BILAN DU MODULE
Nous voici à la fin de ce module. Nous avons déjà vu beaucoup de concepts de base Python 3 dont voici les principaux :
— Nous avons vu que l’interpréteur Python 3 peut être utilisé en mode interactif ou en mode script en particulier dans l’envi-
ronnement PyCharm.
— Nous avons vu qu’un code Python peut utiliser des valeurs et expressions entières (int), fractionnaires (float) ou chaînes de
caractères (str pour string), la fonction prédéfinie type(x) donnant le type de x.
— Votre code peut être déclaré incorrect parce qu’il contient des erreurs syntaxiques.
— Nous avons également vu que Python peut se créer des variables ayant des valeurs grâce à l’instruction d”assignation
(appelée également affectation).
— Les instructions input et print permettent au script Python de “recevoir des données” de l’utilisateur et d” “imprimer
des résultats”.
— Pour avoir un code plus lisible pour le programmeur, des commentaires simples et multilignes peuvent être écrits dans le
code.
— Python offre des fonctions prédéfinies (type(), int(), float(), dir() et help() et max(), round(),
divmod(). . . ), ainsi que des modules comme math et turtle, utilisables via le verbe import.
— Nous avons vu que les diagrammes d’état expliquent de façon graphique comment fonctionne un code Python et que l’outil
Python Tutor (accessible via la page web [Link]) permet de visualiser ces diagrammes d’état en exécutant pas à
pas les petits scripts Python fournis.
— Nous avons également illustré tous ces concepts avec de nombreux exemples et la réalisation d’exercices supervisés ou
réalisés de façon autonome avec UpyLaB.
La vidéo qui suit présente le menu du présent module : l’étude des instructions de contrôle de flux Python. Elles sont appelées
instructions de contrôle de flux parce qu’elles permettent de rompre la simple séquence d’exécution comme ce que nous avons vu
jusqu’à présent. Nous verrons que ces instructions sont essentielles pour rédiger du code Python.
MENU DE CE MODULE
3.2.1 L’instruction if
La présente section vous explique tout ce qui vous sera nécessaire sur l’instruction conditionnelle if.
Cette vidéo introduit l’instruction if qui permet d’exécuter certaines instructions uniquement si une condition est vérifiée.
Comme le traitement va dépendre d’une condition, nous parlerons de l’instruction conditionnelle if.
Nous partons d’un exemple simple avec seulement le mot-clé if pour expliquer le fonctionnement de cette instruction et petit à
petit, nous ajoutons des éléments, en particulier qui utilisent les mots-clés elif et else, pour montrer différentes possibilités.
CC BY-SA 3.0 - 2021 - Sébastien Hoarau - Thierry Massart - Jean Olgiati - Isabelle Poirier 71
Apprendre à coder avec Python, Version - Release 3.0
PRÉSENTATION DE L’INSTRUCTION IF
CONTENU DE LA VIDÉO
La vidéo précédente présente l’instruction conditionnelle if et ses formats possibles : sans parties else et elif, avec une partie
else et avec une partie elif.
Scripts et code sur la console réalisés dans la vidéo
maximum = 0
releve = int(input())
if releve > maximum :
maximum = releve
print("Nous avons un nouveau record")
print("Maximum retenu :", maximum)
>>> 3 < 5
True
>>> 5 < 3
False
>>> type(False)
<class 'bool'>
>>> type(True)
<class 'bool'>
>>> type(3<5)
<class 'bool'>
>>> x = int(input())
>? 5
>>> if x < 0:
... print("ok")
...
>>>
maximum = 10
releve = int(input())
if releve > maximum :
maximum = releve
print("Nous avons un nouveau record")
else:
print("Pas de nouveau record")
print("Maximum retenu :", maximum)
maximum = 10
releve = int(input())
if releve == 0:
print("Pas de pluie aujourd'hui")
elif releve > maximum :
maximum = releve
print("Nous avons un nouveau record")
else:
print("Pas de nouveau record")
print("Maximum retenu :", maximum)
La vidéo en bref
L’instruction conditionnelle if est présentée grâce à des scripts. Sa forme la plus simple est :
if condition:
instructions
où la condition peut par exemple être une comparaison entre deux valeurs en utilisant un opérateur relationnel tel que :
— est strictement inférieur < ou
— est strictement supérieur >.
Cette comparaison donne une valeur de type booléenne vraie (True) ou fausse (False).
L’indentation permet d’identifier les instructions dans le if.
Un else peut être ajouté à la fin de l’instruction if et une ou plusieurs parties elif peuvent être également ajoutées comme
montré dans la vidéo.
L’instruction if avec parties elif et else a la forme :
if condition:
instructions
elif condition:
instructions
elif condition:
instructions
...
else:
instructions
Dans tout les cas, au maximum une seule « branche » est exécutée, et elle correspond au premier test évalué à vrai soit au niveau
du if soit au niveau d’un elif et sinon, au niveau du else s’il existe. Ensuite l’interpréteur Python passe à l’instruction
suivante.
Si tous les tests du if et elif sont évalués à faux et qu’il n’y a pas de partie else, aucune « branche » du if ne sera exécutée.
Nous avons vu qu’un élément clé de l’instruction if est la condition associée, dont la valeur, vraie (True) ou fausse (False), est
souvent le résultat de comparaisons entre valeurs. Donnons ici tous les opérateurs de comparaison, appelés opérateurs relationnels
Python.
Supposons que les variables a et b aient chacun une certaine valeur (par exemple a = 3 et b = 5). Les opérateurs de comparai-
sons, appelés dans le jargon informatique opérateurs relationnels, possibles sont :
Attention : à ne pas confondre ou utiliser l’assignation = à la place de l’opérateur relationnel d’égalité ==.
ANNÉE BISSEXTILE
Continuons ici d’illustrer l’utilisation du if, sur un exemple concret : un code qui reçoit une année et affiche si celle-ci est ou non
bissextile (c’est-à-dire qui comprend 366 jours dont un 29 février).
Version simple sans elif
Dans une première approximation, nous considérons que nous avons une année bissextile tout les quatre ans et que l’année bissextile
est celle dont la valeur est divisible par 4 (par exemple 2020 est bissextile).
Un nombre x est divisible par 4 si le reste de la division entière de x par 4 vaut zéro. En Python cela se teste aisément avec x % 4
== 0.
Le premier code complet est donc :
annee = int(input())
if annee % 400 == 0:
print('bissextile')
elif annee % 100 == 0:
print('non bissextile')
elif annee % 4 == 0:
print('bissextile')
else:
print('non bissextile')
Donnons un autre exemple plus mathématique cette fois : analysons comment écrire un code qui calcule la ou les éventuelles racines
d’une équation du second degré.
Note : Ceux qui ne désirent pas faire des mathématiques maintenant peuvent simplement ignorer cet exemple qui ne donne pas de
nouvelles notions Python.
𝑎𝑥2 + 𝑏𝑥 + 𝑐 = 0
où 𝑎, 𝑏 et 𝑐 sont des valeurs réelles, pour savoir si cette équation a deux, une ou aucune racines réelles, il faut calculer le discriminant
delta qui vaut :
𝑑𝑒𝑙𝑡𝑎 = 𝑏2 − 4𝑎𝑐
Code de l’animation
a= float(input('a : '))
b= float(input('b : '))
c= float(input('c : '))
if delta < 0:
print(" pas de racines réelles")
elif delta == 0:
print("une racine : ")
print("x = ", -b/(2*a))
else:
racine = delta**0.5
(suite sur la page suivante)
Continuons à compléter les possibilités d’une instruction if. Plus précisément regardons les opérateurs qui peuvent être présents
dans une condition associée à un if ou un elif.
La condition d’un if est une expression booléenne qui peut utiliser la valeur True ou False, ou une comparaison de valeurs avec
des opérateurs relationnels, ou également les opérateurs logiques and, or et not.
Regardons sur quelques exemples comment fonctionnent les opérateurs logiques, appelés aussi opérateurs booléens, en supposant
que la variable x contient une valeur entière.
— 0 <= x and x < 10 : teste si la valeur de x est dans l’intervalle [0 .. 10[ c’est-à-dire si la valeur de x est supérieure ou
égale à 0 et aussi strictement inférieure à 10.
— flag = x < 0 or 10 <= x : assigne à la variable flag une valeur logique vraie si la valeur de x est soit strictement
inférieure à 0 soit supérieure ou égale à 10, et fausse sinon.
— not (x < 0) : est équivalent à x >= 0.
Notez que, pour x valant 6,
if x % 2 == 0 or x % 3 == 0:
print('x pair ou multiple de 3')
a b not a a and b a or b
False False True False False
False True True False True
True False False False True
True True False True True
(expression)
** associatif à droite
* / // % associatifs à gauche
+- associatifs à gauche
< <= > >= != == associatifs à gauche
not x
and associatif à gauche
or associatif à gauche
où les opérateurs sur une même ligne ont le même niveau de priorité.
Lois de De Morgan
Les lois de De Morgan sont fréquemment utilisées pour simplifier les tests ; ayant des expressions logiques a et b
— not (a or b) est équivalente à (not a) and (not b) ;
— not (a and b) est équivalente à (not a) or (not b).
Ainsi :
est équivalent à
qui par ailleurs vaut, en prenant les opérateurs duaux de <= et de < (sachant que > est l’opérateur dual de <= et vice versa) :
0 > x or x >= 10
Grâce à l’utilisation des opérateurs logiques, nous pouvons maintenant produire un code plus simple du script qui affiche si une
année lue en input est bissextile.
En effet, comme il n’y a que deux cas possibles (soit l’année est bissextile soit elle ne l’est pas) il est logique d’avoir une simple
instruction if qui teste par exemple tous les cas où l’année est bissextile suivie d’un seul else dans le cas contraire.
Voici un exemple de code pour cela :
Notez que les parenthèses ont été mises pour clarifier la lecture du code, mais vu que le and est plus prioritaire que le or, elles ne
sont pas nécessaires.
SYNTAXE GÉNÉRALE DU IF
Maintenant que nous avons introduit progressivement à partir d’exemples comment fonctionne l’instruction if, découvrons sa
forme générale. Effectivement, avant de pouvoir utiliser l’instruction if totalement à bon escient, il faut connaître ses syntaxe et
sémantique ainsi qu’un certain nombres de règles que nous vous livrons dans cette activité.
La syntaxe générale de l’instruction if, telle que vous la trouverez dans les manuels de référence Python, est donnée par :
"if" expression ":" suite
("elif" expression ":" suite )*
["else" ":" suite]
où :
— "if", "elif", "else" sont des mots-clés ; les doubles apostrophes ne doivent pas être écrites,
— expression est une expression booléenne,
— le caractère ":" sans les doubles apostrophes est mis après expression à la ligne du if ou des elif ou après le mot-clé
else,
— suite est un bloc d’instructions indentées, c’est-à-dire décalées par exemple de 4 caractères vers la droite mises sur la ou
les lignes suivantes,
— ( ... )* est une méta-notation signifiant que la ligne peut ne pas être mise ou être mise une ou plusieurs fois,
— [...] est une méta-notation signifiant que la ligne est optionnelle, c’est-à-dire peut ou non être mise.
MOTS-CLÉS ET IDENTIFICATEURS
Dans les présentations précédentes de ce module, nous avons parlé de mots-clés. Avant de continuer, il est important d’expliquer un
peu plus le but de ces mots-clés et ce à quoi il faut faire attention.
Mots-clés
Les mots-clés (keywords en anglais) Python caractérisent certains éléments du langage. Par exemple, le mot-clé if exprime que
ce qui suit est une instruction conditionnelle. Ils doivent être écrits tel que spécifié ; par exemple pour le mot-clé if, les caractères
doivent être des minuscules.
Python possède une trentaine de mots-clés dont la liste (pour Python 3.7) est la suivante :
Nous en avons déjà vu certains, comme import, if, elif, else, and, or, . . .
Nous en verrons d’autres dans ce cours, mais pas tous. Certains correspondent en effet à des concepts avancés.
Identificateurs
En dehors des mots-clés, un programme Python utilise entre autres des variables et des fonctions. Chaque variable et fonction porte
généralement un nom. Par exemple dans les exemples précédents nous avions x, a et delta comme noms de variables ou int,
input, print comme noms de fonctions prédéfinies ou de type.
Dans le jargon informatique, ces noms de variables, fonctions, types sont appelés identificateurs. Comme son nom l’indique, un
identificateur est le nom qui identifie quelque chose. Un identificateur n’est pas un mot-clé.
Comme les mots-clés sont des mots réservés pour dénoter quelque chose de précis dans le langage, il ne peuvent évidemment pas
être utilisés à d’autres fins. Ainsi, essayer d’appeler une variable avec le nom d’un mot-clé va générer une erreur lors de l’exécution.
Par exemple si nous demandons à l’interpréteur d’exécuter
if = 5
SyntaxError: invalid syntax
il m’indique qu’il y a une erreur de syntaxe puisque l’interpréteur s’attend, après le mot-clé if, à avoir une expression booléenne et
une suite bien précise et pas un symbole d’assignation comme ici.
Lors de la rédaction d’un code Python, nous devons donc bien faire attention à ne pas utiliser un mot-clé pour nommer par exemple
une variable.
Notons que réutiliser, comme nom d’identificateur, le nom d’un identificateur prédéfini est possible même si c’est une très mauvaise
idée. Ainsi on peut écrire :
print = 3
donnera une erreur puisque print ne correspond plus à la fonction prédéfinie, mais à une variable entière et donc lui accoler des
parenthèses ne veut plus rien dire.
Ne faites donc pas cela !
Respectez parfaitement l”indentation des instructions Python, c’est-à-dire le fait d’écrire les lignes de code associées à un if, elif
ou else, en les décalant de par exemple 4 caractères.
Faites-y toujours bien attention sachant que :
où, quelle que soit la valeur lue, le message “Au revoir” est affiché à l’écran, est différent du code :
où le message “Au revoir” n’est affiché que si la valeur lue est strictement positive.
L’oubli ou une mauvaise indentation est une erreur très fréquente quand vous débutez en programmation Python. Cela peut générer
des erreurs de syntaxe ou pire, des erreurs dans les instructions qu’il fallait exécuter pour que le code soit correct.
IF IMBRIQUÉS
Un code Python peut également avoir des if imbriqués par exemple pour distinguer des sous-cas. Il faut bien faire attention à
l’indentation comme le montrent les deux bouts de code suivants :
Code 1
if a > 0 :
if b > 0 :
print("cas 1")
else :
print("cas 2")
if a > 0 :
if b > 0 :
print("cas 1")
else :
print("cas 2")
ÉVALUATION PARESSEUSE
Il nous reste à voir une dernière règle qui pourra s’avérer très utile sur l’évaluation des expressions booléennes. Python est paresseux
quand il évalue certaines expressions.
En clair, en Python,
— si l’expression booléenne est un and et la valeur de gauche est évaluée à Faux, la partie à droite du and n’est jamais évaluée
et la réponse au test complet est Faux ;
— de façon duale, si l’expression booléenne est un or et si la valeur de gauche est Vraie, la partie à droite du or n’est jamais
évaluée et la réponse au test complet est Vrai.
L’évaluation paresseuse peut être utile si par exemple la première partie de la condition détermine si le second test peut être réalisé.
Par exemple : avec deux variables a et b contenant chacune une valeur entière positive, le code suivant est correct :
if a != 0 and b % a == 0:
print(b, "est un multiple de", a)
Il teste d’abord la condition a != 0 ; si ce test est faux, l’évaluation de la condition complète s’arrête et a la valeur False. Si par
contre la condition a != 0 a la valeur True, l’évaluation de la condition b % a == 0 est effectuée par l’interpréteur.
Cette façon de faire permet donc de s’assurer que le calcul du modulo (b % a) ne va pas donner une erreur à l’exécution (division
par zéro) et sinon de ne pas faire cette opération.
Maintenant que vous maîtrisez les subtilités de l’instruction if, passons à la pratique !
Écrivons d’abord un programme qui propose un petit jeu à l’utilisateur. Par la suite nous compléterons ce jeu et nous reviendrons à
ce programme plus tard dans ce module afin d’illustrer d’autres instructions.
Commençons par une première version simplifiée dans laquelle :
Consignes : le programme :
— choisit aléatoirement un nombre entre 0 et 5 sans en afficher la valeur (et donc sans que l’utilisateur connaisse cette valeur)
et le place dans la variable secret ;
— demande à l’utilisateur de deviner la valeur choisie ;
— affiche "gagné !" si l’utilisateur trouve la bonne réponse et
— affiche "perdu ! La valeur était " suivi de la valeur de secret dans le cas contraire.
Petite astuce pour vous permettre de vous lancer
En informatique, la génération de nombres aléatoires se fait généralement par une fonction qui fait des calculs en fonction de
paramètres divers et produit un résultat dans l’intervalle demandé. On parle donc plutôt de génération de nombre pseudo aléatoire.
En effet, si le nombre est vu par l’utilisateur comme étant aléatoire, il provient en réalité de calculs précis effectués par l’ordinateur.
En Python, le module random peut être utilisé à cette fin. En particulier random contient la fonction prédéfinie randint(a,
b) où a et b sont des valeurs entières (par exemple 0 et 5). À chaque nouvel appel, randint génère un nombre pseudo aléatoire
dans l’intervalle entre la valeur a et la valeur b toutes deux comprises ([a, b]).
Le code peut donc commencer par :
import random
secret = [Link](0, 5)
À vous de jouer ! Écrivez un script dans votre IDE (Thonny ou PyCharm par exemple) qui résout l’exercice proposé avec les
consignes données ci-dessus.
PROPOSITION DE SOLUTION
Quand plusieurs personnes écrivent du code pour résoudre un problème, comme ici avec le petit jeu de devinette, les codes sont très
certainement différents même s’ils peuvent tous parfaitement résoudre le problème. Malgré cela, il peut quand même être intéressant
de comparer les solutions pour voir laquelle semble la plus claire ou la plus efficace. Ainsi, si vous voulez comparer votre solution
avec un autre code qui résout le problème quand vous aurez terminé, ou si vous avez besoin d’un petit coup de pouce, la vidéo
suivante propose une solution.
PROPOSITION DE SOLUTION
CONTENU DE LA VIDÉO
La vidéo précédente présente une solution du petit jeu de devinette. Le code d’une solution est donné plus bas.
import random
secret = [Link](0,5)
choix_utilisateur = int(input("Donnez votre choix pour la valeur secrète : "))
if secret == choix_utilisateur:
print("gagné !")
else:
print("perdu ! La valeur était", secret)
print("Au revoir !")
Nous voici arrivés à la troisième phase d’apprentissage en ce qui concerne l’instruction if. Dans l’activité qui va suivre, nous
vous proposons d’utiliser notre exerciseur UpyLaB pour tester de manière autonome plusieurs exercices qui demandent d’utiliser
l’instruction if.
Vous pouvez désormais réaliser les exercices UpyLaB 3.1 à 3.8 du Module 3, donnés aux pages qui suivent. Avant cela, lisez bien
les rappels et recommandations ci-dessous.
RAPPELS IMPORTANTS
Note : Nous n’insisterons jamais assez sur le fait que, lors du développement de chacun de vos codes, il est plus que vivement
conseillé d’utiliser un environnement de développement de type PyCharm ou Python Tutor pour tester ou même déboguer pas par
pas votre code avant de passer aux tests UpyLaB. En effet, faire tester directement par UpyLaB un code dont vous n’avez pas une
certaine confiance dans le fait qu’il soit correct s’avère souvent être un gouffre au niveau du temps étant donné qu’UpyLaB est
moins précis qu’un environnement de développement pour vous expliciter où se situent les éventuels problèmes qui ne manqueront
pas d’apparaître.
La démarche la plus efficace pour développer du code en Python est donc :
1. de comprendre exactement ce qui vous est demandé,
2. de développer une solution dans votre IDE en la testant, éventuellement avec Python Tutor, pour vous assurer qu’elle résout
correctement le problème posé,
3. de tester l’ensemble de votre code dans UpyLaB (en le transférant dans UpyLaB grâce au copier / coller du code depuis
votre IDE) pour faire valider votre script.
Attention : Rappelez-vous également de bien suivre les autres Conseils et consignes lors de la réalisation d’exercices Upy-
LaB (cf section 2.5) et que le but de réaliser les exercices UpyLaB est de vous rendre autonome en programmation. C’est vous
qui devez trouver la ou une solution, en terme de code Python, à chaque exercice demandé. Le forum ne doit donc pas être
l’endroit où des codes complets ou substantiels sont échangés. Vos éventuelles questions doivent être précises et les réponses
ponctuelles.
N’oubliez pas ce qui a été dit en début de cours sur les exercices UpyLaB !
1) Contrairement aux quiz, les exercices UpyLaB peuvent être testés autant de fois que vous le désirez.
2) Pour enregistrer votre réponse dans un exercice UpyLaB vous devez cliquer sur le bouton « Vérifier » même si vous savez
que votre code n’est pas correct ; ce n’est pas un souci puisque le nombre de fois que vous vérifiez chaque exercice UpyLaB
n’est pas limité.
3) Attention, si pour un exercice UpyLaB, la dernière vérification est négative, la plateforme ne retient pas si une vérification
précédente avait été positive. En clair, la plateforme ne vous accorde les points que si la dernière vérification de cet exercice
est positive.
Énoncé
Écrire un programme qui lit 3 nombres entiers, et qui, si au moins deux d’entre eux ont la même valeur, imprime cette valeur (le
programme n’imprime rien dans le cas contraire).
Exemple 1
2
1
2
Exemple 2
1
2
3
Exemple 3
42
42
42
42
Consignes
— Attention, nous rappelons que votre code sera évalué en fonction de ce qu’il affiche, donc veillez à n’imprimer que le résultat
attendu.
— En particulier, il ne faut rien écrire à l’intérieur des appels à input (int(input()) et non int(input("Entrer un
nombre : ")) par exemple), ni ajouter du texte dans ce qui est imprimé (print(res) et non print("résultat
:", res) par exemple).
Quand votre solution sera validée, cliquez sur le bouton « AFFICHER LA RÉPONSE » pour trouver des conseils de bonnes
pratiques et éventuellement améliorer votre façon de coder.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Pour tester votre code, UpyLaB va l’exécuter plusieurs fois en lui fournissant à chaque test des nombres différents en entrée.
Il vérifiera alors que le résultat affiché par votre code correspond à ce qui est attendu. N’hésitez donc pas à tester votre code
en l’exécutant plusieurs fois dans votre IDE (Thonny ou PyCharm par exemple) avec des valeurs différentes en entrée.
— Si rien ne marche : consultez la FAQ sur UpyLaB 3.1.
Énoncé
Écrire un programme qui, si temperature (entier lu sur input correspondant à la température maximale prévue pour aujour-
d’hui) est strictement supérieur à 0, teste si temperature est inférieur ou égal à 10, auquel cas il imprime le texte :
— Il va faire frais.
et qui, si temperature n’est pas supérieur à 0, imprime le texte :
— Il va faire froid.
Dans les autres cas, le programme n’imprime rien.
Exemple 1
Il va faire frais.
Exemple 2
20
Exemple 3
-1
Il va faire froid.
Consignes
— Attention, nous rappelons que votre code sera évalué en fonction de ce qu’il affiche, donc veillez à n’imprimer que
le résultat attendu. En particulier, il ne faut rien écrire à l’intérieur des appels à input (int(input()) et non
int(input("Entrer un nombre : ")) par exemple), ni ajouter du texte dans ce qui est imprimé (print(res)
et non print("résultat :", res) par exemple).
— Faites attention d’écrire les messages à l’identique de ce qui est demandé (majuscule au début de la ligne, une espace entre
chaque mot, etc) . Un conseil pour avoir des messages identiques est de les copier depuis l’énoncé pour les coller dans votre
code.
— Lors de l’affichage des résultats, en cas d’erreur dans certains tests, UpyLaB pourra marquer : « Le résultat attendu était :
aucun résultat ». Cela voudra bien dire qu’il ne faut rien imprimer dans ce cas.
Quand votre solution sera validée, cliquez sur le bouton « AFFICHER LA RÉPONSE » pour trouver des conseils de bonnes
pratiques et éventuellement améliorer votre façon de coder.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Pour tester votre code, UpyLaB va l’exécuter plusieurs fois en lui fournissant à chaque test des nombres différents en entrée.
Il vérifiera alors que le résultat affiché par votre code correspond à ce qui est attendu. N’hésitez donc pas à tester votre code
en l’exécutant plusieurs fois dans votre IDE (Thonny ou PyCharm par exemple) avec des valeurs différentes en entrée.
— Si rien ne marche : consultez la FAQ sur UpyLaB 3.2.
Énoncé
Exemple 1
3
2
1
Exemple 2
3
2
4
15
Exemple 3
3
2
5
Erreur
Consignes
— Attention, nous rappelons que votre code sera évalué en fonction de ce qu’il affiche, donc veillez à n’imprimer que le résultat
attendu en respectant l’orthographe, les majuscules / minuscules, les espacements, etc.
— En particulier, il ne faut rien écrire à l’intérieur des appels à input (int(input()) et non int(input("Entrer un
nombre : ")) par exemple), ni ajouter du texte dans ce qui est imprimé (print(res) et non print("résultat
:", res) par exemple).
Quand votre solution sera validée, cliquez sur le bouton « AFFICHER LA RÉPONSE » pour trouver des conseils de bonnes
pratiques et éventuellement améliorer votre façon de coder.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Pour tester votre code, UpyLaB va l’exécuter plusieurs fois en lui fournissant à chaque test des nombres différents en entrée.
Il vérifiera alors que le résultat affiché par votre code correspond à ce qui est attendu. N’hésitez donc pas à tester votre code
en l’exécutant plusieurs fois dans votre IDE (Thonny ou PyCharm par exemple) avec des valeurs différentes en entrée.
— Si rien ne marche : consultez la FAQ sur UpyLaB 3.3.
Énoncé
Écrire un programme qui teste la parité d’un nombre entier lu sur input et imprime True si le nombre est pair, False dans le cas
contraire.
Exemple 1
13
False
Exemple 2
42
True
Consignes
— Attention, nous rappelons que votre code sera évalué en fonction de ce qu’il affiche, donc veillez à n’imprimer que le résultat
attendu.
— En particulier, il ne faut rien écrire à l’intérieur des appels à input (int(input()) et non int(input("Entrer un
nombre : ")) par exemple), ni ajouter du texte dans ce qui est imprimé (print(res) et non print("résultat
:", res) par exemple).
Quand votre solution sera validée, cliquez sur le bouton « AFFICHER LA RÉPONSE » pour trouver des conseils de bonnes
pratiques et éventuellement améliorer votre façon de coder.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Pour tester la parité d’un nombre, on peut s’intéresser au reste de la division de ce nombre par 2 et utiliser l’opérateur
modulo.
— Pour tester votre code, UpyLaB va l’exécuter plusieurs fois en lui fournissant à chaque test des nombres différents en entrée.
Il vérifiera alors que le résultat affiché par votre code correspond à ce qui est attendu. N’hésitez donc pas à tester votre code
en l’exécutant plusieurs fois dans votre IDE (Thonny ou PyCharm par exemple) avec des valeurs différentes en entrée.
— Si rien ne marche : consultez la FAQ sur UpyLaB 3.4.
Énoncé
Écrire un programme qui lit en entrée deux nombres entiers strictement positifs, et qui vérifie qu’aucun des deux n’est un diviseur
de l’autre.
Si tel est bien le cas, le programme imprime True. Sinon, il imprime False.
Exemple 1
6
42
False
Exemple 2
5
42
True
Consignes
— Notez qu’il n’est pas demandé de vérifier que les deux nombres en entrée sont strictement positifs. Vous pouvez supposer
que ce sera le cas pour toutes les entrées proposées par UpyLaB lors des tests.
— Attention, nous rappelons que votre code sera évalué en fonction de ce qu’il affiche, donc veillez à n’imprimer que
le résultat attendu. En particulier, il ne faut rien écrire à l’intérieur des appels à input (int(input()) et non
int(input("Entrer un nombre : ")) par exemple), ni ajouter du texte dans ce qui est imprimé (print(res)
et non print("résultat :", res) par exemple).
Quand votre solution sera validée, cliquez sur le bouton « AFFICHER LA RÉPONSE » pour trouver des conseils de bonnes
pratiques et éventuellement améliorer votre façon de coder.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Dire qu’un nombre entier 𝑥 est un diviseur d’un nombre entier 𝑦 revient à dire que le reste de la division euclidienne de 𝑦
par 𝑥 est égal à 0.
— Pour tester votre code, UpyLaB va l’exécuter plusieurs fois en lui fournissant à chaque test des nombres différents en entrée.
Il vérifiera alors que le résultat affiché par votre code correspond à ce qui est attendu. N’hésitez donc pas à tester votre code
en l’exécutant plusieurs fois dans votre IDE (Thonny ou PyCharm par exemple) avec des valeurs différentes en entrée.
— Si rien ne marche : consultez la FAQ sur UpyLaB 3.5.
Énoncé
√
Écrire un programme qui imprime la moyenne géométrique 𝑎.𝑏 (la racine carrée du produit de 𝑎 par 𝑏) de deux nombres positifs
𝑎 et 𝑏 de type float lus en entrée.
Si au moins un de ces nombres est strictement négatif, le programme imprime le texte « Erreur ».
Exemple 1
1.0
2.0
1.4142135623730951
Exemple 2
-1.0
2.0
Erreur
Consignes
— Attention, nous rappelons que votre code sera évalué en fonction de ce qu’il affiche, donc veillez à n’imprimer que le résultat
attendu.
— En particulier, il ne faut rien écrire à l’intérieur des appels à input (float(input()) et non float(input("Entrer
un nombre : ")) par exemple), ni ajouter du texte dans ce qui est imprimé (print(res) et non
print("résultat :", res) par exemple).
Quand votre solution sera validée, cliquez sur le bouton « AFFICHER LA RÉPONSE » pour trouver des conseils de bonnes
pratiques et éventuellement améliorer votre façon de coder.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Pour calculer la racine carrée d’un nombre positif, on pourra trouver une fonction utile dans le module math, ou se rappeler
que cela correspond à la puissance d’exposant 21 .
— Si vous calculez la puissance d’exposant 12 , pensez bien aux priorités des différents opérateurs.
— Pour tester votre code, UpyLaB va l’exécuter plusieurs fois en lui fournissant à chaque test des nombres différents en entrée.
Il vérifiera alors que le résultat affiché par votre code correspond à ce qui est attendu. N’hésitez donc pas à tester votre
code en l’exécutant plusieurs fois dans votre IDE (Thonny ou PyCharm par exemple) ou dans Python Tutor avec des valeurs
différentes en entrée.
— Si rien ne marche : consultez la FAQ sur UpyLaB 3.6.
Énoncé
Exemple 1
7
9
qui indiquent que le joueur parie sur le numéro 7 et que le numéro sorti est le 9,
le résultat à imprimer vaudra donc
Exemple 2
16
4
qui indiquent que le joueur parie sur la couleur noire et que le numéro sorti est le 4 (qui est noir),
le résultat à imprimer vaudra donc
20
Exemple 3
7
7
qui indiquent que le joueur parie sur le numéro 7 et que le numéro sorti est bien le 7,
le résultat à imprimer vaudra donc
120
Consignes
— Ne mettez pas d’argument dans les input : data = input() et non data = input("Donnée suivante :")
par exemple.
— Le résultat doit juste faire l’objet d’un print(res) sans texte supplémentaire (pas de print("résultat = ",
res) par exemple).
Quand votre solution sera validée, cliquez sur le bouton « AFFICHER LA RÉPONSE » pour trouver des conseils de bonnes
pratiques et éventuellement améliorer votre façon de coder.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Lisez bien l’énoncé. Que représente chacune des deux entrées ? Avez-vous parfaitement analysé les différents cas ?
— Même si le hasard intervient dans cette situation, ici il ne faut pas utiliser le module random. Nous ne simulons pas le tirage
de la roulette, c’est l’utilisateur (le croupier) qui saisira les deux entrées correspondant au pari du joueur, et au résultat du
tirage.
— Pensez à utiliser les opérateurs logiques, mais faites attention à leur priorité : voir section 3.2.3.
— Si rien ne marche : consultez la FAQ sur UpyLaB 3.7.
Énoncé
Les cinq polyèdres réguliers de Platon sont représentés ci-dessous, avec la formule de leur volume.
Source des images de polyèdres : Vikidia, l’encyclopédie pour les jeunes, qui explique aux enfants et à ceux qui veulent une
présentation simple d’un sujet ([Link]
√
2 3
Tétraèdre 12 𝑎
Cube 𝑎3
√
2 3
Octaèdre 3 𝑎
√
15+7 5 3
Dodécaèdre 4 𝑎
√
5(3+ 5) 3
Icosaèdre 12 𝑎
Exemple 1
C
2.0
8.0
Exemple 2
I
2.0
17.4535599249993
Exemple 3
A
2.0
Consignes
— Attention, nous rappelons que votre code sera évalué en fonction de ce qu’il affiche, donc veillez à n’imprimer que le résultat
attendu.
— En particulier, il ne faut rien écrire à l’intérieur des appels à input (float(input()) et non float(input("Entrer
un nombre : ")) par exemple), ni ajouter du texte dans ce qui est imprimé (print(res) et non
print("résultat :", res) par exemple).
Quand votre solution sera validée, cliquez sur le bouton « AFFICHER LA RÉPONSE » pour trouver des conseils de bonnes
pratiques et éventuellement améliorer votre façon de coder.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— La fonction input retourne systématiquement un résultat de type chaîne de caractères. Si ce qui est à lire est un texte ou
un simple caractère, on peut donc utiliser directement le retour de cette fonction, mais s’il s’agit d’un nombre, il faut penser
à le convertir à l’aide des fonctions int ou float.
— Pour tester votre code, UpyLaB va l’exécuter plusieurs fois en lui fournissant à chaque test des nombres différents en entrée.
Il vérifiera alors que le résultat affiché par votre code correspond à ce qui est attendu. N’hésitez donc pas à tester votre code
en l’exécutant plusieurs fois dans votre IDE (Thonny ou PyCharm par exemple) avec des valeurs différentes en entrée.
— Si rien ne marche : consultez la FAQ sur UpyLaB 3.8.
La présente section vous explique tout ce qui vous sera nécessaire sur l’instruction while. Cette vidéo introduit l’instruction while
qui permet d’exécuter certaines instructions de façon répétitive tant qu’une certaine condition est vérifiée. Comme le traitement peut
s’exécuter plusieurs fois, nous parlerons pour l’instruction while mais aussi pour l’instruction for que nous verrons juste après,
d’instructions répétitives while et for. Encore une fois, nous partons d’un exemple simple pour expliquer le fonctionnement de
l’instruction while, et ensuite nous élaborons pour montrer différentes possibilités.
Notons aussi que dans le jargon informatique, les instructions répétitives while et for sont également appelées « boucles » while
ou for pour marquer cette notion de répétition.
CONTENU DE LA VIDÉO
DISTANCE = 3844.0e5
nombre_pliages = 0
epaisseur = 0.0001
while epaisseur < DISTANCE :
epaisseur = 2 * epaisseur
nombre_pliages = nombre_pliages + 1
print('nombre de pliages nécessaire : ', nombre_pliages)
La vidéo en bref
avec le mot-clé while, suivi d’une expression booléenne que l’on appelle souvent condition de continuation, suivie de « : »,
puis de toutes les instructions qui sont indentées par rapport à cette première ligne et qui constituent les instructions associées au
while.
Dans le jargon informatique, on appelle ces instructions le «corps de la boucle while».
Lors de l’exécution d’une instruction while, la condition de continuation est évaluée, et si elle est vraie, le corps de la boucle
while est exécuté, ensuite, on recommence cette séquence : évaluation de la condition, exécution du corps de la boucle jusqu’au
moment où la condition est évaluée à faux.
Notons que cette condition peut être directement fausse ; dans ce cas, le corps de la boucle n’est pas exécuté et l’interpréteur passe
directement à l’instruction après l’instruction while.
42 correspond à la première valeur de 𝑥 telle que 0.0001.2𝑥 ≥ 3.844.108 . Notons pour les forts en math que cela correspond
à la première solution entière de l’inéquation 384400000 < 0.0001.2𝑛 c’est-à-dire à la première valeur entière supérieure à
𝑙𝑜𝑔2 (3844000000000) (en python ceil(log(3840000000000, 2)) où log et ceil (valeur plafond) ont été importées
du module math (from math import ceil, log). C’est donc très facile d’aller sur la Lune : il suffit de plier une feuille 42
fois et de se mettre dessus !
while condition:
instructions
où condition est une expression booléenne appelée condition de continuation et instructions est une instruction ou une
séquence d’instructions indentées par rapport à la ligne while condition:, que l’on nomme généralement corps de la boucle
while.
Un autre exemple plus mathématique mais simple, qui illustre parfaitement l’utilisation de l’instruction répétitive while est le
calcul du plus grand commun diviseur de deux nombres entiers positifs. Rappelons d’abord ce qu’est le plus grand commun diviseur.
Définition du plus grand commun diviseur (pgcd)
Ayant deux nombres entiers positifs 𝑥 et 𝑦 (par exemple 132 et 36),
le plus grand diviseur (pgcd) des deux nombres est le nombre 𝑑 qui est :
— un diviseur entier à la fois de 𝑥 et de 𝑦, c’est-à-dire que
— 𝑥 divisé par 𝑑 donne un nombre entier,
— et de même pour 𝑦 divisé par 𝑑,
— et de plus tel qu’il n’existe pas d’autre entier strictement plus grand que 𝑑 également diviseur entier à la fois de 𝑥 et de
𝑦.
Ainsi on peut vérifier que 12 est le plus grand commun diviseur de 132 et 36.
Calcul du plus grand commun diviseur (pgcd) avec la méthode d’Euclide améliorée
Le calcul du plus grand commun diviseur est un très bel exemple d’utilisation de l’instruction while vu sa simplicité. La mini
capsule vidéo suivante explique le problème du calcul du pgcd(x,y) et sa solution simple en Python.
CONTENU DE LA VIDÉO
La vidéo précédente présente un script qui calcule le plus grand commun diviseur de deux nombres lus en entrée.
Script réalisé dans la vidéo
x = int(input("x = "))
y = int(input("y = "))
while y > 0:
x, y = y, x % y
print(x, y)
print("pgcd = ", x)
La vidéo en bref
Notons que Python met à votre disposition la fonction gcd du module math, qui calcule le plus grand commun diviseur de deux
nombres entiers.
CONJECTURE DE SYRACUSE
Si l’on était parti d’un autre entier, en lui appliquant les mêmes règles, on aurait obtenu une suite de nombres différente. A priori, il
serait possible que la suite de Syracuse de certaines valeurs de départ n’atteigne jamais la valeur 1, soit qu’elle aboutisse à un cycle
différent du cycle trivial, soit qu’elle diverge vers l’infini. Or, on n’a jamais trouvé d’exemple de suite obtenue suivant les règles
données qui n’aboutisse pas à 1 et, par suite, au cycle trivial.
La conjecture de Syracuse est l’hypothèse mathématique selon laquelle la suite de Syracuse de n’importe quel entier strictement
positif atteint 1.
Cette conjecture mobilisa tant les mathématiciens durant les années 1960, en pleine guerre froide, qu’une plaisanterie courut selon
laquelle ce problème faisait partie d’un complot soviétique visant à ralentir la recherche américaine.
Un grand mathématicien du 20ème siècle, Paul Erdős a dit, à propos de la conjecture de Syracuse : « Les mathématiques ne sont
pas encore prêtes pour de tels problèmes ».
Nous voulons écrire un code qui génère la suite de Syracuse d’un nombre n lu sur input, jusqu’à ce qu’elle atteigne la valeur 1.
Développons le problème.
Le nombre n est lu sur input :
Enfin pour tester si la suite satisfait la conjecture, il faut continuer à calculer de nouvelles valeurs jusqu’à ce que n vaille 1 :
while n != 1:
if n % 2 == 0 : # si un nombre entier modulo 2 vaut 0, il est pair
n = n // 2
else: # cas où le nombre est impair
n = 3 * n + 1
Notons que si la conjecture n’est pas satisfaite, ce programme boucle indéfiniment, ce qui signifie que ici que la boucle while
ne s’arrêtera jamais sauf si l’utilisateur coupe l’exécution du programme. Des informaticiens ont testé la conjecture pour tous les
entiers jusqu’à des valeurs de l’ordre de 260 sans trouver de contre-exemple. Mais à l’heure actuelle aucune preuve mathématique
n’existe qu’il n’en existe pas un plus grand qui ne la satisfait pas.
N’hésitez pas à mettre tous les morceaux de code ensemble pour obtenir un programme complet. Pour voir si votre code complet
ressemble au nôtre, une solution vous est proposée ici.
Une solution pour Syracuse
Assez souvent le programmeur qui a un code à produire retrouve des « canevas » classiques qui lui permettent rapidement de savoir
quelles instructions utiliser. Le canevas type pour une instruction while contient souvent les quatre parties initialisation,
condition, traitement, changement :
initialisation
while condition:
traitement
changement
avec :
— une partie initialisation avant le while permettant après de tester la condition de continuation ;
— la ligne contenant le while avec la condition de continuation qui détermine si une itération supplémentaire doit
être réalisée dans le while ;
— la partie traitement dans le corps du while ;
— une partie que l’on peut qualifier de changement à la fin du corps du while qui constitue une sorte de réinitialisation qui
va permettre le test suivant de la condition de continuation.
Par exemple, dans le code Syracuse que nous venons de présenter :
Les parties initialisation et changement initialisent et modifient n qui sera testé au niveau de la condition de while ;
la partie traitement imprime la nouvelle valeur de n.
n = "première valeur"
while "n ne correspond pas à la valeur pour arrêter":
traitement
n = "nouvelle valeur"
Il est fréquent que l’on lise une suite de données et fasse un certain traitement sur ces données tant que le code ne lit pas une valeur
qui spécifie la fin de la suite des données à lire.
Par exemple si l’on doit lire une suite de données jusqu’à une valeur dite « sentinelle » valant "F", le canevas classique, avec deux
lignes d’input nécessaires, est le suivant :
N’oubliez pas que la fonction input() renvoie un résultat de type chaîne de caractères (par exemple '1', '32', '-66' ou 'F')
et que la fonction int(x) ou float(x) transforme une chaîne de caractères x, qui dénote respectivement un nombre entier, et
fractionnaire, en la valeur correspondante de type int ou float. Vous pouvez bien sûr utiliser les deux fonctions en séquence
directe, par exemple :
n = int(input())
x = input()
if x != 'F':
n = int(x)
...
...
Une des hantises du programmeur est un programme qui boucle, c’est-à-dire qui réexécute sans fin et de façon erronée la même sé-
quence d’instructions. L’utilisation de l’instruction while est une des causes possibles d’un tel programme qui boucle indéfiniment,
comme illustré dans la capsule vidéo suivante :
CONTENU DE LA VIDÉO
La vidéo précédente présente des exemples d’instructions répétitives while qui bouclent indéfiniment.
Scripts réalisés dans la vidéo
i = 0
while i >= 0 :
i = i + 1
print(i)
i = 0
while i >= 0 :
i = i + 1
print("le programme n'arrivera jamais ici")
La vidéo en bref
Des codes peuvent ne pas s’arrêter tout seuls, comme montré avec les scripts donnés dans la vidéo, où des instructions while
ont la condition de continuation qui n’est jamais évaluée à faux durant leur exécution. Dans ce cas, il faudra arrêter l’exécution
de ces codes généralement erronés, grâce à une touche clavier ou un bouton spécifique d’interruption d’exécution.
INSTRUCTION FOR
La seconde instruction répétitive de Python est l’instruction for, également appelée boucle for.
La vidéo suivante illustre le fonctionnement de l’instruction for par un exemple très simple. Cet exemple introduit également la
notion de séquence sur laquelle nous reviendrons plus en détails dans le module de cours suivant. Nous allons voir que l’instruction
for répète un traitement pour tous les éléments d’une séquence.
CONTENU DE LA VIDÉO
for c in "Bonjour":
print(c)
for i in range(5):
print(i)
somme = 0
for val in range(5) :
somme = somme + val
print(somme)
La vidéo en bref
L’instruction for réalise un traitement donné pour tous les éléments d’une séquence.
La vidéo montre trois scripts : un premier qui réalise un traitement sur tous les caractères d’une chaîne de caractères, et deux
autres qui utilisent la fonction range pour faire un traitement avec une séquence de valeurs entières.
La syntaxe de base d’une instruction for est ensuite donnée dans la vidéo (voir plus loin dans le cours).
RANGE
for i in range(5):
print(i)
affiche
0
1
2
3
4
Nous avons vu dans la vidéo précédente que la syntaxe de l’instruction répétitive for est :
for c in sequence:
instructions
où :
— c est la variable de contrôle qui reçoit séquentiellement chacune des valeurs de la séquence
— sequence est, ou génère, la séquence de valeurs utilisée
— instructions constitue le corps de la boucle for
Pour que votre code fonctionne correctement, il faut absolument que les instructions dans le corps du for ne modifient pas
la variable c (et ce même si Python ne l’interdit pas explicitement). Si vous modifiez c, votre code va souvent produire des effets
assez aléatoires !
DESSIN D’UN CARRÉ, D’UN POLYGONE RÉGULIER OU D’UNE ÉTOILE AVEC TURTLE
Pour mettre en pratique l’instruction for, utilisons à nouveau le module turtle pour dessiner des polygones.
Une boucle for permet de dessiner très simplement un carré (par exemple dont les côtés ont une longueur de 100).
import turtle
for i in range(4):
[Link](100)
[Link](90)
[Link]()
À vous ! Reprenez ce code pour écrire et exécuter dans votre IDE (Thonny ou PyCharm par exemple) un script qui trace un polygone
régulier à 𝑛 côtés avec 𝑛 au moins égal à 3, ou une étoile à 𝑛 branches avec 𝑛 au moins égal à 5 et de valeur impaire.
Rappelons-nous (module 2 Activité 2.6.3) que pour dessiner un polygone à 𝑛 côtés (par exemple 𝑛 = 5), l’angle intérieur entre
deux côtés est de 360∘ /𝑛. Si n vaut 5 cela donne donc 72∘ .
Rappelons-nous également que si l’on veut dessiner des étoiles à 𝑛 branches et en supposant 𝑛 impair au moins égal à 5, l’angle
intérieur sera de (𝑛 − 1) * 180∘ /𝑛 (par exemple 144∘ pour 𝑛 valant 5).
Dans le paragraphe précédent nous avons expliqué comment dessiner une étoile ayant un nombre impair, au moins égal à 5, de
branches. En supposant que l’on désire dessiner une étoile à n branches par une succession de segments contigus, une telle étoile
peut être dessinée pour toutes les valeurs de n impaires à partir de 5 et la plupart des valeurs paires.
En dessous de 5 nous ne pouvons tracer d’étoile. Une exception notoire au dessus de 5 est l’étoile à 6 branches qui, comme le montre
la figure « Etoile à 6 branches », demande d’effectuer deux tracés distincts où à chaque fois, on dessine un triangle.
Confectionnons à présent un code qui reçoit en entrée le nombre n de branches et qui, s’il est possible de tracer une étoile à n
branches en un seul tracé contigu, la dessine avec turtle.
Pour trouver comment faire, analysons la situation avec une valeur n paire. Prenons l’exemple de n valant 8. Le principe est de
prendre un cercle et de le découper en n sections comme on découpe une tarte en n parts égales. Le dessin ci-dessous représente une
telle découpe pour n valant 8.
Ensuite, le principe est de partir du point 0 et de tracer un segment vers un autre point. Nous répétons cela n fois. Partant de 0, le
point suivant peut par exemple être le point 3. Ensuite, l’idée est de continuer avec le même incrément, donc le point 6 et ainsi de
suite, en ajoutant 3 à chaque fois. Quand on arrive à un nombre plus grand que 7, on effectue un modulo 8. Dans notre exemple,
après 6 on aura 6 + 3 donne 9 ; dans ce cas 9 modulo 8 nous dit que le point suivant est 1.
Donc le tracé passe séquentiellement par les points 0, 3, 6, 1, 4, 7, 2, 5, et retour à 0, comme le montre le schéma suivant.
De façon générale avec n sommets et n au moins égal à 5 (en dessous on ne pourra tracer une étoile), partant du point 0, il faut
trouver un incrément inc qui modulo n fera passer par tous les points avant de revenir au point 0. L’incrément inc devra être plus
grand que 1 sinon, nous traçons un polygone et non pas une étoile. Nous prenons aussi inc inférieur à n/2 sinon le tracé se fera
en traçant par la droite et non par la gauche. Il se peut que plusieurs incréments soient possibles. Si nous désirons l’étoile avec les
branches les plus fines possibles, il faut que inc soit le plus proche de n/2. Quand n est impair la valeur inc telle que n = 2 .
inc + 1 fonctionne toujours (en Python il suffit si n est impair de définir inc = n // 2). Si n est pair ce n’est pas aussi facile.
Mais les mathématiques nous disent qu’il faut que inc soit la plus grande valeur entière strictement plus petite à n / 2 telle que le
pgcd(n, inc) soit égal à 1 .
Le code Python suivant effectue le travail :
""" trace une étoile à n côtés, si elle peut l'être sans lever la plume"""
import turtle
from math import gcd # fonction du module math qui calcule le pgcd de 2 nombres
Notons qu’à partir de 5 branches, l’étoile à 6 branches est la seule qui ne puisse être tracée avec ce programme. En effet 6 est la
seule valeur n entière positive telle qu’aucune valeur entière positive i dans l’intervalle entre 1 non compris et n/2 non compris, soit
telle que pgcd(i, n) == 1.
Bons dessins d’étoiles !
Mettons ensemble en pratique ce que nous avons vu sur les boucles while et for Python. Avant de vous proposer de résoudre,
de façon autonome, des exercices UpyLaB, commençons par des exercices avec correction pour comparer votre solution à la nôtre
et vous guider dans votre apprentissage pratique : une activité sur la suite de Fibonacci suivie d’une activité de dessin d’un pavé
hexagonal.
SUITE DE FIBONACCI
simplifiées, à savoir : chaque couple de lapins, dès son troisième mois d’existence, engendre chaque mois un nouveau couple de
lapins, et ce indéfiniment.
Partons donc d’un couple de lapins le premier mois. Le deuxième mois, on n’a toujours que ce même couple, mais le troisième mois
on a déjà 2 couples, puis 3 couples le quatrième mois, 5 couples le cinquième mois, etc. La croissance de cette population est bel et
bien décrite par la suite de Fibonacci en partant de 0 et 1 comme deux premiers nombres de cette suite.
Nous vous proposons d’écrire deux petits programmes qui calculent et impriment les premiers termes de la suite de Fibonacci dans
deux cas de figure :
— problème 1 : pour les n premiers termes
— problème 2 : pour tous les termes inférieurs à une valeur n donnée.
Pour simplifier, supposons que pour les 2 problèmes, n est supérieur ou égal à 2.
Ces deux problèmes illustrent parfaitement la règle suivante qui guide le choix, lorsque l’on doit répéter un traitement, de l’utilisation
de l’instruction for ou while :
Avertissement : Règles : Lorsqu’un traitement répétitif doit être réalisé par un programme Python,
— l’utilisation d’une instruction répétitive for est à favoriser
quand nous savons facilement, au début de l’exécution de la boucle, combien d’itérations devront être réalisées ou si l’on
demande de traiter tous les éléments d’une séquence comme nous le verrons au module sur le séquences ;
— l’utilisation d’une instruction répétitive while est à favoriser
quand a priori le nombre d’itérations n’est pas facilement déterminable avant le début de son exécution.
— N’essayez pas cette expérience avec votre couple de lapins !
Les deux codes commencent donc par « lire une valeur entière n » (c’est-à-dire, lire une valeur entière et assigner cette valeur à la
variable n).
Comme on ne sait pas calculer n termes en une simple séquence d’assignations et de if puisque que n n’est connu qu’à l’exécution
quand le script du code est déjà écrit, il est clair que pour les deux codes, il faut utiliser une instruction répétitive (une boucle). Une
façon habituelle de coder dans ce type d’exemple est de calculer un nouveau terme à chaque itération.
Encore faut-il savoir comment mettre cela en musique et si c’est une instruction while ou for qu’il faut utiliser.
Pour les deux problèmes qui nous préoccupent, comme pour le calcul du plus grand commun diviseur, une façon classique de
calculer un terme suivant est d’avoir deux variables, que l’on nomme par exemple prec et succ, qui vont contenir l’avant-dernier
et le dernier terme calculés.
Initialement on a
prec = 0
succ = 1
À chaque itération, il faut calculer le terme suivant mais aussi conserver l’avant-dernier, c’est-à-dire celui qui était dans succ pour
nous permettre de continuer.
Typiquement on pourra écrire :
Si l’on veut écrire les n premiers termes de la suite, il suffit de les calculer un à un et de les afficher, par exemple avec
for i in range(n):
prec, succ = succ, prec + succ
print(succ)
Plus précisément, le code complet animé par Python Tutor du problème 1 est :
Code pour le problème 1
Pour le problème 2, on ne sait pas a priori combien d’itérations devront être effectuées. Dans ce cas, un while est la bonne
instruction à utiliser.
Le code animé par Python Tutor du problème 2 est donc :
Code pour le problème 2
Notons qu’ici en plus d’utiliser un while, succ est imprimé juste après le test (condition de continuation du while) pour s’assurer
qu’il faut effectivement l’imprimer.
Le programmeur devra toujours essayer d’avoir non seulement un code correct pour toutes les exécutions possibles, mais également
le plus efficace possible tout en étant le plus clair possible. Nous reviendrons sur cet aspect plus tard.
Note : une instruction for peut en général facilement être traduite par un while même si cela donne du code plus compliqué et
donc moins lisible ; c’est donc à déconseiller. Par exemple :
Une instruction for peut être réécrite en un while comme le montre l’exemple ci-dessous :
for i in range(10) :
print(i)
Note : Codes animés avec Python Tutor : voir cours en ligne en section 3.5.1
Pour être précis, les deux codes n’ont pas un effet totalement équivalent : à la sortie du for, i vaut 9 et pas 10 comme à la sortie
du while.
Un exemple beaucoup plus difficile à ce stade de votre apprentissage est d’écrire un code qui utilise turtle pour faire un pavé
hexagonal tel que demandé au module précédent, mais en ayant le code le plus succinct possible grâce à l’utilisation d’instructions
for.
En effet, on peut constater qu’un tel pavé est constitué de trois losanges, chacun constitué de quatre côtés de même taille, mais reliés
avec des angles alternativement de 60∘ ou de 120∘ .
Comme nous n’avons pas encore vu la notion de séquence qui nous aidera pour faire l’exemple complet, essayez d’écrire le code qui
utilise en particulier des instructions for pour tracer l’ensemble des lignes de l’hexagone, mais sans changer de couleur ni remplir
les surfaces, tel que montré ici :
Aide : on peut voir que le code suivant imprime quatre fois la valeur d’une variable angle en alternant entre les deux valeurs 120 et
60 (120, 60, 120, 60). En effet ce code utilise le fait que 180 - 120 vaut 60 et 180 - 60 vaut 120.
angle = 120
for j in range(4):
print(angle)
angle = 180 - angle
Par ailleurs,
— le premier losange commence son tracé par un segment de ligne horizontal,
— le second, par un segment qui forme un angle de 120° par rapport au premier segment,
— le troisième, par un segment qui forme un angle de 120° par rapport au second segment.
En résumé, il faut répéter trois fois :
— tracer un losange (où à chaque fois il faut tracer quatre segments)
— ensuite tourner à droite de 120°.
Le canevas général sera donc :
À vous de jouer pour écrire un programme complet réalisant le tracé du pavé hexagonal.
PROPOSITION DE SOLUTION
Vous avez du mal pour réaliser l’exercice ou vous l’avez réussi mais voulez avoir une autre solution ? Nous vous en proposons une :
Maintenant que nous avons ensemble rédigé des scripts avec des « boucles », il vous reste l’ultime étape dans l’apprentissage de ce
module : devenir autonome dans la rédaction de tels codes. Nous vous demandons de réaliser les exercices UpyLaB 3.9 à 3.17 du
Module 3 proposés dans les pages qui suivent. En particulier, l’exercice UpyLaB 3.14 est une version plus élaborée du petit jeu de
devinette présenté en section 3.3 du présent module.
Énoncé
Écrire un programme qui demande à l’utilisateur combien de plis de papier sont nécessaires pour se rendre sur la Lune, et pose la
question tant que l’utilisateur n’a pas saisi la bonne réponse. Si la réponse saisie par l’utilisateur n’est pas correcte, le programme
affiche le message "Mauvaise réponse.", puis pose à nouveau la question. Si la réponse saisie par l’utilisateur est correcte, le
programme affiche le message "Bravo !", et s’arrête. Exemple
Dans cet exemple d’exécution, le texte est affiché par le programme, alors que les nombres sont saisis par l’utilisateur :
Consignes
— UpyLaB va vérifier le bon fonctionnement du programme en comparant ce qui est affiché à l’écran avec ce qu’il attend.
Veillez donc à bien respecter le texte à afficher (casse, espaces, ponctuation. . . ).
— En particulier, pour lire les données utilisez précisément l’instruction :
int(input("Combien de plis sont-ils nécessaires pour se rendre sur la Lune ? : "))
et pour afficher utilisez précisément les instructions
print("Mauvaise réponse.")
et
print("Bravo !")
— Pour rappel, la réponse attendue a été calculée par le script de Sébastien dans la vidéo présentant la boucle while, en section
4.3.1. Cette réponse n’est pas à faire calculer par votre programme, qui se contente de la demander à l’utilisateur.
Quand votre solution sera validée, cliquez sur le bouton « AFFICHER LA RÉPONSE » pour trouver des conseils de bonnes
pratiques et éventuellement améliorer votre façon de coder.
Conseils
Énoncé
Écrire un programme qui calcule la taille moyenne (en nombre de salariés) des Petites et Moyennes Entreprises de la région.
Les tailles seront données en entrée, chacune sur sa propre ligne, et la fin des données sera signalée par la valeur sentinelle -1. Cette
valeur n’est pas à comptabiliser pour le calcul de la moyenne, mais indique que l’ensemble des valeurs a été donné.
Après l’entrée de cette valeur sentinelle -1, le programme affiche la valeur de la moyenne arithmétique calculée.
On suppose que la suite des tailles contient toujours au moins un élément avant la valeur sentinelle -1, et que toutes ces valeurs sont
positives ou nulles.
Exemple 1
11
8
14
5
-1
9.5
Exemple 2
12
6
7
-1
8.333333333333334
Consignes
— Attention, nous rappelons que votre code sera évalué en fonction de ce qu’il affiche, donc veillez à n’imprimer que le résultat
attendu.
— En particulier, il ne faut rien écrire à l’intérieur des appels à input (int(input()) et non int(input("Entrer un
nombre : ")) par exemple), ni ajouter du texte dans ce qui est imprimé (print(res) et non print("résultat
:", res) par exemple).
Quand votre solution sera validée, cliquez sur le bouton « AFFICHER LA RÉPONSE » pour trouver des conseils de bonnes
pratiques et éventuellement améliorer votre façon de coder.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Il sera utile de créer deux variables, une qui stockera la somme des valeurs entrées et l’autre leur nombre, et que l’on
actualisera après chaque lecture.
— N’oubliez pas de supprimer les textes à l’intérieur des appels à input lorsque vous soumettez le code à UpyLaB.
— Pour tester votre code, UpyLaB va l’exécuter plusieurs fois en lui fournissant à chaque test des nombres différents en entrée.
Il vérifiera alors que le résultat affiché par votre code correspond à ce qui est attendu. N’hésitez donc pas à tester votre code
en l’exécutant plusieurs fois dans votre IDE (Thonny ou PyCharm par exemple) avec des valeurs différentes en entrée.
— Si rien ne marche : consultez la FAQ sur UpyLaB 3.10.
Nous avons vu que la fonction print() affiche l’ensemble des valeurs données en argument. Ainsi le code suivant :
date_1 = 1515
date_2 = 1789
print("Bataille de Marignan", date_1)
print("Révolution française", date_2)
date_1 = 1515
date_2 = 1789
print("Bataille de Marignan", date_1, sep=' : ', end='/')
print("Révolution française", date_2, sep=' : ', end='\n-----\n')
Énoncé
Écrire un programme qui lit sur input une valeur naturelle n et qui affiche à l’écran un carré de n caractères X (majuscule) de côté.
Exemple 1
XXXXXX
XXXXXX
XXXXXX
XXXXXX
(suite sur la page suivante)
Exemple 2
XX
XX
Consignes
— Attention, nous rappelons que votre code sera évalué en fonction de ce qu’il affiche, donc veillez à n’imprimer que
le résultat attendu. En particulier, il ne faut rien écrire à l’intérieur des appels à input (int(input()) et non
int(input("Entrer un nombre : ")) par exemple).
— Il n’est pas demandé de tester si la valeur n est bien positive ou nulle, vous pouvez supposer que ce sera toujours le cas pour
les valeurs transmises par UpyLaB.
Quand votre solution sera validée, cliquez sur le bouton « AFFICHER LA RÉPONSE » pour trouver des conseils de bonnes
pratiques et éventuellement améliorer votre façon de coder.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Si votre programme est rejeté par UpyLaB alors qu’il semble produire le résultat attendu, vérifiez bien que vous n’ajoutez
pas d’espaces superflus, en début ou en fin de ligne, et que votre code n’affiche pas une ligne vide supplémentaire.
— Pour tester votre code, UpyLaB va l’exécuter plusieurs fois en lui fournissant à chaque test des nombres différents en entrée.
Il vérifiera alors que le résultat affiché par votre code correspond à ce qui est attendu. N’hésitez donc pas à tester votre code
en l’exécutant plusieurs fois dans votre IDE (Thonny ou PyCharm par exemple) avec des valeurs différentes en entrée.
— Si rien ne marche : consultez la FAQ sur UpyLaB 3.11.
Énoncé
Exemple 1
XXXXXX
XXXXX
XXXX
XXX
XX
X
Exemple 2
XX
X
Consignes
— Attention, nous rappelons que votre code sera évalué en fonction de ce qu’il affiche, donc veillez à n’imprimer que
le résultat attendu. En particulier, il ne faut rien écrire à l’intérieur des appels à input (int(input()) et non
int(input("Entrer un nombre : ")) par exemple).
— Il n’est pas demandé de tester si la valeur n est bien positive ou nulle, vous pouvez supposer que ce sera toujours le cas pour
les valeurs transmises par UpyLaB.
Quand votre solution sera validée, cliquez sur le bouton « AFFICHER LA RÉPONSE » pour trouver des conseils de bonnes
pratiques et éventuellement améliorer votre façon de coder.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— La concaténation (qui consiste à coller deux textes ensemble) et l’opérateur * sur les chaînes de caractères pourront s’avérer
utiles ici.
— Si votre programme est rejeté par UpyLaB alors qu’il semble produire le résultat attendu, vérifiez bien que vous n’ajoutez
pas d’espaces superflus, en début ou en fin de ligne, et que votre code n’affiche pas une ligne vide supplémentaire.
— Pour tester votre code, UpyLaB va l’exécuter plusieurs fois en lui fournissant à chaque test des nombres différents en entrée.
Il vérifiera alors que le résultat affiché par votre code correspond à ce qui est attendu. N’hésitez donc pas à tester votre code
en l’exécutant plusieurs fois dans votre IDE (Thonny ou PyCharm par exemple) avec des valeurs différentes en entrée.
— Si rien ne marche : consultez la FAQ sur UpyLaB 3.12.
Énoncé
Écrire un programme qui additionne des valeurs naturelles lues sur input et affiche le résultat.
La première donnée lue ne fait pas partie des valeurs à sommer. Elle détermine si la liste contient un nombre déterminé à l’avance
de valeurs à lire ou non :
— si cette valeur est un nombre positif ou nul, elle donne le nombre de valeurs à lire et à sommer ;
— si elle est égale à -1, cela signifie qu’elle est suivie d’une liste de données à lire qui sera terminée par le caractère "F"
signifiant que la liste est terminée.
Exemple 1
4
1
3
5
7
16
Exemple 2
-1
1
3
5
7
21
F
37
Exemple 3
Avec la donnée :
Consignes
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Dans la cas où la liste est terminée par le caractère "F", envisagez de lire l’input, puis de tester si la valeur lue est différente
du caractère "F", avant de chercher à la convertir en int et à l’ajouter à ce qui a déjà été sommé ;
— Utilisez un for dans le cas où le nombre de valeurs à sommer est connu, un while dans le cas contraire.
— Si rien ne marche : consultez la FAQ sur UpyLaB 3.13.
Énoncé
Exemple 1
50
Trop grand
8
Trop petit
20
Trop petit
27
Gagné en 4 essai(s) !
Exemple 2
50
Trop grand
24
Trop petit
37
Trop petit
43
Trop grand
40
Trop petit
41
Perdu ! Le secret était 42
Consignes
— Attention, au dernier essai, le programme ne doit afficher ni « Trop petit » ni « Trop grand », mais le verdict comme illustré
plus haut.
— Pour qu’Upylab puisse tester que votre solution est correcte, il faut que vous respectiez strictement la séquence décrite dans
l’énoncé. Si par exemple, vous n’affichez pas « Trop petit » ou « Trop grand », le nombre suivant ne sera pas fourni par le
système et votre solution sera considérée comme incorrecte.
— En pratique, pour la génération du nombre secret, vous devez débuter votre code comme suit :
import random
NB_ESSAIS_MAX = 6
secret = [Link](0, 100)
et ne pas faire d’autre appel à randint ou à une autre fonction du module random.
Quand votre solution sera validée, cliquez sur le bouton « AFFICHER LA RÉPONSE » pour trouver des conseils de bonnes
pratiques et éventuellement améliorer votre façon de coder.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Pour tester notre code, UpyLaB va exécuter le programme en ajoutant l’instruction [Link](argument), où
argument est une certaine valeur. Cette instruction permet de générer les mêmes suites de nombres aléatoires lors des
appels aux fonctions du module random à chaque exécution du programme.
Si, avec votre IDE, vous souhaitez reproduire le comportement exact d’UpyLaB lors des tests, il faudra donc rajouter cette
instruction juste après l’import du module random, en remplaçant argument par la valeur indiquée dans le test d’UpyLaB.
Vous serez ainsi sûr que votre code génèrera le même nombre secret qu’UpyLaB, ce qui peut faciliter le débogage en cas de
test invalidé par exemple.
Notez bien que l’argument de la fonction seed n’est pas le nombre à deviner, mais un paramètre qui permet de le générer.
Attention, cette instruction ne doit pas figurer dans le code que vous soumettez à UpyLaB.
— Si vous rencontrez l’erreur EOF Error, vérifiez que votre programme se termine bien dès que l’utilisateur découvre le
nombre secret et ce, même en moins de 6 essais, ou bien dès que le nombre maximal d’essais est atteint.
— Si rien ne marche : consultez la FAQ sur UpyLaB 3.14.
Énoncé
Comme mes écureuils s’ennuyaient, je leur ai fabriqué une roue avec des barreaux pour qu’ils puissent faire de l’exercice.
La roue fait 100 barreaux. Pour m’y retrouver, je les numérote de 0 à 99.
Très vite je me suis rendu compte que chacun utilisait la roue en faisant des sauts identiques (Up fait des sauts de 7 barreaux à
chaque fois, Py des sauts 9, LaB des sauts de 13, . . . ).
Je mets une noisette sur un des barreaux de la roue. Aidez-moi à savoir si un de mes écureuils va l’attraper sachant que je vais
mettre l’écureuil qui fait le test, par exemple Up, sur le barreau 0 et que je connais son comportement (Up fait toujours des sauts de
7 barreaux) et que je sais le numéro de barreau, différent de 0, où se trouve la noisette (Up n’aura donc pas la noisette au départ).
Écrire un programme qui teste si pour une configuration donnée, un écureuil va ou non atteindre un moment la noisette. Il reçoit
deux valeurs entières en entrée, une valeur saut et une valeur position_cible toutes deux entre 1 et 99.
Le programme va calculer une valeur position_courante, initialement la valeur 0, et vérifier si en calculant de façon répétitive
la valeur position_courante, celle-ci aboutira un moment à la valeur position_cible.
Notez que pour calculer la valeur suivante de position_courante (initialement mise à 0), il faut incrémenter la valeur actuelle
de position_courante de la valeur saut et ensuite, si le résultat est plus grand ou égal à 100, calculer la position en faisant
un modulo 100 de la valeur obtenue (ce qui donne à chaque fois une valeur position_courante entre 0 et 99). (Notez que
l’on peut systématiquement faire le modulo 100 du résultat sans tester si position_courante est ou non supérieur à 100 pour
obtenir sa bonne valeur).
Notez également, pour ne pas épuiser mon écureuil sans fin, que s’il atteint à nouveau le barreau 0, j’arrête l’expérience sachant
qu’il prendra toujours les mêmes barreaux sans jamais atteindre position_cible (la noisette).
À la fin votre programme dira si oui ou non la noisette a été atteinte ou non.
En pratique, après avoir lu les deux valeurs saut et position_cible, votre programme affichera chaque valeur de
position_courante sur une ligne différente à partir de la seconde valeur (pas la position_courante initiale qui vaut
toujours 0). La dernière position_courante affichée sera soit 0 soit la dernière valeur de position_courante avant
qu’elle n’aie la valeur de position_cible, si l’écureuil trouve la noisette. Votre programme terminera en affichant, sur une
nouvelle ligne, le message donnant le résultat :
— "Cible atteinte" si l’écureuil a trouvé la noisette,
— "Pas trouvée" si l’écureuil est revenu en position 0 sans trouver la noisette.
Vous pouvez supposer que les valeurs lues sont bien des entiers qui respectent les consignes.
Exemple 1
9
7
9
18
27
36
45
54
63
72
81
90
99
8
17
26
35
44
53
62
71
80
89
98
Cible atteinte
Exemple 2
8
7
8
16
24
32
40
48
56
64
72
80
88
96
4
12
20
28
(suite sur la page suivante)
Consignes
— Attention, nous rappelons que votre code sera évalué en fonction de ce qu’il affiche, donc veillez à n’imprimer que le résultat
attendu.
— En particulier, il ne faut rien écrire à l’intérieur des appels à input (int(input()) et non int(input("Entrer un
nombre : ") par exemple), et à afficher précisément le texte demandé ; par exemple : print("Cible atteinte")
et non print("La cible a été atteinte") par exemple.
Quand votre solution sera validée, cliquez sur le bouton « AFFICHER LA RÉPONSE » pour trouver des conseils de bonnes
pratiques et éventuellement améliorer votre façon de coder.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Il sera utile de définir trois variables, une qui stockera la valeur saut (inchangée tout au long du programme puisqu’elle est
utilisée comme incrément), une qui stockera la valeur position_cible où se trouve la noisette, et enfin une qui stockera
la valeur position_courante. Nous vous conseillons au début d’assigner à cette variable position_courante la
valeur saut soit la position le l’écureuil après un saut (la position initiale de l’écureuil valant 0).
— Nous rappelons que l’opérateur modulo (% en Python) donne le reste de la division euclidienne. Ainsi, 42 % 5 est égal à 2
car 42 = 5 * 8 + 2.
— Pour tester votre code, UpyLaB va l’exécuter plusieurs fois en lui fournissant à chaque test des nombres différents en entrée.
Il vérifiera alors que le résultat affiché par votre code correspond à ce qui est attendu. N’hésitez donc pas à tester votre code
en l’exécutant plusieurs fois dans votre IDE (Thonny ou PyCharm par exemple) avec des valeurs différentes en entrée.
— Si rien ne marche : consultez la FAQ sur UpyLaB 3.15.
RANGE
Nous avons déjà utilisé range lors de la présentation de l’instruction for à la section précédente. Expliquons plus complètement
les différentes formes d’utilisation de cette instruction.
range génère une séquence de valeurs entières. On l’utilise en lui donnant de 1 à 3 arguments entiers.
range avec un argument
Nous avons vu l’utilisation avec un seul argument, comme avec :
for i in range(5):
print(i)
0
1
2
3
4
soit une séquence avec les valeurs entières depuis 0 compris jusque 5 non compris.
range avec deux arguments
Si nous utilisons dans un code range avec deux arguments, le premier argument spécifie la première valeur de la séquence (si la
séquence n’est pas vide), et le deuxième argument la borne finale (non incluse). Par exemple :
somme = 0
for i in range(1,11):
somme = somme + i
print(somme)
affiche
1
3
6
10
15
21
28
36
45
55
soit les différentes valeurs de somme sommant en 10 étapes les valeurs entières de 1 à 10.
range avec trois arguments
Si nous utilisons dans un code range avec trois arguments, les deux premiers arguments spécifient la première valeur de la séquence
et la borne finale non comprise. Le troisième argument donne le pas ou incrément pour calculer la valeur suivante à partir de la valeur
précédente. Par exemple :
0 5 10 15 20 25 30 35 40 45 50
depuis la valeur 0 jusqu’à la valeur 51 non comprise par pas de 5 (à chaque étape, pour avoir la valeur suivante, on incrémente la
précédente de 5).
Dans cet exemple les multiples de 5, entre 0 et 50 compris, sont affichés sur la même ligne et séparés d’une espace grâce à l’argument
nommé end = ' ' ; et après la dernière valeur affichée, le print() placé après l’instruction for, permet de passer à la ligne
suivante pour tout affichage ultérieur.
Notons que :
— la valeur du pas peut être négative (par exemple : range(10, -1, -1) )
— range peut donner une séquence vide (par exemple : range(0), range(1, 1), range(0, 10, -1))
Énoncé
Ecrivez un code qui lit un nombre entier strictement positif 𝑛 et affiche sur 𝑛 lignes une table de multiplication de taille 𝑛 × 𝑛, avec,
pour i entre 1 et 𝑛, les n premières valeurs multiples de i strictement positives sur la ième ligne. Ainsi, les 𝑛 premiers multiples de 1
strictement positifs (0 non compris) sont affichés sur la première ligne, les 𝑛 premiers multiples de 2 sur la deuxième, et caetera.
Exemple 1
1 2 3
2 4 6
3 6 9
Exemple 2
10
1 2 3 4 5 6 7 8 9 10
2 4 6 8 10 12 14 16 18 20
3 6 9 12 15 18 21 24 27 30
4 8 12 16 20 24 28 32 36 40
5 10 15 20 25 30 35 40 45 50
6 12 18 24 30 36 42 48 54 60
7 14 21 28 35 42 49 56 63 70
8 16 24 32 40 48 56 64 72 80
9 18 27 36 45 54 63 72 81 90
10 20 30 40 50 60 70 80 90 100
Exemple 3
Consignes
— Attention, nous rappelons que votre code sera évalué en fonction de ce qu’il affiche, donc veillez à n’imprimer que
le résultat attendu. En particulier, il ne faut rien écrire à l’intérieur des appels à input (int(input()) et non
int(input("Entrer un nombre : ")) par exemple), ni ajouter du texte dans ce qui est imprimé.
— Il n’est pas requis que les nombres soient alignés verticalement. Pour cet exercice, UpyLaB ne tiendra pas compte du nombre
d’espaces séparant les nombres sur chaque ligne, ni de la présence d’espace en fin de ligne.
Quand votre solution sera validée, cliquez sur le bouton « AFFICHER LA RÉPONSE » pour trouver des conseils de bonnes
pratiques et éventuellement améliorer votre façon de coder.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— L’utilisation de range(...) peut être utile.
Énoncé
On peut calculer approximativement le sinus d’un nombre 𝑥 en effectuant la sommation des premiers termes de la série (une série
est une somme infinie) :
𝑥3 𝑥5 𝑥7
𝑠𝑖𝑛(𝑥) = 𝑥 − + − + ...
3! 5! 7!
où 𝑥 est exprimé en radians et 3 ! désigne la factorielle de 3.
Écrire un programme qui lit une valeur flottante 𝑥 en entrée et imprime une approximation de 𝑠𝑖𝑛(𝑥).
Cette approximation sera obtenue en additionnant successivement les différents termes de la série jusqu’à ce que la valeur du terme
devienne inférieure (en valeur absolue) à une constante 𝜖 que l’on fixera à 10−6 .
Exemple 1
0.8
0.7173557231746032
Remarque : Compte-tenu du manque de précision concernant les calculs sur les float, vous pourrez obtenir un résultat sensiblement
différent. Ce n’est pas un problème, car UpyLaB acceptera toute réponse suffisamment proche de celle attendue, avec une tolérance
de l’ordre de 1.0e-5.
Exemple 2
-0.5
-0.479425533234127
Consignes
— Nous rappelons que votre code sera évalué en fonction de ce qu’il affiche, donc veillez à n’imprimer que le résultat attendu.
En particulier, il ne faut rien écrire à l’intérieur des appels à input (int(input()) et non int(input("Entrer un
nombre : ")) par exemple), ni ajouter du texte dans ce qui est imprimé (print(res) et non print("résultat
:", res) par exemple).
Quand votre solution sera validée, cliquez sur le bouton « AFFICHER LA RÉPONSE » pour trouver des conseils de bonnes
pratiques et éventuellement améliorer votre façon de coder.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Dans cet exercice, notre programme doit calculer une approximation du sinus d’un nombre mais il ne faut pas utiliser la
fonction sin du module math.
— Pour éviter de calculer explicitement la valeur des factorielles, on pourra chercher à exprimer chacun des termes en fonction
du précédent.
— Notez bien que les exposants de 𝑥 ne sont que les nombres impairs, et que le signe alterne entre + et -.
Énoncé
Écrire un code qui lit un nombre entier strictement positif n et imprime une pyramide de chiffres de hauteur n (sur n lignes
complètes, c’est-à-dire toutes terminées par une fin de ligne).
— La première ligne imprime un “1” (au milieu de la pyramide).
— La ligne i commence par le chiffre i % 10 et tant que l’on n’est pas au milieu, le chiffre suivant a la valeur suivante ((i+1) %
10).
— Après le milieu de la ligne, les chiffres vont en décroissant modulo 10 (symétriquement au début de la ligne).
Notons qu’à la dernière ligne, aucune espace n’est imprimée avant d’écrire les chiffres 0123....
Exemple 1
Exemple 2
1
232
Exemple 3
10
1
232
34543
4567654
567898765
67890109876
7890123210987
890123454321098
90123456765432109
0123456789876543210
Consignes
— Attention, nous rappelons que votre code sera évalué en fonction de ce qu’il affiche, donc veillez à n’imprimer que le résultat
attendu.
— En particulier, il ne faut rien écrire à l’intérieur des appels à input (int(input()) et non int(input("Entrer un
nombre : ")) par exemple), ni ajouter du texte dans ce qui est imprimé.
Quand votre solution sera validée, cliquez sur le bouton « AFFICHER LA RÉPONSE » pour trouver des conseils de bonnes
pratiques et éventuellement améliorer votre façon de coder.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Pour tester votre code, UpyLaB va l’exécuter plusieurs fois en lui fournissant à chaque test des nombres différents en entrée.
Il vérifiera alors que le résultat affiché par votre code correspond à ce qui est attendu. N’hésitez donc pas à tester votre code
en l’exécutant plusieurs fois dans votre IDE (Thonny ou PyCharm par exemple) avec des valeurs différentes en entrée y
compris supérieure à 10.
Avant de terminer ce module, nous voudrions vous présenter l’instruction pass. L’instruction pass est une instruction simple,
même très simple.
Sa syntaxe unique est
pass
if x < 0 :
pass # TODO compléter le code (cas où x < 0)
else :
print('traitement du cas où x est positif')
l’instruction pass, éventuellement avec un commentaire du type A_FAIRE (ou TO DO en anglais), permet d’avoir un code syn-
taxiquement correct tout en soulignant qu’une partie du code reste à écrire.
Dans ce module nous avons appris comment fonctionne la plupart des instructions de contrôle de flux Python.
Pour bien assimiler la matière, analysons quelques bouts de code pour déterminer ce qu’ils font.
QUIZ
BILAN EN BREF
BILAN DU MODULE
Python permet de découper les programmes grâce à des fonctions. Dans ce module nous allons vous expliquer comment définir
et utiliser une fonction dans un code Python et comment écrire des programmes modulaires, ce qui signifie ici des programmes
dont le code est découpé en parties avec des fonctions. Comme dans le module précédent, nous passerons de sections théoriques
d’introduction à des sections de mise en pratique des concepts, d’abord supervisées et ensuite que vous réaliserez de façon autonome.
MENU DE CE MODULE
FONCTIONS PRÉDÉFINIES
Note : Voir la vidéo de la section 4.2.1 : Les fonctions prédéfinies et leur utilisation
CC BY-SA 3.0 - 2021 - Sébastien Hoarau - Thierry Massart - Jean Olgiati - Isabelle Poirier 129
Apprendre à coder avec Python, Version - Release 3.0
CONTENU DE LA VIDÉO
La vidéo précédente présente plusieurs fonctions Python prédéfinies, utilisables directement par l’interpréteur ou après leur impor-
tation par exemple des modules math, random ou time.
Code sur la console réalisé dans la vidéo
>>> x = 666
>>> y = 7
>>> z = 3.14159
>>> abs(x)
666
>>> abs(-10)
10
>>> dir(x)
['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__', '__dir__',
˓→'__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__
˓→_', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__
>>> divmod(x, y)
(95, 1)
>>> float(x)
666.0
>>> input()
>? 1111
'1111'
>>> int(z)
3
>>> max(x, y, 1515)
1515
>>> min(x, 1551, y+3, 27)
10
>>> round(z, 3)
3.142
>>> type(z)
<class 'float'>
>>> help(divmod)
Help on built-in function divmod in module builtins:
divmod(x, y, /)
Return the tuple (x//y, x%y). Invariant: div*y + mod == x.
>>> divmod(x, y)
(95, 1)
>>> 666 // 7
95
>>> 666 % 7
1
>>> print("x vaut:", x)
x vaut: 666
>>> print()
log(...)
log(x[, base])
>>> log(3)
1.0986122886681098
>>> log(100,10)
2.0
>>> import random
>>> [Link](1, 100)
77
>>> import time
>>> [Link](5)
>>>
La vidéo en bref
Nous illustrons l’utilisation des fonctions prédéfinies abs, dir, divmod, float, input, int, max, min, round, type,
help et print.
Nous montrons ce que réalisent certaines fonctions ou valent certaines constantes des modules math (log, cos, pi), random
(randint) et time (sleep).
CONTENU DE LA VIDÉO
La vidéo précédente illustre, à partir de l’exemple du pgcd, comment on peut créer ses propres fonctions en Python.
Script réalisé dans la vidéo
La vidéo en bref
Nous avons présenté la syntaxe d’une définition de fonction sur l’exemple de la fonction pgcd : avec la ligne d’entête suivie
d’un docstring expliquant ce que reçoit la fonction comme paramètres et ce qu’elle fait et du corps de la fonction terminée par
l’instruction return.
Après avoir défini la fonction pgcd, la suite du code peut en faire usage.
La séquence d’exécution lors de la définition et de l’appel à une fonction est détaillée dans l’unité suivante.
CONTENU DE LA VIDÉO
La vidéo précédente présente la séquence d’exécution lors de l’appel à une telle fonction Python.
Script réalisé dans la vidéo
La vidéo en bref
Lorsqu’une fonction est appelée par une autre fonction ou dans le code « principal » (que nous appelons le code « appelant »), la
séquence du traitement est la suivante :
1) Les variables locales à la fonction appelée, correspondantes aux paramètres formels, sont créées (et mises dans le nouvel
« espace de nom » associé à cette instance de la fonction).
2) Les paramètres sont transmis (passés) entre le code appelant et la fonction appelée. Ceci est décrit plus en détails à la
sous-section suivante.
3) L’exécution du code appelant est suspendue pour laisser la place à l’exécution de la fonction appelée.
Notons qu’un espace de nom (Namespace) est l’endroit où des variables locales sont stockées, sachant qu’en Python une variable
est un nom pour un objet.
Il doit y avoir une correspondance entre les paramètres formels et les paramètres effectifs selon la position. Cela signifie que le
i-ème paramètre effectif en ordre d’apparition dans la liste doit correspondre au i-ème paramètre formel.
Le passage de paramètres suit le même fonctionnement qu’une assignation : un paramètre effectif soit désigne un objet existant soit
est une expression dont la valeur donne un objet ; le paramètre formel correspondant est une variable locale à la fonction qui lors de
son exécution, sera un nom local de cet objet.
Donc avec def pgcd(x, y) : l’appel pgcd(26, a) aura comme effet que dans l’instance de la fonction pgcd, x désigne
l’objet entier valant 26 et y, la valeur de la variable nommée par ailleurs a.
Le mot instance de fonction signifie exemplaire ; en effet une fonction peut être appelée plusieurs fois, et peut même s’appeler elle
même « récursivement » ce qui entraîne plusieurs instances simultanées lors de l’exécution. La récursivité ne sera pas abordée dans
ce cours.
Pour définir une nouvelle fonction, il faut écrire son entête qui commence par le mot-clé « def » suivi du nom de la fonction et des
paramètres appelés dans le jargon standard paramètres formels entourés de parenthèses, le tout terminé par le caractère deux-points
(« : »).
Le corps de la fonction est identifié par l’ensemble des lignes de code qui suivent indentées par rapport à l’entête.
L’utilisation de la fonction se fait quand une instruction donne le nom de cette fonction avec les paramètres effectifs, également
appelés paramètres réels ou arguments, correspondants.
nom(arguments)
Chaque fonction peut être vue comme un outil résolvant un certain problème. Les autres fonctions peuvent alors utiliser cet outil
sans se soucier de sa structure, juste pour le résultat qu’il donne. Pour pouvoir l’utiliser, il leur suffit de savoir comment l’employer,
c’est-à-dire de connaître le nom de la fonction, les valeurs qu’elle nécessite et la façon dont elle renvoie un ou plusieurs résultats.
Cette technique a, en particulier, deux avantages :
— chaque fonction peut (généralement) être testée indépendamment du reste du programme ;
— si une partie contient une séquence d’instructions qui doit être réalisée à différents endroits du programme, il est possible de
n’écrire cette séquence qu’une seule fois.
En gros, une fonction peut être vue comme une opération dont la valeur est définie par le programmeur en fonction des paramètres
reçus.
Nous avons dit que la fonction renvoie le résultat de son travail. Mais comment ? Par une petite instruction bien particulière nommée
return. Souvenez-vous de la définition de notre fonction pgcd :
C’est parce qu’il y a cette instruction return x que l’on peut effectuer l’affectation suivante :
Attention, dès que l’exécution de votre code rencontre un return, la fonction en question se termine. Ainsi, toute instruction se
trouvant après le return sera tout simplement ignorée. Considérons cette fonction :
def foo(x):
if x > 0:
return [Link](x)
print('Fini')
>>> foo(10)
3.1622776601683795
Explications : lors de l’appel, la variable locale x vaut 10, le test est donc vrai et le code exécute l’instruction return qui quitte la
fonction. Le print n’est donc pas atteint. Par contre, ce deuxième appel, affiche bien Fini à l’écran :
>>> foo(-1)
Fini
Il semble ne pas y avoir de différence. . . et pourtant il y en a une et de taille. Informellement, la version originale, avec l’instruction
return, nous renvoie la valeur calculée du pgcd. Dans la seconde version, elle ne fait que nous la montrer, sans que nous puissions
en disposer. Lors des appels dans l’interprète interactif, le premier appel renvoie à l’interprète la valeur calculée 2 et c’est l’interprète
qui nous affiche cette valeur. Dans le second appel c’est la fonction qui réalise l’affichage par l’appel à la fonction print. Ainsi :
Mais,
Avant d’examiner de plus près les possibilités et le fonctionnement des fonctions Python, ce quiz va vous aider à vérifier que vous
avez bien assimilé ce que nous avons vu jusqu’ici.
Donnons d’autres exemples de fonctions, qui varient en particulier selon les paramètres reçus et le ou les résultat(s) renvoyé(s) :
Fonction booléenne : La fonction est_pair est une fonction booléenne, c’est-à-dire dont le résultat est une valeur booléenne,
qui renvoie vrai ( True ) si la valeur reçue en paramètre est paire.
def est_pair(x):
"""Renvoie vrai si et seulement si x est pair."""
return x % 2 == 0
Fonction qui renvoie None : La fonction print_line affiche un résultat sur l’écran (l’output) mais ne retourne pas de valeur.
Par défaut, la fonction renvoie la valeur None. Il s’agit d’une valeur d’un type à part (NoneType) qui symbolise l’absence de
valeur. Cela signifie que l’instruction return sans rien derrière équivaut à return None. Par ailleurs, un return implicite
existe à la fin de toute fonction pour revenir au code appelant (avec la valeur de retour None).
Fonction qui renvoie un tuple : La fonction min_et_max renvoie deux valeurs :
Plus précisément, toute fonction Python renvoie une seule valeur à la fin de son exécution. Ici min_et_max renvoie en réalité un
objet de type tuple qui contient deux valeurs. Nous verrons dans le prochain module, qui traite des séquences, cette notion de tuple
plus en détails.
Fonction sans paramètre : Notons que nous pouvons définir une fonction sans paramètre. Dans ce cas, dans l’entête de cette
dernière, il faut quand même mettre des parenthèses sans rien dedans. Par exemple, le code suivant utilise turtle, et en particulier
la fonction circle, pour dessiner un symbole Yin et yang. Pour ce faire, nous utilisons la fonction prédéfinie [Link]
avec un ou deux paramètres :
[Link](rayon [, angle]) :
— trace un cercle ou un arc de cercle de |rayon| (valeur absolue de rayon) ;
— le cercle est complet si le paramètre angle n’existe pas ;
— le cercle ne fait qu’un arc de angle degrés si angle est donné.
Par exemple [Link](100,180) trace un demi cercle (soit 180 degrés) de rayon de 100 points :
— si rayon est positif, le cercle est tracé dans le sens positif, c’est-à-dire anti-horlogique, sinon (rayon est négatif), il est
tracé dans le sens horlogique ;
— si angle est positif, la tortue avance, sinon elle recule.
Le code ci-dessous donne une solution à la fonction yin_yang() :
""" Exemple de code sans paramètre :
yin et yang dessiné avec turtle
"""
import turtle
def yin_yang():
""" dessine un logo yin-yang de rayon 200 """
[Link]() # met la plume en mode tracé (si ce n'était déjà le cas)
[Link](2) # grosseur du tracé de 2 points
# dessine le yin externe
[Link]("black", "black") # le tracé et le remplissage seront en noir
turtle.begin_fill() # la ou les formes suivantes seront remplies
[Link](-100, 180) # demi cercle intérieur tournant vers la droite
[Link](-200, -180) # demi cercle extérieur, en marche arrière
[Link](-100, -180) # demi cercle intérieur qui complète le yin
turtle.end_fill() # remplissage
# dessine le yang interne
[Link]("white") # couleur blanche
[Link]() # on ne trace pas ce qui suit
# déplace la tortue au bon endroit
[Link](90)
[Link](80)
[Link](90)
# tracé du disque yang (blanc) interne au yin
[Link]()
turtle.begin_fill()
[Link](-20)
turtle.end_fill()
# se replace au centre
[Link]()
[Link](90)
(suite sur la page suivante)
[Link]("black")
# déplace la tortue au bon endroit
[Link]()
[Link](90)
[Link](80)
[Link](90)
[Link]()
# trace le disque
turtle.begin_fill()
[Link](-20)
turtle.end_fill()
# se replace au centre
[Link]()
[Link](90)
[Link](80)
[Link](90)
[Link]()
[Link]()
return
#code principal
yin_yang() #réalise le logo
L’exécution du code ci-dessus donne le résultat montré par la petite vidéo donné en section 4.3.1 du cours en ligne.
Note : Voir la vidéo de la section 4.3.1 du cours en ligne : Dessin d’un yin-yang avec turtle
COMPLÉMENT D’INFORMATIONS
Notons dans le code précédent l’utilisation de [Link](couleur1, couleur2) qui demande que les tracés aient
les contours en couleur1 ("black" par exemple) et les surfaces remplies (grâce à turtle.begin_fill() et turtle.
end_fill() ) en couleur2 ("white" par exemple pour faire le yang).
Nous discuterons de la qualité de ce code dans la section suivante qui parle de règles de bonnes pratiques pour coder ; nous y verrons
pourquoi un programmeur expérimenté n’aurait pas écrit la fonction yin_yang telle quelle.
Avant de mettre en pratique les fonctions, les points suivants, plus techniques, doivent être mis en évidence car ils sont importants
pour ne pas écrire de codes erronés.
Même si en pratique ce n’est généralement pas le cas, en théorie une fonction Python peut recevoir différents types de paramètres
et renvoyer des résultats de types différents : c’est ce que l’on appelle la surcharge des paramètres.
Par exemple avec la définition :
def sum(a,b):
"""renvoie la somme ou concaténation des deux paramètres"""
return a+b
print(sum(3,5))
print(sum('cha', 'peau'))
print(sum(3, 'peau'))
renvoient respectivement :
8
chapeau
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "<input>", line 2, in sum
TypeError: unsupported operand type(s) for +: 'int' and 'str'
La fonction sum peut donc faire des sommes de valeurs, des concaténations de texte (qui consistent à coller deux textes ensemble)
ou même produire des erreurs, suivant le type des arguments utilisés. Dans le jargon informatique, on parle de polymorphisme, ce
qui signifie que quelque chose, ici une fonction, de même forme, peut en fait représenter plusieurs choses ou comme ici, avoir des
effets différents.
En Python, il est donc généralement fort conseillé, si l’on n’est pas sûr du code appelant, que la fonction vérifie elle-même que les
arguments donnés aient un type adéquat pour son exécution.
La section suivante explique une bonne façon de faire cela.
ASSERT
L’instruction assert vérifie si une certaine condition est rencontrée. Dans l’exemple précédent, si les seuls types permis pour les
paramètres de notre fonction sum sont des int ou des float, une instruction à ajouter en début du code de la fonction juste après
l’entête et le docstring de la fonction est :
assert (type(a) is int or type(a) is float) and (type(b) is int or type(b) is float)
qui, lors de son exécution, teste la condition ; si elle est vraie, l’interpréteur passe à l’instruction suivante, sinon il provoque une
erreur qui indique que l’assertion est fausse.
Dans la section précédente, nous avons vu que lors de son exécution, la fonction appelée utilise des variables qui lui sont locales.
Nous avons vu comment s’effectue le passage de paramètres entre les arguments effectifs et les paramètres formels. Par ailleurs,
le code principal utilise des variables globales que l’interpréteur continue à manipuler après l’exécution de la fonction. La présente
unité revient en détails sur les mécanismes qui gèrent les variables : en effet, nous devons bien les comprendre, sous peine d’écrire
des codes qui ne font pas du tout ce que nous désirons. Allons-y !
Assignation : Nous avons vu en section 2.7 qu’après les instructions :
a = b = 3
b = 2 * b
Pour vous en convaincre complètement, vous pouvez exécuter étape par étape l’exemple avec l’animation Python Tutor suivante :
Note : Voir la première animation Python Tutor en section 4.3.2 du cours en ligne
a = 3
fun(a)
print(a)
On peut voir que la variable a n’a pas été modifiée par la fonction comme le montre le diagramme d’état au moment du return.
Note : Exécution étape par étape du code avec Python Tutor : voir cours en ligne section 4.3.2
def fun(x):
x = x**2
return x
x = 3
fun(x)
print(x)
Nous pouvons exécuter étape par étape l’exemple avec l’animation Python Tutor suivante :
Note : Voir la troisième animation Python Tutor en section 4.3.2 du cours en ligne
Les animations Python Tutor présentées précédemment montrent clairement qu’une variable locale, comme le paramètre formel
x de la fonction fun, n’est pas connue en dehors de l’exécution de l’instance de fonction où elle est créée. De plus à la fin de
l’exécution de cette instance de fonction, les variables locales à cette instance de fonction sont supprimées. Ce qui nous amène à la
question suivante :
Pourquoi les fonctions Python utilisent-elles des variables locales ?
Quand le programmeur écrit une fonction fun, l’échange de valeurs et de résultats entre la fonction fun et la fonction (ou le
programme global) est réalisé via les mécanismes du passage des paramètres et par l’instruction return. Pour que les codes de
la fonction et du programme soient « propres », il faut éviter toute autre inférence : c’est ce qui est réalisé par le mécanisme des
variables locales qui permet d’isoler proprement le code de la fonction fun (utilisant uniquement des variables locales qui lui sont
propres) du code qui utilise cette fonction fun et d’autres variables.
Attention, jusqu’à présent, aucun type d’objets présenté dans ce cours n’est modifiable. En effet, par exemple
x = 1
x = 2
crée un premier objet de type int valant 1 nommé x via l’affectation et ensuite un second objet de même type valant 2 et le nom x
est donné à ce second objet via la seconde affectation ; ce qui rend le premier objet inaccessible puisqu’il n’a plus de nom. Un nom
de variable peut donc désigner des objets différents tout au long de l’exécution, mais dans cet exemple les objets eux-mêmes de type
int sont non modifiables.
Nous verrons dans le prochain module que certains objets (par exemple les listes) sont modifiables. Dans ce cas, si c’est requis pour
la fonction fun, le mécanisme de passage de paramètres permettra à la fonction de modifier un paramètre, c’est-à-dire un objet reçu
du code appelant la fonction fun. Notez cependant que si aucune modification de paramètre n’est demandée, une règle de bonne
pratique est de veiller à ne pas modifier ceux-ci dans le code de la fonction. Les exemples plus haut de fonction fun qui modifient
le paramètre formel x sont donc à éviter.
Certains mécanismes permettent de déroger au mécanisme de variables locales et globales en permettant, par exemple, à une fonction
de manipuler des variables globales. Comme ce n’est généralement pas utile ni une bonne pratique pour obtenir un code « propre »,
nous vous recommandons de ne pas utiliser ces mécanismes et de n’utiliser que des variables locales. Dans ce cours, seules des
constantes globales seront utilisées, comme nous le verrons à la section suivante.
Les variables qui sont créées et ensuite supprimées font appel à deux concepts : portée et index :visibilité. Expliquons ces termes
utilisés fréquemment par les programmeurs.
Dans le jargon informatique, l’ensemble des endroits où dans un programme, une variable existe est appelé sa portée (scope en
anglais). L’ensemble des endroits où une variable est visible est appelé sa visibilité.
Dans l’exemple précédent, une variable globale, comme x, existe depuis sa création jusqu’à la fin de l’exécution du programme,
mais n’est pas visible dans la fonction fun : en l’occurrence la variable x locale cache la variable x globale.
TRACEBACK
Nous avons déjà rencontré le mot Traceback lorsque notre code s’arrêtait en produisant une erreur. Le Traceback est une information
que l’interpréteur donne au programmeur pour qu’il trouve son erreur de code. Une traduction possible de ce verbe est retracer. C’est
donc une trace de l’exécution au moment de l’erreur. Expliquons la notion de Traceback sur un exemple. L’exécution du code ci-
dessous (où nous avons rajouté les numéros de ligne pour que ce soit plus clair), comme script PyCharm sauvé dans mon répertoire
Desktop par exemple,
1 def ma_fun():
2 une_autre_fun()
3
4 def une_autre_fun():
5 encore_une_fun()
6
7 def encore_une_fun():
8 # une_erreur est utilisé ligne 9 sans avoir été définie !
9 une_erreur = une_erreur + 1
10
11 ma_fun()
génère le message d’erreur suivant quand l’interpréteur essaye d’exécuter l’instruction une_erreur = une_erreur + 1
alors que la variable une_erreur n’est pas encore définie (aucune assignation n’a été effectuée avant).
Le message d’erreur explique le type de l’erreur (en dernière ligne) tandis que les lignes précédentes donnent un résumé du « che-
min » pris lors de l’exécution pour arriver à l’instruction qui a causé cette erreur. On peut ainsi retracer la séquence des appels en
cours quand l’erreur s’est produite.
Après cette longue suite d’explications, il est grand temps de mettre en pratique les nouveaux concepts que nous avons vus dans ce
module.
Reprenons le principe du calcul des nombres de Fibonacci présenté dans le module 3, section 3.5.1.
Rappelons que les premiers nombres de Fibonacci sont :
0 1 1 2 3 5 8 13 21 34. . .
où après les deux premiers qui sont donnés, la valeur des nombres suivants est donnée en sommant les deux précédents.
Plus mathématiquement, nous pouvons dénoter les nombres de Fibonacci par :
𝐹0 = 0 (4.1)
𝐹1 = 1 (4.2)
𝐹𝑖+1 = 𝐹𝑖−1 + 𝐹𝑖 , pour i > 0 (4.3)
Supposons que notre programme utilise régulièrement des nombres de Fibonacci. Une solution simple est d’écrire une fonction qui
calcule et renvoie 𝐹𝑛 pour l’indice n désiré.
Commençons par choisir un nom à notre fonction et déterminer le ou les paramètre(s) formel(s).
Les règles de bonnes pratiques pour encoder des programmes Python, comme discutées dans la section suivante, demandent que
les noms des fonctions, comme celui des variables, débutent par une lettre alphabétique en minuscule et soient formés de lettres
alphabétiques minuscules, de chiffres ou du caractère souligné '_'. Dans le jargon, cette convention s’appelle « snake case ».
Appelons notre fonction fibo et le paramètre formel n qui correspond à l’indice du nombre de Fibonacci à calculer.
def fibo(n):
Ensuite, écrivons le docstring en indiquant ce que fait fibo et le contenu initial de n au moment de chaque appel :
"""calcule le n-ième nombre de Fibonacci, avec : n de type int et
fibo(0) valant 0
fibo(1) valant 1 et
fibo(n+1) valant fibo(n-1) + fibo(n)
si n < 0 : fibo(n) retourne None"""
À VOUS DE JOUER !
Ouvrez un nouveau script dans PyCharm et complétez le code pour avoir une définition complète de la fonction fibo(n).
Un conseil : pour le cas général, une instruction répétitive pourrait être utile.
Ensuite, en dessous de la définition, rajoutez un code qui teste la fonction, par exemple en imprimant le résultat pour les valeurs
entre 0 et 100 non compris.
Votre code aura donc la structure suivante :
def fibo(n):
"""calcule le n-ième nombre de Fibonacci, avec : n de type int et
fibo(0) valant 0
fibo(1) valant 1 et
fibo(n+1) valant fibo(n-1) + fibo(n)
si n < 0 : fibo(n) retourne None"""
...
code correspondant au corps de la fonction fibo
...
return res
for i in range(100):
print(fibo(i))
Vous n’arrivez pas à réaliser l’exercice. Voici une solution pour le résoudre :
def fibo(n):
"""calcule le n-ième nombre de Fibonacci, avec : n de type int et
fibo(0) valant 0
fibo(1) valant 1 et
fibo(n+1) valant fibo(n-1) + fibo(n)"""
if n < 0 : # fibo(n) retourne None
res = None
else:
res = 0
suivant = 1
for _ in range(n): # calcule n fois le nombre de Fibonacci suivant
res, suivant = suivant, res + suivant
return res
for i in range(100):
print(fibo(i))
La programmation de la fonction fibo peut se faire en utilisant une technique algorithmique plus évoluée : la récursivité. Même
si la récursivité ne fait pas partie de la matière abordée dans ce cours, pourquoi ne pas être curieux et chercher avec votre
navigateur récursivité ?
En pratique une fonction est récursive si (directement ou indirectement) elle s’appelle elle-même !
Ainsi une version récursive simple (ici sans docstring et qui, pour simplifier, suppose que n vaut au moins 0) de la fonction fibo
pourra s’écrire :
def fibo(n):
if n < 2:
res = n # fibo(0) vaut 0 et fibo(1) vaut 1
else: # n >= 2
res = fibo(n-1) + fibo(n-2)
return res
Notez que si une solution récursive simple est très concise, dans ce cas-ci, sans technique plus élaborée comme la programmation
dynamique (non vue dans ce cours), elle n’est pas une bonne idée car pas efficace en temps d’exécution.
Énoncé
Écrire une fonction deux_egaux(a, b, c) qui reçoit trois nombres en paramètre et qui renvoie la valeur booléenne True
si au moins deux de ces nombres ont la même valeur, et la valeur booléenne False sinon.
Ensuite, écrire un programme qui lit trois données de type int, x, y et z, et affiche le résultat de l’exécution de deux_egaux(x,
y, z).
Exemple 1
1
2
3
False
Exemple 2
42
6
42
True
Consignes
— Dans cet exercice, il vous est demandé d’écrire une fonction, puis un programme appelant cette fonction sur des valeurs lues
en entrée. Notez qu’UpyLaB testera ces deux points, en exécutant le programme entier mais aussi en appelant directement
la fonction avec les arguments de son choix.
— Plus précisément UpyLaB testera d’abord l’existence d’une définition de la fonction deux_egaux avec le bon nombre de
paramètres. Si la fonction existe bien, UpyLaB testera votre programme en ajoutant 2 appels à la fonction deux_egaux
pour vérifier que celle-ci n’effectue aucun print. C’est en effet à votre programme d’effectuer le print demandé. Ensuite
différents tests de votre programme complet et de la fonction seront effectués par UpyLaB.
— Il n’est pas demandé que la fonction deux_egaux teste le type des paramètres reçus.
— Attention, nous rappelons que votre code sera évalué en fonction de ce qu’il affiche, donc veillez à n’imprimer que
le résultat attendu. En particulier, il ne faut rien écrire à l’intérieur des appels à input (int(input()) et non
int(input("Entrer un nombre : ")) par exemple), ni ajouter du texte dans ce qui est imprimé (print(res)
et non print("résultat :", res) par exemple).
— Par contre quand UpyLaB teste spécifiquement le code d’une fonction (ici la fonction deux_egaux), le type (et on verra
plus tard aussi la structure) du résultat est égaement validé. Veillez donc bien à renvoyer un résultat de type requis.
Quand votre solution sera validée, cliquez sur le bouton « AFFICHER LA RÉPONSE » pour trouver des conseils de bonnes
pratiques et éventuellement améliorer votre façon de coder.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Veillez à ce que la fonction retourne bien les valeurs booléennes True ou False, et non les chaînes de caractères "True"
ou "False".
— Pour retourner une valeur, une fonction doit utiliser l’instruction return valeur et non pas l’instruction print.
— La fonction doit retourner True si au moins deux nombres passés en paramètre sont égaux, que doit alors retourner l’appel
deux_egaux(2, 2, 2) ?
— Si rien ne marche : consultez la FAQ sur UpyLaB 4.1.
Énoncé
Attention : cet exercice est composé de l’exercice UpyLaB 4.2.a suivi en dessous de l’exercice UpyLaB 4.2.b.
Le Petit Prince vient de débarquer sur la planète U357, et il apprend qu’il peut y voir de belles aurores boréales !
La planète U357 a deux soleils : les étoiles E1515 et E666. C’est pour cela que les tempêtes magnétiques sont permanentes, ce qui
est excellent pour avoir des aurores boréales.
Par contre, il y fait souvent jour sauf bien évidemment quand les deux soleils sont couchés en même temps.
Heureusement pour nous, une journée U357 s’écoule sur 24 heures comme sur notre Terre, et pour simplifier, nous ne prendrons
pas en compte les minutes (on ne donne que les heures avec des valeurs entières entre 0 et 23).
Nous vous demandons d’aider le Petit Prince à déterminer les périodes de jour et de nuit.
UPYLAB 4.2A
Pour cela, vous allez dans un premier temps écrire une fonction soleil_leve qui, pour un soleil particulier, reçoit trois valeurs
et qui renvoie une valeur booléenne vraie si le soleil est levé sur la planète à l’heure donnée en troisième argument et fausse, s’il est
couché.
On supposera que chacun des soleils ne se lève et ne se couche au plus qu’une seule fois par jour. Il est toutefois possible que le
lever ait lieu après l’heure du coucher, ce qui signifie dans ce cas que le soleil est levé au début de la journée, puis qu’il se couche,
puis qu’il se lève à nouveau plus tard dans la journée. Enfin, si l’heure du lever est la même que l’heure du coucher :
— soit toutes deux valent 12, cela signifie que le soleil ne se lève pas de la journée,
— soit toutes les deux valent 0, cela signifie que le soleil ne se couche pas de la journée.
Exemple 1
doit retourner
True
Exemple 2
soleil_leve(15, 8, 12)
doit retourner
False
Exemple 3
doit retourner
False
Exemple 4
soleil_leve(0, 0, 22)
doit retourner
True
Consignes
— Pour cet exercice, il vous est demandé d’écrire la fonction soleil_leve. Le code que vous soumettrez à UpyLaB ne doit
donc comporter que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne
fait en particulier aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Plus précisément UpyLaB testera d’abord l’existence d’une définition de fonction soleil_leve avec le bon nombre de
paramètres. Si la fonction existe bien, UpyLaB testera votre fonction en exécutant un code qui réalise un appel à votre
fonction et affiche le résultat, ceci pour vérifier que celle-ci n’effectue aucun print. Ensuite différents tests de votre fonction
seront effectués par UpyLaB.
— Il n’est pas demandé que la fonction soleil_leve teste le type du paramètre reçu.
— Quand UpyLaB teste spécifiquement le code d’une fonction (ici la fonction soleil_leve), le type du résultat est égale-
ment validé. Veillez donc bien à renvoyer un résultat de type requis. En particulier, les objets True et "True" ne sont pas
du même type.
Quand votre solution sera validée, cliquez sur le bouton « AFFICHER LA RÉPONSE » pour trouver des conseils de bonnes
pratiques et éventuellement améliorer votre façon de coder.
UPYLAB 4.2B
Exemple 1
6
18
10
21
0 *
1 *
2 *
3 *
4 *
5 *
(suite sur la page suivante)
Exemple 2
15
8
6
17
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Consignes
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Veillez à ce que la fonction retourne bien les valeurs booléennes True ou False, et non les chaînes de caractères "True"
ou "False".
— Pour retourner une valeur, une fonction doit utiliser l’instruction return valeur et non pas l’instruction print.
— La difficulté réside dans l’identification de tous les cas possibles. N’hésitez donc pas à tester votre fonction dans votre IDE
ou dans PythonTutor avec plusieurs jeux de valeurs.
— Si rien ne marche : consultez la FAQ sur UpyLaB 4.2.
L’exercice 4.3 d’UpyLaB vous propose une fonction assez classique à rédiger, qui teste si un nombre n, reçu en paramètre, est
premier.
Par définition, un nombre entier naturel est premier s’il est divisible (entièrement) uniquement par deux nombres différents, par 1
et par lui-même. 1 n’est pas premier. Le plus petit nombre premier est 2. Tous les nombres premiers suivants sont impairs puisque
tous les nombres pairs sont divisibles par 2.
Il faut rédiger une fonction booléenne (dont le résultat est True ou False), qui reçoit un entier positif et renvoie True si et
seulement si n est un nombre premier.
MODULO
Dans la fonction premier, il faut vérifier que n n’est divisible par aucun des nombres entiers à partir de 2 et strictement inférieurs
à lui-même. Pour cela, notons que l’opérateur modulo peut être utile : le test n % i == 0 est vrai si i divise n entièrement.
NB : Il est toutefois intéressant de constater qu’il n’est en fait nécessaire de vérifier cette condition que pour les nombres entiers qui
sont inférieurs ou égaux à la racine carrée du nombre n. Si vous souhaitez rendre votre code plus efficace en réduisant le nombre
d’instructions exécutées, la fonction sqrt du module math s’avèrera utile ici.
Énoncé
Écrire une fonction booléenne premier(n) qui reçoit un nombre entier positif n et qui renvoie True si n est un nombre premier,
et False sinon.
Ensuite, écrire un programme qui lit une valeur entière x et affiche, grâce à des appels à la fonction premier, tous les nombres
premiers strictement inférieurs à x, chacun sur sa propre ligne.
Exemple 1
2
3
5
Exemple 2
2
3
5
7
Consignes
— Dans cet exercice, il vous est demandé d’écrire une fonction, puis un programme appelant cette fonction. Notez qu’UpyLaB
testera ces deux points, en exécutant le programme entier mais aussi en appelant directement la fonction avec les arguments
de son choix.
— Plus précisément UpyLaB testera d’abord l’existence d’une définition de la fonction premier avec le bon nombre de
paramètres. Si la fonction existe bien, UpyLaB testera un programme qui réalise 2 appels à la fonction et réalise deux
print ; ceci pour vérifier que celle-ci n’effectue aucun print. C’est en effet à votre programme d’effectuer les print
demandés. Ensuite différents tests de votre programme complet et de la fonction seront effectués par UpyLaB.
— Il n’est pas demandé que la fonction premier teste le type du paramètre reçu, ni si sa valeur est bien positive ou nulle.
— Attention, nous rappelons que votre code sera évalué en fonction de ce qu’il affiche, donc veillez à n’imprimer, ou pour
les fonctions ne renvoyer, que le résultat attendu. En particulier, il ne faut rien écrire à l’intérieur des appels à input
(int(input()) et non int(input("Entrer un nombre : ")) par exemple), ni ajouter du texte dans ce qui
est imprimé (print(res) et non print("résultat :", res) par exemple).
Quand votre solution sera validée, cliquez sur le bouton « AFFICHER LA RÉPONSE » pour trouver des conseils de bonnes
pratiques et éventuellement améliorer votre façon de coder.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Pour tester si un nombre est premier, l’idée est de chercher, parmi les nombres qui lui sont inférieurs (0 et 1 exclus), un
éventuel diviseur. Une instruction itérative, une instruction conditionnelle if et l’opérateur % (modulo) s’avèreront donc
utiles.
— Pour déterminer si le paramètre n reçu est premier, votre fonction premier doit donc s’assurer que n n’est divisible par
aucune valeur entière entre 2 et n - 1 compris.
— Pour le programme principal, ne pas hésiter à s’inspirer de ce qui est proposé dans le texte accompagnant cet exercice.
— Attention, le programme ne doit pas afficher la valeur de x, même si celui-ci est premier.
— Si rien ne marche : consultez la FAQ sur UpyLaB 4.3.
Jusqu’à présent nous avons appris de nouveaux éléments montrant ce qui était possible avec le langage Python. Parfois, il faut aussi
parler de ce qui est possible mais doit être évité. La parallèle peut être fait avec l’apprentissage de la vie en société. C’est bien de
savoir que l’on peut bouger, communiquer, et satisfaire ses besoins divers, encore faut-il connaître le code de la bonne conduite en
société pour ne pas avoir des soucis avec les autres ou se faire ostraciser !
De même, quand un programmeur écrit un code pour résoudre un problème, il faut d’abord que ce code soit correct, c’est-à-dire
résolve le problème pour toutes les configurations possibles (données, contextes,. . . ). Ensuite il vaut mieux que le code soit efficace
en prenant le moins de temps possible et en occupant le moins de place mémoire lors de son exécution.
Pour bien programmer, un autre critère essentiel est que le programme ou le code soit « propre » : un code est propre s’il a un
certain nombre de qualités de lisibilité pour un programmeur, de structuration, s’il est bien commenté, . . . . Python édicte des règles
à suivre au mieux lors de l’écriture du code pour que ce dernier soit propre. Libre à chaque programmeur de suivre ces règles ou
pas. Mais dans ce dernier cas, ne vous étonnez pas que personne ne communique avec vous vu les difficultés pour les autres de
comprendre votre code !
Plus globalement, les recommandations et améliorations pour le langage Python sont répertoriées dans des documents appelés PEPs
(Python Enhancement Proposals) sur le site officiel [Link] Chaque PEP porte un numéro. Le document intitulé
« PEP 8 – Style Guide for Python Code » contient un certain nombre de ces « règles de bonnes pratiques ». Ne pas suivre ces
règles peut aboutir à un programme correct et efficace, mais probablement moins propre. Ces règles parlent de constantes globales,
de convention de codage, de taille des fonctions, de conventions typographiques (endroits où l’on met des espaces ou des lignes
blanches), . . . Nous en parlons dans ce module et le suivant, mais donnons directement un exemple de code qui suit ces règles.
Constantes globales
Nous avons vu qu’un programme complet pouvait contenir des définitions de fonctions, du code, des commentaires, mais également
des importations de fonctions prédéfinies ou de modules complets. Généralement, un programme utilise également des valeurs
constantes, plus simplement appelées constantes dans le jargon informatique. Ces constantes peuvent être un « paramètre » du
programme, par exemple le nombre maximum d’éléments à traiter ou une valeur approchée de pi (3.14159. . . ). Reprenons le petit
jeu proposé dans le module précédent en section 3.3, pour améliorer le code proposé. Si notre programme doit deviner un nombre
entier entre 0 et 5 que nous avons choisi en utilisant la fonction randint du module random, il peut être intéressant de donner un
nom aux valeurs minimales et maximales de l’intervalle, et donc de définir des « constantes globales » :
Ces constantes seront bien sûr utilisées ensuite tout au long du programme. Un des gros avantages de cette pratique est que si plus
tard, le programmeur veut changer cet intervalle de valeurs, il lui suffit de corriger ces deux lignes en début du code.
Structure d’un programme
Les règles de bonnes pratiques nous demandent qu’un programme complet soit formé dans l’ordre :
— du docstring initial du programme contenant, le nom de l’auteur, la date d’écriture, une brève explication de ce qu’il fait, des
entrées lues et résultats affichés ;
— des éventuels imports de modules ou de parties de modules ;
— des définitions des constantes globales ;
— des définitions des fonctions globales ;
— et enfin du code du traitement principal.
La découpe du code en fonctions est également importante pour sa clarté. Donnons-en un simple exemple.
Code amélioré du petit jeu de devinette : Continuons avec l’exemple du petit jeu proposé dans le module précédent (section 3.3). Le
code suivant vous montre un exemple complet où nous supposons que :
— la valeur aléatoire est choisie dans l’intervalle [VALEUR_MIN, VALEUR_MAX] ;
— l’utilisateur propose bien une valeur entière, mais peut se tromper et proposer une valeur en dehors de l’intervalle.
Par ailleurs, par souci de clarté, nous avons découpé le code grâce à des fonctions :
— une fonction tirage qui s’occupe du tirage aléatoire ;
— une fonction entree_utilisateur qui demande à l’utilisateur son choix et redemande si ce dernier ne propose pas un nombre
dans l’intervalle ;
— une fonction affichage_resultat qui affiche à l’écran si l’utilisateur a ou non trouvé le nombre tiré aléatoirement.
L’exemple qui suit respecte bien l’ordre dans lequel les différents éléments de code doivent être placés : import, définitions de
constantes globales, de fonctions et finalement code principal.
Nous noterons qu’il respecte également les autres règles prescrites dont nous parlerons plus loin.
"""
Petit jeu de devinette (version 2)
Auteur: Thierry Massart
Date : 10 octobre 2018
Petit jeu de devinette d'un nombre entier tiré aléatoirement
par le programme dans un intervalle donné
Entrée : le nombre proposé par l'utilisateur
Résultat : affiche si le nombre proposé est celui tiré
aléatoirement
"""
# Code principal
format()
Le code utilise la fonction (appelée méthode dans le jargon) format pour imprimer du texte lors d’un input (ici pour demander le
choix de l’utilisateur). Cette méthode peut servir, lors d’un print, à formater les impressions, par exemple si l’on veut imprimer un
float avec un certain nombre de chiffres après le point décimal.
Notons que l’instruction Python "Votre choix de valeur entre {0} et {1} : ".format(10, 100) donne le
texte où les « paramètres » {0} et {1} dans le texte ont été remplacés par les valeurs 10 et 100 donnés commme arguments dans
la méthode format.
Pour voir son effet plus précis, essayez par exemple, dans une console PyCharm ou de votre environnement Python 3 :
print("pi vaut plus ou moins {0:7}".format(3.14))
print("pi vaut plus ou moins {0:7.4}".format(3.14159265359))
print("pi vaut plus ou moins {0:07.4}".format(3.14159265359))
Si vous désirez avoir une connaissance approfondie de son fonctionnement, reportez-vous au manuel python qui malheureusement
est souvent un peu ardu à lire.
Les f-strings
À partir de Python 3.6, la notion de f-string a été introduite pour remplacer avantageusement la méthode format(). Voici deux
exemples simples d’utilisation d’une f-string. Pour une description complète, nous vous conseillons le PEP-0498 (la source).
Une f-string consiste donc en une chaîne de caractères qui commence par un f ou un F avant le guillemet ou le quote simple et qui
contient, en plus de votre texte, des marqueurs { }. Le marqueur va contenir, une expression que Python sait évaluer ainsi que des
informations de formattage pour la valeur calculée.
La syntaxe générale est la suivante :
f' <texte> { <expression/variable> : <format> } <texte> ... '
Pour des nombres à virgule, le format est sous cette forme (les crochets signifient que les indications sont optionnelles) :
[alignement][signe][largeur][groupage][+precision][type]
print('\ndes entiers')
print(f'{123:=+10}')
print(f'{12998788:=+10}')
des flottants
3.141280
-0.79
des entiers
+ 123
+ 12998788
Rajoutons quelques règles de bonnes pratiques pour avoir un code « propre ». Nous avons déjà vu que parmi celles-ci :
— une convention habituelle en Python pour choisir un nom à une variable ou à une fonction est que ce nom soit formé de lettres
alphabétiques en minuscules, de chiffres ou du caractère souligné '_' et qu’elle évoque le contenu qu’elle représente. Par
exemple, resultat_final est un nom de variable correct pour recevoir un résultat ;
— si on définit une constante, c’est-à-dire que l’on donne un nom à une valeur que l’on ne modifie pas tout au long de l’exécution
du programme, la convention pour donner un nom à cette constante est d’utiliser des majuscules et le caractère souligné,
par exemple DIM_MAX = 100 définit la constante DIM_MAX (on suppose que le programmeur ne réassigne pas une autre
valeur à DIM_MAX ailleurs dans le programme).
En matière de bonnes pratiques, voici encore quelques éléments indispensables :
Indentation : La règle simple est d’ajouter 4 caractères pour chaque nouvelle indentation plutôt que d’utiliser la tabulation. Un
bon éditeur de script, par exemple celui fourni dans PyCharm, vous aidera grandement pour cela en faisant la plupart du travail
automatiquement.
Lignes de continuation : Les lignes doivent normalement avoir moins de 79 caractères (72 pour les Docstrings). Les blocs de
texte plus longs s’écrivent sur plusieurs lignes. Il se peut que le caractère de continuation anti-slash (en anglais backslash) '\' en
fin de ligne soit nécessaire, même si la plupart du temps, ce caractère de continuation peut être évité quand l’interpréteur sait que
l’instruction ou l’expression sur la ligne a une suite.
Par exemple, ayant dans une console Python :
>>> ma_variable_dont_le_nom_est_trop_long = 0
si nous voulons incrémenter cette variable, la ligne suivante donnera une erreur de syntaxe :
ou le caractère de continuation :
>>> ma_variable_dont_le_nom_est_trop_long += 1
Lignes blanches : Les règles de bonnes pratiques conseillent de mettre deux lignes blanches avant et entre chacune des définitions
de fonction globales et une ligne blanche pour mettre en évidence une nouvelle partie dans une fonction.
Une dernière remarque dans cette activité : en Python, une fonction fun_2 peut être définie à l’intérieur d’une autre fonction
fun_1 à condition que fun_2 soit locale à fun_1, c’est-à-dire utilisée uniquement lors du traitement de fun_1. Par exemple,
dans la fonction pgcd(x, y), on pourrait définir la fonction suivant (même si dans ce cas, cela ne simplifie pas fort le code)
comme suit :
# code de pgcd
while y > 0:
x, y = suivant (x, y)
return x
La fonction suivant n’est utilisée que par pgcd : en dehors de l’exécution de pgcd, suivant n’existe pas. Notons que certains
langages de programmation connus, tels que les langages C, C++, Java, ne supportent pas les définitions de fonctions imbriquées.
Vous n’avez évidemment pas vu toutes les notions utiles pour écrire un programme Python. Et probablement vous n’avez pas in-
tégré toutes les règles que nous venons de présenter. Ce n’est pas grave ! Pour vous aider, voici un petit manuel que vous pouvez
télécharger en cliquant sur le lien petit manuel des bonnes pratiques de programmation (Python) <[Link]
v1:ulb+44013+session05+type@asset+block@[Link], qui donne les règles de bonnes pratiques que nous vou-
drions que vous respectiez pour coder proprement vos programmes Python.
Pourquoi ne pas imprimer cette page pour toujours l’avoir sous la main quand vous écrirez du code ?
Ce manuel d’une page est découpé en cinq parties :
— traduction d’un problème en programme ;
— programmation ;
— nommage de variables, fonctions, etc. ;
— documentation du code ;
— structure globale d’un programme.
Chaque partie de ce manuel est essentielle et doit être suivie pour veiller à obtenir le code le plus lisible possible.
— La traduction d’un problème en programme passe par une phase d’analyse et est suivie de codage où il faut choisir les
fonctions que nous désirons définir et utiliser.
— La partie programmation parle de style de programmation et de quelques erreurs classiques à éviter.
— Nous avons déjà parlé de conventions de nommage des variables, des fonctions, etc.
— La documentation du code signifie que, dans vos programmes, vous devez mettre des commentaires (docstrings ou commen-
taires en fin de ligne, . . . ) pour que, si quelqu’un ou même vous, plus tard, relisez le code, il sera facile de comprendre ce
qu’il fait. La documentation est donc inutile pour l’ordinateur, et en particulier pour l’interpréteur, mais est bien utile pour
les pauvres humains que nous sommes qui essayons de comprendre ce que fait un code !
— Enfin, la dernière partie rappelle et illustre la structure globale d’un programme.
Ce petit manuel est également donné ci-dessous : à vous de lire et d’apprendre l’ensemble des consignes !
Une dernière bonne nouvelle : l’éditeur de script PyCharm intègre la plupart de ces règles et vous indique là où il considère que
vous ne les respectez pas.
4.4.5 La règle du return unique et les instructions dont on ne veut pas prononcer le nom
Pour ceux, comme vous probablement, qui débutent l’apprentissage de la programmation, nous avons l’habitude de rajouter quelques
« règles de bonnes pratiques » supplémentaires. Certaines de ces règles peuvent être assouplies pour les programmeurs avertis qui
n’ont plus besoin de « guide » pour bien coder.
Ces règles obligent les codes à respecter l’ordre « normal » d’exécution. Par exemple, si le code contient une instruction « if »,
« while » ou « for » ou une séquence d’instructions, il nous semble important pour bien comprendre la logique du code, de ne pas
interrompre ce code en plein milieu.
Malheureusement la plupart des langages de programmation dits « impératifs » comme Python permet de déroger à cette règle en
offrant au programmeur certaines instructions de « rupture de séquence ». Nous ne vous en avons pas parlé puisque nous ne voulons
pas que vous les utilisiez ! Nous comparons souvent l’utilisation de ce type d’instructions, à quelqu’un qui visite une maison et qui
en sort par la fenêtre : ce n’est pas très poli !
En fait au sein des fonctions, nous vous avons parlé d’une de ces instructions : l’instruction return. Elle permet de sortir d’une
instance de fonction pour revenir au code appelant. Le fonctionnement de Python oblige de terminer l’exécution de toute fonction
par un return explicite si l’on veut renvoyer une valeur précise, ou implicite si la fonction renvoie la valeur None. Il n’est donc
pas question de proscrire l’instruction return, mais bien de la cadrer de façon précise.
La règle de bonne pratique que nous voulons que vous respectiez est la suivante :
— Une fonction de type None ne doit pas contenir de return.
— Une fonction d’un type différent de None ne doit contenir qu’un seul return avec le résultat, et ce return doit être placé
comme dernière instruction de cette fonction en dehors de toute instruction composée (if, while, for, . . . ).
Habituez-vous à respecter cette règle qui vous permet d’écrire du code plus « propre » : ce n’est pas si difficile !
Et pourquoi ne pas reprendre vos codes UpyLaB précédents et s’ils ne suivent pas les règles de bonnes pratiques de codage, les
corriger ?
Parmi les recommandations et améliorations pour le langage Python, répertoriées dans les PEPs (Python Enhancement Proposals),
nous trouvons le PEP 20. Le PEP 20 résume les 20 aphorismes (dont seulement 19 ont été rédigés) utilisés par Guido van Rossum,
le BDFL Python (Benevolent Dictator for Life) jusqu’en 2018, pour concevoir le langage lui-même.
(Note : Le dictionnaire Larousse définit aphorisme par : phrase, sentence qui résume en quelques mots une vérité fondamentale.
(Exemple : Rien n’est beau que le vrai.))
La lecture du PEP 20 est assez hermétique pour les programmeurs débutants ; ne vous arrêtez donc pas à cela. Si vous êtes quand
même curieux de son contenu (en anglais) ouvrez une console PyCharm et tapez la commande :
import this
qui vous dévoilera son contenu inspiré par l’humour absurde des Monty Python dont Guido van Rossum était féru.
Comme exercice, nous vous demandons de dessiner une spirale ou une courbe assez proche d’une spirale avec le module turtle. La
technique que nous vous proposons pour dessiner la spirale est assez simple : il suffit d’assembler bout à bout des quart de cercles
de rayon de plus en plus grand.
La vidéo suivante montre l’affichage d’un petit programme qui appelle une fonction spirale. Le code utilise turtle et la fonction
circle pour dessiner des quarts de tour de plus en plus grands. Les autres fonctions du module turtle utilisées par mon code sont
reset, color, speed et width.
L’exercice suivant met en pratique ce que nous avons vu sur les fonctions. Écrivez, dans un script Python, un code qui réalise un
affichage similaire grâce à une fonction spirale qui a deux paramètres :
— la couleur,
— la largeur du trait.
Ainsi, la figure précédente est l’exécution répétée de : spirale('red', 10)
PROPOSITION DE SOLUTION
Vous avez du mal pour réaliser l’exercice ou vous l’avez réussi mais voulez avoir un autre code qui solutionne l’exercice demandé ?
Nous vous proposons une solution.
import turtle
[Link](couleur)
[Link](largeur)
for i in range(100):
[Link](i*(largeur/2),90)
while True:
[Link]()
[Link](0)
spirale('red', 10)
Notez que la solution proposée boucle indéfiniment : le programme n’arrêtera son exécution que lorsque l’on le « tue », par exemple
avec la touche clavier cmd-F2 (commande-F2) ou CTRL-c (contrôle-c) en étant dans la fenêtre Run du script PyCharm en exécution.
Continuons de pratiquer la matière de ce module avec turtle qui nous permet de facilement visualiser le résultat et donc d’en
valider notre compréhension. Supposons que nous désirions dessiner diverses figures. Nous pouvons, pour ce faire, imaginer définir
différentes fonctions. Prenons le cas d’une fonction qui dessine un polygone régulier.
À nouveau, la première chose à déterminer est le nom de la fonction et quels paramètres elle aura.
Supposons que l’on appelle cette fonction polygone_turtle. Il faut ensuite penser à l’ensemble des paramètres.
Les paramètres pourraient être :
— le nombre de côtés du polygone régulier ;
— les coordonnées (x, y) du centre de la figure sur la fenêtre turtle ;
— la taille du rayon du cercle qui circonscrit le polygone ;
— la couleur du polygone.
Par exemple, le dessin suivant provient d’un programme qui a appelé la fonction polygone_turtle et défini cinq couleurs
différentes, le nombre de côtés, le centre et le rayon étant choisis aléatoirement.
Le code dessine séquentiellement 5 polygones remplis : noir, bleu, rouge, vert et jaune, de taille, nombre de côtés et emplacement
choisis pseudo-aléatoirement.
EXERCICE À RÉALISER
À vous !
Écrivez dans un script Python un programme complet figures_geometriques qui définit et utilise cette fonc-
tion polygone_turtle. Vous pouvez également le compléter d’une fonction etoile_turtle(n, x, y, rayon,
couleur) qui dessine une étoile à n branches avec les mêmes spécifications qu’avec la fonction polygone_turtle.
Ici nous ne vous donnons pas une solution complète. Comme le résultat est graphique, il vous sera possible de vérifier s’il fonctionne
correctement. Nous vous donnons quand même une aide pour réaliser le programme figures_geometriques, si vous avez des
soucis avec les formules trigonométriques.
Petite aide pour réaliser le programme figures_geometriques
Ayant importé turtle, cos, sin et pi, après avoir positionné, avec [Link](x+rayon, y) la tortue au premier point
du polygone de centre (x, y) et de rayon rayon, le code suivant trace le polygone à n côtés
YIN-YANG REVISITÉ
Reprenons le code de la fonction yin_yang donné en section 4.3 pour le corriger en suivant les bonnes pratiques discutées avant
dans ce module. Cette fonction avait été proposée sans paramètre. Pour respecter les règles de bonnes pratiques d’un codeur Python,
cette fonction a plusieurs défauts :
1. elle est trop longue en terme de séquence monolithique de lignes. Il faudrait essayer de la découper en utilisant plusieurs
sous-fonctions.
2. elle devrait avoir des paramètres :
— ici le yin-yang a un rayon de 200 points. Si nous voulons faire un yin-yang d’une autre taille, il faudrait corriger des valeurs
un peu partout dans le code, ce qui peut être une belle source d’erreurs.
— on pourrait imaginer un yin-yang avec d’autres couleurs, non centré, . . .
3. si l’on regarde le code, il fait plus ou moins deux fois la même chose puisque le yin à la même forme que le yang. Seuls
l’emplacement et la couleur changent. Il serait donc bien d’essayer de n’avoir qu’un seul code qui trace à la fois le yin et le
yang en fonction des arguments donnés à l’exécution.
Python propose de donner des valeurs par défaut aux paramètres lors de sa définition. Rappelons que « par défaut » signifie « si
rien n’est donné explicitement ». Ici, « par défaut » signifie donc « si lors de l’appel à la fonction la valeur de l’argument n’est pas
donnée ».
Par exemple nous pouvons définir l’entête d’une fonction yin_yang comme suit : def yin_yang(rayon,
color1='black', color2='white'): le corps de la fonction étant défini normalement. Avec cet entête, si lors de l’appel
à la fonction yin_yang, seulement deux paramètres sont donnés, le premier argument sera donné pour le paramètre rayon et le
second pour le paramètre color1. Le paramètre color2 prendra la valeur par défaut 'white'.
Si lors d’un appel à la fonction yin_yang, un seul argument est donné (pour le paramètre rayon), color1 vaudra sa valeur par
défaut 'black' et color2 sa valeur par défaut c’est-à-dire 'white'. Notons que comme le paramètre rayon n’a pas de valeur
par défaut dans sa définition, il faudra au moins donner un argument lors de tout appel à la fonction.
Notons que Python a également la possibilité d’effectuer la transmission des arguments aux paramètres par mot-clé comme avec
print(res1, res2, res3, end="", sep="/") qui spécifie que les paramètres end et sep prennent respectivement la
valeur chaîne de caractères vide ("") et la caractère barre oblique.
À vous de jouer !
Nous vous proposons donc, à nouveau dans votre IDE, de modifier le code précédent pour mieux le structurer et permettre d’autres
couleurs (le contour restant en noir).
Pour vous aider, voici la structure proposée : la fonction yin_yang définit en son sein deux fonctions :
— la fonction yin qui fait la moitié du symbole (soit le yin soit le yang). Elle sera donc appelée deux fois par la fonction
yin_yang ;
— la fonction yang qui fait le disque yang (respectivement yin) à l’intérieur du yin (resp. yang) et qui est appelée au sein de la
fonction yin.
L’ossature du code proposé est donc comme suit :
#code de yin_yang
[Link]()
(suite sur la page suivante)
#code principal
yin_yang(200) #réalise le logo de rayon 200
Si vous ne trouvez pas la bonne réponse, n’hésitez pas à en discuter via le [Forum général du Module 4] pour y arriver !
Si malgré tout, vous avez du mal pour réaliser l’exercice ou vous l’avez réussi mais voulez avoir une autre solution, nous vous en
proposons une.
PROPOSITION DE SOLUTION
#code de yin_yang
[Link]()
[Link](2)
yin(rayon, color1, color2)
(suite sur la page suivante)
#code principal
yin_yang(200) #réalise le logo
ÉNONCÉ DE L’EXERCICE
Nous avons écrit durant l’activité 2.6.3, du code pour tracer un pavé. L’activité suivante réalise le codage d’une fonction :
CANEVAS DE CODE
import turtle
from math import pi, sin, cos
import random
import time
[Link]()
[Link](0)
[Link]()
[Link](5)
Votre code complet devrait produire un résultat similaire à celui de la vidéo de la section 4.5.5
RÉSULTAT DU CODE
Note : Notez que la seconde partie de la vidéo est la séquence vidéo inversée réalisée avec le logiciel screenflow.
Nous sommes arrivés à la fin de ce module, où vous devez devenir autonome dans la rédaction de code Python utilisant des fonctions.
Pour cela réalisez tous les exercices UpyLaB du module 4 qu’il vous reste à faire.
N’oubliez pas qu’UpyLaB est un environnement de test et non un environnement de développement. En particulier, la plupart
des codes demandés par la suite par UpyLaB ne sont qu’une partie d’un programme complet. Par exemple, UpyLaB demande de
définir une fonction foo, et complètera votre définition par un code qui testera l’exécution de votre fonction pour plusieurs jeux
de paramètres. Avant de soumettre à UpyLaB, il est fortement conseillé de développer dans un environnement de développement
(Thonny ou PyCharm par exemple) un programme complet qui définisse foo mais également qui fasse des appels pour tester si elle
est correcte. C’est ce que l’on appelle réaliser des test unitaires ; l’unité étant un bout de code comme une fonction, ici la fonction
foo.
Bon travail !
Énoncé
Écrire une fonction alea_dice(s) qui génère trois nombres (pseudo) aléatoires à l’aide de la fonction randint du module
random, représentant trois dés (à six faces avec les valeurs de 1 à 6), et qui renvoie la valeur booléenne True si les dés forment un
421, et la valeur booléenne False sinon.
Le paramètre s de la fonction est un nombre entier, qui sera passé en argument à la fonction [Link] au début du code de
la fonction. Cela permettra de générer la même suite de nombres aléatoires à chaque appel de la fonction, et ainsi de pouvoir tester
son fonctionnement.
Exemple 1
doit retourner :
False
Exemple 2
doit retourner :
True
Consignes
— Pour cet exercice, il vous est demandé d’écrire la fonction alea_dice. Le code que vous soumettrez à UpyLaB ne doit
donc comporter que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne
fait en particulier aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Plus précisément UpyLaB testera d’abord l’existence d’une définition de votre fonction avec le bon nombre de paramètres.
Si la fonction existe bien, UpyLaB testera votre fonction : il ajoutera des appels à votre fonction pour vérifier que celle-ci
n’effectue aucun print. Ensuite différents tests de votre fonction seront effectués par UpyLaB.
— Il n’est pas demandé que la fonction alea_dice teste le type du paramètre reçu.
— N’importe quelle combinaison de trois dés permettant de former le nombre 421 sera acceptée, quel que soit l’ordre de la
combinaison. Par exemple, les tirages 2, 4, 1 forment bien 421.
— La première instruction de la fonction, après l’import du module random, sera [Link](s).
— On rappelle que la fonction randint(a, b) retourne un nombre (pseudo) aléatoire compris entre les bornes a et b
incluses.
Quand votre solution sera validée, cliquez sur le bouton « AFFICHER LA RÉPONSE » pour trouver des conseils de bonnes
pratiques et éventuellement améliorer votre façon de coder.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Veillez à ce que la fonction retourne bien les valeurs booléennes True ou False et non les chaînes de caractères "True"
ou "False".
— Il n’est demandé ici que de définir la fonction. Mais pour tester son fonctionnement dans votre IDE, pensez à ajouter
l’instruction print(alea_dice(s)), en remplaçant s par une valeur entière. En particulier, vous pouvez remplacer ce
paramètre s par l’argument utilisé par UpyLaB dans chacun de ces tests.
— Python Tutor pourra s’avérer particulièrement utile ici pour observer ce qu’il se passe exactement lors de l’appel de la
fonction.
— Si rien ne marche : consultez la FAQ sur UpyLaB 4.4.
Note pour réaliser les exercices qui suivent
Certains exercices dont l’exercice UpyLaB suivant utilisent des valeurs de type tuple. Les tuples sont des séquences de données
qui seront étudiées en détail au module suivant. Pour réaliser les exercices de ce présent module, ayant des valeurs v1 et v2 (par
exemple int ou float), il faut juste savoir que :
Énoncé
Considérons les billets et pièces de valeurs suivantes : 20 euros, 10 euros, 5 euros, 2 euros et 1 euro.
Écrire une fonction rendre_monnaie qui reçoit en paramètre un entier prix et cinq valeurs entières x20, x10, x5, x2 et
x1, qui représentent le nombre de billets ou de pièces de chaque valeur que donne un client pour l’achat d’un objet dont le prix est
mentionné.
La fonction doit renvoyer cinq valeurs, représentant le nombre de billets et pièces de chaque sorte qu’il faut rendre au client, dans
le même ordre que précédemment. Cette décomposition doit être faite en rendant le plus possible de billets et pièces de grosses
valeurs.
Si la somme d’argent avancée par le client n’est pas suffisante pour effectuer l’achat, la fonction retournera cinq valeurs None.
Exemple 1
rendre_monnaie(38, 1, 1, 1, 1, 1)
doit retourner :
(0, 0, 0, 0, 0)
Exemple 2
rendre_monnaie(56, 5, 0, 0, 0, 0)
doit retourner :
(2, 0, 0, 2, 0)
Exemple 3
rendre_monnaie(80, 2, 2, 2, 3, 3)
doit retourner :
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Plus précisément UpyLaB testera d’abord l’existence d’une définition de votre fonction avec le bon nombre de paramètres.
Si la fonction existe bien, UpyLaB testera votre fonction : il ajoutera des appels à votre fonction pour vérifier que celle-ci
n’effectue aucun print. Ensuite différents tests de votre fonction seront effectués par UpyLaB.
— Il n’est pas demandé que la fonction rendre_monnaie teste le type des paramètres reçus.
— On suppose qu’il y a toujours suffisamment de billets et pièces de chaque sorte.
— Pour retourner cinq valeurs, on pourra utiliser l’instruction return res20, res10, res5, res2, res1.
Cela renvoie en réalité un tuple de cinq valeurs (apparaissant entre parenthèses lorsqu’on l’affiche). La notion de tuple sera introduite
au module suivant ; pour l’instant, ne vous préoccupez pas de ceci.
Quand votre solution sera validée, cliquez sur le bouton « AFFICHER LA RÉPONSE » pour trouver des conseils de bonnes
pratiques et éventuellement améliorer votre façon de coder.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Il n’est demandé ici que de définir la fonction. Mais pour tester son fonctionnement dans votre IDE, pensez à ajouter du code
qui l’appelle et teste son résultat, sur plusieurs valeurs, comme print(rendre_monnaie(70, 2, 1, 2, 2, 2))
par exemple.
— Pour déterminer le nombre de billets et pièces de chaque sorte, l’opérateur // pourra s’avérer utile, ainsi que l’opérateur %
pour calculer la somme restant à décomposer.
— Si rien ne marche : consultez la FAQ sur UpyLaB 4.5.
Énoncé
Dans cet exercice, nous allons mettre en pratique la notion de valeur par défaut des paramètres d’une fonction.
Écrire une fonction somme(a, b) qui retourne la somme de deux valeurs entières a et b. Par défaut, la valeur de a est 0 et la
valeur de b est 1.
Exemple 1
somme(24, 18)
doit retourner :
42
Exemple 2
somme(4)
doit retourner :
Exemple 3
somme()
doit retourner :
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Plus précisément UpyLaB testera d’abord l’existence d’une définition de votre fonction avec le bon nombre de paramètres.
Si la fonction existe bien, UpyLaB testera votre fonction : il ajoutera des appels à votre fonction pour vérifier que celle-ci
n’effectue aucun print. Ensuite différents tests de votre fonction seront effectués par UpyLaB.
— Il n’est pas demandé que la fonction somme teste le type des paramètres reçus.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Il n’est demandé ici que de définir la fonction. Mais pour tester son fonctionnement dans votre IDE, pensez à ajouter du code
qui l’appelle et teste son résultat, sur plusieurs valeurs, comme print(somme(3, 2)) par exemple.
— N’hésitez pas à revoir comment on a défini des valeurs par défaut pour certains paramètres de la fonction yin_yang.
— Si rien ne marche : consultez la FAQ sur UpyLaB 4.6.
Énoncé
Écrire une fonction rac_eq_2nd_deg(a, b, c) qui reçoit trois paramètres de type float correspondant aux trois coefficients
de l’équation du second degré 𝑎𝑥2 + 𝑏𝑥 + 𝑐 = 0, où 𝑎 est différent de 0, et qui renvoie la ou les solutions s’il y en a, sous forme
d’un tuple.
Exemple 1
rac_eq_2nd_deg(1.0,-4.0,4.0)
doit retourner :
(2.0,)
Exemple 2
rac_eq_2nd_deg(1.0,1.0,-2.0)
doit retourner :
(-2.0, 1.0)
Exemple 3
rac_eq_2nd_deg(1.0,1.0,1.0)
doit retourner :
()
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Plus précisément UpyLaB testera d’abord l’existence d’une définition de votre fonction avec le bon nombre de paramètres.
Si la fonction existe bien, UpyLaB testera votre fonction : il ajoutera des appels à votre fonction pour vérifier que celle-ci
n’effectue aucun print. Ensuite différents tests de votre fonction seront effectués par UpyLaB.
— Il n’est pas demandé que la fonction rac_eq_2nd_deg teste le type des paramètres reçus.
— Le résultat retourné par la fonction rac_eq_2nd_deg est un tuple.
— S’il n’y a pas de solution réelle, elle retourne un tuple vide tuple().
— S’il y a une unique racine r1, elle retourne le tuple (r1,).
— S’il y a deux solutions réelles, r1 et r2, la plus petite des deux devra être la première composante du tuple retourné
(composante d’indice 0). La fonction pourra retourner le tuple (min(r1, r2), max(r1, r2)).
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Il n’est demandé ici que de définir la fonction. Mais pour tester son fonctionnement dans votre IDE, pensez à ajouter du
code qui l’appelle et teste son résultat, sur plusieurs valeurs, comme print(rac_eq_2nd_deg(1.0, 1.0, 1.0))
par exemple.
— Les calculs permettant d’obtenir les éventuelles solutions de l’équation ont été présentés au module 3 de ce cours, lors de
l’introduction de l’instruction conditionnelle if.
— Si rien ne marche : consultez la FAQ sur UpyLaB 4.7.
Énoncé
Écrire une fonction catalan(n), où n est un nombre entier positif ou nul, qui renvoie la valeur du n-ième nombre de Catalan.
Exemple 1
catalan(5)
doit retourner :
42
Exemple 2
catalan(0)
doit retourner :
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Il n’est pas demandé que la fonction catalan teste le type du paramètre reçu.
— Plus précisément UpyLaB testera d’abord l’existence d’une définition de votre fonction avec le bon nombre de paramètres.
Si la fonction existe bien, UpyLaB testera votre fonction : il ajoutera des appels à votre fonction pour vérifier que celle-ci
n’effectue aucun print. Ensuite différents tests de votre fonction seront effectués par UpyLaB.
— Votre fonction doit renvoyer une valeur entière.
— Rappelons aussi que si une fonction est demandée, UpyLaB va tester à la fois que les résultats envoyés par cette fonction
sont corrects et qu’ils ont le bon type.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Vous pouvez utiliser la fonction factorial du module math, ou écrire votre propre fonction factorielle ou encore
ne pas calculer explicitement ces factorielles en étudiant comment l’on passe d’un nombre de Catalan au suivant.
— Si rien ne marche : consultez la FAQ sur UpyLaB 4.8.
Cet exercice et le suivant vous demandent de programmer le petit jeu appelé « Pierre-feuille-ciseaux » ou « Pierre-papier-ciseaux »
(et qui porte encore d’autres noms comme indiqué dans la page Pierre-papier-ciseaux sur Wikipedia que nous utilisons pour rédiger
l’énoncé ci-dessous).
Énoncé
Pierre-feuille-ciseaux est un jeu effectué avec les mains et qui oppose un ou plusieurs joueurs. Ici nous nous supposerons qu’il y a
deux joueurs : l’ordinateur et le joueur lui-même.
Déroulement du jeu
Les deux joueurs choisissent simultanément un des trois coups possibles en le symbolisant de la main :
— Poing fermé : Pierre ;
— Main ouverte, doigts collés les uns aux autres : Feuille ;
— Main avec pouce, annulaire et auriculaire fermé, index et majeur ouvert en forme de V : Ciseaux.
Résultat du jeu :
— La pierre bat les ciseaux (en les émoussant),
— les ciseaux battent la feuille (en la coupant),
— la feuille bat la pierre (en l’enveloppant).
Ainsi chaque coup bat un autre coup, fait match nul contre le deuxième (son homologue) et est battu par le troisième.
Écrire une fonction bat(joueur_1, joueur_2) où joueur_1 et joueur_2 ont chacun une valeur entière 0, 1 ou 2, qui
encode ce que le joueur a fait comme coup (0 : PIERRE, 1 : FEUILLE, 2 : CISEAUX) qui renvoie un résultat booléen :
— vrai si joueur_1 bat le joueur_2 :
— faux si joueur_2 bat joueur_1 ou fait match nul contre lui.
Exemple 1
bat(0, 0)
doit retourner :
False
Exemple 2
bat(0, 1)
doit retourner :
False
Exemple 3
bat(2, 1)
doit retourner :
True
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes et des trois défini-
tions des constantes PIERRE, FEUILLE, CISEAUX, et ne fait en particulier aucun appel ni à la fonction demandée ni aux
fonctions input et print.
— Il n’est pas demandé que la fonction bat teste le type ou les valeurs des paramètres reçus.
Quand votre solution sera validée, cliquez sur le bouton « AFFICHER LA RÉPONSE » pour trouver des conseils de bonnes
pratiques et éventuellement améliorer votre façon de coder.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Il n’est demandé ici que de définir la fonction. Mais pour tester son fonctionnement dans votre IDE, pensez à ajouter du code
qui l’appelle et teste son résultat, sur plusieurs valeurs, comme print(bat(2, 2))) par exemple. Notez que comme
chaque paramètre peut avoir 3 valeurs, la fonction bat doit gérer 9 cas possibles. N’hésitez pas à les tester tous avant de
mettre votre code dans UpyLaB.
— Si rien ne marche : consultez la FAQ sur UpyLaB 4.9.
Énoncé
Pierre-feuille-ciseaux est un jeu effectué avec les mains et qui oppose un ou plusieurs joueurs.
Déroulement du jeu
Les deux joueurs choisissent simultanément un des trois coups possibles en le symbolisant de la main :
— Poing fermé : Pierre ;
— Main ouverte, doigts collés les uns aux autres : Feuille ;
— Main avec pouce, annulaire et auriculaire fermé, index et majeur ouvert en forme de V : Ciseaux.
De façon générale, la pierre bat les ciseaux (en les émoussant), les ciseaux battent la feuille (en la coupant), la feuille bat la pierre
(en l’enveloppant). Ainsi chaque coup bat un autre coup, fait match nul contre le deuxième (son homologue) et est battu par le
troisième.
Écrire un programme qui réalise 5 manches du jeu Pierre-feuille-ciseaux entre l’ordinateur et le joueur. Chaque manche va consis-
ter en :
— la génération (pseudo) aléatoire d’un nombre entre 0 et 2 compris, à l’aide de la fonction randint du module random, et
qui va représenter le coup de l’ordinateur (0 valant Pierre, 1 Feuille et 2 Ciseaux) ;
— la lecture en entrée (input) d’une valeur entière entre 0 et 2 compris qui représente le coup du joueur ;
— l’affichage du résultat sous une des formes :
— coup_o bat coup_j : points
— coup_o est battu par coup_j : points
— coup_o annule coup_j : points
où
— coup_o et coup_j sont respectivement le coup de l’ordinateur et du joueur : "Pierre" s’il a joué 0,
"Feuille" s’il a joué 1 et "Ciseaux" s’il a joué 2.
— points donne le résultat des manches jusqu’à présent sachant que le compteur points part de zéro, et est
incrémenté de un chaque fois que le joueur gagne une manche, et décrémenté de un chaque fois que l’ordinateur
gagne une manche (les matchs nuls ne modifiant pas le compteur points).
À la fin des cinq manches, votre programme affichera Perdu, Nul ou Gagné suivant que le compteur est négatif, nul ou strictement
positif.
Pour plus de clarté dans votre code, nous vous conseillons de définir les trois constantes symboliques :
PIERRE = 0
FEUILLE = 1
CISEAUX = 2
Par ailleurs, votre code doit importer le module random et, avant de commencer les manches, pour permettre à UpyLaB de
valider les résultats, doit d’abord lire une valeur entière s et appeler la fonction [Link](s). Vous devez donc intégrer le
code suivant :
import random
PIERRE = 0
FEUILLE = 1
CISEAUX = 2
...
s = int(input())
[Link](s)
Votre code fera donc un appel à [Link] suivi de cinq appelq à [Link], un par manche. Aucun autre appel à
une fonction de random ne pourra être effectué.
Vous pouvez bien sûr utiliser la fonction bat de l’exercice 4.9 mais nous vous conseillons vivement de définir aussi d’autres
fonctions (par exemple , une fonction qui réalise une manche et imprime la ligne de message) pour structurer votre code.
Exemple 1
[Link](65)
for i in range(5):
print([Link](0,2))
donne le résultat :
1
1
1
2
0
65
0
1
2
1
0
doit afficher :
Exemple 2
[Link](1515)
for i in range(5):
print([Link](0,2))
donne le résultat :
2
1
0
2
2
1515
0
1
2
1
0
doit afficher :
Exemple 3
[Link](2001)
for i in range(5):
print([Link](0,2))
donne le résultat :
2
0
1
0
0
2001
0
1
2
1
0
doit afficher :
Consignes
— Dans cet exercice, il vous est demandé d’écrire un programme contenant des fonctions.
— Attention, nous rappelons que votre code sera évalué en fonction de ce qu’il affiche, donc veillez à n’imprimer que le résultat
attendu en respectant majuscules et minuscules et en veillant à n’avoir qu’un espace entre les mots et signes et aucune espace
supplémentaire en fin de ligne. En particulier, il ne faut rien écrire à l’intérieur des appels à input (int(input()) et non
int(input("Entrer un nombre : ")) par exemple), ni ajouter du texte supplémentaire dans ce qui est imprimé
(print(points) et non print("résultat :", points) par exemple).
Quand votre solution sera validée, cliquez sur le bouton « AFFICHER LA RÉPONSE » pour trouver des conseils de bonnes
pratiques et éventuellement améliorer votre façon de coder.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Si rien ne marche : consultez la FAQ sur UpyLaB 4.10.
BILAN EN BREF
BILAN DU MODULE
Nous voici à la fin de ce module. Nous y avons vu principalement comment structurer notre code grâce à la définition et l’utilisation
de fonctions. De façon plus précise, nous avons vu :
— que plusieurs fonctions prédéfinies bien utiles sont disponibles ;
— que la librairie standard regorge de modules qui peuvent être importés et sont remplis de fonctions prédéfinies biens utiles
également ;
— que le programmeur peut également définir des fonctions Python ;
— que la définition et l’utilisation de fonctions sont essentielles pour écrire un « bon » code, c’est-à-dire un code « bien
structuré » facilement « lisible » pour le programmeur et toute personne qui devrait consulter le code ;
— que le mécanisme de passage de paramètres permet d” « isoler » le code d’une fonction du code appelant ;
— qu’il existe toutes sortes de formes de fonctions qui renvoient un résultat ou dont le but est d’effectuer un autre type de
traitement ;
— qu’un résultat d’une fonction peut être un tuple de valeurs, ce qui permet en pratique à la fonction de renvoyer plusieurs
résultats lors d’un seul return.
Nous avons également illustré tous ces concepts avec des exemples et la réalisation d’exercices supervisés ou réalisés de façon
autonomes avec UpyLaB.
Dans ce module et les modules précédents, nous avons appris à écrire des codes complets et modulaires. Les deux modules qui vont
suivre vont compléter le tableau. Nous allons voir les séquences de données. Ces types de données vont nous permettre de résoudre
des problèmes beaucoup plus ambitieux que ce que nous avons fait jusqu’à présent. En route donc vers l’infini et au-delà ! Enfin
presque.
MENU DE CE MODULE
Nous voici arrivés au module 5 de notre cours. Ce module est important à la fois au niveau de son contenu et au niveau de son
volume.
Nous allons parler de structures de données plus complexes que ce que nous avons vu jusqu’à présent. En clair, nous allons analyser
de façon fouillée les trois types de données chaînes de caractères, tuples et listes.
CONTENU DE LA VIDÉO
La vidéo précédente introduit dans un premier temps le menu de ce module : l’étude des trois séquences Python : les chaînes de
caractères, les tuples et les listes.
Nous présentons ensuite les manipulations de base sur les chaînes de caractères dont certaines ont déjà été présentées au module 2.
Code sur la console réalisé dans la vidéo
>>> mon_str = "bonjour"
>>> long_t = """******************************
... * Bon anniversaire *
... ******************************"""
>>> print(long_t)
******************************
(suite sur la page suivante)
CC BY-SA 3.0 - 2021 - Sébastien Hoarau - Thierry Massart - Jean Olgiati - Isabelle Poirier 179
Apprendre à coder avec Python, Version - Release 3.0
La vidéo en bref
Après avoir présenté le copieux menu de ce module, nous montrons les manipulations de base des chaînes de caractères, parfois
plus simplement appelés textes. Les constantes chaînes de caractères sont entourées de simples ou doubles apostrophes (appelées
également simples ou doubles quotes) ou de trois simples ou doubles quotes ; ces dernières peuvent être multilignes.
Nous rappelons que l’opérateur + sur les chaînes de caractères effectue la concaténation de celles-ci (le fait de coller deux textes
ensemble), et que nous pouvons répéter une chaîne avec l’opérateur * suivi ou précédé d’un nombre entier qui donne le facteur
de répétition.
Nous montrons que nous pouvons obtenir la valeur d’une composante d’une séquence (ici chaînes de caractères) en indiçant la
séquence avec une valeur entière entre 0 et sa longueur moins 1 (par exemple de 0 à 6 pour le texte « bonjour »).
Demander une composante plus grande donne une erreur à l’exécution. Par contre demander la composante d’indice -1, -2, . . .
revient à demander, respectivement la dernière composante, l’avant dernière, . . . .
Enfin pour un texte s, len(s) donne sa longueur, c’est-à-dire le nombre de ses composantes.
CONTENU DE LA VIDÉO
La vidéo précédente présente les listes et les tuples ainsi que leurs manipulations de base.
Code sur la console réalisé dans la vidéo
>>>
La vidéo en bref
Des listes (list) et des tuples (tuples), en plus des chaînes de caractères, sont définis et manipulés soit globalement soit en
prenant une composante. Les fonctions prédéfinies len (qui donne la longueur) et type (qui donne le type) sont applicables sur
les trois types de séquences.
Note : Voir la vidéo de la section 5.1.3 : Les séquences : for, in, opérateurs relationnels
CONTENU DE LA VIDÉO
La vidéo précédente revient sur l’instruction for qui manipule tous les éléments d’une séquence, présente l’opérateur in dans
un test (une condition) qui permet de déterminer si une composante d’une séquence vaut une valeur donnée et montre comment
l’interpréteur Python compare les séquences entre elles au niveau de l’égalité, de la différence ou de l’ordre.
Code sur la console réalisé dans la vidéo
>>> personnages = ["le serpent", "le mouton", "le petit prince", "l'aviateur",
... "la rose", "le Monsieur cramoisi", "le roi", "le vaniteux",
... "le buveur","le businessman", "l'allumeur de réverbères",
... "le géographe", "la fleur à trois pétales", "les roses du jardin",
... "le renard", "l'aiguilleur", "le marchand"]
>>> somme = 0
>>> for i in range(10):
... somme += i
...
>>> somme
45
>>> for elem in personnages:
... print(elem)
...
le serpent
le mouton
le petit prince
l'aviateur
la rose
le Monsieur cramoisi
le roi
le vaniteux
le buveur
le businessman
l'allumeur de réverbères
le géographe
la fleur à trois pétales
les roses du jardin
le renard
l'aiguilleur
le marchand
>>> nom = "Gertrude"
>>> for c in nom:
... print("Caractère suivant :", c)
...
Caractère suivant : G
Caractère suivant : e
Caractère suivant : r
Caractère suivant : t
Caractère suivant : r
Caractère suivant : u
Caractère suivant : d
Caractère suivant : e
>>> for i in range(len(nom)):
... print("le caractère d'indice ", i, " :", nom[i])
...
le caractère d'indice 0 : G
le caractère d'indice 1 : e
le caractère d'indice 2 : r
le caractère d'indice 3 : t
le caractère d'indice 4 : r
le caractère d'indice 5 : u
(suite sur la page suivante)
La vidéo en bref
Des exemples de manipulations de séquences avec des instructions for sont donnés. L’opérateur in est utilisé dans un for
pour itérer sur tous les éléments d’une séquence. L’opérateur in peut également être utilisé dans une condition pour tester si un
élément est dans une séquence. Son fonctionnement précis ainsi que le fonctionnement des opérateurs relationnels (==, !=, <,
<=, >, >=) sont expliqués grâce à divers exemples.
Pour les textes s et t, s in t teste si le texte s est une sous-chaîne de la chaîne de caractères t. Ce n’est pas le cas pour les
tuples ou les listes, et la vidéo explique pourquoi.
Dans les vidéos que nous venons de présenter, nous avons parlé de comparaison entre caractères. Mais, par exemple, quel est le
résultat du code ?
c1 = '#'
c2 = ' C'
if c1 < c2:
print("Ce code est juste un exemple")
Pour le savoir nous devons nous pencher sur la codification des caractères en Python.
En fait, Python encode ces caractères grâce à la codification UTF-8. Regardons ce que cela veut dire.
D’après l’entrée UTF-8 de Wikipedia : « UTF-8 (abréviation de l’anglais Universal Character Set Transformation Format 1 - 8 bits)
est un codage de caractères informatiques conçu pour coder l’ensemble des caractères du « répertoire universel de caractères codés
» . . . Il s’agit du codage le plus utilisé dans les systèmes GNU, Linux et compatibles pour gérer le plus simplement possible des
textes et leurs traductions dans tous les systèmes d’écritures et tous les alphabets du monde. »
En clair, à chaque caractère est attribué, par la norme UTF-8, un numéro qui lui est propre et que Python utilise pour le stocker mais
aussi pour le comparer aux autres caractères. UTF-8 essaye de donner un numéro à tous les caractères de tous les alphabets connus.
ORD(C)
En Python, la fonction prédéfinie ord(x) donne le numéro dans le classement UTF-8 du caractère x.
Ainsi '#' < ' C' est vrai car ord('#') vaut 35 et ord(' C') vaut 8364. Une des seules choses que vous devez retenir est
que :
— les caractères qui correspondent aux chiffres '0' à '9' ont des numéros contigus (ord('0') vaut 48, ord('1') vaut
49, . . . ) ;
— idem pour les lettres minuscules 'a' .. 'z' (ord('a') vaut 97, ord('b') vaut 98, . . . ), et pour les lettres majuscules
'A'.. 'Z' (ord('A') vaut 65, . . . ).
Ainsi ayant un caractère dans la variable c, le test Python
'a' <= c and c <= 'z'
teste bien si c est une lettre de l’alphabet en minuscule. On peut faire la même chose avec les caractères majuscules ou les caractères
qui correspondent à des chiffres. Attention à ne pas mélanger la valeur 0 et le caractère '0' dont la codification UTF-8 (ord('0'))
vaut 48.
CHR(V)
La fonction prédéfinie chr(v) est l’inverse de ord( ) : chr(v) reçoit en paramètre un nombre entier positif v, et renvoie la
caractère UTF-8 correspondant. Par exemple chr(65) renvoie 'A'.
5.1.5 Illustrons ce que nous avons vu jusqu’à présent sur les séquences
TEMPÊTE OU CYCLONE
Même si nous n’avons pas encore suffisamment vu comment manipuler les séquences pour faire énormément de programmes
intéressants, nous allons quand même imaginer deux petits exercices, que nous allons réaliser ensemble, pour illustrer ce que nous
avons déjà vu.
D’après l’échelle de Saffir-Simpson, une tempête est définie si les vents enregistrés (vents moyens pendant une minute à une hauteur
de 10 mètres) sont de 64 à 118 km/h. Au delà de 118 km/h, selon l’endroit dans le monde où l’on se trouve, on parle d’ouragan, de
typhon ou de cyclone.
Les cyclones sont classés suivant leur force, par l’échelle de Saffir-Simpson allant de 1 à 5 :
— Catégorie 1 : Vents de 119 à 153 km/h
— Catégorie 2 : Vents de 154 à 177 km/h
— Catégorie 3 : Vents de 178 à 209 km/h
— Catégorie 4 : Vents de 210 à 250 km/h
— Catégorie 5 : Vents supérieurs à 250 km/h
Un territoire qui subit des vents de catégorie 5 subira des dégâts considérables.
Supposons que l’on ait une liste mes_valeurs de valeurs entières positives correspondant aux vents maximums enregistrés aux
Bermudes chaque année depuis l’an 2000, la composante 0 désignant l’an 2000, 1, 2001, . . . .
Par exemple, avec des chiffres totalement inventés :
mes_valeurs = [75, 200, 230, 260, 100, 80, 50, 45, 180, 100, 200, 63, 64, 65,\
118, 119, 153, 154, 280, 345]
HISTORIQUE_TEMPETES
Écrivons une fonction historique_tempetes qui reçoit en paramètre formel la liste vent_max de ces valeurs et imprime
pour chaque année si les îles ont subi une tempête ou un cyclone et si c’est le cas, de quelle catégorie.
Découpe de la fonction historique_tempetes
La fonction doit traiter chaque élément de la liste séquentiellement. Une instruction for est donc adaptée. Pour chaque élément, il
faut tester dans quelle catégorie se trouve la valeur. Remarquons que l’on peut découper la valeur en 3 classes : 1) pas de tempête,
2) tempête, 3) cyclone d’une certaine catégorie. Pour ne pas avoir à plusieurs endroits dans le programme du code assez semblable,
une fonction categorie semble indiquée, qui reçoit une valeur de vent supérieure à 118 km/h et renvoie un nombre entre 1 et 5
suivant la catégorie.
def categorie(vent):
"""renvoie la catégorie de cyclone enregistré en fonction du vent"""
assert vent > 118 # sinon provoque une erreur dans le code
def historique_tempetes(vent_max):
"""affiche pour chaque année la catégorie de vents subis cette année-là
entrée : vent_max: liste des vents maximums enregistrés en km/h
chaque année (composante 0 étant pour l'an 2000)"""
annee = 2000
for vent in vent_max:
if vent < 64:
print("En", annee, ": pas de tempête enregistrée")
elif vent < 119:
print("En", annee, ": il y a eu au moins une tempête mais pas de cyclone")
else:
print("En", annee, ": le plus gros cyclone enregistré était de catégorie",
categorie(vent))
annee += 1
historique_tempetes(mes_valeurs)
CYCLONE_ANNEE
Avec la même liste mes_valeurs des vitesses de vents maximums, écrivons une autre fonction : tempete_annee qui reçoit
en paramètre la liste vent_max et annee entre 2000 et 2018, et qui renvoie la catégorie de cyclone à laquelle ont été confrontées
les îles cette année.
Nous supposons comme résultat possible 0 pour aucun cyclone, et une valeur entre 1 à 5 comprises pour donner la catégorie de
cyclone.
La fonction peut se définir comme suit :
assert annee >= 2000 # si annee est inférieure à 2000, provoque une erreur
qui peut être testée comme suit pour les années 2001 à 2003 et 2009 :
Ces deux exemples illustrent bien ce que nous avons vu jusqu’ici sur les séquences de données Python. L’activité suivante demande
que vous codiez de façon autonome des problèmes qui se résolvent en utilisant des séquences. À vous de jouer !
EXERCICES UPYLAB
Comme mise en bouche autonome pour ce module, faites l’exercice 5.1 d’UpyLaB. Cet exercice vous demande de mettre en pratique
la manipulation simple de tuples, dans ce cas des couples représentant des noms et des prénoms.
Dans ce cours, nous dirons couple pour parler d’un tuple à deux composantes.
Notez que dans le projet, nous utiliserons des couples, c’est-à-dire des tuples à deux valeurs, pour représenter des coordonnées de
points dans un espace à deux dimensions.
Énoncé
Écrire une fonction signature qui reçoit un paramètre identite. Ce paramètre est un couple (tuple de deux composantes)
dont la première composante représente un nom et la seconde un prénom.
Cette fonction doit retourner la chaîne de caractères formée du prénom suivi du nom, séparés par une espace.
Exemple
signature(('Massart', 'Thierry'))
doit retourner :
'Thierry Massart'
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Vous pouvez supposer que l’argument passé à la fonction est valide (couple de deux chaînes de caractères).
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Il n’est demandé ici que de définir la fonction. Mais pour tester son fonctionnement dans votre IDE, pensez à ajouter du code
qui l’appelle et teste son résultat, sur plusieurs valeurs, comme print(signature(('Hoarau', 'Sébastien')))
par exemple.
— Notez que la fonction signature n’accepte qu’un seul paramètre. Ainsi, un entête du type def signature(nom, prenom) ne
correspond pas à ce qui est attendu, puisque dans ce cas, on définit deux paramètres. Le paramètre atttendu est un tuple, dont
on pourra accéder aux composantes dans le corps de la fonction (revoir si besoin la matière correspondante).
— Pensez à utiliser la concaténation de chaînes de caractères.
— Les apostrophes présentes dans le retour de la fonction ne font pas partie de la chaîne de caractères. Elles indiquent que
l’objet retourné est de type str.
— Si rien ne marche : consultez la FAQ sur UpyLaB 5.1.
Énoncé
On représente un brin d’ADN par une chaîne de caractères qui peut contenir quatre caractères différents : “A”(Adénine), “C”
(Cytosine),”G” (Guanine) et “T” (Thymine).
Écrire une fonction est_adn qui reçoit une chaîne de caratères en paramètre et qui retourne True si cette chaîne de caractères
n’est pas vide et peut représenter un brin d’ADN, False sinon.
Exemple 1
est_adn("TAGCAT")
doit retourner :
True
Exemple 2
est_adn("ISA")
doit retourner :
False
Exemple 3
est_adn("CTaG")
doit retourner :
False
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Vous pouvez supposer que l’argument passé à la fonction sera toujours une chaîne de caractères ; notez que l’appel de la
fonction sur une chaîne vide doit retourner False.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Il n’est demandé ici que de définir la fonction. Mais pour tester son fonctionnement dans votre IDE, pensez à ajouter du code
qui l’appelle et teste son résultat, sur plusieurs valeurs, comme print(est_adn(("ADN"))) par exemple.
— Pensez à parcourir la chaîne de caractères passée en argument et tester si chaque caractère se trouve bien dans la chaîne
« ACGT ».
— Si rien ne marche : consultez la FAQ sur UpyLaB 5.2.
Énoncé
Écrire une fonction duree qui reçoit deux paramètres debut et fin. Ces derniers sont des couples (tuples de deux composantes)
dont la première composante représente une heure et la seconde les minutes.
Cette fonction doit calculer la durée qui s’est écoulée entre ces deux instants. Le résultat sera donné sous la forme d’un tuple
(heure, minutes).
Exemple 1
doit retourner :
(4, 6)
Exemple 2
doit retourner :
(23, 15)
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Notez que l’appel duree ((6, 0), (5, 15)) retourne le couple (23, 15) et non (0, 45). Le premier argument
correspond à l’instant initial et le second à l’instant final.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Il n’est demandé ici que de définir la fonction. Mais pour tester son fonctionnement dans votre IDE, pensez à ajouter du code
qui l’appelle et teste son résultat, sur plusieurs valeurs, comme print(duree ((6, 0), (5, 15))) par exemple.
— Si rien ne marche : consultez la FAQ sur UpyLaB 5.3.
Énoncé
Écrire une fonction distance_points() qui reçoit en paramètres deux tuples de deux composantes représentant les coordon-
nées de deux points et qui retourne la distance euclidienne séparant ces deux points.
Pour rappel, la distance euclidienne entre les points (𝑥1 , 𝑦1 ) et (𝑥2 , 𝑦2 ) se calcule grâce à la formule :
√︀
𝑑𝑖𝑠𝑡 = (𝑥1 − 𝑥2 )2 + (𝑦1 − 𝑦2 )2
√ 1
où 𝑎 désigne la racine carrée de 𝑎 et correspond à 𝑎 2 .
Exemple 1
doit retourner :
1.0
Exemple 2
3.0413812651491097
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Il n’est pas demandé que la fonction distance_points teste le type des paramètres reçus.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Il n’est demandé ici que de définir la fonction. Mais pour tester son fonctionnement dans votre IDE, pensez à ajouter du code
qui l’appelle et teste son résultat, sur plusieurs valeurs, comme print(distance_points((0.0, 0.0), (1.0,
1.0))) par exemple.
— Notez que la fonction distance_points n’accepte que deux paramètres. Ainsi, un entête du type `` def dis-
tance_points(x1, y1, x2, y2)`` ne correspond pas à ce qui est attendu, puisque dans ce cas, on définit quatre paramètres.
Les deux paramètres attendus sont des tuples, dont on pourra accéder aux composantes dans le corps de la fonction (revoir
si besoin la matière correspondante).
— Si rien ne marche : consultez la FAQ sur UpyLaB 5.4.
RASSEMBLER
Pour que vous puissiez faire l’exercice UpyLaB suivant, nous devons d’abord introduire deux mécanismes bien pratiques que Python
offre en association avec les fonctions : l’opération qui consiste à rassembler (gather en anglais) et à la sous-section suivante, le
mécanisme inverse. Commençons par le gather : sans entrer dans tous les détails, dans la définition d’une fonction Python, on peut
rajouter une astérisque devant le seul ou le dernier paramètre. Par exemple :
def ma_fonction(*valeurs) :
print("Le paramètre est un tuple valant :", valeurs)
Dans ce cas, les valeurs reçues lors de chaque appel sont rassemblées dans un tuple.
Par exemple dans une console Python :
Notez comment un tuple vide ou un tuple d’un élément est dénoté. En particulier :
t = (2)
mettra l’entier 2 dans t (les parenthèses étant considérées comme faisant partie de l’expression arithmétique même si elles ne
rajoutent rien).
La virgule dans (2,) permet donc de stipuler que l’on parle d’un tuple.
SÉPARER
L’inverse du gather est aussi possible et est appelé en anglais scatter (disperser) qui distribue les valeurs d’une séquence comme
étant une séquence d’arguments lors de l’appel à une fonction.
Expliquons le scatter sur un simple exemple. La fonction prédéfinie max renvoie le maximum des valeurs transmises, soit sous
forme de liste, soit d’une séquence.
Ainsi analysons dans une console Python, la séquence suivante :
>>> max('bonjour')
'u'
>>> max([3, 7, 2, 5])
7
>>> liste1 = [2, 5, 7, 3]
>>> liste2 = [1, 5, 21, -15]
>>> max(liste1, liste2)
[2, 5, 7, 3]
>>> max(*liste1, *liste2)
21
— le premier max regarde parmi la séquence de lettres celle qui a la valeur maximale (pour la codification UTF-8) ;
— le second, le maximum des valeurs de la liste ;
— le troisième compare deux listes et celle qui commence par 2 est plus grande que celle qui commence par la valeur 1 ;
— la dernière instruction, « met à plat » les valeurs de liste1 et de liste2. Nous obtenons l’équivalent de max(2, 5,
7, 3, 1, 5, 21, -15) qui renvoie la valeur maximale soit 21.
À présent vous pouvez effectuer l’exercice UpyLaB 5.5 qui utilise le rassemblement (gather).
Énoncé
Écrire une fonction longueur(*points) qui reçoit en paramètres un nombre arbitraire de points (tuples de deux composantes),
et retourne la longueur de la ligne brisée correspondante.
Cette longueur se calcule en additionnant les longueurs des segments formés par deux points consécutifs.
Exemple 1
doit retourner :
2.0
Exemple 2
7.1122677042334645
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Pour simplifier, on supposera qu’il y aura toujours au moins deux points passés en paramètre lors des appels à la fonction
longueur.
— Il est conseillé d’utiliser la fonction distance_points définie lors de l’exercice précédent.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Il n’est demandé ici que de définir la fonction. Mais pour tester son fonctionnement dans votre IDE, pensez à ajouter du code
qui l’appelle et teste son résultat, sur plusieurs valeurs, comme print(longueur((0.0, 0.0), (1.0, 1.0)))
par exemple.
— Notez que la fonction longueur accepte un nombre arbitraire de tuples en arguments, et non une liste ou un tuple de tuples.
N’hésitez pas à revoir la matière présentée dans l’onglet de cours précédent.
— Si rien ne marche : consultez la FAQ sur UpyLaB 5.5.
Nous voici de retour pour apprendre de la nouvelle matière sur les séquences. Nous avons vu que les séquences permettent de stocker
plusieurs valeurs soit de type texte avec les chaînes de caractères, soit de différents types pour les tuples et les listes. Il nous reste à
voir beaucoup de matière dans ce gros module sur les séquences, en terme de manipulations plus sophistiquées. En particulier, nous
allons voir comment modifier des séquences, par exemple pour ajouter des éléments ou en supprimer.
Continuons donc à découvrir d’autres façons de manipuler les séquences.
Trois capsules vidéo sont proposées ici :
— la première vidéo présente la notion de tranche et comment étendre une liste ;
— la seconde présente la notion de diagramme d’état, qui va nous permettre de bien comprendre comment l’interpréteur Python
gère les séquences dans la mémoire du programme ;
— la dernière vidéo présente des séquences imbriquées, et les notions d’emballage et de déballage (pack / unpack).
TRANCHE DE SÉQUENCE
CONTENU DE LA VIDÉO
Tranches de séquences (slicing), modifications d’une composante, et extensions de listes (append et extend) y sont présentés.
Code sur la console réalisé dans la vidéo
La vidéo en bref
Continuons ici la présentation sur les séquences, en montrant les éléments communs aux trois types présentés. Les tranches de
séquence (slices) sont présentées. Ensuite nous montrons que l’on peut modifier une composante d’une liste contrairement aux
chaînes de caractères et tuples. Les méthodes append et extend sur les listes sont présentées.
Note : Référez-vous à l’ aide mémoire pour avoir un résumé ce que fait chaque méthode sur les séquences.
Note : Voir la vidéo de la section 5.2.2 : Opérateurs is et stockage des séquences en mémoire
CONTENU DE LA VIDÉO
Dans cette capsule vidéo, nous parlons d’identité des objets et de l’opérateur is. Nous voyons plus précisément les mécanismes
d’assignation et de passage de paramètre lors de l’appel à une fonction.
Code sur la console et scripts réalisés dans la vidéo
def fun(s):
s[1] = 666
ma_liste = [1, 2, 3]
fun(ma_liste)
print(ma_liste)
def fun(s):
s = [4, 5, 6]
ma_liste = [1, 2, 3]
fun(ma_liste)
print(ma_liste)
La vidéo en bref
L’assignation multiple, l’identificateur d’un objet et le verbe is sont illustrés par le premier code exécuté dans une console
PyCharm. Les deux codes suivants, exécutés dans Python Tutor, illustrent le passage d’un paramètre liste lors de l’appel à une
fonction, la modification de cette liste dans la fonction et le mécanisme d’assignation qui correspond à donner un ou plusieurs
noms à un objet.
Note : Voir la vidéo de la section 5.2.3 : Séquences non simples, tranches, in, emballage et déballage
CONTENU DE LA VIDÉO
Dans cette capsule vidéo, nous affinons des concepts déjà vus et abordons plusieurs nouveaux concepts sur les séquences et sur les
listes Python en particulier. Nous montrons des exemples de séquences non simples, c’est-à-dire dont les éléments sont eux-mêmes
des séquences. Nous regardons plus en détails ce qui peut être réalisé avec des tranches de liste, comment fonctionne le test in et
les notions d’emballage et de déballage (pack et unpack en anglais).
Codes sur la console réalisés dans la vidéo
>>> personnages = ["le serpent", "le mouton", "le petit prince", "l'aviateur",
... "la rose", "le Monsieur cramoisi", "le roi", "le vaniteux",
... "le buveur","le businessman", "l'allumeur de réverbères",
... "le géographe", "la fleur à trois pétales", "les roses du jardin",
... "le renard", "l'aiguilleur", "le marchand"]
>>> print(personnages)
['le serpent', 'le mouton', 'le petit prince', "l'aviateur", 'la rose', 'le Monsieur cramoisi',
˓→'le roi', 'le vaniteux', 'le buveur', 'le businessman', "l'allumeur de réverbères", 'le
˓→géographe', 'la fleur à trois pétales', 'les roses du jardin', 'le renard', "l'aiguilleur",
˓→'le marchand']
>>> len(personnages)
17
>>> personnages[0]
'le serpent'
>>> personnages[0][1]
'e'
>>> for p in personnages:
... for c in p:
... print(c, end = ' ')
... print()
...
l e s e r p e n t
l e m o u t o n
l e p e t i t p r i n c e
l ' a v i a t e u r
l a r o s e
l e M o n s i e u r c r a m o i s i
l e r o i
l e v a n i t e u x
l e b u v e u r
l e b u s i n e s s m a n
l ' a l l u m e u r d e r é v e r b è r e s
l e g é o g r a p h e
l a f l e u r à t r o i s p é t a l e s
l e s r o s e s d u j a r d i n
l e r e n a r d
l ' a i g u i l l e u r
(suite sur la page suivante)
>>> tp = 2, 3, 5
>>> x, y, z = tp
>>> x
2
>>> y
3
>>> z
5
>>> x, y = 33, 666
>>> x, y = y, x
>>> x
666
>>> y
33
La vidéo en bref
Nous illustrons comment manipuler une séquence de données non simple, c’est-à-dire dont les éléments sont eux-mêmes des
séquences. Nous utilisons la liste des personnages du petit prince avec des instructions for imbriquées ainsi qu’avec un double
indiçage, personnages[0][1] par exemple. Nous expliquons encore une fois la différence dans l’utilisation du in dans les
séquences et dans les chaînes de caractères, et montrons ce que donne le slicing à gauche d’une assignation (voir prem[4:7]
= [11, 13]). La notion d’emballage et de déballage est expliquée sur des exemples.
Avant de mettre en pratique ce que nous avons vu dans les vidéos qui précèdent, revenons brièvement aux notions de base. Comme
déjà mentionné au module 2, Python manipule des objets contenant les valeurs et des variables qui sont des noms pour les objets.
Ainsi
prem = sec = [2, 3]
crée un objet de type liste contenant deux sous-objets entiers valant respectivement 2 et 3 ; prem et sec sont deux noms donnés à
cet objet de type liste. En fait le terme Python approprié n’est pas type mais classe liste. Les notions de classe et d”objet sont liées
au fait que Python est un langage orienté-objet. Nous n’en dirons pas beaucoup plus dans ce cours qui n’aborde pas ces concepts
avancés de Python.
Ce qui est important à savoir maintenant est qu’une classe, comme la classe liste, est définie avec des attributs et aussi des méthodes.
Nous avons vu dans la première vidéo de cette sous-section les méthodes append et extend. De façon générale, une méthode
réalise un certain traitement sur un objet de cette classe (par exemple [Link](666) qui ajoute une composante à la liste
prem, ayant la valeur entière 666).
La syntaxe pour utiliser une méthode est le nom de l’objet, suivi d’un point suivi du nom de la méthode et terminé par les arguments
entre parenthèses, les parenthèses étant obligatoires même s’il n’y a pas d’arguments.
La section 5.4 est consacrée à l’apprentissage de nombreuses méthodes associées aux séquences ; celles-ci vont nous permettre assez
facilement de réaliser une multitude de traitements.
Illustrons les manipulations de listes sur un exemple complet que nous allons développer ensemble dans cette activité. Ce sera
également l’occasion de montrer quelques techniques classiques utilisées par les programmeurs Python.
Supposons que nous voulions récolter les valeurs des précipitations de pluie, pour un mois de l’année, par exemple septembre, pour
ensuite pouvoir communiquer ces valeurs à la demande.
Dans cette section, nous partons d’un code pluie_1.py sans séquence qui ne répond que très partiellement au problème et
construisons le code pluie_2.py, qui manipule une séquence de données pour mieux y répondre. Ce sera l’occasion de discuter
sur les façons classiques pour initialiser des séquences de données. Avec tout ce bagage en plus, en fin de section nous produisons,
avec le code pluie_3.py, une version complète et structurée avec des fonctions répondant au problème.
PLUIE_1.PY
Partons d’un programme sans séquences qui calcule les valeurs cumulées de pluies collectées pendant le mois de septembre.
Code pluie_1.py
Notons :
— l’utilisation de str() qui traduit la valeur i en texte, associé à l’opérateur de concaténation +, il permet de donner un seul
paramètre de type chaîne de caractères à la fonction input(),
— l’utilisation de l’opérateur += pour cumuler dans la variable somme_pluie, au départ initialisée à 0, les valeurs des pluies
cumulées,
— le range(1,31) dans le for pour que l’indice i corresponde au jour concerné de septembre.
PLUIE_2.PY
Supposons maintenant que nous désirions enregistrer les valeurs individuelles lues, ainsi que la somme des valeurs cumulées, pour
pouvoir faire plus de manipulations de valeurs.
Le code suivant propose une solution en ce sens :
""" programme qui enregistre les valeurs quotidiennes
des pluies pour septembre, entrées (input)
et affiche en sortie les valeurs de pluie demandées
(0 pour le cumul des valeurs)"""
Code pluie_2.py
Notons que :
— le code commence par se créer une variable pluie_septembre de type liste à 31 composantes (d’indice 0 à 30)
contenant des 0 (notons l’utilisation de [0]* 31 pour cela) ;
— les composantes i de pluie_septembre sont mises à jour ;
— ensuite la composante 0 reçoit la somme des composantes ;
— enfin, le code renvoie les valeurs demandées jusqu’à ce que l’utilisateur envoie une valeur -1 pour signifier qu’il ne désire
plus que le code affiche des valeurs.
Les codes pluie_1.py et pluie_2.py montrent comment on peut initialiser une liste avec des valeurs lues avec input. Comme
la lecture et l’initialisation de séquences de données (chaînes de caractères, tuples ou listes) sont des traitements fréquents en
programmation, il est important ici d’ouvrir une parenthèse et de discuter sur quelques techniques classiques pour le faire en Python.
Lecture et initialisation d’une chaîne de caractères
Cette opération est aisée puisque l’instruction input() le permet directement avec :
s = input()
où s est la variable qui reçoit la chaîne de caractère lue.
Lecture et initialisation d’un tuple de valeurs
Si l’on suppose que l’utilisateur introduit la séquence de valeurs en mettant une virgule entre chaque valeur le tout sur une seule
ligne, l’utilisation de la fonction prédéfinie eval() peut être faite.
s = [None] * n
for i in range(n):
s[i] = int(input())
où n est une valeur entière donnant le nombre d’éléments à initialiser (n = 31 par exemple). L’utilisateur du programme tape sur
la touche return du clavier après chaque donnée introduite.
Dans ce cas, le code commence par créer une liste avec le bon nombre n de composantes, initialisées avec des valeurs quelconques
(0, None, . . . ), valeurs qui ne sont pas utilisées et sont changées dans l’instruction for qui suit.
Si le nombre d’éléments est inconnu, la méthode append peut être utilisée. Dans ce cas, une technique classique est de demander
à l’utilisateur d’entrer une donnée à la fois, et à la fin, d’introduire une valeur convenue, appelée généralement valeur sentinelle (par
exemple -1 si les données sont toutes positives) pour signifier que la liste des valeurs communiquées est terminée. La forme du code
est la suivante :
La même technique utilisant la fonction prédéfinie eval() pour initialiser un tuple peut être employée pour créer une liste. Il suffit
que l’utilisateur encode la liste sur une ligne. Par exemple l’exécution de l’instruction :
s = eval(input())
avec comme entrée :
[2, 3, 5, 7]
initialise s avec la liste correspondante.
Création d’une séquence à partir d’une autre
Analysons d’autres cas de figure.
Types différents :
Si les données que le programme désire utiliser pour créer une séquence sont déjà présentes dans une autre séquence s d’un autre
type, les fonctions prédéfinies tuple, list, et str peuvent être utiles.
Ces fonctions ont comme seul paramètre la séquence préexistante.
— list(s) essaye de changer le type du paramètre s en liste,
— tuple(s) essaye de changer le type du paramètre s en tuple,
— str(s) crée une chaîne de caractères qui correspond à ce qui serait imprimé par un print(s).
Par exemple, ayant un tuple s valant (2, 3, 5, 7, 9)
t = list(s)
assigne à t la liste [2, 3, 5, 7, 9]
Autre exemple :
t = list("bonjour")
assigne à t une liste de 7 composantes où chacune est un caractère du texte "bonjour"
Mêmes types :
Créer une séquence t de type tuple ou chaîne de caractères avec une séquence s de même type se fait par une simple assignation.
Comme les listes sont modifiables, une simple assignation ne suffit en général pas dans ce cas, et il faut faire une copie. La copie de
listes sera vue plus en détail en section 5.6.
PLUIE_3.PY
Après cette partie de cours explicative sur l’initialisation de séquences, discutons du programme pluie_3.py dont le but est de
donner une version complète et structurée du code qui effectue relevé et communication des données de pluie pour une période
donnée.
Pour améliorer la structure du code, pluie_3.py sera donc composé des deux fonctions :
— collecte_donnees qui construit la liste des valeurs
— affiche_valeur qui affiche une information demandée ; ajoutons la possibilité de demander les pluies sur une période
entre deux jours, par exemple du 3 au 10.
Donnons la fonction collecte_donnees qui construit et renvoie la liste :
def collecte_donnees(nb_jours):
"""construit et renvoie une liste avec dans la composante i,
les valeurs entières lues de pluie cumulée du jour i
et en composante 0, la somme des pluies pour le mois entier
"""
Notons :
— les tests sur le type et la valeur de la variable requete ;
— l’instruction print("...", sum(pluie[requete[0]: requete[1]+1])) qui calcule la somme des valeurs de
pluie entre requete[0] et requete[1] incluse et l’affiche avec print.
Il nous reste à donner le code principal qui appelle les fonctions collecte_donnees et affiche_valeur.
# main - code principal
pluies_septembre = collecte_donnees(30) # lecture données
# délivre les informations désirées
print("Donnez le jour 'j' ou la période 'i, j'",
"dont vous désirez la valeur des pluies cumulées")
print("(0 pour avoir tout le mois et -1 pour terminer)")
jour = eval(input("Jour ou période ? :"))
while jour != -1:
affiche_valeur(pluies_septembre, jour)
jour = eval(input("Jour ou période ? :"))
print("Au revoir et merci ! ")
Notons l’instruction jour = eval(input("Jour ou période ? :")) qui utilise la fonction prédéfinie eval comme
expliqué plus haut dans cette section. Dans ce cas,
— si l’utilisateur a introduit 7 : jour est un entier,
— si l’utilisateur a introduit 3,10 : jour est un couple (tuple) d’entiers.
Code de pluie_3.py
Le code complet du programme pluie_3.py est donné ci-dessous :
""" programme qui enregistre les valeurs quotidiennes
des pluies pour septembre, entrées (input)
et donne ensuite les valeurs à la demande
et le cumul du mois si on entre 0 comme jour """
# réserve la composante 0 pour enregistrer les pluies cumulées du mois
Nous voici au terme de cet exercice qui nous a permis d’illustrer les manipulations vues jusqu’ici de séquences listes, tuples et
chaînes de caractères, et également de voir comment initialiser de telles séquences.
Passons à l’apprentissage autonome de la matière vue jusqu’ici sur les séquences.
Réalisez les exercices 5.6 à 5.8 d’UpyLaB. Ces exercices vont vous permettre de manipuler les séquences, leurs composantes,
tranches ainsi que les méthodes déjà vues sur ces séquences de données.
Énoncé
Écrire une fonction transcription_arn(brin_codant) qui reçoit une chaîne de caractères en paramètre, correspondant
à un brin codant d’ADN, et qui retourne la chaîne de caractère représentant le brin d” ARN correspondant. ».
Nous rappelons qu’un brin d’ADN peut être modélisé par une chaîne de caractères, dont les caractères sont pris parmi les quatre
suivants : “A”(Adénine), “C” (Cytosine),”G” (Guanine) et “T” (Thymine). La transcription en ARN se traduit par le remplacement
des nucléotides de Thymine par des nucléotides d’Uracile, que l’on représentera par le caractère “U”.
Exemple
transcription_arn('AGTCTTACCGATCCAT')
doit retourner :
'AGUCUUACCGAUCCAU'
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Il n’est pas demandé que la fonction teste le type de l’argument passé, ni même que cet argument corresponde à un brin de
molécule d’ADN.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Il n’est demandé ici que de définir la fonction. Mais pour tester son fonctionnement dans votre IDE, pensez à ajouter du
code qui l’appelle et teste son résultat, sur plusieurs valeurs, comme print(transcription_arn('ACGTACGT'))
par exemple.
— N’oubliez pas qu’une chaîne de caractères est une séquence non modifiable.
— Si rien ne marche : consultez la FAQ sur UpyLaB 5.6.
Énoncé
Écrire une fonction plus_grand_bord(w) qui reçoit un mot w et retourne le plus grand bord de ce mot.
On dit qu’un mot u est un bord du mot w si u est à la fois un préfixe strict et un suffixe strict de w, c’est-à-dire qu’on retrouve le mot
u au début et à la fin du mot w, sans que u soit égal à w lui-même.
Exemples : 'a' et 'abda' sont des bords de 'abdabda'. En effet, 'abdabda' commence et se termine par 'a', ainsi que par
'abda'. Le plus grand bord de 'abdabda' est 'abda'.
Si w n’a pas de bord, la fonction retourne la chaîne de caractères vide.
Exemple 1
plus_grand_bord('abdabda')
doit retourner :
'abda'
Remarque : Notez que les apostrophes indiquent ici que l’objet retourné est de type str. Ces apostrophes ne font pas partie de la
chaîne de caractères elle-même.
Exemple 2
plus_grand_bord('abcabd')
doit retourner :
''
Exemple 3
plus_grand_bord('abcba')
doit retourner :
'a'
Exemple 4
plus_grand_bord('aaaaa')
doit retourner :
'aaaa'
Consignes
Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter que la
définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier aucun appel
ni à la fonction demandée ni aux fonctions input et print.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Il n’est demandé ici que de définir la fonction. Mais pour tester son fonctionnement dans votre IDE, pensez à ajouter du
code qui l’appelle et teste son résultat, sur plusieurs valeurs, comme print(plus_grand_bord('abdabda')) par
exemple.
— Notez que le bord d’un mot se retrouve à l’identique au début et à la fin de ce mot, sans symétrie. Si le préfixe est 'abda',
on doit retrouver le suffixe 'abda' et non 'adba'.
— Pour un mot de longueur 5, par exemple, le plus grand bord aura une taille maximale de 4 caractères. On pourra donc tester si
la sous-chaîne composée des 4 premiers caractères se retrouve pas à la fin du mot. Si ce n’est pas le cas, il faut alors regarder
la sous-chaîne formée des 3 premiers caractères, puis la sous-chaîne formée des 2 premiers caractères, et ainsi de suite.
— Si rien ne marche : consultez la FAQ sur UpyLaB 5.7.
Énoncé
Écrire une fonction prime_numbers qui reçoit comme paramètre un nombre entier nb et qui renvoie la liste des nb premiers
nombres premiers.
Si le paramètre n’est pas du type attendu, ou ne correspond pas à un nombre entier positif ou nul, la fonction renvoie None.
Exemple 1
prime_numbers(4)
doit retourner :
[2, 3, 5, 7]
Exemple 2
prime_numbers(-2)
doit retourner :
None
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes (ici par exemple, une
fonction qui détermine si le nombre passé en argument est premier ou non), et ne fait en particulier aucun appel ni à la
fonction demandée ni aux fonctions input et print.
— On rappelle qu’un nombre premier est un entier naturel qui possède exactement deux diviseurs distincts et positifs, 1 et
lui-même.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Il n’est demandé ici que de définir la fonction. Mais pour tester son fonctionnement dans votre IDE, pensez à ajouter du code
qui l’appelle et teste son résultat, sur plusieurs valeurs, comme print(prime_numbers(5)) par exemple.
— N’oubliez pas, lors de ces tests dans votre IDE, d’appeler votre fonction avec un argument invalide ; cela ne doit occasionner
aucune erreur, la fonction retourne None dans ces cas-là.
— On pourra utiliser la fonction premier de l’exercice UpyLaB 4.3.
— Si rien ne marche : consultez la FAQ sur UpyLaB 5.8.
Avant de continuer l’étude des séquences Python, ce quiz va vous aider à vérifier que vous avez bien assimilé ce que nous avons vu
jusqu’ici sur cette matière.
DIAGRAMME D’ÉTAT
Il est intéressant de voir, en exécutant avec Python Tutor le code de la question 6 ci-dessous, les diagrammes d’état qui montrent
que chaque composante de la liste globale construite pointe vers la même sous-liste [2, 3] :
AIDE-MÉMOIRE
Nous avons vu comment définir et manipuler des séquences, leurs composantes et tranches. Pour les listes, nous avons aussi vu
les méthodes append et extend pour les étendre avec de nouveaux éléments. Python fournit de nombreuses méthodes pour
manipuler les trois types de séquences que nous étudions dans ce module.
Dans les capsules vidéo qui suivent, nous allons terminer l’étude des séquences de données chaînes de caractères, tuples et listes
Python 3 et leurs manipulations, en présentant un bon nombre de ces méthodes. Elles vont nous permettre de résoudre de nombreux
problèmes.
Pour nous faciliter la tâche dans la conception de nos codes, nous avons confectionné un petit aide-mémoire téléchargeable ici
résumant l’effet de chacune des fonctions et méthodes présentées ou que nous allons présenter dans la suite de ce cours.
Nous pourrons ainsi décider quelles méthodes peuvent nous aider, et éventuellement si nous devrons écrire d’autres fonctions de
manipulation pour résoudre les problèmes soumis.
Note : Quand la syntaxe d’une instruction ou expression Python est donnée la méta-notation "[...]" signifie que cette partie est
optionnelle. Ainsi :
[Link](sub [,start [,end]])
signifie que [Link] peut avoir un, deux ou trois arguments.
Ainsi :
— "Bonjour UpyLaB!".count('o') renvoie 2 (le caractère 'o' est 2 fois dans "Bonjour UpyLaB!")
— "Bonjour UpyLaB!".count('o', 3) renvoie 1 (le caractère 'o' est 1 fois dans le texte "Bonjour UpyLaB!
"[3:])
— "Bonjour UpyLaB!".count('o', 3, 4) renvoie 0 (le caractère 'o' n’est pas dans le texte "Bonjour
UpyLaB!"[3:4] (rappelez-vous que dans ce cas, l’indice 4 est non inclus).
Comme pour le manuel de bonnes pratiques, pourquoi ne pas imprimer cet aide-mémoire pour toujours l’avoir sous la main quand
vous écrirez du code ?
N’hésitez pas à le consulter et à tester par vous-même l’effet de chacune d’elles.
CONTENU DE LA VIDÉO
Cette vidéo présente des méthodes de recherche et de comptage sur les séquences ainsi que les fonctions zip et enumerate.
Codes sur la console réalisés dans la vidéo
>>> min("bonjour")
'b'
>>> sum([2, 5, 6])
13
>>> sum("bonjour")
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'
>>> prem = [2, 3, 5, 7, 11]
>>> 7 in prem
True
>>> [Link](7)
3
>>> [Link](9)
Traceback (most recent call last):
File "<input>", line 1, in <module>
ValueError: 9 is not in list
(suite sur la page suivante)
La vidéo en bref
Les méthodes min, sum, index, enumerate et zip sont présentées. Référez-vous à l’ aide-mémoire pour un résumé de ce
qu’elles font.
CONTENU DE LA VIDÉO
Cette vidéo présente des méthodes de manipulation spécifiques aux chaînes de caractères.
Code sur la console réalisé dans la vidéo
>>> s = 'Bonjour'
>>> [Link]()
'bonjour'
>>> s
'Bonjour'
>>> s = [Link]()
>>> [Link]()
'BONJOUR'
>>> [Link]()
True
>>> [Link]()
(suite sur la page suivante)
class str(object)
| str(object='') -> str
| str(bytes_or_buffer[, encoding[, errors]]) -> str
|
| Create a new string object from the given object. If encoding or
| errors is specified, then the object must expose a data buffer
| that will be decoded using the given encoding and error handler.
| Otherwise, returns the result of object.__str__() (if defined)
| or repr(object).
| encoding defaults to [Link]().
| errors defaults to 'strict'.
|
| Methods defined here:
|
...
>>> [Link]('o')
1
>>> s
'bonjour'
>>> [Link]('o', 2)
4
>>> s = "madame Claude rencontre madame Dominique"
>>> [Link]('madame', 'monsieur')
'monsieur Claude rencontre monsieur Dominique'
>>> s
'madame Claude rencontre madame Dominique'
>>> [Link]()
'Madame claude rencontre madame dominique'
>>> s = 'bOnjouR'
>>> [Link]()
'Bonjour'
>>> [Link]()
'bOnjouR'
La vidéo en bref
Des méthodes de manipulation de chaînes de caractères sont présentées : lower(), upper(), islower(), isdigit(),
isalnum(), isalpha(), find(), replace(), capitalize(), strip().
Référez-vous à l’ aide-mémoire pour un résumé de ce qu’elles font.
MANIPULATION DE LISTES
MODIFICATION EN PLACE
Dans les sections précédentes, nous avons parlé de fonctions, puis nous avons introduit le terme de méthode pour parler de fonction
propre à un objet avant de présenter plusieurs de ces méthodes pour l’objet chaîne de caractères. Les chaînes de caractères étant
immuables, les méthodes les manipulant ne peuvent les modifier. Par exemple si la variable s référence la chaîne 'python' alors
[Link]() crée un nouvel objet 'PYTHON'.
Avec les listes, nous avons vu des méthodes qui modifient l’objet qui réalise l’appel. On parle de modification en place. C’est le cas
par exemple de la méthode sort. Si ma_liste vaut [3, 2, 1] alors après l’appel ma_liste.sort(), ma_liste vaudra
[1, 2, 3]. Parfois on peut ne pas vouloir modifier son objet initial lors du tri. On pourra alors utiliser la fonction sorted
qui crée un nouvel objet. Ainsi, toujours avec ma_liste, sorted(ma_liste) crée une nouvelle liste [1, 2, 3] mais ne
modifie pas ma_liste.
Les méthodes insert, append sont d’autres méthodes qui modifient en place la liste appelante. N’hésitez pas, lorsque vous
croisez de nouvelles méthodes sur des objets mutables comme les listes à vous poser la question : est-ce une modification en place
ou non ? Si oui et si vous ne voulez pas modifier votre objet alors il faut rechercher une fonction équivalente qui crée un nouvel
objet. . . ou l’écrire, si elle n’existe pas.
CONTENU DE LA VIDÉO
La vidéo en bref
Des méthodes de manipulation de listes sont présentées : insert(), pop(), remove(), reverse(), sort(), copy() ;
ainsi que l’instruction del et la fonction sorted.
Référez-vous à l’ aide-mémoire pour un résumé de ce qu’elles font.
L’utilisation de tranches (slicing) pour modifier les listes est également illustrée.
5.4.4 Exemples simples qui utilisent des méthodes sur des séquences
TROIS EXEMPLES
Pour digérer la matière vue dans cette section, nous développons ensemble trois exemples qui utilisent méthodes et fonctions
prédéfinies sur les chaînes de caractères et listes. À nouveau pour chaque problème, nous vous invitons à écrire une solution.
Ensuite, comparez votre solution avec celle proposée pour valider ou trouver d’autres techniques.
La fonction keep_alnum retourne la chaîne passée en argument, en lui ayant retiré tous les caractères qui ne sont pas des lettres
ou des chiffres. Elle utilise un for pour itérer sur chaque caractère et un if qui teste s’il doit être retenu.
def keep_alnum(s):
"""Nettoie s en lui retirant les caractères non alphanumériques."""
res = ''
for letter in s:
if [Link]():
res = res + letter
return res
L’appel :
keep_alnum('he23.?56th')
'he2356th'
Nous verrons à la section 5.6 qu’une version plus compacte et plus simple de keep_alnum peut être définie avec la notion de
compréhension de liste.
res=[]
for letter in word1:
if letter in word2 and letter not in res:
[Link](letter)
return res
Une autre version de lecture de liste de valeurs. Ici, la fonction demande à l’utilisateur d’encoder une liste de valeurs entières sur
une ou plusieurs lignes, terminée par une ligne vide (touche clavier return sans rien avant), et renvoie la liste des nombres entiers
lus.
La méthode split est utilisée pour décortiquer les lignes lues.
def lecture(invite):
"""Lit et renvoie une liste d'entiers.
Les données peuvent être sur plusieurs lignes.
"""
res = []
x = input(invite)
while x != '':
decoupe = [Link]()
# liste des parties de x séparées par une/des espace(s) ou tab
for elem in decoupe:
[Link](int(elem))
x = input()
return res
Essayez ce code par exemple avec les entrées sur 5 lignes dont la dernière vide :
2 3 5
7 11
13
17 19
5.4.5 Mise en pratique : exercices Upylab 5.9 et suivants avec ou sans méthode !
Énoncé
Une anagramme d’un mot v est un mot w qui comprend les mêmes lettres que le mot initial v, en même quantité, mais non
nécessairement dans le même ordre (par exemple, « marion » et « romina » sont des anagrammes). Notez que anagramme est un
mot féminin.
Écrire une fonction anagrammes(v, w) qui renvoie la valeur booléenne True si les mots v et w sont des anagrammes.
La fonction retourne la valeur booléenne False dans le cas contraire.
Exemple 1
anagrammes('marion', 'romina')
doit retourner :
True
Exemple 2
anagrammes('bonjour', 'jour')
doit retourner :
False
Exemple 3
anagrammes('pate', 'patte')
doit retourner :
False
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Votre code ne doit pas tester si les mots existent bien dans un quelconque dictionnaire.
— Pour simplifier, on supposera que tout mot est une anagramme de lui-même (par exemple, anagrammes('jour',
'jour') renvoie True), et on ne considèrera que des mots écrits en minuscule. Par ailleurs, il n’est pas demandé que
votre fonction teste si les mots sont recensés dans un dictionnaire quelconque.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Il n’est demandé ici que de définir la fonction. Mais pour tester son fonctionnement dans votre IDE, pensez à ajouter du code
qui l’appelle et teste son résultat, sur plusieurs valeurs, comme print(anagrammes('marion', 'romina')) par
exemple.
— Pensez bien à tester avec les différents cas possibles, référez-vous en particulier aux exemples proposés.
— Si rien ne marche : consultez la FAQ sur UpyLaB 5.9.
Énoncé
Exemple 1
dupliques([1, 2, 3, 4])
doit retourner :
False
Exemple 2
doit retourner :
True
Exemple 3
dupliques('abcda')
doit retourner :
True
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Il n’est pas demandé que la fonction teste le type de l’argument ; vous pouvez supposer qu’il s’agira bien d’une séquence.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Il n’est demandé ici que de définir la fonction. Mais pour tester son fonctionnement dans votre IDE, pensez à ajouter du code
qui l’appelle et teste son résultat, sur plusieurs valeurs, comme print(dupliques(['a','b', 'c', 'd'])) par
exemple.
— Si rien ne marche : consultez la FAQ sur UpyLaB 5.10.
Énoncé
Écrire une fonction intersection(v, w) qui calcule l’intersection entre deux chaînes de caractères v et w.
On définit l’intersection de deux mots comme étant la plus grande partie commune à ces deux mots. Par exemple, l’intersection de
« programme » et « grammaire » est « gramm ».
Si les deux chaînes n’ont aucun caractère en commun, la fonction retourne la chaîne vide, ''.
Si plusieurs solutions sont possibles, la fonction retournera la sous-chaîne d’indice minimal dans v. Par exemple,
intersection('bbaacc', 'aabb') renvoie 'bb'.
Exemple 1
intersection('programme', 'grammaire')
doit retourner :
'gramm'
Exemple 2
intersection('salut', 'merci')
doit retourner :
''
Exemple 3
intersection('merci', 'adieu')
doit retourner :
'e'
Consignes
Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter que la
définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier aucun appel
ni à la fonction demandée ni aux fonctions input et print.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Il n’est demandé ici que de définir la fonction. Mais pour tester son fonctionnement dans votre IDE, pensez à ajou-
ter du code qui l’appelle et teste son résultat, sur plusieurs valeurs, comme print(intersection('thierry',
'sébastien')) par exemple.
— On peut penser à parcourir toutes les sous-chaînes de v et vérifier leur présence dans w.
— Si rien ne marche : consultez la FAQ sur UpyLaB 5.11.
Énoncé
Écrire une fonction my_insert qui reçoit comme premier paramètre une liste d’entiers relatifs triée par ordre croissant et comme
deuxième paramètre un entier relatif n, et qui renvoie une liste correspondant à la liste reçue, mais dans laquelle le nombre n a été
inséré à la bonne place.
La liste passée en paramètre ne doit pas être modifiée par la fonction.
Vous pouvez supposer que le premier paramètre sera bien une liste triée d’entiers, mais si le deuxième paramètre n’est pas du bon
type, la fonction retourne None.
Exemple 1
my_insert([1, 3, 5], 4)
doit retourner :
[1, 3, 4, 5]
Exemple 2
my_insert([2, 3, 5], 1)
doit retourner :
[1, 2, 3, 5]
Exemple 3
doit retourner :
None
Consignes
Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter que la
définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier aucun appel
ni à la fonction demandée ni aux fonctions input et print.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Il n’est demandé ici que de définir la fonction. Mais pour tester son fonctionnement dans votre IDE, pensez à ajouter du
code qui l’appelle et teste son résultat, sur plusieurs valeurs, comme print(my_insert([2, 6, 12, 15], 9))
par exemple.
— N’oubliez pas, lors de ces tests dans votre IDE, d’appeler votre fonction avec un argument invalide ; cela ne doit occasionner
aucune erreur et la fonction retourne None dans ces cas-là.
— Si rien ne marche : consultez la FAQ sur UpyLaB 5.12.
Énoncé
L’exercice est le même que le précédent, mais ici, si les paramètres ont le type attendu, la fonction modifie la liste en place et ne
retourne rien. Si les paramètres ne sont pas valides, une erreur se produit à l’exécution.
Exemple 1
l = [1, 3, 5]
my_insert(l, 4)
print(l)
doit afficher :
[1, 3, 4, 5]
Exemple 2
l = [1, 3, 5]
my_insert(l, 'a')
print(l)
AssertionError
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Le code que vous soumettez à UpyLaB ne doit pas non plus contenir la définition de la variable l.
— Pour tester le type des paramètres, vous pouvez utiliser les verbes assert, type ou isinstance.
— l’instruction assert condition laisse continuer l’exécution du code si la condition évaluée est vraie, mais provoque
une erreur (appelée exception en Python) si la condition est fausse.
— type(v) donne le type de v.
— isinstance(v, typ) teste si v est de type typ.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Il n’est demandé ici que de définir la fonction. Mais pour tester son fonctionnement dans votre IDE, pensez à ajouter du code
qui l’appelle et teste son effet, sur plusieurs valeurs. N’hésitez pas à reproduire les exemples donnés ci-dessus.
— N’oubliez pas, lors de ces tests dans votre IDE, d’appeler votre fonction avec un argument invalide ; cela doit cette fois
occasionner une erreur.
— Si rien ne marche : consultez la FAQ sur UpyLaB 5.13.
Énoncé
Exemple 1
distance_mots("lire", "bise")
doit retourner :
Exemple 2
distance_mots("Python", "Python")
doit retourner :
Exemple 3
distance_mots("merci", "adieu")
doit retourner :
Exemple 4
distance_mots("niche", "chien")
doit retourner :
Consignes
Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter que la
définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier aucun appel
ni à la fonction demandée ni aux fonctions input et print.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Il n’est demandé ici que de définir la fonction. Mais pour tester son fonctionnement dans votre IDE, pensez à ajouter du
code qui l’appelle et teste son résultat, sur plusieurs valeurs, comme print(distance_mots("lire", "bise"))
par exemple.
— Si rien ne marche : consultez la FAQ sur UpyLaB 5.14.
Énoncé
Exemple 1
doit retourner :
"bonjour"
Exemple 2
doit retourner :
"chat"
Consignes
— Pour cet exercice, vous pourrez utiliser la fonction distance_mots(mot_1, mot_2) que vous avez précédemment
codée et qui donne la distance entre deux mots de même longueur. N’oubliez pas alors de mettre aussi le code de cette
fonction dans votre solution.
— Le correcteur orthographique demandé est une version simple ; les mots en paramètre auront au maximum une seule lettre
qui diffère par rapport à la bonne orthographe.
— Nous ne prenons pas en compte les mots avec accents, ni les mots composés de tiret, d’apostrophes, d’espace,..
— liste_mots ne contient pas de mots qui se ressemblent ; si Joao écrit le mot « liee », il se peut en effet que cela représente
le mot « lire » ou le mot « lier ». Afin d’éviter cette confusion, deux mots de même longueur de la liste sont au moins à une
distance de 3. Il n’y aura ainsi qu’un seul mot dans liste_mots répondant au problème.
— Vous pouvez supposer que Joao soit arrive à écrire des mots sans fautes, soit fait au plus une erreur.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Notez que les mots de liste_mots ne sont pas tous de la même longueur.
— Si rien ne marche : consultez la FAQ sur UpyLaB 5.15.
Note : Voir la vidéo de la section 5.6.1 : Compréhension et copie profonde (deepcopy) sur les listes
CONTENU DE LA VIDÉO
La vidéo précédente introduit la construction de listes grâce à la technique Python de compréhension de listes.
Elle introduit également grâce à des exemples la nécessité de faire des copies profondes (deepcopy) de listes non simples quand les
copies superficielles (shallow copy) ne sont pas suffisantes.
Code sur la console ou dans Python Tutor réalisé dans la vidéo
s= [2, 3, 5, 7]
t = s[:]
s[0] = 666
print(s)
print(t)
La vidéo en bref
Deux exemples de compréhension de listes sont donnés, la première simple, la suivante avec deux for imbriqués et une condition
if. La problématique des copies superficielles de listes est ensuite illustrée à travers une exécution dans Python Tutor. L’utilité de
la copie profonde d’une liste non simple est ensuite expliquée à nouveau en utilisant Python Tutor pour bien voir les allocations
mémoire des différentes parties des séquences de données.
La technique de compréhension de liste nous permet de construire facilement une liste de valeurs lues (comme dans l’exemple
ci-dessous où l’on suppose que les valeurs sont entières).
Dans le code suivant, l’utilisateur encode sur une ligne une liste de valeurs entières séparées d’au moins une espace (par exemple 1
2 3 21 36 <return>) ; ces valeurs permettent d’initialiser la liste ma_liste :
Un code équivalent peut être écrit en une ligne : il effectue séquentiellement l’ input, le split et enfin la construction de la liste
avec traduction des données en int :
liste = [int(i) for i in input("liste des valeurs").split()]
KEEP_ALNUM VERSION 2
Reprenons la fonction keep_alnum que nous avons présentée dans la sous-section 5.4.4, et dont le but est de renvoyer un texte
nettoyé par rapport au texte reçu. Montrons qu’elle peut être écrite de façon plus compacte en utilisant la notion de compréhension
de liste ainsi que la méthode join qui sert à reconstruire un texte à partir des éléments de la liste construite par compréhension.
def keep_alnum_2(s):
"""Nettoie s en lui retirant les caractères non alphanumériques."""
Les exercices UpyLaB suivants peuvent aussi se résoudre sans utiliser la technique de compréhension de liste. Mais les solutions
sont beaucoup plus courtes avec cette technique ! Nous vous demandons donc si possible de les réaliser avec du code utilisant des
compréhensions de liste.
Énoncé
Écrire une fonction my_pow qui prend comme paramètres un nombre entier m et un nombre flottant b, et qui renvoie une liste
contenant les m premières puissances de b, c’est-à-dire une liste contenant les nombres allant de 𝑏0 à 𝑏𝑚−1 .
Si le type des paramètres n’est pas celui attendu, la fonction retournera la valeur None.
Exemple 1
my_pow(3, 5.0)
doit retourner :
Exemple 2
my_pow(3.0, 5.0)
doit retourner :
None
Exemple 3
my_pow('a', 'b')
doit retourner :
None
Consignes
Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter que la
définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier aucun appel
ni à la fonction demandée ni aux fonctions input et print.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Il n’est demandé ici que de définir la fonction. Mais pour tester son fonctionnement dans votre IDE, pensez à ajouter du code
qui l’appelle et teste son résultat, sur plusieurs valeurs, comme print(my_pow(2, 2.5)) par exemple.
— Pour contrôler le type des arguments, pensez à utiliser la fonction type et à comparer son résultat aux chaînes int ou
float.
— Et n’oubliez pas de tester votre fonction avec des arguments de type incorrect. Cela ne doit pas entraîner d’erreur, mais la
fonction retournera None dans ces cas.
— Si rien ne marche : consultez la FAQ sur UpyLaB 5.16.
Énoncé
On considère une liste qui décrit une séquence t. Chaque élément de cette liste est un tuple de deux composantes : le nombre de
répétitions successives de l’élément x dans la séquence t, et l’élément x lui-même.
Par exemple, la liste [(1, 'He'), (2, 'l'), (1,'o')] décrit la séquence "Hello".
Écrire une fonction decompresse qui reçoit une telle liste en paramètre et renvoie la séquence t sous forme d’une nouvelle
liste.
Exemple
decompresse([(4, 1), (0, 2), (2, 'test'), (3, 3), (1, 'bonjour')])
doit retourner :
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Essayez d’utiliser une compréhension de liste pour cet exercice.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Il n’est demandé ici que de définir la fonction. Mais pour tester son fonctionnement dans votre IDE, pensez à ajouter du code
qui l’appelle et teste son résultat, sur plusieurs valeurs, comme print(decompresse([(1, 'He'), (2, 'l'),
(1,'o')]) par exemple.
— Si rien ne marche : consultez la FAQ sur UpyLaB 5.17.
Énoncé
Écrire une fonction my_filter qui reçoit une liste lst et une fonction booléenne f en paramètres et renvoie une nouvelle liste
constituée des éléments de lst pour lesquels la fonction f renvoie True.
Exemples
Pour tester dans votre IDE (Thonny ou PyCharm par exemple) la fonction my_filter, vous allez devoir définir une fonction
booléenne f et la passer en argument à la fonction my_filter.
Vous pourrez donc d’abord définir la fonction f à l’aide du mot-clé def, mais sachez que l’on peut aussi définir directement la
fonction f lors de l’appel à la fonction my_filter en utilisant ce qu’on appelle une fonction lambda.
Il s’agit de fonctions anonymes que l’on peut utiliser au moment même.
Exemple d’une fonction lambda :
Cette fonction testera si l’objet x qu’on lui passe est de type int et fait le même travail que la fonction is_int plus classiquement
définie ci-dessous :
def is_int(x):
return isinstance(x, int)
La seule différence, c’est que dans le deuxième cas, il faut avoir défini la fonction is_int au préalable (mais l’avantage, c’est
qu’on pourrait la réutiliser dans la suite du code, contrairement à la fonction lambda).
Notez qu’UpyLaB utilisera ces fonctions lambda dans ses tests.
Exemple 1
doit retourner :
[666, 42]
Exemple 2
doit retourner :
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— On rappelle qu’une fonction booléenne est une fonction qui retourne True ou False.
— Essayez d’utiliser une compréhension de liste pour cet exercice.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Il n’est demandé ici que de définir la fonction. Mais pour tester son fonctionnement dans votre IDE, pensez à ajouter du code
qui l’appelle et teste son résultat, sur plusieurs valeurs, comme my_filter(['hello', 666, 42, 'Thierry',
1.5], lambda x : isinstance(x, int)) par exemple, ou en reprenant les tests d’UpyLaB.
— Si la notion de fonctions lambda vous paraît confuse, ne vous en inquiétez pas trop. C’est un point que nous n’abordons pas
davantage dans ce cours d’introduction au langage Python.
— Si rien ne marche : consultez la FAQ sur UpyLaB 5.18.
Ce quiz montre la richesse de Python qui permet de faire un certain traitement de façons totalement différentes. Notons que si nous
regardons chacun des codes, certains sont simples et clairs (et corrects) et d’autres plus compliqués et parfois même erronés. L’art
de la programmation est de trouver le code que tous comprendront facilement : ici simple et clair sont les mots-clés.
Notons qu’au contraire, certains geeks font des concours du code le plus incompréhensible : voir par exemple avec le langage C :
Concours international de code C obscur.
On s’amuse comme on peut !
Note : Voir la vidéo de la section 5.8.1 : Comment manipuler un fichier texte en lecture
CONTENU DE LA VIDÉO
>>> mon_fichier.readline()
'aa\n'
>>> mon_fichier.readline()
'aah\n'
>>> mon_fichier.readline().strip()
'aahing'
>>> for lig in mon_fichier:
... print([Link]())
...
aahs
aal
aalii
...
zymurgy
>>> mon_fichier.readline()
''
>>> mon_fichier.close()
>>> type(mot)
<class '_io.TextIOWrapper'>
>>> [Link]() # peut provoquer une erreur d'encodage !
'a\n'
>>> [Link]()
'à\n'
>>> [Link]()
>>> mot = open("/Users/tmassart/Enseignement/SVN/tmassart/MOOC/Ressources_textuelles_et_livres/
˓→[Link]", encoding="utf-8")
La vidéo en bref
L’ouverture d’un fichier texte avec open, ainsi que les méthodes readline(), strip() et close sont présentées. À nou-
veau, référez-vous à l’ aide-mémoire pour les options et un résumé de ce qu’elles font.
Note : Voir la vidéo de la section 5.8.2 : Comment manipuler un fichier texte (suite)
CONTENU DE LA VIDÉO
La vidéo précédente illustre des manipulations en lecture et écriture de fichier texte par du code Python.
Codes sur la console réalisés dans la vidéo
La vidéo en bref
Deux meilleures façons d’ouvrir et de fermer un fichier texte sont présentées, dans une instruction with ou une instruction for.
À nouveau, référez-vous à l’ aide-mémoire pour les options et un résumé de ce qu’elles font.
Des exemples de filtres, qui ouvrent des fichiers textes en lecture ou écriture et affichent ou écrivent des résultats sur d’autres
fichiers textes, illustrent nos propos.
Remarque : les ensembles seront formellement vus au module 6
1) Les informations sauvées dans des fichiers qui continueront à exister après la fin de l’exécution du programme Python, sont
appelées dans le jargon informatique informations persistantes par opposition aux données volatiles créées en mémoire vive
lors de l’exécution du programme et qui disparaissent en cours ou en fin de cette exécution. Les données persistantes sont
généralement sauvées sur un disque local ou distant (dans le cloud), sous forme soit de fichiers soit de bases de données.
2) Le fichier [Link], téléchargeable ici (que vous pouvez ensuite enregistrer sur votre ordinateur dans le répertoire du projet
Python en cours), a été produit par Christophe Pallier à partir de données du dictionnaire Français-Gutenberg de Christophe
Pythoud. Il contient 336531 mots français. C’est un fichier “plain text”, c’est-à-dire que vous pouvez le lire dans n’importe
quel éditeur de texte, mais également via Python. Il va nous permettre de jouer avec les mots.
3) Le fichier texte [Link], téléchargeable ici (que vous pouvez ensuite enregistrer sur votre ordinateur dans le répertoire du
projet Python en cours) contient 370099 mots d’anglais et a été obtenu de la page [Link] ici
4) Lorsque l’on ouvre une console PyCharm, par défaut le répertoire courant correspond à celui du projet ouvert. Il peut être
intéressant de définir un autre répertoire (directory en anglais) de travail que celui par défaut en particulier pour y manipuler
des fichiers. Le module Python os peut être utile pour cela en permettant avec la fonction chdir, de changer le répertoire
courant.
import os
[Link]('Users/tmassart/Python/scripts')
'/Users/tmassart/Python/scripts/[Link]'
qui donne le nom du fichier avec son chemin complet depuis le répertoire racine ('/') sur l’ordinateur. Ici, chemin et nom
de fichier seront donc des synonymes.
Instruction Effet
f=open(“fichier”) : ouvre “fichier” en lecture
f=open(“fichier”,”w”) : ouvre “fichier” en écriture
f=open(“fichier”,”a”) : ouvre “fichier” en écriture en rajoutant après les données déjà présentes
[Link]() : retourne le contenu du fichier f
[Link]() : lit une ligne
[Link]() : renvoie la liste des lignes de f
[Link](s) : écrit la chaîne de caractères s dans le fichier f
[Link]() : ferme f
À nouveau, manipulons ensemble les notions que nous venons d’introduire, ici les fichiers textes, pour nous familiariser avec celles-
ci. Je vous propose ici trois petits problèmes à résoudre.
GADSBY ET LA DISPARITION
En 1939, Ernest Wright a publié une nouvelle de 50000 mots appelée Gadsby qui ne contient pas la lettre “e”. Comme “e” est la
lettre la plus commune en anglais (et dans d’autres langues y compris le français), ce n’était pas une tâche facile.
Notez que Georges Perec a fait le même exercice en français, dans son livre « La disparition » (1969) où il définit ce qui a disparu
comme “un rond pas tout à fait clos, fini par un trait horizontal”.
Problème
Écrivez un script qui n’affiche que les mots qui ne contiennent pas de “e” et calculez le pourcentage de ceux-ci par rapport à
l’ensemble des mots du fichier [Link].
Proposition de solution
Ci-dessous une proposition de solution (n’oubliez pas de mettre le fichier [Link] dans le répertoire « courant »).
def texte_sans_e(fichier_recu):
"""renvoie True si le texte contenu dans fichier_recu ne contient pas la lettre e,
ni les lettres ``é``, ``è``, ``ê``, ``ë``
Hypothèse: le fichier existe
"""
with open(fichier_recu, encoding="utf-8") as fichier:
texte = [Link]()
texte = [Link]('é', 'e')
texte = [Link]('è', 'e')
texte = [Link]('ê', 'e')
texte = [Link]('ë', 'e')
return 'e' not in texte
Problème
Après avoir téléchargé le fichier [Link], en cliquant [Link] ici, donnez la liste des mots anglais provenant du fichier
[Link], avec trois doubles lettres consécutives. Je vous donne un couple de mots qui sont presque candidats, mais pas tout à
fait. Par exemple, le mot “committee” serait parfait s’il n’y avait pas ce “i” au milieu. Ou “Mississippi” : si on retirait les “i”, cela
marcherait. Il y a cependant au moins un mot qui possède trois paires consécutives de lettres. C’est peut-être le seul mot, ou il peut
y en avoir 500. Existe-il un mot avec les mêmes caractéristiques dans le fichier [Link] ?
Problème
Donnez la liste des mot français, provenant du fichier [Link], avec quatre doubles lettres éventuellement consécutives. Je vous
donne un mot qui est presque candidat, mais pas tout à fait. Par exemple, le mot “commissionnaire” serait parfait s’il se terminait
par « airre » ; il y a donc trois doubles lettres mais pas quatre. Existe-il un mot avec les mêmes caractéristiques dans le fichier
[Link] ?
Proposition de solution
Ci-dessous une proposition de solution.
def triple_double_lettres(mot):
"""renvoie vrai si le mot contient trois double lettres consécutives"""
i = 0
n = len(mot)
res = False
(suite sur la page suivante)
i = 0
long = len(mot)
cont = 0
while cont < n and i < long - 1:
if mot[i] == mot[i + 1]:
cont += 1
i += 2
else:
i += 1
return cont == n
def quadruple_double_non_consecutifs(mot):
"""renvoie vrai si le mot contient quatre double lettres
éventuellement non consécutives"""
return n_double_non_consecutifs(mot, 4)
# code principal
print("triple-doubles consécutifs avec [Link]")
for m in open('[Link]', encoding="UTF-8"):
mon_mot = [Link]()
if triple_double_lettres(mon_mot):
print(mon_mot)
Maintenant que vous avez bien assimilé les manipulations de fichiers textes, en fonction du parcours que vous suivez, à vous d’en
faire de façon autonome avec les exercices UpyLab suivants :
Énoncé
D’après Wikipedia, un acrostiche est un poème, une strophe ou une série de strophes fondés sur une forme poétique consistant en
ce que, lues verticalement de haut en bas, la première lettre ou, parfois, les premiers mots d’une suite de vers composent un mot ou
une expression en lien avec le poème.
Écrire une fonction acrostiche qui reçoit en paramètre le nom d’un fichier et qui retourne la chaîne de caractères formée par
les premières lettres de chaque ligne du fichier.
Exemple
acrostiche("[Link]")
doit retourner :
"MARIA"
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Les fichiers utilisés par UpyLaB pour tester la fonction sont accessibles aux adresses suivantes :
— [Link]
— [Link]
— [Link]
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Il n’est demandé ici que de définir la fonction. Mais pour tester son fonctionnement dans votre IDE, pensez à ajouter du code
qui l’appelle et teste son résultat, sur plusieurs valeurs, comme print(acrostiche(("[Link]"))) par
exemple, en veillant à ce que le fichier utilisé soit bien présent dans le répertoire courant.
— Si rien ne marche : consultez la FAQ sur UpyLaB 5.19.
Énoncé
Écrire une fonction nouveaux_heros dont le but consiste à modifier les héros d’une histoire.
La fonction acceptera deux paramètres : * le premier sera une chaîne de caractères précisant le nom du fichier contenant l’histoire
initiale ; * le deuxième sera une chaîne de caractères précisant le nom du fichier dans lequel sera sauvegardée l’histoire modifiée
comme précisé ci-dessous.
Dans l’histoire initiale, présente dans le fichier dont le nom est donné en premier argument, trois protagonistes interviennent : Pierre,
Paul et Jacqueline. La fonction devra remplacer ces trois héros par, respectivement, Paul, Tom et Mathilde. Le texte ainsi modifié
sera alors stocké dans le fichier dont le nom est donné en deuxième argument. Aucune autre modification ne sera apportée au texte
initial.
Exemple
Si Pierre est le fils de Paul, et si Paul est le frère de Jacqueline, qui est Pierre pour
˓→Jacqueline ?
nouveaux_heros("[Link]//pub/data/histoire_1.txt", "nouvelle_histoire_1.txt")
Si Paul est le fils de Tom, et si Tom est le frère de Mathilde, qui est Paul pour Mathilde ?
Consignes
— Vous pouvez supposer que le fichier dont le nom est passé en premier argument existe bien et est au format UTF-8.
— Les fichiers utilisés par UpyLaB pour tester la fonction sont accessibles aux adresses suivantes :
— [Link]
— [Link]
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Pour tester votre fonction, assurez-vous de copier le fichier à lire dans le répertoire courant (ou de passer comme argument
le chemin complet vers le fichier).
— L’utilisation de la méthode replace sur les chaînes de caractères va s’avérer utile. Mais attention à Paul qui se trouve à la
fois dans les anciens héros et les nouveaux. Une façon de procéder pourrait consister à remplacer, provisoirement, la chaîne
"Paul" par une autre valeur (attention toutefois à ce que cette valeur provisoire ne soit pas elle-même présente dans le
texte), ou, plus astucieusement, de réfléchir à l’ordre dans lequel apporter les modifications attendues.
— Si rien ne marche : consultez la FAQ sur UpyLaB 5.20.
Énoncé
Écrire une fonction liste_des_mots qui reçoit en paramètre le nom d’un fichier texte, que la fonction doit ouvrir, et qui renvoie
la liste des mots contenus dans le fichier.
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— On peut supposer que le fichier est présent et dans le bon format en encodage UTF-8.
— Les mots dans la liste seront écrits en minuscule et triés dans l’ordre donné par la codification UTF-8 (en utilisant la méthode
sort par exemple), les accents n’étant pas gérés de façon spécifique (« a » et « à » sont deux mots différents).
— Un même mot ne peut pas se trouver deux fois dans la liste.
— Dans le fichier source, les mots peuvent être séparés par des caractères blancs habituels (caractère espace, tabulation, passage
à la ligne), ou par n’importe quel caractère parmi les suivants :
— “ »?! :; . , * = ( ) 1 2 3 4 5 6 7 8 9 0
— Certains des fichiers utilisés par UpyLaB pour tester la fonction sont accessibles aux adresses suivantes :
— [Link]
— [Link]
Notez que le fichier [Link] est libre de droit d’auteur sauf en France (voir [Link]
Petit_Prince). Si vous habitez en France, vous ne pouvez donc légalement le télécharger, mais aucun souci ailleurs dans le monde.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Pour tester votre fonction, assurez-vous de copier le fichier à lire dans le répertoire courant (ou de passer comme argument
le chemin complet vers le fichier).
— Si rien ne marche : consultez la FAQ sur UpyLaB 5.21.
Énoncé
Écrire une fonction wc(nomFichier) qui ouvre le fichier en question et renvoie un tuple de trois nombres :
— le nombre de caractères (y compris les caractères de retour à la ligne)
— le nombre de mots
— le nombre de lignes.
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Nous définissons ici un mot comme étant une chaîne de caractères alphanumériques, c’est-à-dire répondant True à la
méthode isalnum(), et maximale, c’est-à-dire entourée d’espaces ou de séparateurs ou de caractères de fin de phrase.
— Les fichiers utilisés par UpyLaB pour tester la fonction sont accessibles aux adresses suivantes :
— [Link]
— [Link]
— [Link]
Pour information, le premier fichier contient les caractères a2x!§t5\n (\n désignant le caractère de fin de ligne). L’appel
de la fonction sur ce fichier retourne donc le tuple (8, 2, 1), les deux mots étant a2x et t5.
Notez que le fichier [Link] est libre de droit d’auteur sauf en France (voir [Link]
Le_Petit_Prince). Si vous habitez en France, vous ne pouvez donc légalement le télécharger, mais aucun souci ailleurs dans
le monde.
— Vous pourriez être tenté d’utiliser la méthode split. Ce n’est peut-être pas une très bonne idée, car la liste des séparateurs
est ici très longue. Par exemple, le fichier pourrait contenir la chaîne "a$ C 𝛼𝜔 $BOnJOur".
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Pour tester votre fonction, assurez-vous de copier le fichier à lire dans le répertoire courant (ou de passer comme argument
le chemin complet vers le fichier).
— Si rien ne marche : consultez la FAQ sur UpyLaB 5.22.
Commençons par un peu de vocabulaire. En programmation, une liste simple d’éléments est aussi appelée vecteur ou tableau à une
dimension.
Par exemple, pour n = 4, nous avons vu en section 5.2, qu’initialiser un vecteur vec à n composantes à 0 pouvait se faire avec le
code :
vec = [0] * n
Nous avons également vu au début de la présente section que la compréhension de liste était une technique puissante pour créer une
nouvelle liste. Par exemple, le code :
vec = [0 for i in range(n)]
Nous voyons que chaque sous-liste est en fait la même liste ; ainsi, si nous modifions un élément, par exemple matrix[2][2] =
666, chaque ligne de la matrice sera modifiée.
Une solution est d’utiliser le code :
La notion de matrice est bien connue en mathématiques. Elle est également bien connue pour toute personne qui fait des jeux, que
ce soit des mots-croisés ou des sudokus dans le journal ou des jeux de plateau comme le jeu de dames, d’échec ou le jeu de go, ou
encore des jeux vidéo qui se déroulent sur une vue en deux dimensions d’une carte géographique ou d’un plan de bâtiment ou autre
comme un plan à deux dimensions de labyrinthe.
Comme déjà mentionné dans la section 7, une matrice est représentée en Python sous le forme d’une liste de listes, chaque sous-liste
représentant les informations d’une ligne de la matrices.
Ce qui suit donne des exemples très intéressants de manipulation de matrices. On y parle de carré magique, de transformation et
aussi du jeu de puissance quatre.
D’après Wikipedia : un carré magique d’ordre n est composé de 𝑛2 entiers strictement positifs, écrits sous la forme d’un tableau
carré. Ces nombres sont disposés de sorte que leurs sommes sur chaque rangée, sur chaque colonne et sur chaque diagonale princi-
pale, soient égales. Un carré magique normal est un cas particulier de carré magique, constitué de tous les nombres entiers de 1 à
𝑛2 , où n est l’ordre du carré.
Le carré magique normal non trivial (n > 1) le plus simple est celui pour n valant 3 (𝑛2 = 9) :
def rotation(carre):
"""renvoie l'image de la matrice carre par rotation de 90° à droite"""
n = len(carre)
return [[carre[i][j] for i in range(n-1,-1,-1)] for j in range(n)]
SYMETRIE_VERTICALE
Ensuite, passons à la fonction symetrie_verticale qui reçoit également une telle matrice et renvoie une matrice où les valeurs
sont changées par symétrie verticale par rapport au milieu comme expliqué.
Proposition de solution
Ci-dessous une proposition de solution.
def symetrie_verticale(carre):
"""renvoie l'image de la matrice carre par symétrie verticale"""
n = len(carre)
return [[carre[i][j] for j in range(n-1, -1, -1)] for i in range(n)]
NOTE
Notez que les deux fonctions sont de très beaux exemples d’utilisation de la technique de compréhension de liste.
Beaucoup de jeux de sociétés se jouent sur un plateau (jeu de dames, d’échec, . . . ). Le jeu de puissance 4 est un autre exemple :
Puissance 4 (parfois aussi appelé 4 en ligne) est un jeu de stratégie.
Règles du jeu puissance 4 : le but du jeu est d’aligner une suite de 4 pions de même couleur sur une grille comptant 6 rangées
et 7 colonnes. Chaque joueur dispose de 21 pions d’une couleur (par convention, en général jaune ou rouge). Tour à tour les deux
joueurs placent un pion dans la colonne de leur choix, le pion coulisse alors jusqu’à la position la plus basse possible dans ladite
colonne à la suite de quoi c’est à l’adversaire de jouer. Le vainqueur est le joueur qui réalise le premier un alignement (horizontal,
vertical ou diagonal) consécutif d’au moins quatre pions de sa couleur. Si, alors que toutes les cases de la grille de jeu sont remplies,
aucun des deux joueurs n’a réalisé un tel alignement, la partie est déclarée nulle.
L’état du jeu peut être représenté par une matrice de 6 lignes et 7 colonnes qui détermine pour chaque case si elle est occupée par
un pion rouge, par un pion jaune ou si elle est libre. Un dernier petit élément pour donner l’état complet est de savoir qui doit jouer
le prochain tour. Par exemple, le plateau de jeu suivant où les jaunes doivent jouer au prochain tour :
si l’on prend comme référence que le ligne du bas est la ligne 0 dans jeu (la première ligne du code Python) et que :
— “V” encode une case vide
Un jeu sur un damier peut généralement être encodé avec une matrice de valeurs, par exemple entières. Ayant un fichier qui a un tel
encodage, comment le lire et initialiser une matrice Python avec son encodage ?
Le code que nous vous avons proposé pour lire une liste d’entiers, peut être étendu pour lire une matrice d’entiers. Ici nous supposons
que fichier_encodage est le nom du fichier à ouvrir et qui contient les valeurs, à raison d’une ligne par ligne de la matrice à
initialiser où chaque entier est séparé par au moins une espace.
La fonction lire_matrice réalise une telle lecture et encodage et renvoie la matrice créée comme résultat :
def lire_matrice(fichier_encodage):
with open(fichier_encodage, encoding='utf-8') as fichier_in:
return [[int(colonne) for colonne in [Link]()] for ligne in fichier_in]
Notons que l’utilisation de compréhensions de liste donne un code très court mais assez dense et difficile à comprendre pour un
débutant.
5.9.3 Passons à la mise en pratique sur les matrices avec les exercices UpyLaB 5.26 et sui-
vants
À nouveau en fonction du parcours que vous suivez, nous vous demandons de réaliser les exercices UpyLaB 5.23 à 5.27 qui
manipulent des matrices.
Énoncé
Écrire une fonction init_mat(m, n) qui construit et renvoie une matrice d’entiers initialisée à la matrice nulle et de dimension
m x n.
Exemple 1
init_mat(2, 3)
doit retourner :
Exemple 2
init_mat(0, 0)
doit retourner :
[]
Consignes
Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter que la
définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier aucun appel
ni à la fonction demandée ni aux fonctions input et print.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Il n’est demandé ici que de définir la fonction. Mais pour tester son fonctionnement dans votre IDE, pensez à ajouter du code
qui l’appelle et teste son résultat, sur plusieurs valeurs, comme print(init_mat(2, 2)) par exemple.
— Si votre fonction semble retourner le bon résultat, mais n’est pourtant pas acceptée par UpyLaB, nous vous proposons de
tester le code suivant dans votre IDE (après la définition de la fonction) :
m = init_mat(3, 2)
m[0][0] = 1 #modifie le premier élément de la matrice
print(m)
Que se passe-t-il ?
— N’hésitez pas à revoir la matière dispensée dans la section 5.9.1 concernant l’initialisation de tableaux, ni à utiliser Python
Tutor et observer en particulier les diagrammes d’état.
— Si rien ne marche : consultez la FAQ sur UpyLaB 5.23.
Énoncé
Écrire une fonction print_mat(M) qui reçoit une matrice M en paramètre et affiche son contenu.
Les éléments d’une même ligne de la matrice seront affichés sur une même ligne, et séparés par une espace, les éléments de la ligne
suivante étant affichés sur une nouvelle ligne.
Exemple
doit afficher :
1 2
3 4
5 6
Consignes
— Important : Afin de permettre à UpyLaB de tester votre fonction, votre code contiendra également, après le code de la
définition de la fonction print_mat, les instructions suivantes :
ma_matrice = eval(input())
print_mat(ma_matrice)
— Si la matrice vide [] est passée en argument, la fonction affiche une ligne vide.
— Dans cet exercice, la présence d’espaces en fin de ligne ne sera pas sanctionnée. Par contre, veillez à ce qu’il n’y ait pas de
ligne supplémentaire.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Notez que la fonction print_mat ne retourne rien, mais procède à un affichage.
— Si rien ne marche : consultez la FAQ sur UpyLaB 5.24.
Énoncé
Écrire une fonction trace(M) qui reçoit en paramètre une matrice M de taille 𝑛 × 𝑛 contenant des valeurs numériques (de type
int ou float), et qui renvoie sa trace, c’est-à-dire la somme de tous les éléments de la première diagonale.
Exemple 1
doit retourner :
15
Exemple 2
trace([])
doit retourner :
Consignes
— Dans cet exercice, il vous est demandé d’écrire seulement la fonction trace. Le code que vous soumettez à UpyLaB doit
donc comporter uniquement la définition de cette fonction, et ne fait en particulier aucun appel à input ou à print.
— Les éléments de la première diagonale sont les éléments dont l’indice de ligne est égal à l’indice de colonne. Ainsi :
𝑛−1
∑︁
𝑡𝑟𝑎𝑐𝑒(𝑀 ) = 𝑚𝑖𝑖
𝑖=0
— Vous pourrez supposer que les matrices passées en argument seront bien carrées (même nombre de lignes et de colonnes).
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Il n’est demandé ici que de définir la fonction. Mais pour tester son fonctionnement dans votre IDE, pensez à ajouter du code
qui l’appelle et teste son résultat, sur plusieurs valeurs, comme print(trace([[1, 2, 3], [4, 5, 6], [7, 8,
9]])) par exemple.
— Si rien ne marche : consultez la FAQ sur UpyLaB 5.25.
Énoncé
Une matrice 𝑀 = {𝑚𝑖𝑗 } de taille 𝑛 × 𝑛 est dite antisymétrique lorsque, pour toute paire d’indices 𝑖, 𝑗, on a 𝑚𝑖𝑗 = −𝑚𝑗𝑖 .
Écrire une fonction booléenne antisymetrique(M) qui teste si la matrice M reçue est antisymétrique.
Exemple 1
doit retourner :
True
Exemple 2
doit retourner :
False
Exemple 3
doit retourner :
False
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Vous pourrez supposer que les matrices passées en argument sont bien carrées (même nombre de lignes et de colonnes).
— On rappelle qu’une fonction booléenne retourne les valeurs True ou False.
— La fonction retourne True pour la matrice vide.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Il n’est demandé ici que de définir la fonction. Mais pour tester son fonctionnement dans votre IDE, pensez à ajouter du code
qui l’appelle et teste son résultat, sur plusieurs valeurs, comme print(antisymetrique([[0, 1, 1], [-1, 0,
1], [-1, -1, 0]])) par exemple.
— N’oubliez pas que la condition doit aussi s’appliquer lorsque les indices 𝑖 et 𝑗 sont égaux.
— Si rien ne marche : consultez la FAQ sur UpyLaB 5.26.
Énoncé
Écrire une fonction symetrie_horizontale(A) qui reçoit une matrice carrée A (de taille 𝑛 × 𝑛) et qui renvoie l’image de A
par symétrie horizontale par rapport à la ligne du milieu : la première ligne devenant la dernière, la seconde, l’avant-dernière, etc.
Exemple 1
doit retourner :
Exemple 2
doit retourner :
Exemple 3
symetrie_horizontale([])
doit retourner :
[]
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Vous pourrez supposer que les matrices passées en argument sont bien carrées (même nombre de lignes et de colonnes).
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Il n’est demandé ici que de définir la fonction. Mais pour tester son fonctionnement dans votre IDE, pensez à ajouter du code
qui l’appelle et teste son résultat, sur plusieurs valeurs, comme print(symetrie_horizontale([[1, 2, 3],
[4, 5, 6], [7, 8, 9]])) par exemple.
— N’oubliez pas de tester le fonctionnement de votre fonction sur les cas limites, comme ici la matrice vide.
— Si rien ne marche : consultez la FAQ sur UpyLaB 5.27.
BILAN DU MODULE 5
LES ENSEMBLES
CONTENU DE LA VIDÉO
La vidéo précédente présente le menu de ce module. Nous y présentons un nouveau type de structure de données : les ensembles.
Tests réalisés sur la console dans la vidéo
CC BY-SA 3.0 - 2021 - Sébastien Hoarau - Thierry Massart - Jean Olgiati - Isabelle Poirier 251
Apprendre à coder avec Python, Version - Release 3.0
La vidéo en bref
Nous montrons comment manipuler les ensembles (set) Python, les façons de les créer, les opérateurs ensemblistes qui en créent
d’autres, les méthodes d’ajout et de suppression d’éléments ainsi que les opérateurs d’inclusion stricte ou non dans les deux sens.
Référez-vous à l’ aide mémoire pour avoir un résumé de ce que fait chaque méthode sur les ensembles.
Comme exemple de script qui utilise un ensemble Python, nous pouvons écrire une version plus complète et plus compacte du
code proposé dans le module précédent, qui lit un fichier de mots (pour simplifier, nous supposons que chaque mot est séparé du
suivant par une espace ou un passage à la ligne '\n') et écrit sur un autre fichier la liste des mots rencontrés, un mot par ligne, en
supprimant les doublons. De plus, cette version trie les mots.
with open('mots_un_par_ligne_avec_duplic.txt') as mots:
mots_valides = set([Link]().split()) # set permet de supprimer les doublons
liste_mots = list(mots_valides) # transforme en liste
liste_mots.sort() # trie la liste
LES DICTIONNAIRES
CONTENU DE LA VIDÉO
Dans la vidéo précédente nous introduisons maintenant les dictionnaires : un type de données très important étant donné les possi-
bilités importantes qu’il ouvre en matière de programmation.
Tests réalisés dans la vidéo sur la console et avec un script
>>> ang2fr = {'one':'un', 'two': 'deux', 'three': 'trois'}
>>> type(ang2fr)
<class 'dict'>
>>> ang2fr['four'] = 'quatre'
>>> ang2fr
{'one': 'un', 'two': 'deux', 'three': 'trois', 'four': 'quatre'}
>>> ang2fr['two']
'deux'
>>> ang2fr['five']
Traceback (most recent call last):
File "<input>", line 1, in <module>
KeyError: 'five'
>>> d = {}
>>> d = {'ent': 1, 'list': [1, 2, 3], (1,2): 3.14, dic: ang2fr}
Traceback (most recent call last):
File "<input>", line 1, in <module>
NameError: name 'dic' is not defined
>>> d = {'ent': 1, 'list': [1, 2, 3], 1:'un', (1,2): 3.14, 'dic': ang2fr}
>>> d[[3,4]] = 45
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: unhashable type: 'list'
>>> d['dic']
{'one': 'un', 'two': 'deux', 'three': 'trois', 'four': 'quatre'}
>>> d['dic']['two']
'deux'
(suite sur la page suivante)
def histogram(s):
"""Renvoie le dictionnaire des lettres dans s avec leur fréquence"""
d = {}
for c in s:
if c in d:
d[c] += 1
else:
d[c] = 1
return d
h = histogram('brontosaurus')
print(h)
La vidéo en bref
Nous montrons comment manipuler les dictionnaires (dict) Python, les façons de les créer avec pour chaque élément sa clé (key)
et sa valeur (value), d’ajouter des nouveaux éléments, ainsi que la façon de manipuler les dictionnaires ou leurs éléments.
Dans la vidéo précédente, nous avons vu, lorsque nous avons demandé à l’interpréteur d’ajouter à un dictionnaire une composante
avec un clé de type liste, que l’opération n’avait pas eu lieu et que l’interpréteur avait donné le message d’erreur
Python impose une restriction à l’utilisation de l’instruction for pour itérer tous les éléments d’un dictionnaire ou d’un ensemble :
le corps du for ne peut ajouter ou supprimer de composante dans la séquence sur laquelle il itère. Par exemple le code suivant
provoque une erreur à l’exécution :
Cette restriction est assez sensée puisqu’il faut permettre à l’interpréteur, qui dans cet exemple au départ veut réaliser cinq itérations
(une par élément de l’ensemble s), de s’y retrouver.
Note : Petite astuce pour les utilisateurs d’ordinateurs Mac : comment écrire le caractère « | » sur mon clavier ? Tapez alt +
Majuscule + L
QUELQUES EXEMPLES
À nouveau pour assimiler la matière vue dans cette section, nous développons ensemble quelques exemples qui manipulent fichiers
textes, ensembles et dictionnaires. Pour chaque problème, nous vous invitons à écrire une solution. Ensuite, comparez votre solution
avec celle proposée.
Problème
Dans la section 5 du module 5, nous avons déjà écrit un code pour trouver la liste des lettres communes à deux mots. Ceci se fait de
façon immédiate en utilisant des ensembles avec le code :
with open('[Link]') as f:
print([[Link]() for w in f if {'a','e','i','o','u','y'} <= set(w)])
Pour vous faciliter le travail, et pour que vous puissiez le relire et refaire cet exercice par vous-même, nous retranscrivons ci-dessous
le code, présenté dans la capsule précédente, qui utilise un dictionnaire pour déterminer comment compter la fréquence de chaque
lettre dans une chaîne de caractères. Cet exemple est en effet une belle illustration de l’utilisation de dictionnaire.
Problème
Écrivez la fonction histogram(s) qui reçoit une chaîne de caractère s et renvoie un dictionnaire dont les clés sont les lettres
rencontrées et la valeur associée est la fréquence de la lettre dans s.
def histogram(s):
"""Renvoie le dictionnaire des lettres dans s avec leur fréquence."""
d = {} # dictionnaire vide
for c in s:
if c not in d:
d[c] = 1
else:
d[c] += 1
return d
Ce code :
h = histogram('brontosaurus')
print(h)
renvoie :
Supposons que nous ayons envie d’avoir une vue globale des amis de chacune de nos connaissances. Pour cela, nous pouvons
construire un dictionnaire dont les clés sont les prénoms des personnes nommées (pour simplifier on suppose que deux personnes
n’ont pas le même prénom) et la valeur de chaque entrée est l’ensemble des amis de la personne.
Problème
Écrivez une fonction qui reçoit une liste de couples (prénom1, prénom2) voulant dire que prénom1 déclare prénom2 comme étant
son ami et qui construit le dictionnaire tel que décrit plus haut.
Une solution, et son code de test, pourrait être donnée par le code suivant :
def construction_dict_amis(liste_amis):
""" construit et renvoie un dictionnaire de personnes qui ont chacun
l'ensemble de leurs amis
liste_amis : liste de couple (p1, p2) : p1 a comme ami p2"""
amis = {}
for prenom1, prenom2 in liste_amis:
if prenom1 not in amis:
amis[prenom1] = {prenom2}
else:
amis[prenom1].add(prenom2) # pas d'effet si déjà présent
if prenom2 not in amis:
amis[prenom2] = set() # nouvelle entrée prenom2
return amis
t = 'Thierry'
m = 'Michelle'
s = 'Sébastien'
p = 'Pierre'
a = 'Ariane'
q = 'Quidam'
ma_liste = [(t, m), (t, s), (t, p), (t, a), (m, t), (m, a), (m, p),
(p, a), (a, p), (s, t), (p, s), (s, q)]
print(construction_dict_amis(ma_liste))
Dans le code de la solution proposée, notez en particulier que, par souci de cohérence, si un couple est lu, par exemple :
('Thierry', 'Sébastien'), le code s’assure que les deux entrées sont créées dans le dictionnaire (même si l’ensemble
des amis de 'Sébastien' est vide).
6.1.4 Mise en pratique des ensembles et dictionnaires avec les exercices UpyLaB 6.1 et sui-
vants
Réalisez de façon autonome les exercices 6.1 à 6.7 d’UpyLaB. Ces exercices vont vous permettre de manipuler les ensembles et les
dictionnaires.
Énoncé
Après avoir longuement réfléchi et un peu visité notre monde, le Petit Prince décide de ne pas rentrer sur sa planète mais de s’installer
dans les Cévennes pour profiter de la belle nature qu’on y trouve. Il y trouve une petite demeure pour y habiter, et plusieurs de
ses amis veulent l’aider en lui proposant des meubles, des denrées, des livres ou d’autres choses qui pourraient l’intéresser pour
aménager son nouveau domicile.
Nous vous proposons de l’aider.
Écrire une fonction inventaire(offres, objets) où :
— offres est un dictionnaire contenant, comme clés, les objets proposés par les amis du Petit Prince, et comme valeurs
associées, le nom de l’ami proposant cet objet
— objets est une liste contenant tous les objets dont on a besoin le Petit Prince.
La fonction retourne l’ensemble des amis chez qui il lui faut se rendre pour sa récolte.
Exemple
doit retourner :
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Vous pourrez supposer que les arguments passés à la fonction sont du bon type, et que les objets souhaités par le Petit Prince
figurent bien parmi les objets proposés par ses amis.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Si rien ne marche : consultez la FAQ sur UpyLaB 6.1.
Énoncé
Exemple
doit retourner :
13.0
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Vous pourrez supposer que les arguments passés à la fonction sont du bon type, et que les produits souhaités par Monsieur
Germain figurent bien dans le catalogue du magasin.
Énoncé
Exemple
doit retourner :
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Vous pourrez supposer que l’argument passé à la fonction est du bon type.
— Vous pourrez supposer que les candidats ont des moyennes différentes, et qu’ils sont plus de trois.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Si rien ne marche : consultez la FAQ sur UpyLaB 6.3.
Énoncé
Lors de prises de notes, il nous arrive souvent de remplacer des mots par des abréviations (bonjour est remplacé par bjr par exemple).
Nous allons utiliser un dictionnaire qui associe à chacune de ces abréviations sa signification.
Écrire une fonction substitue(message, abreviation) qui renvoie une copie de la chaîne de caractères message dans
laquelle les mots qui figurent parmi les clés du dictionnaire abreviation sont remplacés par leur signification (valeur).
Exemple
doit retourner :
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Pour simplifier, on suppose que les mots de la chaîne message sont séparés par des espaces.
— Vous pourrez supposer que les arguments passés à la fonction sont du bon type.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Si rien ne marche : consultez la FAQ sur UpyLaB 6.4.
Énoncé
Écrire une fonction construction_dict_amis qui reçoit une liste de couples (prenom1, prenom2) signifiant que
prenom1 déclare prenom2 comme étant son ami.
La fonction construit et renvoie un dictionnaire dont les clés sont les prénoms des personnes nommées, et la valeur de chaque entrée
est l’ensemble des amis de la personne.
Exemple
construction_dict_amis([('Quidam', 'Pierre'),
('Thierry', 'Michelle'),
('Thierry', 'Pierre')])
doit retourner :
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Si, dans la liste reçue, nous avons le couple (prenom1, prenom2), cela n’induit pas que prenom1 figure parmi les
amis de prenom2. Si le couple (prenom2, prenom1) n’est pas dans cette liste, nous aurons une amitié à sens unique !
— Vous pourrez supposer que les arguments passés à la fonction sont du bon type.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Si rien ne marche : consultez la FAQ sur UpyLaB 6.5.
Énoncé
Écrire une fonction symetrise_amis qui reçoit un dictionnaire d d’amis où les clés sont des prénoms et les valeurs, des
ensembles de prénoms représentant les amis de chacun.
Cette fonction modifie le dictionnaire d de sorte que si une clé prenom1 contient prenom2 dans l’ensemble de ses amis, l’inverse
soit vrai aussi.
La fonction accepte un second paramètre englobe.
Si englobe est vrai, la fonction ajoutera les éléments nécessaires pour symétriser le dictionnaire d.
Sinon, la fonction enlèvera les éléments nécessaires pour symétriser d.
Exemple 1
Exemple 2
{'Thierry': {'Michelle'},
'Michelle' : {'Thierry'},
'Bernadette' : set()}
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Notez que les prénoms figurant dans les ensembles d’amis font eux-même partie des clés du dictionnaire d.
— Vous pourrez supposer que les arguments passés à la fonction sont du bon type.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Notez que la fonction symetrise_amis ne retourne rien mais modifie le dictionnaire qui lui est passé en argument.
— Notez aussi qu’il ne faut pas modifier le nombre d’éléments d’une séquence sur laquelle on est en train d’itérer.
— Si rien ne marche : consultez la FAQ sur UpyLaB 6.6.
Énoncé
Écrire une fonction prime_odd_numbers(numbers) qui reçoit une liste de nombres et qui renvoie un couple d’ensembles
contenant respectivement les nombres premiers présents dans la liste et les nombres impairs.
Pour cela, nous vons demandons d’écrire au préalable deux fonctions annexes qui seront appelées dans le corps de la fonction
prime_odd_numbers :
— la fonction even qui accepte un nombre entier en paramètre et renvoie l’ensemble des nombres naturels pairs qui lui sont
inférieurs ou égaux
— la fonction prime_numbers(max_nb) qui accepte un nombre entier en paramètre et renvoie l’ensemble des nombres
premiers qui lui sont inférieurs ou égaux.
Exemple 1
Exemple 2
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Cet exercice a pour unique but de vous faire manipuler les ensembles et les opérations ensemblistes. Et donc, malgré les
apparences, il n’y a pas de contradiction entre le fait que l’on vous demande d’écrire la fonction even et le fait que la
fonction prime_odd_numbers s’intéresse aux nombres impairs. C’est volontaire.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Prêtez bien attention au type des paramètres pour chacune des fonctions à écrire.
— Quel argument allez-vous passer aux fonctions even et prime_numbers lorsque vous lez appelez dans le code de la
fonction prime_odd_numbers ?
— Si rien ne marche : consultez la FAQ sur UpyLaB 6.7.
Voici un petit quiz qui récapitule les notions vues jusqu’à présent dans ce module sur les ensembles et les dictionnaires.
Note : Voir la vidéo de la section 6.3.1 : Les méthodes des dictionnaires Python
CONTENU DE LA VIDÉO
>>> d = {}
>>> d = {'yes': 'oui', 'no': 'non'}
>>> d2 = [Link]()
>>> d2
(suite sur la page suivante)
pop(...)
[Link](k[,d]) -> v, remove specified key and return the corresponding value.
If key is not found, d is returned if given, otherwise KeyError is raised
>>> [Link]('three')
'trois'
>>> eng2fr
(suite sur la page suivante)
>>> d = {'a':0}
>>> [Link](zip('bcd', range(1, 4)))
>>> d
{'a': 0, 'b': 1, 'c': 2, 'd': 3}
La vidéo en bref
Nous présentons les nombreuses méthodes associées aux dictionnaires : copy, clear, fromkeys, get, setdefault, keys,
values, items, pop, update, ainsi que l’utilisation du in, dict et du deepcopy.
Référez-vous à l’aide mémoire pour avoir un résumé de ce que fait chaque méthode sur les dictionnaires.
NOTES IMPORTANTES
Ensuite, le code essaye d’accéder à l’indice 0 de val ce qui donne une erreur car l’objet ne peut être manipulé avec des indices,
comme on pourrait le faire avec une séquence (list, tuple ou str).
Si l’on veut construire une séquence, par exemple une liste, avec un objet généré par range, (resp. [Link](), [Link]()
ou [Link]()), il faut explicitement transformer l’objet produit, avec list(range(...)) (resp. list([Link]()),
list([Link]()) ou list([Link]())), comme ici avec la variable list_val.
QUELQUES EXEMPLES
À nouveau pour assimiler l’utilisation des différentes méthodes sur les dictionnaires que nous venons d’introduire, nous développons
ensemble quelques exemples qui manipulent ces différentes méthodes. Comme toujours, pour chaque problème, nous vous invitons
à écrire une solution. Ensuite, comparez votre solution avec celle proposée.
Problème
Réécrivez la fonction histogram() (fonction qui renvoie le dictionnaire des lettres dans s avec leur fréquence) sans instruction
conditionnelle explicite, en utilisant la méthode get.
Voici une proposition de solution.
def histogram(s):
"""Renvoie le dictionnaire des lettres dans s
avec leur fréquence."""
d = {}
for c in s:
d[c] = [Link](c,0) + 1
return d
Problème
Supposons que nous voulons écrire une fonction get_keys(d, value) qui reçoit une valeur value et un dictionnaire d, et
qui renvoie la liste des clés d’une valeur du dictionnaire donné.
Une idée est de parcourir le dictionnaire et rajouter à une liste les clés correspondant aux éléments ayant la bonne valeur. Notons
que les clés d’un dictionnaire sont uniques, mais il peut y avoir une même valeur pour différentes clés.
Un code possible pour la fonction, et un code de test associé sont donnés ici :
def get_keys(d, value):
"""Renvoie la liste des clés de d ayant la valeur value."""
t = []
for k in d:
if d[k] == value:
[Link](k)
return t
d = histogram('evenement')
(suite sur la page suivante)
DICTIONNAIRE INVERSÉ
Problème
Il est fréquent de vouloir inverser un dictionnaire. Par exemple ayant un dictionnaire amis, dont chaque clé est un prénom de
personne, et la valeur associée, la liste de ses amis, on pourrait vouloir le dictionnaire avec les personnes comme clés, et comme
valeurs associées la liste des personnes qui le connaissent. Ici prenons un exemple plus simple.
Problème plus simple
La fonction histogram est pratique mais nous pourrions avoir besoin d’obtenir ces informations de manière inversée.
Exemple : Au lieu de :
qui montre que la liste des lettres présentes une seule fois dans le texte est ['m', 't', 'v'], . . .
Le problème est donc de savoir comment inverser les clés et les valeurs d’un dictionnaire.
L’idée est de créer un nouveau dictionnaire qui contiendra des listes. Pour chaque valeur du dictionnaire de départ, nous ajoutons
une paire dans le nouveau dictionnaire si celle-ci n’est pas présente, sinon, nous mettons à jour la paire.
Un code possible pour la fonction, et un code de test associé sont donnés ici :
def invert_dict(d):
"""Renvoie le dictionnaire inversé de d."""
inv = {}
for k in d:
val = d[k]
if val not in inv:
inv[val] = [k]
else:
inv[val].append(k)
return inv
d = histogram('evenement')
inv_d = invert_dict(d)
print(inv_d) # imprime {1: ['m', 't', 'v'], 2: ['n'], 4: ['e']}
Énoncé
Écrire une fonction store_email(liste_mails) qui reçoit en paramètre une liste d’adresses e-mail et qui renvoie un dic-
tionnaire avec comme clés les domaines des adresses e-mail et comme valeurs les listes d’utilisateurs correspondantes, triées par
ordre croissant (UTF-8).
Exemple
store_email(["ludo@[Link]", "[Link]@[Link]",
"thierry@[Link]", "sébastien@[Link]",
"[Link]@[Link]", "bernard@[Link]",
"jean@[Link]" ])
retourne le dictionnaire :
Consignes
Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter que la
définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier aucun appel
ni à la fonction demandée ni aux fonctions input et print.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Si rien ne marche : consultez la FAQ sur UpyLaB 6.8.
Énoncé
Écrire une fonction compteur_lettres(texte) qui renvoie un dictionnaire contenant toutes les lettres de l’alphabet asso-
ciées à leur nombre d’apparition dans texte.
Exemple
retourne :
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Les clés du dictionnaire seront les lettres de l’alphabet en minuscule. Si le texte contient des majuscules, celles-ci seront
comptabilisées comme la lettre minuscule correspondante.
— Le texte passé en paramètre ne comportera aucun caractère accentué.
— Les espaces et autres caractères de ponctuation doivent être ignorés.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Si rien ne marche : consultez la FAQ sur UpyLaB 6.9.
Énoncé
Écrire une fonction valeurs(dico) qui doit fournir, à partir du dictionnaire donné en paramètre, une liste des valeurs du
dictionnaire triées selon leur clé.
Exemple
retourne :
En effet, les clés correspondantes sont “one” < “three” < “two” (ordre UTF-8).
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Vous pourrez supposer que les clés du dictionnaire sont des chaînes de caractères.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— La méthode sort pourra être appliquée à la liste de clés.
— Si rien ne marche : consultez la FAQ sur UpyLaB 6.10.
QUIZ DE SYNTHESE
Supposons comme dans le dernier quiz que l’on désire tester différentes fonctions avec les mêmes arguments en nombre et valeurs,
Python permet d’itérer sur une séquence de fonctions comme montré dans l’exemple qui suit :
où les différentes fonctions anagramme_xxx ont toutes été définies avant. À chaque itération f référence une des fonctions de la
séquence. Notez l’utilisation de l’attribut __name__ pour imprimer le nom de la fonction utilisée à chaque itération.
EXERCICES DIVERS
Nous arrivons doucement à la fin de ce cours en ligne. Les exercices UpyLaB suivants peuvent parfois manipuler des dictionnaires
parfois des ensembles, listes ou autres structures de données. C’est l’occasion pour vous de vous entraîner en récapitulant les
matières vues jusqu’ici dans l’ensemble des modules du cours.
Énoncé
Le Petit Prince a peur des baobabs qui, en poussant, pourraient abîmer sa minuscule planète. Par contre, il adore les arbres à fleurs
que Monsieur Jardinier lui montre.
Touché par son enthousiasme, Monsieur Jardinier lui offre 1 000 graines de ces arbres à fleurs, mais maintenant, le Petit Prince doit
trouver une planète suffisamment grande pour les accueillir, sachant que chacun de ces arbres nécessite une surface de 50 m2 pour
se développer sereinement.
Écrire une fonction booléenne bonne_planete(diametre) qui reçoit en paramètre un nombre représentant le diamètre, en
mètres, d’une planète candidate. La fonction retourne la valeur True ou False selon la planète convient ou non.
Écrire ensuite un programme qui lit un diamètre depuis l’entrée et affiche
— la chaîne de caractères "Bonne planète" si le résultat de l’appel à la fonction bonne_planete est True
— la chaîne de caractères "Trop petite" sinon.
Exemple 1
bonne_planete(500)
retourne :
"Bonne planète"
Exemple 2
bonne_planete(100)
retourne :
"Trop petite"
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Nous rappelons que l’aire d’une sphère, solide auquel est assimilée une planète pour les besoins de l’exercice, s’obtient par
le calcul 𝜋𝑑2 où 𝑑 désigne le diamètre de la sphère.
Énoncé
Écrire une fonction belongs_to_file(word, filename) qui reçoit deux chaînes de caractères en paramètre. La première
correspond à un mot, et la deuxième au nom d’un fichier contenant une liste de mots, chacun sur sa propre ligne. La fonction vérifie
si le mot figure dans cette liste, et retourne True si c’est bien le cas, False sinon.
Exemple
L’appel de la fonction suivant, où [Link] est le fichier indiqué dans les consignes ci-dessous et en supposant qu’il se trouve
dans le même répertoire que le programme :
belongs_to_file("renard", "[Link]")
retourne :
False
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Vous pourrez supposer que le fichier passé en paramètre contient bien une liste de mots, chacun sur sa propre ligne.
— N’oubliez pas d’ouvrir le fichier dans le code de la fonction.
— Le fichier utilisé par UpyLaB pour effectuer les tests est disponible à l’adresse [Link]
data/[Link].
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— N’oubliez pas d’ôter le caractère de fin de ligne lorsque vous voulez comparer les deux chaînes de caractères.
— Si rien ne marche : consultez la FAQ sur UpyLaB 6.12.
Énoncé
Voici le début d’une suite logique inventée par John Horton Conway (et connue donc sous le nom de suite de Conway).
1
1 1
2 1
1 2 1 1
1 1 1 2 2 1
3 1 2 2 1 1
...
— la quatrième ligne décrit la troisième ligne, où l’on voit un “2” et un “1”, d’où 1 2 1 1 ;
— et ainsi de suite.
Écrire une fonction next_line(line) qui reçoit une liste d’entiers, et qui retourne la liste correspondant à la ligne suivante.
Notez que les valeurs de la liste reçue sont toujours entières, mais cette dernière peut ne pas correspondre à une suite de Conway
(par exemple [4,2] pourrait être donné).
Exemple 1
next_line([1, 2, 1, 1])
doit retourner :
[1, 1, 1, 2, 2, 1]
Exemple 2
next_line([1])
doit retourner :
[1, 1]
Exemple 3
next_line([])
doit retourner :
[1]
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Notez que l’appel next_line([]) sur la liste vide retourne par convention la liste [1].
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Il n’est demandé ici que de définir la fonction. Mais pour tester son fonctionnement dans votre IDE, pensez à ajouter du code
qui l’appelle et teste son résultat, sur plusieurs valeurs, comme print(next_line([1, 2, 1, 1])) par exemple.
N’hésitez pas à tester votre fonction sur les cas « limites » comme la liste vide, [], ou la liste singleton [1], en vous référant aux
exemples donnés.
— Si rien ne marche : consultez la FAQ sur UpyLaB 6.13.
Énoncé
Exemple 1
doit retourner :
Exemple 2
doit retourner :
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Vous pourrez supposer que les arguments passés à la fonction seront valides.
— Il n’est pas demandé de vérifier si la grille contient un alignement gagnant.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Si rien ne marche : consultez la FAQ sur UpyLaB 6.14.
Énoncé
Cette fonction renverra 'R' si le joueur à la couleur rouge a gagné, 'J' si le joueur à la couleur jaune a gagné ou bien None si
aucun joueur n’a gagné.
Exemple 1
doit retourner :
'J'
Exemple 2
doit retourner :
None
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Vous pourrez supposer que la matrice passée à la fonction est valide, et qu’il n’y a pas à la fois une configuration gagnante
pour chacune des couleurs.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Si rien ne marche : consultez la FAQ sur UpyLaB 6.15.
Énoncé
— Écrire une fonction file_histogram(fileName) qui prend en paramètre le nom, sous forme d’une chaîne de ca-
ractères, d’un fichier texte, et qui renvoie un dictionnaire associant à chaque caractère du texte contenu dans ce fichier son
nombre d’occurrences.
— Écrire une fonction words_by_length(fileName) qui prend en paramètre le nom, sous forme d’une chaîne de
caractères, d’un fichier texte, et qui renvoie un dictionnaire associant à une longueur l la liste triée (dans l’ordre utf-8
croissant) des mots de longueur l présents dans le texte contenu dans le fichier. Ces mots seront écrits en minuscules.
Exemple 1
file_histogram('/pub/data/[Link]')
Exemple 2
words_by_length('/pub/data/[Link]')
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Les fichiers utilisés par UpyLaB pour tester votre code sont :
— [Link]
— [Link]
— [Link]
— Pour la fonction words_by_length, on supposera qu’un mot est une séquence de caractères alphabétiques. La méthode
isalpha() pourra être utile.
Par exemple, la chaîne de caractères 'cat4dog' sera considérée comme formant deux mots : 'cat' et 'dog'.
Veillez aussi à ce qu’un même mot n’apparaisse pas plusieurs fois dans la même liste.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Vérifiez que vos fonctions répondent bien à toutes les contraintes de l’énoncé.
— Veillez à ne pas faire trop de passages sur le contenu du fichier, qui peut être de taille conséquente. Sinon, UpyLaB pourrait
stopper l’exécution de votre code qu’il trouve trop longue.
— Si rien ne marche : consultez la FAQ sur UpyLaB 6.16.
6.5.8 Exercice UpyLaB 6.17 (y compris 6.17a, 6.17b et 6.17c) (Parcours Bleu et Rouge)
Notez que cet exercice est découpé en quatre : l’exercice complet et 3 parties (UpyLaB 6.17a, 6.17b, 6.17c, 6.17). Chacun des 4
exercices est comptabilisé pour 1 point (soit 4 points au total).
Énoncé
Le sudoku est un jeu de logique dans lequel le joueur reçoit une grille de 9 x 9 cases, chacune pouvant contenir un chiffre de 1 à
9 ou bien être vide. La grille est divisée en 9 lignes, 9 colonnes ainsi qu’en 9 « sous-grilles », appelées régions, formées de 3 x 3
boîtes contiguës. Le but du jeu est de remplir les cases vides avec des chiffres de 1 à 9, de telle sorte que, dans chaque ligne, chaque
colonne et chaque région, soient présents tous les chiffres de 1 à 9, sans doublons.
Écrire une fonction check_sudoku capable de vérifier si la grille passée en paramètre, sous forme d’une matrice 9 x 9 d’entiers,
est une solution au problème du sudoku. La fonction retournera la réponse (True ou False).
Cette fonction devra utiliser les trois fonctions suivantes (que vous devez aussi définir) :
— check_rows qui prend en paramètre une grille sous forme de matrice à deux dimensions et vérifie si toutes les lignes sont
valides (c’est-à-dire que sur chaque ligne, chaque chiffre apparaît une et une seule fois).
— check_cols qui prend en paramètre une grille sous forme de matrice à deux dimensions et vérifie si toutes les colonnes
sont valides (c’est-à-dire que sur chaque colonne, chaque chiffre apparaît une et une seule fois).
— check_regions qui prend en paramètre une grille sous forme de matrice à deux dimensions et vérifie si toutes les régions
sont valides (c’est-à-dire que dans chaque région, chaque chiffre apparaît une et une seule fois).
Exemple 1
check_sudoku([[9, 6, 3, 1, 7, 4, 2, 5, 8],
[1, 7, 8, 3, 2, 5, 6, 4, 9],
[2, 5, 4, 6, 8, 9, 7, 3, 1],
[8, 2, 1, 4, 3, 7, 5, 9, 6],
[4, 9, 6, 8, 5, 2, 3, 1, 7],
[7, 3, 5, 9, 6, 1, 8, 2, 4],
[5, 8, 9, 7, 1, 3, 4, 6, 2],
[3, 1, 7, 2, 4, 6, 9, 8, 5],
[6, 4, 2, 5, 9, 8, 1, 7, 3]])
retourne :
True
Exemple 2
check_sudoku([[1, 2, 3, 4, 5, 6, 7, 8, 9],
[2, 3, 4, 5, 6, 7, 8, 9, 1],
[3, 4, 5, 6, 7, 8, 9, 1, 2],
[4, 5, 6, 7, 8, 9, 1, 2, 3],
[5, 6, 7, 8, 9, 1, 2, 3, 4],
[6, 7, 8, 9, 1, 2, 3, 4, 5],
[7, 8, 9, 1, 2, 3, 4, 5, 6],
[8, 9, 1, 2, 3, 4, 5, 6, 7],
[9, 1, 2, 3, 4, 5, 6, 7, 8]])
retourne :
False
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Vous pourrez supposer que la grille passée en paramètre est valide.
— Aucune des fonctions ne doit modifier la grille passée en paramètre.
— Pour vous aider, nous vous proposons trois exercices intermédiaires, qui vont vous permettre d’écrire et de tester les trois
fonctions auxiliaires, avant de les utiliser ici.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Si rien ne marche : consultez la FAQ sur UpyLaB 6.17.
Énoncé
Le sudoku est un jeu de logique dans lequel le joueur reçoit une grille de 9 x 9 cases, chacune pouvant contenir un chiffre de 1 à
9 ou bien être vide. La grille est divisée en 9 lignes, 9 colonnes ainsi qu’en 9 « sous-grilles », appelées régions, formées de 3 x 3
boîtes contiguës. Le but du jeu est de remplir les cases vides avec des chiffres de 1 à 9, de telle sorte que, dans chaque ligne, chaque
colonne et chaque région, soient présents tous les chiffres de 1 à 9, sans doublons.
Écrire une fonction check_rows(grid) qui prend en paramètre une grille sous forme de matrice à deux dimensions et vérifie
si toutes les lignes sont valides (c’est-à-dire que sur chaque ligne, chaque chiffre apparaît une et une seule fois).
Exemple 1
check_rows([[9, 6, 3, 1, 7, 4, 2, 5, 8],
[1, 7, 8, 3, 2, 5, 6, 4, 9],
[2, 5, 4, 6, 8, 9, 7, 3, 1],
[8, 2, 1, 4, 3, 7, 5, 9, 6],
[4, 9, 6, 8, 5, 2, 3, 1, 7],
[7, 3, 5, 9, 6, 1, 8, 2, 4],
[5, 8, 9, 7, 1, 3, 4, 6, 2],
[3, 1, 7, 2, 4, 6, 9, 8, 5],
[6, 4, 2, 5, 9, 8, 1, 7, 3]])
retourne :
True
Exemple 2
check_rows([[9, 6, 3, 1, 7, 4, 2, 5, 8],
[1, 7, 8, 3, 2, 5, 6, 4, 9],
[2, 5, 4, 6, 8, 9, 7, 3, 1],
[8, 2, 1, 4, 3, 7, 5, 9, 6],
[4, 9, 6, 8, 4, 2, 3, 1, 7],
[7, 3, 5, 9, 6, 1, 8, 2, 4],
[5, 8, 9, 7, 1, 3, 4, 6, 2],
[3, 1, 7, 2, 4, 6, 9, 8, 5],
[6, 4, 2, 5, 9, 8, 1, 7, 3]])
retourne :
False
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Vous pourrez supposer que la grille passée en paramètre est valide.
— La fonction ne doit pas modifier la grille passée en paramètre.
Énoncé
Le sudoku est un jeu de logique dans lequel le joueur reçoit une grille de 9 x 9 cases, chacune pouvant contenir un chiffre de 1 à
9 ou bien être vide. La grille est divisée en 9 lignes, 9 colonnes ainsi qu’en 9 « sous-grilles », appelées régions, formées de 3 x 3
boîtes contiguës. Le but du jeu est de remplir les cases vides avec des chiffres de 1 à 9, de telle sorte que, dans chaque ligne, chaque
colonne et chaque région, soient présents tous les chiffres de 1 à 9, sans doublons.
Écrire une fonction check_cols qui prend en paramètre une grille sous forme de matrice à deux dimensions et vérifie si toutes
les colonnes sont valides (c’est-à-dire que sur chaque colonne, chaque chiffre apparaît une et une seule fois).
Exemple 1
check_cols([[9, 6, 3, 1, 7, 4, 2, 5, 8],
[1, 7, 8, 3, 2, 5, 6, 4, 9],
[2, 5, 4, 6, 8, 9, 7, 3, 1],
[8, 2, 1, 4, 3, 7, 5, 9, 6],
[4, 9, 6, 8, 5, 2, 3, 1, 7],
[7, 3, 5, 9, 6, 1, 8, 2, 4],
[5, 8, 9, 7, 1, 3, 4, 6, 2],
[3, 1, 7, 2, 4, 6, 9, 8, 5],
[6, 4, 2, 5, 9, 8, 1, 7, 3]])
retourne :
True
Exemple 2
check_cols([[1, 2, 3, 4, 5, 6, 7, 8, 9],
[2, 3, 4, 5, 6, 7, 8, 9, 1],
[3, 4, 5, 6, 7, 8, 9, 1, 2],
[4, 5, 6, 7, 8, 9, 1, 2, 3],
[5, 6, 7, 8, 9, 1, 2, 3, 4],
[6, 7, 8, 9, 1, 2, 3, 4, 5],
[7, 8, 5, 1, 2, 3, 4, 9, 6],
[8, 9, 1, 2, 3, 4, 5, 6, 7],
[9, 1, 2, 3, 4, 5, 6, 7, 8]])
retourne :
False
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Vous pourrez supposer que la grille passée en paramètre est valide.
Énoncé
Énoncé
Le sudoku est un jeu de logique dans lequel le joueur reçoit une grille de 9 x 9 cases, chacune pouvant contenir un chiffre de 1 à
9 ou bien être vide. La grille est divisée en 9 lignes, 9 colonnes ainsi qu’en 9 « sous-grilles », appelées régions, formées de 3 x 3
boîtes contiguës. Le but du jeu est de remplir les cases vides avec des chiffres de 1 à 9, de telle sorte que, dans chaque ligne, chaque
colonne et chaque région, soient présents tous les chiffres de 1 à 9, sans doublons.
Écrire une fonction check_regions qui prend en paramètre une grille sous forme de matrice à deux dimensions et vérifie si
toutes les régions sont valides (c’est-à-dire que dans chaque région, chaque chiffre apparaît une et une seule fois).
Exemple 1
check_regions([[9, 6, 3, 1, 7, 4, 2, 5, 8],
[1, 7, 8, 3, 2, 5, 6, 4, 9],
[2, 5, 4, 6, 8, 9, 7, 3, 1],
[8, 2, 1, 4, 3, 7, 5, 9, 6],
[4, 9, 6, 8, 5, 2, 3, 1, 7],
[7, 3, 5, 9, 6, 1, 8, 2, 4],
[5, 8, 9, 7, 1, 3, 4, 6, 2],
[3, 1, 7, 2, 4, 6, 9, 8, 5],
[6, 4, 2, 5, 9, 8, 1, 7, 3]])
retourne :
True
Exemple 2
check_regions([[1, 2, 3, 4, 5, 6, 7, 8, 9],
[2, 3, 4, 5, 6, 7, 8, 9, 1],
[3, 4, 5, 6, 7, 8, 9, 1, 2],
[4, 5, 6, 7, 8, 9, 1, 2, 3],
[5, 6, 7, 8, 9, 1, 2, 3, 4],
[6, 7, 8, 9, 1, 2, 3, 4, 5],
[7, 8, 9, 1, 2, 3, 4, 5, 6],
[8, 9, 1, 2, 3, 4, 5, 6, 7],
[9, 1, 2, 3, 4, 5, 6, 7, 8]])
retourne :
False
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Vous pourrez supposer que la grille passée en paramètre est valide.
— La fonction ne doit pas modifier la grille passée en paramètre.
Énoncé
Le sudoku est un jeu de logique dans lequel le joueur reçoit une grille de 9 x 9 cases, chacune pouvant contenir un chiffre de 1 à
9 ou bien être vide. La grille est divisée en 9 lignes, 9 colonnes ainsi qu’en 9 « sous-grilles », appelées régions, formées de 3 x 3
boîtes contiguës. Le but du jeu est de remplir les cases vides avec des chiffres de 1 à 9, de telle sorte que, dans chaque ligne, chaque
colonne et chaque région, soient présents tous les chiffres de 1 à 9, sans doublons.
Une méthode de résolution passe par l’analyse des candidats uniques. Ce qu’on appelle candidat est un nombre permis pour une
case car on ne le retrouve pas ailleurs dans la ligne, la colonne et la région de cette case.
Si une grille est telle que chaque case vide se retrouve avec un candidat unique, alors la résolution du sudoku est évidente.
Des deux grilles suivantes, seule la première peut être résolue de cette manière : par exemple, en indiçant le tableau à partir de
0, (0,0) étant en haut à gauche, à la case d’indice (4,7), seule la valeur 3 est possible. On peut ensuite faire de même jusqu’à la
résolution complète du sudoku.
Écrire une fonction naked_single(grid) qui reçoit en paramètre une matrice 9 x 9 d’entiers représentant une grille de
sudoku, et qui renvoie un couple de valeurs :
— un booléen ok qui indique si la grille peut être résolue en utilisant cette seule méthode du candidat unique,
— la grille complétée si ok est égal à True, None sinon.
Exemple 1
naked_single([[4, 0, 3, 0, 9, 6, 0, 1, 0],
[0, 0, 2, 8, 0, 1, 0, 0, 3],
[0, 1, 0, 0, 0, 0, 0, 0, 7],
[0, 4, 0, 7, 0, 0, 0, 2, 6],
[5, 0, 7, 0, 1, 0, 4, 0, 9],
[1, 2, 0, 0, 0, 3, 0, 8, 0],
[2, 0, 0, 0, 0, 0, 0, 7, 0],
[7, 0, 0, 2, 0, 9, 8, 0, 0],
[0, 6, 0, 1, 5, 0, 3, 0, 2]])
retourne :
Exemple 2
naked_single([[0, 0, 6, 0, 4, 0, 1, 0, 0],
[0, 5, 0, 0, 9, 0, 0, 6, 0],
[8, 0, 0, 0, 0, 0, 0, 0, 5],
[0, 0, 0, 3, 0, 4, 0, 0, 0],
[3, 1, 0, 0, 0, 0, 0, 4, 8],
[0, 0, 0, 8, 0, 7, 0, 0, 0],
[6, 0, 0, 0, 0, 0, 0, 0, 9],
[0, 2, 0, 0, 3, 0, 0, 5, 0],
[0, 0, 1, 0, 5, 0, 7, 0, 0]])
retourne :
(False, None)
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Dans la grille passée en paramètre, les cases vides sont représentées par l’entier 0.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— N’hésitez pas à définir vos propres fonctions annexes.
— Si rien ne marche : consultez la FAQ sur UpyLaB 6.18.
Énoncé
Un dictionnaire peut nous permettre de manipuler des tableaux partiellement remplis, en ne stockant que les cases non vides et en
leur associant leur valeur.
Par exemple, le tableau suivant
MY_PRECIOUS = 1
TRAP = -1
my_map = {}
my_map[(2,2)] = MY_PRECIOUS
my_map[(3,4)] = TRAP
my_map[(5,6)] = TRAP
my_map[(2,4)] = TRAP
my_map[(4,3)] = TRAP
Exemple 1
create_map(4, 5)
pourrait retourner :
Exemple 2
play_game(5, {(3, 4): -1, (4, 1): 1, (2, 3): -1, (1, 5): -1})
"4 2 4 4 1 3 4 4 3 1 4 4 4 3 1 1 3 1 3 2 2 1 4 3 1 2 4 1 "
retourne :
True
Exemple 3
play_game(5, {(3, 4): -1, (4, 1): 1, (2, 3): -1, (1, 5): -1})
"4 7 4 3 a 5 2 3"
retourne :
False
Consignes
— Pour cet exercice, il vous est demandé d’écrire une fonction. Le code que vous soumettrez à UpyLaB ne doit donc comporter
que la définition de cette fonction, accompagnée éventuellement de définitions de fonctions annexes, et ne fait en particulier
aucun appel ni à la fonction demandée ni aux fonctions input et print.
— Notez que la numérotation des cases de la carte commence à (1, 1).
— Pour la fonction create_map, pensez à utiliser le module random, et le dictionnaire retourné ne comportera que les cases
occupées.
— Pour la fonction play_game, les coordonnées saisies par l’utilisateur seront données sous la forme d’une série de deux
entiers séparés par une espace, une case par ligne.
— Pour la fonction play_game, si les valeurs saisies par le joueur ne sont pas du bon type (entières) , ni dans le bon intervalle
(comprises entre 1 et map_size), ces saisies seront ignorées par le programme.
— Notez enfin que les deux fonctions sont séparées et indépendantes l’une de l’autre.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Le dictionnaire généré par la fonction create_map ne doit comporter que les cases occupées soit par un piège, soit par le
trésor. Les cases vides ne figurent pas dans le dictionnaire.
— Si rien ne marche : consultez la FAQ sur UpyLaB 6.19.
Énoncé
Arthur nous a envoyé des statistiques produites par UpyLaB contenant des informations sur des exercices et sur des apprenants.
Nous souhaitons utiliser ces informations pour classer les exercices.
Chaque jeu de données est formé de deux fichiers de type csv (produit par un tableur du type Excel ou LibreOffice) :
— un fichier '[Link]'
— un fichier '[Link]'
La structure d’un fichier “[Link]”
est la suivante :
En première ligne, nous trouvons les intitulés des exercices, chacun séparé du suivant par un caractère point-virgule “ ;”.
Chacune des lignes suivantes correspond aux résultats d’un apprenant : chaque ligne a le même nombre d’éléments que le nombre
d’intitulés, et chaque élément vaut soit le texte 'VRAI', soit le texte 'FAUX', soit est vide (respectivement suivant que l’apprenant
a validé tous les tests UpyLaB pour l’exercice correspondant, a demandé la validation par UpyLaB, mais malheureusement ce
dernier a répondu par la négative, ou n’a pas encore testé l’exercice dans UpyLaB). À nouveau sur une même ligne, chaque valeur
est séparée de la suivante par un caractère point-virgule “ ;”.
La structure du fichier “[Link]”
est similaire à celle du premier fichier, à la différence près que les textes “VRAI” ou “FAUX” sont remplacés par des nombres
naturels strictement positifs donnant le nombre de fois où l’apprenant a testé son code. À nouveau l’entrée est vide si aucune
validation n’a été demandée par l’apprenant.
De façon précise, la structure d’un fichier '[Link]' est la suivante :
En première ligne, nous trouvons les intitulés des exercices, chacun séparé du suivant par un caractère point-virgule “ ;”.
Chacune des lignes suivantes correspond aux résultats d’un apprenant : chaque ligne a le même nombre d’éléments que le nombre
d’intitulés, et chaque élément représente soit un nombre entier strictement positif, soit est vide (respectivement suivant que l’appre-
nant a validé ou essayé de valider les tests UpyLaB pour l’exercice correspondant ou n’a pas encore testé l’exercice dans UpyLaB).
À nouveau sur une même ligne, chaque valeur est séparée de la suivante par un caractère point-virgule “ ;”.
Écrire un programme qui lit depuis l’entrée deux chaînes de caractères, représentant les noms des deux fichiers décrits ci-dessus
(dans l’ordre, le fichier de type “[Link]” suivi du fichier du type “[Link]”), et qui imprime la liste des intitulés,
un par ligne, dans l’ordre décroissant des « valeurs » calculées comme suit.
La « valeur » d’un intitulé est le nombre des « apprenants fiables » ayant réussi l’exercice correspondant.
Un « apprenant fiable » est un apprenant qui n’a jamais testé plus de dix fois chacun des codes qu’il a essayé de valider.
Par exemple, si un apprenant n’a testé que trois exercices en soumettant respectivement 1, 2 et 10 essais, il est réputé « fiable ».
Si un autre apprenant a testé tous les exercices, mais en soumettant 11 essais pour l’un d’entre eux, il n’est pas considéré comme
« fiable ».
Exemple
ex1;ex2;ex3
VRAI;VRAI;VRAI
VRAI;VRAI;VRAI
VRAI;FAUX;FAUX
VRAI;VRAI;VRAI
VRAI;VRAI;
FAUX;VRAI;VRAI
ex1;ex2;ex3
2;3;5
1;2;4
4;2;666
11;6;3
1;1;
7;7;7
le programme affiche :
ex2
ex3
ex1
En effet, les apprenants 3 et 4 ne sont pas fiables. Ainsi, la valeur de ex2 est égale à 4 ; ex1 et ex3 ont tous les deux une valeur égale
à 3 mais ex3 est supérieur à ex1 dans l’ordre utf-8.
Consignes
— Notez que dans cet exercice, il vous est demandé d’écrire un programme qui fera appel aux fonctions input et print.
— Nous rappelons que votre code sera évalué en fonction de ce qu’il affiche, donc veillez à n’imprimer que le résultat attendu.
En particulier, il ne faut rien écrire à l’intérieur des appels à input (input()) et non input("Entrer un nom de
fichier : ") par exemple), ni ajouter du texte supplémentaire dans ce qui est imprimé (print(intitules) et non
print("liste des intitulés :",intitules) par exemple).
— Les fichiers utilisés par UpyLaB pour tester votre code sont :
— [Link]
— [Link]
— [Link]
— [Link]
— En cas d’égalité, les exercices seront classés selon l’ordre décroissant UTF-8 de leurs intitulés.
— Nous vous conseillons de définir des fonctions annexes que votre programme appellera.
— Le nombre maximal d’essais pour être supposé « apprenant fiable », 10 ici, peut être vu comme une constante globale du
programme.
Remarque
Cet exercice vous demande de lire des fichiers csv. Cela peut se faire bien entendu avec ce qui a été vu jusque là dans ce cours, mais
vous pouvez aussi consulter la section 6.6 qui présente les outils spécifiques à la manipulation de ces fichiers csv.
Vous avez du mal pour réaliser l’exercice. Voici quelques conseils qui peuvent vous aider :
Conseils
— Comme pour les premiers programmes que vous avez écrits lors de ce MOOC, UpyLaB va vérifier que ce qu’imprime votre
code correspond exactement à ce qui est attendu. Veillez donc à ne pas ajouter d’espace superflue en fin de ligne, ni de ligne
vide supplémentaire. Veillez aussi à ne pas ajouter de texte lors des appels à la fonction input.
— Si rien ne marche : consultez la FAQ sur UpyLaB 6.20.
Nous avons vu que nous pouvions manipuler des données stockées dans des fichiers texte. Nous pouvons lire des fichiers, récupérer
ces données et les traiter. Nous pouvons aussi écrire dans des fichiers pour sauvegarder de façon pérenne les données de nos
programmes.
La format csv est un format de fichier texte où chaque ligne du fichier contient des données séparées par des virgules. Les lettres
CSV signifient Comma Separated Values. Ci-dessous un exemple de fichier csv contenant les données d’apprenants d’un MOOC :
id,result,attestation
apprenant_1,0.9,1
apprenant_2,0.87,1
apprenant_3,0.43,0
Nous constatons que la première ligne du fichier représente les étiquettes des données et que les lignes suivantes stockent les données
de chacun des apprenants : son identifiant, son résultat et l’obtention de l’attestation.
Les méthodes et les fonctions vues sur les fichiers, les chaînes de caractères et les dictionnaires nous permettraient de créer, à partir
de ces données, les dictionnaires suivants, regroupés dans une liste :
Le format csv est très répandu et les séparateurs peuvent être la virgule bien sûr mais aussi le point-virgule, l’espace, la tabulation
(on parle alors de format tsv) ou tout autre caractère choisi par le programmeur et qui ne doit pas apparaître dans les données.
Pour aller plus loin, un module python nommé csv existe et facilite la lecture d’un fichier de ce format et la création d’une structure
de données adéquate.
CSV CONCRÈTEMENT
Voici un exemple de fonction qui crée la liste des dictionnaires codant les informations de notre fichier. Cette fonction prend en
paramètres un nom de fichier csv et une chaine de caractères représentant le séparateur des données du fichier csv.
Puis, si on considère la deuxième ligne (et donc la première ligne de données), il est important de voir que “identifiant_1” correspond
à l’entête “id”, que 0.9 correspond à “result” et que 1 correspond à “attestation”. C’est via les indices de nos listes que nous faisons
cette correspondance, avec, par exemple l’utilisation de la fonction prédéfinie enumerate.
Le module csv offre un certain nombre de méthodes pour faciliter les choses. Notons notamment la méthode DictReader :
def charger(filename):
with open(filename, 'r', encoding='utf-8') as mon_csvfile:
reader = [Link](mon_csvfile)
return list(reader)
Si nous manipulons des données sous la forme d’une liste de dictionnaires, voici une fonction qui permet de créer un fichier csv
stockant ces données :
La construction de la ligne d’entêtes du fichier permet également de récupérer la liste des entêtes, c’est-à-dire des clés des diction-
naires. Chaque dictionnaire correspond alors à une ligne de données dans notre fichier csv. Attention lors de l’écriture des données,
il faut s’assurer de récupérer les informations dans le même ordre que l’ordre des entêtes. C’est pour cela que nous parcourons les
clés via la liste l_entetes.
Lorsque vos données sont déjà stockées dans un tableur, il est possible d’enregistrer ces données au format csv directement depuis
votre application de tableur.
Une autre possibilité est d’utiliser le format JSON et le module python associé. Le format JSON est également un format texte
de fichier qui permet de stocker une structure de données, liste ou dictionnaire. JSON signifie JavaScript Object Notation. Il per-
met l’échange de données entre programmes et un module traitant de ce format est disponible dans la plupart des langages de
programmation.
En reprenant l’exemple de nos apprenants, voici un fichier JSON contenant notre liste :
En Python, le module json va nous permettre de lire un fichier pour y récupérer la structure stockée et d’écrire un fichier pour y
stocker une structure (liste ou dictionnaire).
Dès lors la méthode load du module json permet de récupérer les données :
import json
[{'id': 'apprenant_1', 'result': 0.9, 'attestation': 1}, {'id': 'apprenant_2', 'result': 0.87,
˓→'attestation': 1}, {'id': 'apprenant_3', 'result': 0.43, 'attestation': 0}]
Le code Python pour récupérer la donnée serait le même. La différence est que la structure sera un dictionnaire :
import json
La méthode pour écrire un fichier json est dump. Voici l’utilisation basique de cette méthode. On suppose qu’un dictionnaire est
stocké dans une variable mon_dict.
import json
Dès lors, le fichier texte [Link] sera créé et contiendra une unique ligne :
Un paramètre optionnel nommé indent permet de présenter les données dans le fichier avec des indentations, sur plusieurs lignes
pour une meilleure lisibilité :
import json
{
"apprenant_1": {
"result": 0.9,
"attestation": 1
},
"apprenant_2": {
"result": 0.87,
"attestation": 1
},
"apprenant_3": {
"result": 0.43,
"attestation": 0
}
}
6.7.1 Qu’avons-nous vu ?
ERRATUM
Depuis le session 3 de ce MOOC, la présentation du module shelve a été remplacée par celle du module json
BILAN DU MODULE
Dans ce module, nous vous avons présenté deux types de séquences Python : les ensembles (set) et les dictionnaires (dict).
Un ensemble s :
— est créé en donnant ses éléments entre accolades {e1, e2, ...} ou avec la fonction set(s) où s est une séquence
d’éléments ;
— set() crée un ensemble vide ;
— les propriétés mathématiques des ensembles s’appliquent, les doublons sont supprimés ;
— len(s) donne le nombre d’éléments de l’ensemble s ;
— ayant deux ensembles a et b, les opérateurs suivants existent
— a | b (union),
— a & b (intersection),
— a - b (différence),
— a ^ b (différence symétrique),
la différence symétrique prend les éléments dans un des deux ensembles mais pas dans l’autre ;
— la préposition in peut également être utilisée comme test d’appartenance ou dans une instruction for pour itérer sur tous
les éléments de l’ensemble ;
— les opérateurs relationnels (==, !=, <, <=, >, >=) correspondent aux opérateurs d’égalité ou non et d’inclusion stricte ou
non dans un sens ou l’autre.
Un dictionnaire d :
— est créé en donnant ses éléments clé : valeur entre accolade {k1:v1, k2:v2, ...} ;
— un dictionnaire vide est créé en mettant deux accolades sans rien à l’intérieur {} ;
— chaque clé d’un dictionnaire identifie un élément et peut être de n’importe quel type non modifiable (une clé ne peut être une
liste ou un ensemble ou un autre dictionnaire). Les valeurs correspondantes peuvent être de n’importe quel type ;
— nous pouvons accéder à une composante de d en écrivant d[key] où key est une valeur de clé ;
— d[cle] = valeur ajoute une composante cle : valeur à d si elle n’existe pas ou modifie la composante cle si elle existe
déjà dans d ;
— nous pouvons utiliser la préposition in pour tester si une clé fait partie de d ou dans un for pour itérer sur toutes les clés
de d ;
— ayant deux dictionnaires d1 et d2, les seuls opérateurs relationnels qui fonctionnent sont l’égalité d1 == d2 et la différence
d1 != d2 ;
— del(d[k]) supprime l’élément de d de clé k.
Nous avons présenté en section 6.2.1 les différentes méthodes permettant de manipuler facilement des dictionnaires :
— [Link]() : supprime tous les éléments de d
— [Link]() : shallow copie de d
— {}.fromkeys(s,v) : crée un dict avec les clés de s et la valeur v
— [Link](k [,v]) : renvoie la valeur d[k] si elle existe, v sinon
— [Link]() : liste des items (k,v) de d
— [Link]() : liste des clés
— [Link](k [,v]) : enlève d[k] s’il existe et renvoie sa valeur ou v sinon
— [Link]() : supprime un item (k,v) et retourne l’item sous forme de tuple
— [Link](k [,v]) : d[k] si elle existe sinon v et rajoute d[k] = v
— [Link](s) : s est une liste de tuples que l’on rajoute à d
— [Link]() : liste des valeurs de d
Pour vous aider à les retenir, toutes ces méthodes et leurs fonctionnalités sont reprises dans l” aide-mémoire à votre disposition.
Nous avons aussi vu qu’il est possible de créer un dictionnaire persistant grâce au module json.
Nous avons illustré tous ces concepts avec des exemples et la réalisation d’exercices supervisés ou réalisés de façon autonome avec
UpyLaB.
6.7.2 Et maintenant ?
Il se peut que l’un ou l’autre des exercices UpyLaB que nous vous avons proposés dans nos différents modules de ce cours en ligne
ne soit pas terminé. Il se peut aussi que vos ayez choisi le parcours bleu ou rouge et que vous ayez maintenant envie d’en faire plus.
En tout les cas, n’oubliez pas l’adage
C’est en forgeant qu’on devient forgeron
mais suivez aussi les conseils de Nicolas Boileau dans L’art poétique :
Maintenant, si ce n’est déjà fait, terminez tous les exercices UpyLaB que nous vous avons proposés tout au long de ce cours ; ceci
afin d’intégrer toute la matière vue dans ce cours en ligne !
Bon travail !
Outre le projet je vous voudrez sans doute réaliser, si ce n’est déjà fait, et qui vous permet de faire la synthèse de la plupart des
matières vues, nous voici à la fin de ce MOOC. Que de chemin parcouru depuis le début. Nous espérons qu’il vous a plu. Vous y
avez réellement appris et acquis une multitude de connaissances et de compétences. Voici ce qui nous vient à l’esprit au premier
abord, mais nous sommes persuadés que vous en avez d’autres en tête :
En terme de connaissances
— Python 3 est un langage interprété dont l’apprentissage permet rapidement de réaliser énormément de types de traitements
possibles ;
— un code Python manipule des valeurs et variables de différents types (entier, fractionnaire, booléen, séquence de caractères,
séquence de valeurs d’autres types, dictionnaire, ensemble,. . . ) ;
— un petit nombre d’instructions différentes permet de réaliser des calculs et traitements divers ;
— des fonctions et méthodes prédéfinies, importées de modules préexistants ou définies dans le programme permettent de
structurer le code et de rapidement réaliser les traitements désirés ;
— des fichiers textes peuvent être facilement lus ou créés par un programme Python.
En terme de compétences
— Nous avons également illustré tous ces concepts avec de nombreux exemples et la réalisation d’exercices supervisés ou
réalisés avec notre outil UpyLaB ; ceci afin de vous rendre autonome pour résoudre de nouveaux problèmes de traitement de
l’information. Vous avez donc acquis une connaissance active de la matière qui vous permet cette autonomie.
— Nous avons également pris le temps de comprendre les mécanismes, par exemple grâce aux diagrammes d’états et l’outil
Python Tutor qui permettent de voir exactement ce qui se passe à chaque étape de l’exécution du programme.
— Nous avons aussi donné de nombreux exemples pour montrer une palette de problèmes qui peuvent être traités grâce à la
programmation en général et Python en particulier.
Vous avez dès à présent les connaissances pour écrire de nombreux scripts et résoudre des problèmes. Réfléchissez à un problème
qui vous tient à coeur et voyez comment le résoudre avec un programme informatique. Lancez-vous ! Vous verrez qu’avec votre
bagage actuel vous pourrez déjà envisager de nombreux problèmes.
Parfois vous aurez l’impression qu’il vous manque des outils ou que vous êtes en train de réinventer la roue. Et vous aurez proba-
blement raison. Vous pouvez approfondir vos connaissances en algorithmique ainsi que sur des modules externes existants et offrant
une panoplie d’outils supplémentaires optimisés.
Approfondir ses connaissances en algorithmique
Lors de la résolution d’un vrai problème, bien souvent la solution va passer par l’utilisation d’une méthode connue d’où l’idée
d’aller explorer ces algorithmes.
De nombreux cours traitent de diverses techniques algorithmiques existentes :
— La récursivité et ses applications
— Les algorithmes de jeux
— La théorie des graphes
— L’apprentissage automatique
— ...
Explorer d’autres modules disponibles en Python
Il existe nombre de petits modules très utiles traitant de choses aussi variées que les arguments sur la ligne de commande, des notions
de dates et d’heures, etc.
D’autres modules beaucoup plus gros, issus de la vaste communauté très active méritent qu’on y consacre plusieurs heures. Citons
par exemple le module numpy pour le calcul numérique, souvent associé à scipy pour le calcul scientifique. Ces modules sont
complétés par matplotlib pour le tracé.
Des modules de parser (analyse de code) vous permettront de compléter efficacement vos connaissances si vous souhaitez traiter
des données récupérées automatiquement sur le web.
Voir d’autres paradigmes de programmation
Ce cours vous a initié à la programmation impérative et vous a donné les bases. Vous pouvez aussi appréhender d’autres paradigmes
de la programmation : la programmation orientée objet est probablement ce qu’il convient de voir juste après. Python est un langage
orienté objet et l’étude des classes est une suite logique à votre premier cours. Vous aurez ainsi l’avantage de rester sur un langage
que vous connaissez déjà tout en vous confrontant au monde des objets de façon simple mais néanmoins efficace.
Si vous souhaitez vous orienter dans la programmation de jeux ou de site web dynamique, la programmation événementielle sera
incontournable.
La programmation Python ou autre peut toucher encore énormément d’autres domaines !
De toute façon, nous espérons que nous vous avons donné l’envie de continuer dans cette matière ou au moins le désir de comprendre
ce qui se passe derrière toutes les applications informatiques que nous utilisons au quotidien dans nos ordinateurs ou nos portables,
et pourquoi pas par exemple commencer à comprendre et à créer grâce à vos programmes de l’intelligence artificielle dont on parle
tant.
Terminons par deux préceptes importants :
Le premier est de Confucius :
– Confucius
On ne voit bien qu’avec le coeur. L’essentiel est invisible pour les yeux.
Votre projet
INFORMATION PRÉLIMINAIRE
Le projet que nous vous proposons dans ce MOOC est évalué via une évaluation entre pairs, suivie d’une auto-évaluation. Contraire-
ment aux autres exercices, la réalisation du projet, si vous décidez de la faire, doit donc être synchronisée avec les autres apprenants
pour permettre à cette évaluation de se dérouler harmonieusement.
Nous avons décidé de vous proposer 2 sessions pour réaliser votre projet. Une session d’automne (voir calendrier), et une session
du printemps. Libre à vous de participer à l’une, l’autre ou même aux deux sessions, sachant que dans ce cas, la note maximale des
deux notes qui vous seront attribuées sera retenue dans l’évaluation finale.
Si vous réalisez le parcours bleu ou le parcours rouge, et désirez participer à la session d’automne pour le projet, il est temps de
réaliser ce dernier.
Ce module donne l’énoncé du projet que nous vous proposons dans le cadre de ce cours en ligne, ainsi que les procédures d’évalua-
tion.
Note : Si vous ne comptez pas faire de projet, nous vous proposons de parcourir quand même cette section ; vous pourrez encore
décider de ne pas faire de projet comme vous aviez prévu ou bien d’en faire une partie ou finalement de le faire soit en session
d’automne ou plus tard à la session du printemps.
Le projet peut être réalisé dès que vous avez vu la matière du cours jusque et y compris la section 6.1, soit les instructions et fonctions
Python, les séquences (chaînes de caractères, tuples et listes) et le début sur les dictionnaires et les ensembles.
CC BY-SA 3.0 - 2021 - Sébastien Hoarau - Thierry Massart - Jean Olgiati - Isabelle Poirier 299
Apprendre à coder avec Python, Version - Release 3.0
Lancelot entre dans le château au sommet du Python des Neiges, muni de son précieux sac de rangement et de sa torche fraîchement
allumée aux feux de Beltane. Il doit trouver la statue de sainte Axerror, le chef-d’oeuvre de Gide de Rome, dit le « tyran malfaisant
éternel ».
Heureusement, pour l’aider dans sa quête, Merlin, son maître, lui a fourni un plan minutieux des salles et des couloirs du château.
Ce plan lui sera fort utile, vu l’énormité du bâtiment, tant par sa taille que par le nombre de ses pièces !
Avant de partir, Merlin lui a donné la clef de la porte d’entrée du château et lui a prodigué moults conseils, dont celui de bien garder
tous les objets qu’il trouvera lors de sa quête : ceux-ci lui permettront de répondre aux diverses énigmes que ne manqueront pas de
poser les gardes postés devant les portes à l’intérieur du château.
Merlin a affirmé à son disciple que, s’il procède avec intelligence, sa quête sera satisfaite.
EN BREF
Ce projet, si vous le menez jusqu’au bout, va vous faire programmer un petit jeu du type jeu d’évasion (escape game) dans lequel le
joueur commande au clavier les déplacements d’un personnage au sein d’un « château » représenté en plan. Le château est constitué
de cases vides (pièces, couloirs), de murs, de portes, que le personnage ne pourra franchir qu’en répondant à des questions, d’objets
à ramasser, qui l’aideront à trouver les réponses à ces questions et de la case de sortie / quête du château. Le but du jeu est d’atteindre
cette dernière.
Le programme utilisera le module turtle comme interface graphique et comportera deux parties principales :
1. le tracé du plan du château,
2. la gestion du jeu sur le plan tracé (gestion des déplacements du personnage au sein du château, affichage des objets recueillis,
gestion de l’ouverture des portes).
Les données nécessaires (plan du château, objets, portes) sont encodées dans trois fichiers texte. Vous disposerez d’un jeu de fichiers
de données que nous vous proposons et devrez réaliser un programme de jeu qui met en œuvre ces données. Vous pourrez ensuite si
vous le souhaitez encoder votre propre château en préparant d’autres fichiers de données, qui tourneront avec le même programme.
Votre château pourra aussi bien être du type labyrinthe (entièrement fait de couloirs étroits, sans portes) que du type escape game
(un ensemble de pièces, entre lesquelles un personnage circule pour rassembler des objets lui permettant de répondre à des questions
ou résoudre des énigmes).
Ce projet vous permettra d’écrire un code plus substantiel que ce que nous vous demandons ailleurs dans le cours, et va vous
demander de manipuler de nombreux concepts vus tout au long du cours.
Il vous est demandé que votre programme puisse gérer divers jeux de données construits sur les mêmes principes que les nôtres.
Cela permettra à chacun des participants de tester son programme sur les données proposées par d’autres.
NIVEAUX DE PROJET
Dans le cadre de ce projet, 4 niveaux de jeux peuvent être réalisés correspondant à des difficultés croissantes :
— Niveau 1 : construction et affichage du plan du château Ce niveau consiste à tracer correctement le plan du château à
partir du fichier de données. La gestion du jeu après affichage du plan ne fait pas partie de ce niveau.
— Niveau 2 : en plus du niveau 1, la gestion des déplacements au clavier, sans portes ni objets à ramasser Ce niveau
consiste à gérer les déplacements d’un personnage dans le plan construit au niveau 1. Ici on suppose qu’aucun objet ni porte
n’est présent dans le plan : leur gestion n’est pas prise en compte.
— On déplace le personnage de case en case à l’aide des 4 flèches du clavier.
— Le personnage ne doit pas pouvoir traverser les murs ni sortir du plan.
— Si le personnage arrive sur la case quête / sortie du château, un message lui annonce qu’il a gagné.
— Option non demandée, si vous voulez aller plus loin : les cases déjà parcourues par le personnage peuvent être affichées
dans une couleur spécifique, de façon à ce que la trace de son parcours soit conservée.
— Niveau 3 : niveaux 1 + 2 + gestion des objets à ramasser Dans ce niveau, il y a dans le labyrinthe des objets que le joueur
doit collecter. Outre le fichier contenant le plan, un second fichier de données contient la liste des objets et la case où chaque
objet se trouve.
— Les cases où se trouve un objet doivent apparaître dans une couleur spécifique.
— Lorsque le joueur se déplace sur une case contenant un objet, un message lui signale qu’il a trouvé un objet, et ce dernier
s’ajoute à l’inventaire affiché en permanence à côté du plan. La case où était l’objet devient vide, puisque l’objet a été
ramassé.
— Option non demandée, si vous voulez aller plus loin : on peut prévoir que la sortie du labyrinthe ne sera accessible
qu’une fois tous les objets rassemblés.
— Niveau 4 (escape game complet) : niveaux 1 + 2 + 3 + gestion des portes Ce niveau consiste à ajouter dans la labyrinthe
des portes que le joueur doit ouvrir en répondant à des questions. Le troisième fichier de données contient la liste des portes
avec les questions et réponses associées.
— Les cases où se trouve une porte doivent apparaître dans une couleur spécifique.
— Lorsque le joueur tente d’accéder à une porte, la question associée lui est posée.
— S’il répond correctement, la porte s’ouvre et il peut alors la franchir. La case de la porte apparaît alors comme une case
vide.
— S’il ne répond pas ou s’il donne une mauvaise réponse, la porte reste fermée et infranchissable.
7.1.3 En pratique
SYSTÈME DE COORDONNÉES
Le module turtle utilise un système de coordonnées dont l’origine (0, 0) est au centre le la fenêtre. L’axe des abscisses est orienté
vers la droite, l’axe des ordonnées est orienté vers le haut.
Point important : Lorsque vous calculerez les coordonnées nécessaires pour tracer une case, souvenez-vous que le numéro de ligne
augmente quand l’ordonnée « y » (pour la fenêtre turtle) diminue.
Vous aurez besoin de distinguer trois zones différentes dans la fenêtre turtle :
— un bandeau en haut pour l’affichage d’annonces, qui peut par exemple faire 40 pixels turtle de hauteur, que vous pourrez
définir par les coordonnées en pixels turtle du début de la ligne de texte,
— en-dessous, une large zone à gauche pour l’affichage du plan, qu’il sera pratique de définir par les coordonnées de son coin
inférieur gauche (abscisse et ordonnée minimales de la zone) et de son coin supérieur droit (abscisse et ordonnée maximales
de la zone),
— la partie restant à droite sera la colonne d’affichage de l’inventaire, que vous pourrez définir par les coordonnées en pixels
turtle du début de la première ligne de texte de l’inventaire.
Les données correspondant à un jeu figurent dans trois fichiers texte dont la structure est décrite ci-dessous.
a. Un fichier texte plan_chateau.txt qui contient les données du plan du château.
Il comporte un certain nombre de lignes, toutes de la même longueur, représentant une ligne de cases du plan. Chaque ligne
du fichier est une suite d’entiers séparés par des espaces, où chaque entier représente une case. Les valeurs de ces entiers
codent chaque nature de case :
— valeur 0 pour une case vide,
— valeur 1 pour un mur (infranchissable),
— valeur 2 pour la case de sortie/victoire,
— valeur 3 pour une porte qui sera franchissable en répondant à une question,
— valeur 4 pour une case contenant un objet à collecter.
b. Un fichier texte [Link] qui contient une liste d’objets associés aux cases sur lesquelles on les trouve.
Chaque ligne sera du type :
(x, y) , "objet"
Ainsi, chaque ligne contient :
— un couple d’entiers positifs ou nuls (numéro de ligne, numéro de colonne) indiquant la case où se trouve l’objet,
— puis une virgule et une espace,
— puis une chaînes de caractères décrivant l’objet.
Par exemple :
(12, 3), "un oreiller magique"
signifiera que la case de coordonnées (12, 3) contient l’objet « un oreiller magique ».
c. Un fichier texte [Link] qui contient une liste de questions/réponses associées aux portes.
Chaque ligne sera du type :
(x, y) , ("question", "réponse")
Ainsi, chaque ligne contient :
— un couple d’entiers positifs ou nuls (numéro de ligne, numéro de colonne) indiquant la case où se trouve la porte,
— puis une virgule et une espace,
— puis un couple de chaînes de caractères avec une question et une réponse.
Par exemple :
(21, 12), ("Capitale de la Belgique ?", "Bruxelles")
signifiera que pour franchir la porte située en case (21, 12), il faudra répondre « Bruxelles » à la question « Capitale de
la Belgique ? ».
Pour vous aider à concevoir et à tester votre programme, un jeu de données comportant trois fichiers types à téléchartger sur le
format spécifié plus haut est donné ici :
— fichier plan_chateau.txt ( [Link] )
— fichier dico_objets.txt ( [Link] )
— fichier ``dico_portes.txt``( [Link] )
Il s’agit d’un escape game très simple avec des questions portant sur Python. Nous vous suggérons de placer ces trois fichiers dans
le même dossier que votre programme, pour pouvoir les appeler sans devoir décrire leur place dans l’arborescence.
Nous supposons aussi que la porte d’entrée du château est ouverte (elle est donc vue comme une case vide), qu’elle est en position
(0, 1) et que le personnage s’y trouve initialement.
Un fichier [Link] ( ( [Link] ) vous est fourni : il donne les dimensions,
couleurs et quelques constantes utilisées par notre programme de référence. Vous pouvez télécharger ce fichier et copier/coller ces
définitions dans votre script ou mieux placer ce fichier [Link] dans le même répertoire que votre script et ajouter à ce dernier
la ligne
Nous supposons donc que la fenêtre turtle est contenue dans un rectangle (de coin inférieur gauche en (-240, -240) et de coin
supérieur droit (240, 240))) et est composée de trois zones :
— la zone affichage du plan (de coin inférieur gauche en (-240, -240) et de coin supérieur droit (50, 200)),
— la zone annonces avec les textes qui seront affichés en (-240, 240) (chaque annonce devra effacer la précédente),
— la zone affichage de l’inventaire (de coin supérieur gauche en (70, 210) et de coin supérieur droit en (240, 210))
Pour faire simple, nous supposons également que le personnage démarre à la case de coordonnée (1,0)
Nous sommes conscients que ce projet, si vous voulez le faire dans sa totalité, est ambitieux surtout pour des programmeurs débu-
tants.
Nous vous proposons donc, pour mener à bien votre projet, de le phaser dans sa réalisation ; de créer dans un premier temps (niveau
1) un embryon de projet, qui va grossir petit à petit (niveaux 2, 3) pour finalement englober la totalité de ce qui vous est demandé.
Le niveau 1 parle de lecture du plan à partir du fichier plan_chateau.txt, de la construction de la matrice correspondante pour
stocker ce plan, et de son affichage grâce au module turtle.
Pour cela différentes fonctions doivent être programmées.
Vous devez écrire une première fonction lire_matrice(fichier), qui recevra en argument le nom d’un fichier texte contenant
le plan à tracer. Elle ouvrira ce fichier et renverra en sortie une matrice, c’est-à-dire une liste de listes, soit une liste dont chaque
élément sera lui-même une liste représentant une ligne horizontale de cases du plan.
Prenons l’exemple de ce plan comprenant 4 lignes et 6 colonnes avec les cases vides blanches, des murs gris, un objet orange et une
porte verte :
1 0 1 1 1 1
1 0 0 0 0 1
1 0 4 0 0 1
1 1 1 3 1 1
Pour tracer le plan du château à partir de la matrice obtenue, vous écrirez une fonction afficher_plan(matrice) utilisant le
module turtle ; cette fonction recevra en entrée la matrice telle que décrite ci-dessus.
Pour réaliser cette fonction, nous vous conseillons de suivre les étapes suivantes :
1. Commencer par une fonction calculer_pas(matrice) qui calcule la dimension à donner aux cases pour que le plan
tienne dans la zone de la fenêtre turtle que vous avez définie : diviser la largeur et la hauteur de la zone en question par
le nombre de cases qu’elle doit accueillir, retenir la plus faible de ces deux valeurs.
Par exemple, pour une zone turtle d’affichage pour le plan de 290 (-240 à 50) de large et 440 (-240 à 200) de haut, si le plan
fait 20 cases en largeur et 44 cases en hauteur, les carrés auront une taille de 10 pour ne pas sortir de la zone (ici le souci, si
la taille est supérieure à 10, sera la hauteur du plan).
2. Définir une fonction coordonnees(case, pas) qui calcule les coordonnées en pixels turtle du coin inférieur gauche
d’une case définie par ses coordonnées (numéros de ligne et de colonne). Souvenez-vous que les lignes sont numérotées de
haut en bas, alors que l’axe des coordonnées verticales va de bas en haut. Par exemple : avec un château de 44 lignes (lignes
0 à 43), la case inférieure gauche du château (c’est-à-dire la case (43, 0)) pour une sous-fenêtre turtle allant de (-240,
-240) à (50, 200) vaudra (-240, -240).
3. Définir une fonction tracer_carre(dimension), traçant un carré dont la dimension en pixels turtle est donnée en
argument.
4. Définir une fonction tracer_case(case, couleur, pas), recevant en arguments un couple de coordonnées en in-
dice dans la matrice contenant le plan, une couleur, et un pas (taille d’un côté) et qui va appeler la fonction tracer_carre
pour tracer un carré d’une certaine couleur et taille à un certain endroit.
5. Définir enfin une fonction afficher_plan(matrice), qui va appeler la fonction tracer_case pour chaque ligne et
chaque colonne du plan, par deux boucles imbriquées. Le principe est : pour chaque élément ligne de la matrice, pour chaque
élément colonne de cet élément ligne, tracer une case à l’emplacement correspondant, dans une couleur correspondant à ce
que dit la matrice.
Bravo si vous avez terminé ce niveau 1. Vous pouvez passer au niveau 2. Ici, nous vous demandons d’ajouter à votre programme la
gestion du déplacement d’un personnage.
Le personnage sera représenté par un petit rond (fonction prédéfinie [Link]). Il pourra se déplacer case par case dans les 4
directions (haut, bas, droite, gauche).
— Lorsque le personnage tentera un déplacement vers une case de mur ou vers l’extérieur du plan, rien ne se produira.
— Lorsqu’il tentera un déplacement vers une case vide, il avancera d’une case (en pratique, il s’agira de retracer la case de
départ pour effacer le personnage, et de replacer ce dernier sur la case de destination).
Pour réaliser cette partie du code nous vous suggérons les parties suivantes :
Nous vous suggérons de définir une fonction principale de gestion des déplacements, qui sera assez simple pour le niveau 2, et que
vous viendrez compléter si vous passez aux niveaux 3 (gestion des objets) et 4 (gestion des portes).
Pour le niveau 2, donc, nous avons besoin d’une fonction deplacer(matrice, position, mouvement) qui reçoit en
arguments : - matrice : le plan du château, - position : un couple définissant la position où se trouve le personnage, -
mouvement : un couple définissant le mouvement demandé par le joueur.
Pour l’instant (niveau 2) cette fonction aura les effets suivants :
— Si le mouvement souhaité fait sortir le personnage des limites du plan, rien ne se passera.
— Si le mouvement souhaité mène le personnage sur un mur, rien ne se passera.
— Si le plan que vous utilisez comprend des objets ou des portes, vous traiterez les objets comme des cases vides et les portes
comme des cases de mur.
Note : Au niveau 2, le traitement des portes et des objets trouvés ne sont pas traités, et sont « vus » comme des murs et des cases
vides. Ces éléments seront traités correctement aux niveaux 3 et 4, expliqués plus bas.
Pour gérer la commande du personnage au clavier, nous allons utiliser de la programmation événementielle. Le principe est d’as-
socier à un événement un certain traitement. Ici, il faudra associer au fait de pousser sur une touche du clavier (les flèches de votre
clavier) un traitement qui gère le déplacement associé de votre personnage.
Pour ceci, nous allons utiliser des fonctions turtle qui n’ont pas été vues dans le MOOC, et nous vous donnons donc ci-dessous
les portions de code nécessaires :
— la fonction [Link]() pour demander à Python « d’écouter » ce qui se passe sur le clavier,
— la fonction [Link]() pour associer une touche du clavier au déclenchement d’une fonction
(notons que cette fonction ne peut avoir de paramètres),
— la fonction [Link]() pour placer le programme en position d’attente d’une action.
Vous placerez donc, dans la partie traitement (corps) de votre programme, le bloc suivant, qui associe aux 4 flèches
du clavier (qui sont identifiées dans turtle avec les noms (chaînes de caractères) "Left" (flèche vers la gauche),
"Right" (flèche vers la droite), "Up" (flèche vers le haut) et "Down" (flèche vers le bas)) les 4 fonctions respec-
tives deplacer_gauche, deplacer_droite, deplacer_haut et deplacer_bas. Nous verrons au point
suivant que, dans notre programme, il faudra définir chacune de ces 4 fonctions pour qu’elle déclenche le traitement
requis chaque fois que la touche clavier correspondante est enfoncée. Ainsi, lorsqu’une des touches de flèche sera
pressée (« onkeypress »), la fonction associée sera appelée.
[Link]() # Déclenche l’écoute du clavier
[Link](deplacer_gauche, "Left") # Associe à la touche Left une fonction
˓→appelée deplacer_gauche
[Link](deplacer_droite, "Right")
[Link](deplacer_haut, "Up")
[Link](deplacer_bas, "Down")
[Link]() # Place le programme en position d’attente d’une action du
˓→joueur
Pour le niveau 3, nous vous demandons d’ajouter au programme tel que rédigé au niveau 2 la gestion des objets, présents dans
le château, que le personnage collecte quand il passe sur la case correspondante. Pour cela les éléments supplémentaires suivants
devront être codés.
donnera le dictionnaire :
Note :
La lecture des données reçues du fichier des objets (et on verra plus loin, aussi le fichiers des portes) peut être facilitée par l’utilisation
de verbe eval. Par exemple, ayant une chaîne de caractères chaine = '(1, 2), "bonjour"', après l’instruction :
a, b = eval(chaine)
Au niveau 2, vous avez défini une fonction gérant le déplacement, qui examine si le personnage est envoyé vers une case vide ou
vers un mur. Vous devez maintenant ajouter un autre cas à cette fonction, celui où le personnage est envoyé vers une case contenant
un objet, et donc définir une fonction ramasser_objet :
— L’objet disparaîtra de la case (à la fois dans le plan et à l’affichage), qui devra donc prendre la couleur des cases vides.
— Le personnage avancera sur la case demandée.
— Une annonce du type « Vous avez trouvé : une clef à molette » s’affichera dans le bandeau d’affichage des annonces.
— L’objet s’ajoutera à l’inventaire des objets collectés affiché dans la colonne d’affichage de l’inventaire.
Pour cela, vous aurez sans doute besoin de passer de nouveaux paramètres à la fonction gérant le déplacement : la matrice contenant
le plan (puisque vous serez amené à modifier la nature de la case contenant l’objet lorsque celui-ci sera ramassé) et l’ensemble
contenant l’inventaire des objets ramassés (puisque l’objet sera ajouté à cet ensemble).
Le niveau 4 demande de réaliser le jeu complet tel qu’annoncé en début d’énoncé. Pour cela les éléments supplémentaires suivants
devront être codés.
Vous aurez besoin de lire le fichier contenant les questions-réponses associées aux portes. Cela peut être réalisé par la fonction
de lecture du fichier des objets (creer_dictionnaire_des_objets) que vous aurez écrite au niveau précédent, puisque la
structure des fichiers est presque la même.
Ainsi le fichier de questions/réponses suivant :
donnera le dictionnaire :
Vous allez maintenant devoir ajouter le cas où la case de destination souhaitée est une porte. Vous aurez besoin d’une fonction
poser_question(matrice, case, mouvement) pour :
— afficher dans le bandeau d’annonces Cette porte est fermée.
— poser au joueur la question correspondant à l’emplacement de la porte et saisir sa réponse,
— si la réponse est bonne, remplacer la porte par une case vide, afficher dans le bandeau d’annonce que la porte s’ouvre, et
avancer le personnage,
— si la réponse est mauvaise, l’annoncer et ne pas déplacer le personnage.
Pour poser une question, vous pouvez utiliser la fonction [Link](). Elle prend en argument 2 chaînes de caractères,
une qui sera le titre de la fenêtre d’input (par exemple « Question ») et une autre qui sera le texte affiché dans la fenêtre d’input (la
question associée à la porte).
Comme cela a été signalé plus haut, utiliser la fonction [Link]() interrompt l’écoute du clavier déclenchée par
[Link](), et vous devrez placer sur la ligne suivante une nouvelle instruction [Link]() pour recommencer
à surveiller le clavier.
Notez que si vous n’avez pas soumis à temps votre projet pour la première phase d’évaluation par les pairs, il vous sera quand même
possible de soumettre votre travail pour la phase suivante d’auto-évaluation, mais alors vous vous noterez sur 24 points et non sur
les 48 points possibles pour le projet.
Modalités de remise
La procédure de remise est expliquée à la section suivante.
De façon binaire nous pourrions dire qu’un programme informatique est bon s’il fait ce qu’on lui demande et sinon il est incorrect.
Ce serait un peu court surtout après avoir parlé de toutes les règles de bonnes pratiques que nous avons vues.
En fait, un projet tel que le projet Château est évalué selon plusieurs critères de correction (programme correct, qui fait bien son
travail) et de style (code qui suit les règles de bonnes pratiques).
Donnons ici des recommandations pour évaluer un projet de programmation niveau débutant.
Principes de base
La réalisation d’un projet informatique comprend plusieurs aspects qui font l’objet de choix qui doivent généralement être justifiés,
ou de mise en application, généralement sous forme de programme structuré.
Tout d’abord, il est important que l’évaluation soit le résultat d’une notation
— positive : qui consiste à donner des points quand certains aspects sont présents dans la solution, et
— négative : qui consiste à enlever des points sur certains aspects qui sont absents ou incorrects.
Il convient aussi in fine d’avoir une évaluation globale où un projet qui fonctionne se voit naturellement attribuer des points même
si plusieurs problèmes existent dans la réalisation.
Le mieux pour obtenir une telle note qui est le fruit d’une évaluation négative et positive, est de découper la note finale en sous
notes, qui chacune évalue un aspect, qui de même fait l’objet d’une évaluation négative et positive avec évaluation globale.
Proposition
Ci-dessous la découpe de la note à donner au projet, que nous vous demandons d’appliquer dans vos évaluations pour obtenir une
notation uniforme pour tous. Le nombre de points pour chaque catégorie est proposée pour une note finale sur 24 points. Comme il
s’agit d’un projet pour débutant, les structures de données et les méthodes pour résoudre les problèmes sont données et ne nécessitent
pas de recherche pour l’apprenant ; aucune note n’est donc donnée pour ces deux aspects.
Grille de notation du projet (sur 24 points)
— Découpe (4 points) [La découpe du code global avec commentaires] initiaux, et respect de l’ordre des parties : import des
modules externes, suivi des définitions des constantes globales, suivi des définitions des fonctions et enfin, code global.
— 4 points si les quatre parties sont présentes et l’ordre est respecté ;
— 3 points si une des quatre parties manque ou est dans le mauvais ordre ;
— 2 points si deux des quatre parties manquent ou sont dans le mauvais ordre ;
— 1 points si trois des quatre parties manquent ou sont dans le mauvais ordre ;
— 0 point si rien n’est satisfaisant.
— Structuration en fonctions (3 points) [La structuration en] fonctions de bonne taille (25 lignes maximum) et cohérentes
(pas de fonctions définies mais non appelées par exemple) est réalisée :
— 3 points si la structuration est satisfaisante ;
— 2 points si des fonctions sont définies, mais certaines sont incohérentes soit sont trop longues ;
— 1 points si des fonctions sont définies, mais certaines sont incohérentes et d’autres sont trop longues ;
— 0 point si aucune fonction n’est définie ou une certaine structuration en fonction existe mais ne respecte pas du tout
les règles de bonnes pratiques.
— Bonnes pratiques (4 points) [Les bonnes pratiques sont] respectées en matière d’utilisation des noms des constantes, va-
riables, fonctions. . . , de l’indentation. . . :
— 4 points si toutes les bonnes pratiques sont respectées ;
— 3 points si les noms des constantes, variables et fonctions respectent les bonnes pratiques, mais l’indentation (4
caractères par incrément) n’est pas respectée ;
— 2 points si les règles sont globalement repectées à quelques exceptions près à la fois au niveau indentations et noms
de constantes, variables ou fonctions ;
— 0 point si les règles de bonnes pratiques en matière d’encodage ne sont globalement pas respectées.
— Commentaires (4 points) [Commentaires et docstrings sont bien] présents : le docstring initial possède les informations
suivantes : identité de l’auteur, date, ce que fait le programme, les fonctions possèdent un docstring décrivant les pa-
ramètres, ce que fait la fonction aux paramètres (par défaut, ils ne sont pas modifiés) et le résultat de la fonction, des
commentaires pertinents existent quand c’est utile à la compréhension
— 4 points si commentaires et docstrings sont présent et respectent les règles de bonnes pratiques ;
— 3 points si un des éléments du docstring initial ou des commentaires est manquant ou non satisfaisant ;
— 2 points si le docstring initial et les commentaires sont manquants ou non satisfaisants, mais que les fonctions ont
des docstrings corrects ;
— 0 point si les trois éléments docstring initial, commentaires et docstrings de fonctions sont manquants ou non satis-
faisants.
— Consignes (2 points) : (voir énoncé du projet)
— 2 points si toutes les consignes du projet sont respectées (niveau 4 de l’énoncé atteint) ;
— 1 point si une bonne partie des consignes est respectée (niveau 2 ou 3 atteint) ;
— 0 point si peu de consignes sont respectées (le niveau 1 n’a pas été dépassé).
— Résultat (7 points) : Le programme fonctionne correctement.
— 7 points si le projet complet fonctionne toujours correctement (niveau 4 de l’énoncé) ;
— 6 points si le programme donne les bons résultats à quelques exceptions près (niveau 3 atteint) ;
— 4 points si certaines parties du projet ne sont pas (bien) réalisées (niveau 2 atteint) ;
— 2 points si une partie du projet seulement est réalisée (niveau 1 atteint) ;
— 0 point si le programme ne s’exécute pas sans échec ou si aucune partie ne fonctionne.
Explication sur l’évaluation
En plus des points attribués, il est essentiel pour l’évaluateur d’expliquer pourquoi telle ou telle note a été donnée, pour que l’auteur
du projet puisse comprendre les notes données et puisse s’améliorer les fois suivantes.
Dans le cadre de ce cours, comme annoncé, l’évaluation de votre projet, se fera en deux temps :
— d’une part par une évaluation par les pairs
— d’autre part, par une auto-évaluation de votre projet après éventuelles améliorations.
En pratique, la remise du projet et son évaluation seront faites en 6 étapes :
1. Après l’avoir réalisé, vous soumettrez votre projet.
2. Vous devrez évaluer trois projets d’autres étudiants choisis au hasard.
3. Vous recevrez les notes et commentaires sur votre propre projet venant d’au moins deux autres de vos pairs (deux autres
apprenants).
4. À la lumière des commentaires donnés par vos pairs, vous corrigerez et soumettrez une version améliorée de votre projet.
5. Vous réaliserez une auto-évaluation, c’est-à-dire évaluerez votre propre projet.
Le document consignes pour la notation, téléchargeable ici reprend les explications et détaille chaque notation et demande de
commenter chaque note donnée.
La note finale de votre travail sera la somme des évaluations par les pairs (24 points) et de votre auto-évaluation (24 points).
Les détails pratiques sur les évaluations seront donnés plus loin.
Temps et délais pour réaliser le projet
L’estimation du temps moyen que va vous mettre le projet Château est très variable. La matière vue jusqu’ici suffit pour sa réalisation.
Vous avez plusieurs jours pour sa remise. Libre à vous de mener en parallèle la suite du module 6 avec la réalisation du projet ou
plutôt de postposer la suite de l’apprentissage du module 6 et de vous atteler dès maintenant au projet.
Vous et tous les autres apprenants débutez en programmation. L’évaluation par les pairs avec les commentaires qui l’accompagnent
ainsi que l’auto-évaluation peuvent être très utiles pour votre apprentissage.
Pour que cela soit le cas, lors des différentes phases de notation, essayez d’être :
— objectif dans vos évaluations,
— clair et précis dans vos commentaires,
— mais toujours courtois et bienveillant
comme vous voudriez que les autres le soient pour vous-même.
Bon travail !
Si vous comptez réaliser votre projet pour la session d’automne, cette section et la section suivante contient les procédures pour
soumettre votre, projet, réaliser et rapporter vos évaluations sur les projets des pairs que nous vous demandons d’effectuer soumettre
à nouveau votre projet et finalement l’auto-évaluer.
Cette sous-section contient trois parties qui vont vous demander des actions :
1) D’abord vous allez soumettre votre projet éventuellement accompagné d’un lien vers l’image d’un résultat de votre pro-
gramme.
2) Ensuite vous allez évaluer le projet de trois de vos pairs (ou plus si demandé et si vous le voulez bien) et remettre des notes
et vos commentaires les plus précis possible.
3) Enfin dans cette partie, vous allez recevoir la note des évaluations d’au moins deux de vos pairs avec les détails des notes et
les commentaires associés.
24 points seront en jeu dans cette partie.
La suite (resoumission de votre projet éventuellement amendé et auto-évaluation) est l’objet de la sous-section qui suivra.
Note : Voir le formulaire d’évaluation du projet par les pairs dans le cours en ligne
..only : : html
Attention à l’horaire
Certains d’entre vous retiennent la date d’échéance indiquée dans la barre latérale sous l’intitulé de cette section.
Attention, regardez bien le calendrier. Cette date correspond à la fin de l’évaluation par les pairs. L’échéance
pour la soumission de votre projet est fixée 15 jours avant cette date !
Cette sous-section contient trois parties qui vont vous demander des actions :
1) D’abord vous allez soumettre une nouvelle fois votre projet éventuellement amendé suite à la lecture des notes et commen-
taires de vos pairs à nouveau éventuellement accompagné d’un lien vers l’image d’un résultat de votre programme.
2) Ensuite vous allez évaluer votre propre projet que vous venez de soumettre et remettre des notes et vos commentaires sur ce
dernier.
3) Enfin, vous allez recevoir la note de votre auto-évaluation.
À nouveau, 24 points seront en jeu dans cette partie, ce qui totalisera 48 points pour la réalisation de votre projet.
Projet donné lors des trois premières sessions du MOOC Apprendre à coder avec
Python
Nous donnons ici l’énoncé du projet que nous avons proposé dans le cadre du cours en ligne (FUN-MOOC) « Apprendre à coder
avec Python », ainsi que les procédures d’évaluation proposées aux apprenants dans le cadre d’une évaluation par les pairs.
Le projet couvre les instructions et fonctions Python ainsi que le BA-ba des séquences (chaînes de caractères et tuples) ce qui
correspond à la matière du MOOC jusque et y compris la section 5.1.
Dans ce qui suit, nous donnons l’énoncé de ce projet, baptisé « projet Vasarely » en référence à l’artiste Victor Vasarely qui a
popularisé cette tendance. (Pour en savoir plus sur cet artiste, n’hésitez pas à consulter la page dédiée suivante : Victor Vasarely).
CC BY-SA 3.0 - 2021 - Sébastien Hoarau - Thierry Massart - Jean Olgiati - Isabelle Poirier 317
Apprendre à coder avec Python, Version - Release 3.0
8.1.2 En pratique
Nous travaillons avec des coordonnées et distances telles que manipulées par les différentes fonctions de turtle (up,
begin_fill, goto, . . . ). En particulier nous demandons de tracer, avec turtle, la vue de dessus d’une figure en 3 dimensions et
donc de manipuler tantôt des coordonnées en 3 dimensions sous forme de triplet (x, y, z), tantôt en 2 dimensions sous forme de
couple (x, y).
Nous vous demandons de réaliser quatre étapes.
ÉTAPE 1
En supposant que turtle est déjà importé, nous vous demandons d’écrire une fonction
hexagone(point, longueur, col, centre, rayon)
qui reçoit :
— le point point sous forme d’un triple (tuple de trois composantes) donnant la valeur des trois coordonnées du centre avant
déformation de l’hexagone à peindre,
— la distance (avant déformation) longueur entre le centre et n’importe quel sommet de l’hexagone,
— le tuple col contenant les trois couleurs (col1, col2, col3) qui vont être utilisées pour dessiner les hexagones,
— le point centre sous forme de triple (c_x, c_y, c_z) qui donne le centre de la sphère de déformation,
— et le rayon de la sphère de déformation.
La fonction peint un hexagone déformé en traçant des lignes droites entre le centre et les extrémités dont la position est calculée
avec la fonction deformation.
col1 représente la couleur du pavé Nord-Est (en haut à droite), col2 représente la couleur du pavé Ouest (à gauche) et col3
représente la couleur du pavé Sud-Est (en bas à droite).
Note : Pour tester votre fonction, vous pouvez dans un premier temps définir la fonction deformation comme suit :
ÉTAPE 2
from math import pi, sin, cos, sqrt, acos, asin, atan2
Entrées :
p : coordonnées (x, y, z) du point du dalage à tracer (z = 0) AVANT déformation
centre : coordonnées (X0, Y0, Z0) du centre de la sphère
rayon : rayon de la sphère
Sorties : coordonnées (xprim, yprim, zprim) du point du dallage à tracer APRÈS
˓→déformation
"""
x, y, z = p
xprim, yprim, zprim = x, y, z
xc, yc, zc = centre
if rayon**2 > zc**2:
zc = zc if zc <= 0 else -zc
r = sqrt(
(x - xc) ** 2 + (y - yc) ** 2) # distance horizontale depuis le
˓→point à dessiner jusqu'à l'axe de la sphère
Ou vous pouvez importer le fichier module_deformation.py en cliquant sur le lien ci-dessous pour ensuite ouvrir le fichier
module_deformation.py et copier / coller la définition de la fonction deformation dans votre code du projet Vasarely.
Pour ceux qui veulent essayer de définir deformation eux-mêmes (attention : la théorie et le code sont beaucoup plus difficiles
que tout ce que nous avons fait jusqu’à présent) :
voici les explications de base en cliquant ici
et voici quelques conseils ou remarques :
— Vous pouvez utiliser la librairie math.
— Les calculs se font sur des points en trois dimensions.
— Le pavage avant déformation se trouve sur le plan avec z = 0.
Note : Notons que nous nous simplifions le problème lors du tracé des hexagones déformés : en effet après calculs des déplacements
des points extrémités grâce à la fonction deformation, le programme tracera des lignes droites (et non pas des lignes déformées)
entre ces extrémités. Ne vous en faites pas : l’effet final n’en est que peu affecté.
Conseil : pour tracer les hexagones utilisez la méthode goto(x,y) de turtle plutôt que forward.
hexagone de centre (0, 0, 0) de longueur d’arête avant déformation 30 avec déformation de centre (-50, -50, 0) et de rayon 90 (en
rose, les contours du pavé avant déformation)
ÉTAPE 3
ÉTAPE 4
Enfin, écrire un code principal qui demande à l’utilisateur les paramètres de l’exécution et qui appelle la fonction pavage pour
réaliser le résultat.
Les paramètres seront donnés comme suit :
— inf_gauche : (valeur entière) donnant les coordonnées (inf_gauche, inf_gauche) du bord inférieur gauche de
la fenêtre de visualisation ;
— sup_droit : (valeur entière) donnant les coordonnées (sup_droit, sup_droit) du bord supérieur droit de la
fenêtre de visualisation ;
— longueur : (valeur entière) longueur d’un segment de pavé (avant déformation) ;
— col : (trois chaîne de caractères) donnant les trois couleurs des pavés ;
-305
305
20
blue
black
red
-50
-50
-50
200
Contrairement aux exercices UpyLaB, ici vos instructions ìnput` peuvent afficher le texte qu’elles désirent ; par exemple une exécu-
tion pourrait donner l’affichage sur la console suivant :
Pour vous permettre de montrer l’image produite par votre programme, après la réalisation du travail, soit vous capturez l’image
résultat, soit votre programme demandera à turtle de sauver le résultat dans un fichier. Pour cela, votre programme pourra
exécuter en fin de programme les deux instructions :
[Link]().postscript(file="[Link]")
[Link]()
où ici le nom du fichier est "[Link]". Notez que le seul format de fichier possible pour turtle est postscript (suffixe eps). Si,
après l’exécution du programme, vous désirez un autre format pour le fichier résultat (jpeg ou pdf par exemple) il vous suffira de
faire traduire le résultat, par exemple en utilisant une traduction en ligne (avec votre navigateur web, cherchez online translation
eps to jpg par exemple).
Au terme de votre projet, si vous le désirez, un exemple de résultat de votre code, avec les couleurs et déformations que vous désirez,
pourra être publié et visible par tous. Utilisez le forum du Projet pour toute question concernant l’énoncé.
EXEMPLES DE RÉSULTATS
— rayon = 300
L’exemple ci-dessous a les mêmes paramètres que celui donné au début, mis à part :
— centre = (-50, -50, 0) et
— rayon = 240
De façon binaire nous pourrions dire qu’un programme informatique est bon s’il fait ce qu’on lui demande et sinon il est incorrect.
Ce serait un peu court surtout après avoir parlé de toutes les règles de bonnes pratiques que nous avons vues.
En fait, un projet tel que le projet Vasarely est évalué selon plusieurs critères de correction (programme correct, qui fait bien son
travail) et de style (code qui suit les règles de bonnes pratiques).
Donnons ici des recommandations pour évaluer un projet de programmation niveau débutant.
Principes de base
La réalisation d’un projet informatique comprend plusieurs aspects qui font l’objet de choix qui doivent généralement être justifiés,
ou de mise en application, généralement sous forme de programme structuré.
Tout d’abord, il est important que l’évaluation soit le résultat d’une notation
— positive : qui consiste à donner des points quand certains aspects sont présents dans la solution, et
— négative : qui consiste à enlever des points sur certains aspects qui sont absents ou incorrects.
Il convient aussi in fine d’avoir une évaluation globale où un projet qui fonctionne se voit naturellement attribuer des points même
si plusieurs problèmes existent dans la réalisation.
Le mieux pour obtenir une telle note qui est le fruit d’une évaluation négative et positive, est de découper la note finale en sous
notes, qui chacune évalue un aspect, qui de même fait l’objet d’une évaluation négative et positive avec évaluation globale.
Proposition
Ci-dessous la découpe de la note à donner au projet, que nous vous demandons d’appliquer dans vos évaluations pour obtenir une
notation uniforme pour tous. Le nombre de points pour chaque catégorie est proposée pour une note finale sur 24 points. Comme il
s’agit d’un projet pour débutant, les structures de données et les méthodes pour résoudre les problèmes sont données et ne nécessitent
pas de recherche pour l’apprenant ; aucune note n’est donc donnée pour ces deux aspects.
Grille de notation du projet (sur 24 points en référence au 24 points obtenu dans le MOOC pour cette partie)
— Découpe (4 points) [La découpe du code global avec commentaires] initiaux, et respect de l’ordre des parties : import des
modules externes, suivi des définitions des constantes globales, suivi des définitions des fonctions et enfin, code global.
— 4 points si les quatre parties sont présentes et l’ordre est respecté ;
— 3 points si une des quatre parties manque ou est dans le mauvais ordre ;
— 2 points si deux des quatre parties manquent ou sont dans le mauvais ordre ;
— 1 points si trois des quatre parties manquent ou sont dans le mauvais ordre ;
— 0 point si rien n’est satisfaisant.
— Structuration en fonctions (3 points) [La structuration en] fonctions de bonne taille (25 lignes maximum) et cohérentes
(pas de fonctions définies mais non appelées par exemple) est réalisée :
— 3 points si la structuration est satisfaisante ;
— 2 points si des fonctions sont définies, mais certaines sont incohérentes soit sont trop longues ;
— 1 points si des fonctions sont définies, mais certaines sont incohérentes et d’autres sont trop longues ;
— 0 point si aucune fonction n’est définie ou une certaine structuration en fonction existe mais ne respecte pas du tout
les règles de bonnes pratiques.
— Bonnes pratiques (4 points) [Les bonnes pratiques sont] respectées en matière d’utilisation des noms des constantes, va-
riables, fonctions. . . , de l’indentation. . . :
— 4 points si toutes les bonnes pratiques sont respectées ;
— 3 points si les noms des constantes, variables et fonctions respectent les bonnes pratiques, mais l’indentation (4
caractères par incrément) n’est pas respectée ;
— 2 points si les règles sont globalement repectées à quelques exceptions près à la fois au niveau indentations et noms
de constantes, variables ou fonctions ;
— 0 point si les règles de bonnes pratiques en matière d’encodage ne sont globalement pas respectées.
— Commentaires (4 points) [Commentaires et docstrings sont bien] présents : le docstring initial possède les informations
suivantes : identité de l’auteur, date, ce que fait le programme, les fonctions possèdent un docstring décrivant les pa-
ramètres, ce que fait la fonction aux paramètres (par défaut, ils ne sont pas modifiés) et le résultat de la fonction, des
commentaires pertinents existent quand c’est utile à la compréhension
— 4 points si commentaires et docstrings sont présent et respectent les règles de bonnes pratiques ;
— 3 points si un des éléments du docstring initial ou des commentaires est manquant ou non satisfaisant ;
— 2 points si le docstring initial et les commentaires sont manquants ou non satisfaisants, mais que les fonctions ont
des docstrings corrects ;
— 0 point si les trois éléments docstring initial, commentaires et docstrings de fonctions sont manquants ou non satis-
faisants.
— Consignes (2 points) : (voir énoncé du projet)
— 2 points si les consignes du projet sont respectées ;
— 1 point si la moitié des consignes est respectée ;
— 0 point si auncune consigne n’est respectée.
— Résultat (7 points) : Le programme fonctionne correctement.
— 7 points si c’est le cas ;
— 6 points si le programme donne les bons résultats sur la plupart des jeux de données ;
— 4 points si le programme donne le bon résultat sur au moins un jeu de données ;
— 2 points si le programme s’exécute sans échec sur au moins un jeu de données ;
— 0 point si le programme ne s’exécute pas sans échec.
Explication sur l’évaluation
En plus des points attribués, il est essentiel pour l’évaluateur d’expliquer pourquoi telle ou telle note a été donnée, pour que l’auteur
du projet puisse comprendre les notes données et puisse s’améliorer les fois suivantes.
Dans le cadre des trois premières sessions du cours « Apprendre à Coder avec Python », l’évaluation de chaque projet, se faisait en
deux temps :
— d’une part par une évaluation par les pairs
— d’autre part, par une auto-évaluation du projet après éventuelles améliorations.
En pratique, la remise du projet et son évaluation étaient faites en 6 étapes :
1. Après l’avoir réalisé, une soumission du projet éventuellement avec un fichier supplémentaire montrant un résultat.
2. Chaque apprenant devait évaluer trois projets d’autres étudiants choisis au hasard.
3. Chacun recevrait les notes et commentaires sur son propre projet venant d’au moins deux autres de vos pairs (deux autres
apprenants).
4. À la lumière des commentaires donnés par les pairs, chacun corrigeait et soumettait une version améliorée de son projet.
5. et réalisait une auto-évaluation, c’est-à-dire chacun évaluait son propre projet.
Le document consignes pour la notation, téléchargeable ici reprend les explications et détaille chaque notation et demande de
commenter chaque note donnée.
La note finale du travail sera la somme des évaluations par les pairs (24 points) et de votre auto-évaluation (24 points).
Temps et délais pour réaliser le projet
L’estimation du temps moyen que va vous mettre le projet Vasarely (en supposant que vous utilisez la fonction deformation qui
vous est fournie), est très variable de quelque heures à plusieurs dizaines d’heures. réalisation.
L’évaluation par les pairs avec les commentaires qui l’accompagnent ainsi que l’auto-évaluation peuvent être très utiles pour l’ap-
prentissage de la programmation,.
Pour que cela soit le cas, lors des différentes phases de notation, essayez d’être :
— objectif dans vos évaluations,
— clairs et précis dans vos commentaires,
— mais toujours courtois et bienveillants
comme vous voudriez que les autres le soient pour vous-même.
Bon travail !
RAPPEL DU CONTEXTE
Lors des 3 premières sessions du MOOC « Apprendre à coder avec Python » le projet consistait à réaliser
— une oeuvre d’art géométrique (Op Art)
— sous la forme d’un pavage hexagonal déformé par une sphère.
Les liens ci-dessous est un recueil des résultats lors des 3 sessions où ce projet a été proposé, finis ou en cours, parfois non conformes
à l’énoncé mais pouvant donner un effet intéressant, ou parfois beaucoup plus sophistiqués que ce qui était demandé, au gré de
l’imagination et de l’expertise de chacun.
Grand merci à toutes et tous pour le plaisir que vous nous avez donné à la vision de ces réalisations !
Isabelle, Sébastien, Thierry et L’équipe Pédagogique
Annexes
CC BY-SA 3.0 - 2021 - Sébastien Hoarau - Thierry Massart - Jean Olgiati - Isabelle Poirier 329
Apprendre à coder avec Python, Version - Release 3.0
Explications
Pour les calculs, les points du pavage sont donnés avec des coordonnées en trois dimen-
sions (x, y, z).
Le pavage sans déformation se trouve sur le plan avec z = 0 (plan x, y). Une sphère est
définie par son centre et son rayon. Cette sphère va définir la déformation.
L’idée de base est que la surface déformée va se coller sur la sphère. Tous les points jus-
qu’aux bords de la déformation ne subissent aucune déformation. Le point au centre de
la déformation va changer de hauteur (coordonnée z), mais ne changera pas non plus de
coordonnées x et y. Par contre tous les autres points, à l’intérieur de la sphère vont avoir
leurs trois coordonnées modifiées par la déformation. Le schéma ci-dessous explique
comment les nouvelles coordonnées d’un point déformé seront calculées.
Nous supposons que le point avant déformation est à l’intérieur de la sphère de défor-
mation et que le centre de déformation est sous le plan z = 0. Si le centre est au dessus, il
suffit d’inverser le signe de z 0 après les calculs.
Regardons d’abord le plan vertical.
r
=↵
Ra
cos(↵) = Z0 R0
r
sin( ) = R
r = [Link](( Ra ).cos 1 ( Z0
0 r
R ))
. [Link](sub [,start [,end]]) : premier indice de s où le sous Méthodes sur les fichiers
string sub est trouvé dans s[start:end]
. f = open('fichier') : ouvre ’fichier’ en lecture (autre para-
. [Link]( old, new[, co]) : copie de s en remplaçant mètres possibles : 'w'(en écriture), 'a'(en écriture avec ajout),
toutes les (ou les co premières) occurrences de old par new. encoding ='utf-8' : encodage UTF-8)
. [Link](...) : copie de s après formatage . with open('fichier'...) as f : ouvre ’fichier’ pour traite-
. [Link]() : copie de s avec première lettre en majuscule ment à l’intérieur du with
. [Link]() : copie de s en retirant les blancs en début et fin . for ligne in open('fichier'...) : ouvre et traite chaque
. [Link](t) : crée un str qui est le résultat de la concaténation ligne de ’fichier’ et le ferme à la fin du for
des éléments de la séquence de str t chacun séparé par le str s . [Link]() : retourne le contenu du fichier texte f
. [Link]([sep [,maxsplit]) : renvoie une liste d’éléments . [Link]() : lit une ligne
séparés dans s par le caractère sep (par défaut blanc) ; au . [Link]() : renvoie la liste des lignes de f
maximum maxsplit séparations sont faites (par défaut l’infini)
. [Link](s) : écrit la chaîne de caractères s dans le fichier f
. [Link]() : ferme f 23.10.2020
. N’utilisez pas les instructions break ou continue . Évitez de paraphraser le code. N’utilisez les commentaires que
. Utilisez la forme raccourcie if(is_leap_year(2008)) plutôt lorsque la fonction d’un bout de code est difficile à comprendre.
que la forme équivalente if(is_leap_year(2008)==true)
Structure d’un programme Python
. Utilisez la forme return <expression booléenne > plutôt que
la forme équivalente
if <expression booléenne >: 1. Voir verso
res = True
else:
res = False
return res
. N’exécutez pas plusieurs fois une fonction alors qu’une exécu-
tion suffit en retenant le résultat.
. Précisez le domaine de validité des paramètres.
CC BY-SA 3.0 - 2021 - Sébastien Hoarau - Thierry Massart - Jean Olgiati - Isabelle Poirier 335
Apprendre à coder avec Python, Version - Release 3.0
sortie, 44
split, 214
strip, 210, 230
sudoku, 280, 284
sum, 209
syntaxe, 44
syntaxe de l'instruction for, 102
syntaxe de l'instruction if, 78
syntaxe de l'instruction while, 96
Ubuntu, 22
update, 264
upper, 210
UpyLaB, 4, 27, 29, 49
while, 95
Windows, 20
with, 231
write, 233
zip, 209