420-SN1 / Programmation en sciences éd. 260516
Copyright © 2025-2026
1. Les programmes
Copyright © 2025-2026
2. Les erreurs et la console
Copyright © 2025-2026
3. Arithmétique et variables
Copyright © 2025-2026
4. Entrées et conditions
Copyright © 2025-2026
5. Les fonctions
Copyright © 2025-2026
6. Boucles while
Copyright © 2025-2026
7. Boucles for
Copyright © 2025-2026
8. Introduction aux listes
Copyright © 2025-2026
9. Manipulation des listes
Copyright © 2025-2026
10. Les chaînes de caractères
Copyright © 2025-2026
11. Fichiers CSV
Copyright © 2025-2026
Intro
Tortue
Mouvement
Ex1
Ligne
Ex2
Ex3
Images
Ex4
Affichage
Ex5
Ex6
Résumé
Ex7
Ex8
Ex9
Ex10
Ex11
Ex12
Ex13
Ex14
Ex15
Erreurs
Ex1
Ex2
Console
Ex3
Tortue
Sauter
Ex4
Couleur
Ex5
Ex6
Commenter
Ex7
Multilignes
Résumé
Ex8
Ex9
Ex10
Ex11
Ex12
Ex13
Ex14
Ex15
Intro
Nombre
Ex1
Ex2
Variable
Nom
Ex3
Ex4
Répéter
Ex5
Arrondir
Ex6
Absolue
Ex7
MinMax
Ex8
Math
Ex9
Modulo
Ex10
Hasard
Ex11
Ex12
Résumé
Ex13
Ex14
Ex15
Ex16
Ex17
Ex18
Input
Type
Ex1
Ex2
Ex3
Comp
Ex4
If
Ex5
Ex6
Else
Ex7
Ex8
Elif
Ex9
AndOr
Not
Ex10
Ex11
Résumé
Ex12
Ex13
Ex14
Ex15
Ex16
Ex17
Ex18
Ex19
Ex20
Ex21
Ex22
Intro
Ex1
Fonction
Ex2
Ex3
Retour
Ex4
Ex5
Afficher
Ex6
Ex7
Effets
Ex8
Ex9
Résumé
Ex10
Ex11
Ex12
Ex13
Ex14
Ex15
Ex16
Ex17
Ex18
Ex19
Ex20
Ex21
Boucle
While
Ex1
Ex2
Accumul
Ex3
WhileTrue
Ex4
Animation
Ex5
Ex6
Break
Ex7
Continue
Ex8
Contrôle
Résumé
Ex9
Ex10
Ex11
Ex12
Ex13
Ex14
Ex15
Ex16
Ex17
Ex18
Ex19
Ex20
For
Range
Ex1
Ex2
Ex3
Décroissant
Ex4
Break
Ex5
Continue
Ex6
Imbrication
Ex7
Ex8
For/While
Résumé
Ex9
Ex10
Ex11
Ex12
Ex13
Ex14
Ex15
Ex16
Ex17
Liste
Contenu
Ex1
Ex2
Append
Ex3
Longueur
Ex4
Ex5
Ex6
Itérer
Ex7
Résumé
Ex8
Ex9
Ex10
Modifier
Ex1
Insérer
Retirer
Ex2
Ex3
Ex4
Concaténer
Ex5
Tranches
Ex6
Ex7
Ex8
Résumé
Ex9
Ex10
Ex11
Ex12
Ex13
Ex14
Ex15
Intro
Ex1
Échappement
Ex2
Spéciaux
Opérations
Longueur
Index
Concaténation
Ex3
Split
Ex4
Ex5
Fichiers
Ex6
Join
Ex7
Ex8
Upper/Lower
Ex9
Ex10
Tests
Ex11
str
f-string
Ex12
Résumé
Ex13
Ex14
Ex15
Ex16
Ex17
Ex18
Intro
Lecture
Ex1
Ex2
Ex3
Ex4
Écriture
Graphique
Courbe
Options
Ex5
Ex6
Résumé
Ex7
Ex8
Ex9
Ex10
Ex11
Ex12
Ex13
Ex14
Ex15

Bienvenue au cours de Programmation en sciences!

BOOT




Auteurs :

Marc-André Bélanger

Maël Charpentier

Christian Côté

Marc Feeley

Olivier Melançon


Illustrations :

Isabelle Feeley


Relecture et commentaires :

Pierre-Olivier Rathé


Ce cours constitue une introduction au domaine de la programmation et propose un parcours progressif à travers ses concepts fondamentaux. Vous explorerez les principes qui permettent d’écrire des programmes et d’en comprendre le fonctionnement, en développant graduellement les compétences nécessaires pour effectuer des calculs scientifiques, analyser des données, créer des simulations physiques et aborder d’autres applications de la programmation. Tout au long de ce voyage, vous partirez à la découverte d’un trésor caché : les connaissances et compétences qui vous permettront de naviguer le monde de la programmation en sciences.


Table des matières

1. Les programmes Qu’est-ce qu’un programme informatique ? 2. Les erreurs et la console Comment lire des messages d’erreurs et utiliser la console ? 3. Arithmétique et variables Comment faire des calculs mathématiques ? 4. Entrées et conditions Comment un programme prend-il des décisions ? 5. Les fonctions Comment créer nos propres fonctions pour réutiliser du code ? 6. Boucles while Comment répéter des actions avec des boucles while ? 7. Boucles for Comment répéter des actions avec des boucles for ? 8. Introduction aux listes Comment combiner des données ? 9. Manipulation des listes Comment traiter un grand nombre de données ? 10. Les chaînes de caractères Comment traiter du texte ? 11. Fichiers CSV Comment traiter les fichiers CSV ?

Qu’est-ce que la programmation ?


Les programmes peuvent prendre de nombreuses formes : une page web, un jeu vidéo, une application mobile ou encore le logiciel qui fait fonctionner un robot. Quelle que soit leur apparence, ils reposent tous sur le même principe : ils sont un ensemble d’instructions à exécuter dans un certain ordre pour atteindre le but désiré. Un programme est donc comparable à une recette qui indique à l’ordinateur comment accomplir une tâche.

L’écriture de ces instructions s’appelle la programmation.

Pour donner ces instructions à l’ordinateur, on utilise un langage de programmation. Un langage de programmation est composé de mots-clés et de symboles qui ont une signification précise pour l’ordinateur. Le code désigne l’ensemble des instructions d’un programme écrites dans un langage de programmation donné.

Dans ce manuel, nous apprendrons à programmer en utilisant le langage Python, un langage très populaire dont le code est relativement simple à lire et à comprendre.

Voici un premier exemple de programme. Il est normal de ne pas tout comprendre immédiatement ; essayez simplement de deviner ce qu’il fait en lisant le code.

clear()
pencolor("red")
image("crab")

À la fin de ce chapitre, vous aurez acquis les notions nécessaires pour comprendre ce programme et en écrire d’autres du même genre.

Dans ce manuel, vous pouvez cliquer sur les exemples de programmes pour les ouvrir dans un environnement de développement. Un environnement de développement permet d’écrire, de modifier et d’exécuter du code.

Cliquez sur l’exemple précédent pour exécuter les trois instructions de ce programme, qui dessine un crabe rouge.

Les dessins avec la tortue


Une façon amusante de produire des dessins avec un ordinateur consiste à utiliser une tortue. Imaginez une petite tortue qui se déplace sur une feuille de papier quadrillé. Lorsqu’elle avance, elle laisse une trace derrière elle et dessine des lignes sur son passage.

Dans l’image ci-dessous, la tortue a dessiné un carré. Le petit triangle rouge indique la position actuelle de la tortue ainsi que la direction dans laquelle elle est orientée - un peu comme une flèche montrant le chemin qu’elle suivra si on la fait avancer.

Ce dessin a été créé par le programme suivant :

fd(50)

rt(90)
fd(50)

rt(90)
fd(50)

rt(90)
fd(50)

Dans l’environnement de développement, vous pouvez exécuter le programme à nouveau à l’aide du bouton (Exécuter).

Lorsque le bouton Exécuter est utilisé, le programme redémarre du début. On peut donc exécuter le programme autant de fois qu’on le désire.

Mouvement de la tortue

fdbk


Voici les principales instructions permettant de déplacer la tortue :

  • fd(n) : faire avancer la tortue de n pixels
  • bk(n) : faire reculer la tortue de n pixels
  • rt(angle) : faire tourner la tortue vers la droite de angle degrés
  • lt(angle) : faire tourner la tortue vers la gauche de angle degrés

Parfois, il est utile d’exécuter un programme lentement, une instruction à la fois, afin de bien comprendre son fonctionnement. Débutez l’exécution du programme ci-dessous en cliquant dessus, puis dans l’environnement de développement, cliquez sur (Exécuter le premier pas), puis continuez avec (Exécuter le prochain pas).

fd(50)

lt(120)
fd(100)

lt(120)
fd(100)

rt(60)
bk(50)

Comme beaucoup de mots-clés en programmation, les noms de ces instructions sont des abbréviations qui proviennent de l’anglais. Par exemple, fd vient de forward (« vers l’avant ») et rt vient de right turn (« tourner à droite »).

Exercice 1


À l’aide de l’environnement de développement à droite, écrivez un programme qui fait un rectangle ayant une largeur de 150 pixels et une hauteur de 50 pixels.

À la fin de l’exécution de votre programme votre dessin doit être identique au dessin ci-dessus.

Pour exécuter votre programme, utilisez le bouton (Exécuter).

Solution

Chaque ligne horizontale est dessiné avec l’instruction fd(150) et chaque ligne verticale est dessiné avec l’instruction fd(50). Entre chaque instruction de déplacement il faut que la tortue tourne de 90° vers la gauche avec l’instruction lt(90) (left turn de 90°) pour que la tortue se dirige dans la bonne direction pour faire la prochaine ligne.

fd(150)

lt(90)
fd(50)

lt(90)
fd(150)

lt(90)
fd(50)

Ligne de la tortue


On peut modifier l’apparence de la ligne laissée par la tortue à l’aide des instructions suivantes :

  • pensize(n) : changer l’épaisseur de la ligne à n pixels
  • pencolor(couleur) : changer la couleur de la ligne

Plusieurs couleurs communes sont disponibles et le nom doit être donné en anglais. Par exemple, pencolor("pink") correspond à la couleur rose et pencolor("yellow") à la couleur jaune. Il est important d’entourer le nom de la couleur de guillemets (").

On peut aussi cacher ou montrer la tortue, et effacer le dessin :

  • ht() : cacher la tortue
  • st() : montrer la tortue
  • clear() : effacer le dessin et réinitialiser la tortue

Voici un exemple qui utilise ces instructions pour dessiner une tour colorée.

lt(90)
bk(60)

pencolor("red")
pensize(60)
fd(60)

pencolor("green")
pensize(50)
fd(50)

pencolor("violet")
pensize(30)
fd(30)

ht()

N’oubliez pas que vous pouvez toujours utiliser les boutons (Exécuter le premier pas) et (Exécuter le prochain pas) pour faire l’exécution du programme un pas à la fois, ou bien, pour tout exécuter, le bouton (Exécuter).

Dans le dessin de la tour l’instruction bk(60) va faire une ligne noire. Cependant l’instruction fd(60) va ajouter une ligne rouge au dessus. La ligne noire n’est donc pas visible.

Exercice 2


À l’aide de l’environnement de développement à droite, écrivez un programme qui utilise la tortue pour dessiner le drapeau de la France.

Les dimensions de ce drapeau sont de 150 pixels de large par 100 pixels de haut. Chaque bande de couleur mesure 50 pixels de large.

Indice

Inspirez-vous de l’exemple de la page précédente en utilisant une ligne de largeur 100 et en dessinant les lignes de gauche à droite.

Solution

En utilisant pensize(100), on peut dessiner le drapeau en trois large lignes de gauche à droite.

Le premier déplacement permet de reculer la tortue à la bordure gauche du drapeau. Puis on fait 3 déplacements de même longueur vers la droite en changeant la couleur avec pencolor("blue") pour la bande bleue, pencolor("white") pour la bande blanche, et pencolor("red") pour la bande rouge.

pensize(100)
pencolor("blue")

bk(75)

fd(50)

pencolor("white")
fd(50)

pencolor("red")
fd(50)

ht()

Exercice 3

30°150


À l’aide de l’environnement de développement à droite, écrivez un programme qui utilise la tortue pour dessiner un triangle rectangle dont la longueur de l’hypothénuse (le plus long côté) est 150 pixels et l’angle entre la base et l’hypothénuse est 30 degrés comme ci-dessus.

Il est bon de se rappeler quelques notions de géométrie : le sinus de 30° vaut 0,5 et le cosinus de 30° vaut approximativement 0,866. Dans ce triangle rectangle, la hauteur correspond à la longueur de l’hypoténuse multipliée par le sinus de 30°, et la base correspond à la longueur de l’hypoténuse multipliée par le cosinus de 30°.

Dans le code on utilise un point (.) dans un nombre décimal pour séparer la partie entière et les décimales, donc 0.866 c’est la valeur qui s’écrit normalement 0,866 en français.

D’autre part, dans le code on se sert du symbole * pour la multiplication. On écrit donc 150 * 0.866 pour calculer 150 multiplié par 0,866.

Solution

Il faut que la tortue fasse trois déplacements avec des rotations après le premier et le deuxième déplacements. Puisque la tortue pointe directement vers la droite, la base du triangle peut se dessiner avec un déplacement par en arrière. La longueur du déplacement sera la longueur de l’hypothénuse multipliée par le cosinus de 30° (0,866). Une rotation de 30° suivie d’un déplacement de 150 pixels va dessiner l’hypothénuse. Pour dessiner la hauteur il reste à faire une rotation de 120° et faire un déplacement de longueur égale à la longueur de l’hypothénuse multipliée par le sinus de 30° (0,5).

bk(150 * 0.866)
lt(30)
fd(150)
rt(120)
fd(150 * 0.5)
ht()

Images prédéfinies

Il peut être difficile de réaliser certains dessins uniquement à l’aide de déplacements et de rotations de la tortue. Pour simplifier le travail, on peut utiliser l’instruction image(nom), qui permet d’afficher des images prédéfinies.

Voici quelques unes des images disponibles :

"square""star""triangle""+""-""T""L""X""elbow""ring""ring180""disk""disk180""disk60""crab""ant""spider""snake""fish""turtle""rocket"

L’orientation de l’image dépend de l’orientation de la tortue au moment où l’image est dessinée. La couleur de l’image correspond à la dernière couleur définie avec pencolor, ou est noire si aucune couleur n’a été spécifiée.

Les images dessinées sont approximativement d’une taille de 100 × 100 pixels.

Pour obtenir une autre taille on peut donner un facteur d’agrandissement après le nom de l’image. Par exemple, ce programme dessine une araignée trois fois la taille normale à un angle de rotation de 30° :

lt(30)
image("spider", 3)
ht()

Dans le cas des images multicolores, telles le poisson, la tortue et la fusée, l’utilisation de pencolor permet de changer la couleur du corps seulement. Par exemple :

pencolor("gold")
image("fish", 3)
ht()

Astuce : la couleur naturelle du corps, c’est-à-dire celle dans le diagramme ci-dessus, peut s’obtenir en utilisant l’instruction pencolor("BLACK").

Exercice 4


Écrivez un programme qui va afficher le dessin ci-dessus en combinant l’image "disk" et l’image "star".

Le disque noir a un diamètre de 100 pixels tandis que l’étoile est 20% plus petite.

Solution

Puisque l’étoile jaune est plus petite que le disque noir il faut faire un rétrécissement de l’étoile en donnant un facteur d’agrandissement inférieur à 1. Avec un facteur d’agrandissement de 0,8 on obtient un rétrécissement de 20%.

image("disk")
pencolor("yellow")
image("star", 0.8)
ht()

Afficher un résultat


L’un des grands avantages des ordinateurs est leur capacité à effectuer des calculs très rapidement. Pour connaître le résultat d’un calcul, il faut l’afficher à l’écran.

L’instruction print permet d’afficher du texte ou des nombres dans la console.

Par exemple, le programme suivant calcule et affiche une estimation du nombre de cheveux sur une tête humaine typique.

print("Nombre de cheveux moyen par cm² :", 200)
print("Superficie moyenne d'un cuir chevelu en cm² :", 1000)
print("Nombre de cheveux sur une tête typique :", 200 * 1000)

L’exécution de ce programme va afficher à la console ce texte :

Nombre de cheveux moyen par cm² : 200
Superficie moyenne d'un cuir chevelu en cm² : 1000
Nombre de cheveux sur une tête typique : 200000

L’instruction print permet d’afficher des lignes contenant plusieurs choses, ci-dessus chaque ligne contient un texte suivi d’un nombre.

Exercice 5


Maintenant utilisez l’environnement de développement à droite pour modifier le programme afin qu’il calcule le nombre de cheveux pour toutes les personnes sur la planète, en supposant que la population mondiale est 8 milliards.

print("Nombre de cheveux moyen par cm² :", 200)
print("Superficie moyenne d'un cuir chevelu en cm² :", 1000)
print("Nombre de cheveux sur une tête typique :", 200 * 1000)

Solution

On modifie le calcul en ajoutant une multiplication par la population mondiale.

Pour un affichage plus clair on peut également adapter le texte affiché par les print.

print("Nombre de cheveux moyen par cm² :", 200)
print("Superficie moyenne d'un cuir chevelu en cm² :", 1000)
print("Population mondiale estimée :", 8000000000)
print("Nombre de cheveux dans le monde :",
      200 * 1000 * 8000000000)

Une instruction print affiche toujours une ligne complète. Même si une instruction s’étend sur plusieurs lignes dans le code, comme la dernière instruction du programme précédent, elle produira une seule ligne à l’écran.

Exercice 6

   #
  ###
 #####
#######

Il est possible d’utiliser print pour afficher du texte qui représente une image.

Écrivez un programme qui utilise print pour afficher à la console la forme pyramidale ci-dessus.

Solution

On affiche les quatre étages de la pyramide un à la fois. Il faut donc utiliser quatre instructions print.

print("   #")
print("  ###")
print(" #####")
print("#######")

Ce genre d’image se nomme Art ASCII. Une recherche de ce terme sur le Web permet de constater la richesse artistique de ce genre d’art. En voici un exemple :

print("               __")
print("              / _)")
print("     _.----._/ /")
print("    /         /")
print(" __/ (  | (  |")
print("/__.-'|_|--|_|")

Résumé

Instruction Description Exemple
print(x) Afficher du texte ou un nombre dans la console. print("Bonjour!")
print((7-1)*7)
fd(n) Avancer la tortue de n pixels vers l’avant. (forward) fd(50)
bk(n) Reculer la tortue de n pixels. (backward) bk(30)
rt(angle) Tourner la tortue vers la droite de angle degrés. (right turn) rt(90)
lt(angle) Tourner la tortue vers la gauche de angle degrés. (left turn) lt(45)
ht() Cacher la tortue. (hide turtle) ht()
st() Montrer la tortue. (show turtle) st()
clear() Retourner la tortue à sa position de départ et efface le dessin et la grille de fond. clear()
pensize(n) Changer l’épaisseur des prochaines lignes dessinées à n pixels. pensize(10)
pencolor(couleur) Changer la couleur des prochaines lignes dessinées par son nom anglais. pencolor("red")
image(nom) Dessiner une image prédéfinie à la position et orientation de la tortue. image("star")
dessinera une étoile
image(nomf) Dessiner une image agrandie d’un facteur f. image("star"1.5)
dessinera une étoile agrandie de 50%

Exercice 7

12080


Écrivez un programme qui affiche à la console l’aire et le périmètre d’un rectangle de largeur 120 et de hauteur 80. Utilisez deux print, le premier pour afficher l’aire et le second pour le périmètre.

Solution

On utilise les formules largeur × hauteur pour l’aire et 2 × (largeur + hauteur) pour le périmètre. On affiche les résultats avec print.

On se rappelle qu’il faut utiliser le symbole * pour la multiplication.

# Aire
print(120 * 80)

# Périmètre
print(2 * (120 + 80))

Cette solution contient des commentaires. Un commentaire est du texte commençant par le symbole #. Tout ce qui suit le # sur la ligne sera ignoré par l’ordinateur. Ça permet d’inclure dans le code des explications pour les humains qui veulent comprendre son fonctionnement. Dans cette solution on comprends que le premier print fait l’affichage de l’aire du rectangle et le deuxième fait l’affichage de son périmètre. Sans ces commentaires la logique du code serait plus difficile à comprendre.

Exercice 8

+-------+-------+
| o o o | o   o |
| o o o | o   o |
+-------+-------+

Écrivez un programme qui utilise print pour afficher à la console l’art ASCII ci-dessus d’un domino fait des caractères o, +, -, | et blanc.

Solution

L’image du domino est composée de quatre lignes de texte, on utilise donc quatre instructions print.

print("+-------+-------+")
print("| o o o | o   o |")
print("| o o o | o   o |")
print("+-------+-------+")

Il est aussi possible d’utiliser les triples guillemets (""") pour écrire un texte de plusieurs lignes dans une seule instruction print.

print("""
+-------+-------+
| o o o | o   o |
| o o o | o   o |
+-------+-------+
""")

Remarquez que le résultat n’est pas exactement le même, car une ligne vide apparaîtra avant et après limage.

Exercice 9

5060°


Écrivez un programme qui utilise la tortue pour dessiner l’hexagone régulier ci-dessus dont chaque côté mesure 50 pixels. Le coin inférieur gauche de l’hexagone doit se trouver aux coordonnées (0, 0).

Solution

Chacun des six côté de l’hexagone sera tracé par l’instruction fd(50). Il est important de tourner la tortue de 60° vers la gauche avec l’instruction lt(60) entre chaque ligne qui est dessinée.

# Dessiner le côté #1
fd(50)

# Dessiner le côté #2
lt(60)
fd(50)

# Dessiner le côté #3
lt(60)
fd(50)

# Dessiner le côté #4
lt(60)
fd(50)

# Dessiner le côté #5
lt(60)
fd(50)

# Dessiner le côté #6
lt(60)
fd(50)

ht()

Ce programme se sert de commentaires pour clarifier le code. Les commentaires sont ignorés par l’ordinateur et aident les humains à comprendre le code.

Exercice 10


Utilisez la tortue pour reproduire le dessin ci-dessus. Les côtés des carrés bleu et vert sont de 130 pixels. Les côtés du carré rose sont de 92 pixels.

Utilisez pencolor("lime") pour obtenir la bonne teinte de vert.

Solution

Cette forme peut être construite en superposant trois carrés. On dessine les carrés dans un ordre précis (bleu, vert, rose) pour qu’ils soient superposés correctement.

Voici une première solution qui dessine chaque carré avec l’image "square" et un facteur d’agrandissement de 1,3 pour obtenir un carré avec des côtés de 130 pixels, et un facteur d’agrandissement de 0,92 pour obtenir un carré avec des côtés de 92 pixels.

pencolor("blue")
image("square", 1.3)

rt(45)
pencolor("lime")
image("square", 1.3)

lt(45)
pencolor("pink")
image("square", 0.92)

ht()

Pour rendre le code plus compact, on peut utiliser un point-virgule (;) pour séparer des instructions placées sur une même ligne, par exemple :

pencolor("blue"); image("square", 1.3)

rt(45)
pencolor("lime"); image("square", 1.3)

lt(45)
pencolor("pink"); image("square", 0.92)

ht()

Voici une deuxième solution qui dessine chaque carré avec un déplacement de tortue et en utilisant pensize pour obtenir un carré de la bonne taille.

pencolor("blue")
pensize(130)
bk(65)
fd(130)
bk(65)

rt(45)
pencolor("lime")
bk(65)
fd(130)
bk(65)

lt(45)
pencolor("pink")
pensize(92)
bk(46)
fd(92)

ht()

Exercice 11


Utilisez la tortue pour reproduire le dessin ci-dessus.

Indice

Il est possible de créer cette image en superposant des carrés de 140 pixels de côté.

Solution

Cette forme peut être construite en superposant quatre carrés jaunes, chacun tourné de 22,5 degrés par rapport au précédent.

pencolor("yellow")

image("square", 1.4)

lt(22.5)
image("square", 1.4)

lt(22.5)
image("square", 1.4)

lt(22.5)
image("square", 1.4)

ht()

Exercice 12


Utilisez la tortue pour dessiner le drapeau de la Suisse.

Ce drapeau est un carré de 100 × 100 pixels. Les dimensions de la croix au centre du drapeau sont de 60 × 60 pixels. L’épaisseur des bandes formant la croix est de 20 pixels.

Solution

On utilise image("square") pour dessiner le fond rouge du drapeau. La croix blanche est ensuite dessinée avec pensize(20) et des déplacements de tortue à partir du centre du drapeau.

# Fond rouge
pencolor("red")
image("square")

# Bande horizontale pour la croix
pencolor("white")
pensize(20)
bk(30)
fd(60)
bk(30)

# Bande verticale pour la croix
rt(90)
bk(30)
fd(60)
bk(30)

ht()

On ne peut pas se servir de image("+", 0.6) pour dessiner la croix car ça ne donnerait pas la bonne épaisseur des lignes de la croix.

# Fond rouge
pencolor("red")
image("square")

# Croix blanche
pencolor("white")
image("+", 0.6)

ht()

Exercice 13

601020101206010201060


Utilisez la tortue pour dessiner le drapeau de la Norvège.

Ce drapeau est de dimensions 220 × 160 pixels. Les dimensions des parties sont inscrites dans le dessin ci-dessus.

Solution

Une astuce pour dessiner ce drapeau est de d’abord dessiner un fond rouge, puis une croix blanche et finalement une croix bleue par-dessus la croix blanche.

# Dessiner le fond rouge
pencolor("red")
pensize(160)
bk(110)
fd(220)

# Dessiner la croix blanche
pencolor("white")
pensize(40)
bk(220)
fd(80)
lt(90)
fd(80)
bk(160)
fd(80)

# Dessiner la croix bleue
pencolor("blue")
pensize(20)
fd(80)
bk(160)
fd(80)
rt(90)
bk(80)
fd(220)

ht()

Exercice 14

30°116


Utilisez la tortue pour faire le dessin ci-dessus d’une enveloppe avec la contrainte que la tortue ne doit pas repasser le long d’une ligne déjà dessinée et pencolor ne doit pas être utilisé. La largeur de l’enveloppe est 116 pixels et les diagonales sont à 30°.

La longueur des diagonales sera égale à la largeur de l’enveloppe divisée par le cosinus de 30° qui vaut approximativement 0,866. Les côtés verticaux de l’enveloppe auront une longueur égale à la moitié de la longueur des diagonales car le sinus de 30° est 0,5.

Dans le code on se sert du symbole / pour la division. On écrit donc 116 / 0.866 pour calculer 116 divisé par 0,866.

Solution

L’astuce pour faire ce dessin c’est de commencer par un des coins inférieurs de l’enveloppe. La longueur des déplacement diagonaux sont égaux à la largeur de l’enveloppe divisé par le cosinus de 30°, donc 116 / 0.866.

# Dessiner la base de l'enveloppe
fd(116)

# Dessiner les sept autres lignes
lt(90);  fd(116/0.866/2)
lt(60);  fd(116/0.866/2)
lt(60);  fd(116/0.866/2)
lt(60);  fd(116/0.866/2)
lt(120); fd(116/0.866)
lt(150); fd(116)
lt(150); fd(116/0.866)

ht()

Exercice 15


Utilisez la tortue pour faire le symbole de radiation ci-dessus.

Indice

Ce symbole peut se dessiner uniquement avec les images "disk" et "disk60" en différentes tailles, couleurs et orientations.

Solution

L’astuce pour faire ce dessin c’est de dessiner les images dans un ordre précis.

Pour faire la bordure noire on commence avec un grand disque noir et on superpose un disque jaune légèrement plus petit.

Ensuite on peut dessiner les trois parties noires avec l’image "disk60" avec des rotations de 120° d’une image à l’autre.

Finalement pour le centre on peut dessiner un disque jaune sur lequel on superpose un disque noir légèrement plus petit.

Les facteurs d’agrandissement ont été trouvés par essai et erreur.

# dessiner la bordure noire autour d'une zone jaune

image("disk")

pencolor("yellow")
image("disk", 0.93)

# dessiner les trois parties noires

pencolor("black")

lt(60)
image("disk60", 0.84)

lt(120)
image("disk60", 0.84)

lt(120)
image("disk60", 0.84)

# dessiner le centre

pencolor("yellow")
image("disk", 0.25)

pencolor("black")
image("disk", 0.17)

ht()

Les erreurs


Tôt ou tard on fait des erreurs dans les instructions données à l’ordinateur. Lorsqu’une instruction dans le code n’a pas de sens, l’environnement de développement affiche un message d’erreur et la position de l’erreur dans le code est surlignée. Voici quelques exemples d’erreurs. Portez attention au message d’erreur!

Une parenthèse fermante a été oubliée :

print("Bonjour!"

On a mal écrit print.

pint("Bonjour!")

Si l’erreur est détectée par l’ordinateur pendant l’exécution du programme, le programme arrête après avoir exécuté une partie du code. Par exemple, dans le programme ci-dessous l’exécution arrêtera à la troisième ligne car c’est à ce moment que l’erreur est détectée (on a oublié d’indiquer l’angle de rotation).

pensize(5)
fd(50)
lt()
fd(100)

En programmant, il est normal de faire des erreurs. Ce qui est important est de bien lire le message d’erreur pour comprendre ce qui s’est passé afin d’apporter un correctif au code.

Exercice 1

<sodipodi:namedview id="base_6" bordercolor="#666666" inkscape:pageshadow="2" inkscape:window-width="787" pagecolor="#ffffff" inkscape:zoom="0.96453460" inkscape:window-x="22" borderopacity="1.0" inkscape:current-layer="Layer_1_6" inkscape:cx="202.55200" inkscape:cy="186.61850" inkscape:window-y="29" inkscape:window-height="510" inkscape:pageopacity="0.0" /> <rdf:RDF > <cc:Work > <dc:format >image/svg+xml</dc:format > <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <cc:license rdf:resource="http://creativecommons.org/licenses/publicdomain/" /> <dc:publisher > <cc:Agent rdf:about="http://openclipart.org/" > <dc:title >Openclipart</dc:title > </cc:Agent > </dc:publisher > <dc:title >Architetto -- tramezzino</dc:title > <dc:date >2010-03-28T10:26:26</dc:date > <dc:description >Drawing by Francesco 'Architetto' Rollandin. From OCAL 0.18 release.</dc:description > <dc:source >https://openclipart.org/detail/34861/architetto----tramezzino-by-anonymous</dc:source > <dc:creator > <cc:Agent > <dc:title >Anonymous</dc:title > </cc:Agent > </dc:creator > <dc:subject > <rdf:Bag > <rdf:li >food</rdf:li > <rdf:li >sandwich</rdf:li > </rdf:Bag > </dc:subject > </cc:Work > <cc:License rdf:about="http://creativecommons.org/licenses/publicdomain/" > <cc:permits rdf:resource="http://creativecommons.org/ns#Reproduction" /> <cc:permits rdf:resource="http://creativecommons.org/ns#Distribution" /> <cc:permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks" /> </cc:License > </rdf:RDF >


Le programme dans votre environnement de développement doit imprimer la facture d’un restaurant, mais le code contient des erreurs. Exécutez le programme et lisez attentivement les messages d’erreurs. Corrigez les erreurs jusqu’à ce que le programme affiche :

Menu du jour
-------------------------
Soupe du jour ....  4.50$
Sandwich .........  6.75$
Café .............  2.00$
-------------------------
Total ............ 13.25$
print("Menu du jour")
print( ------------------------- )
print("Soupe du jour ....  4.50$")
print("Sandwich .........  6.75$")
print("Café .............  2.00$")
prnit("-------------------------")
print("Total ............ 13.25$"

Solution

Pour résoudre ce problème, on exécute le programme. L’environnement de développement nous montre alors où une erreur se trouve dans le code et affiche un message d’erreur qu’il faut lire pour comprendre le problème.

Le programme contenait trois erreurs.

  1. Les guillemets sont manquants autour du texte de la deuxième ligne.
  2. print a été mal écrit à l’avant dernière ligne.
  3. Il manque une parenthèse fermante à la dernière ligne.
print("Menu du jour")
print("-------------------------")
print("Soupe du jour ....  4.50$")
print("Sandwich .........  6.75$")
print("Café .............  2.00$")
print("-------------------------")
print("Total ............ 13.25$")

Exercice 2


Le programme dans votre environnement de développement doit dessiner une pyramide rouge de six étages comme ci-dessus. Malheureusement ce programme contient des erreurs. Corrigez les erreurs jusqu’à ce que le programme complète son dessin.

rt(90)
pencolor("rouge")
pensize(15)
fd(15)
pensize(45)
fd(15)
pensize(75)
fd(15)
pensize(105)
ht(15)
pensize(135)
fd(15)
pensize(165)
fd(15)
ht()

Solution

Comme dans l’exercice précédent, on exécute le programme, on observe ce qui se passe dans le dessin et on lit les messages d’erreur.

Cette fois-ci, le programme contient deux erreurs.

  1. pencolor ne connait pas la signification de "rouge". Il faut plutôt écrire pencolor("red").
  2. Dans l’une des instructions, ht a été utilisé par erreur au lieu de fd.
rt(90)
pencolor("red")
pensize(15)
fd(15)
pensize(45)
fd(15)
pensize(75)
fd(15)
pensize(105)
fd(15)
pensize(135)
fd(15)
pensize(165)
fd(15)
ht()

La console


Les programmes que nous avons vu jusqu’à présent étaient enregistrés dans des fichiers. Parfois, on veut tester de petits fragments de code, par exemple pour apprendre ou pour trouver des erreurs.

Pour exécuter de petits fragments de code, on peut utiliser la console. Dans l’environnement de développement à droite, la fenêtre contenant >>> est appelée la console. Les caractères >>> sont appelés l’invite de commande (prompt en anglais).

Écrivez du code après l’invite de commande, puis appuyez sur la touche Entrée pour l’exécuter. Essayez d’exécuter les instructions suivantes et observez le résultat :

  • 1+2
  • print("bonjour!")
  • fd(100)

À la console la touche de clavier Entrée a la même fonctionalité que le bouton (Exécuter). Sur un clavier anglais cette touche de clavier a souvent l’étiquette Return ou Enter ou le symbole .

Exercice 3

123456789101112


Utilisez la console pour calculer le nombre de secondes dans une année commune, c’est à dire une année qui n’est pas bissextile.

Quel est le nombre de secondes dans une année commune ?

31536000

Solution

Le bonne réponse est 31536000 qu’on peut obtenir en exécutant le calcul 60 * 60 * 24 * 365 à la console.

Mouvement de la tortue avancé


Avec la tortue, quand on connait les composantes x et y d’un déplacement, on peut faire des déplacements en diagonale avec fd et bk :

  • fd(x,y) : avancer de x et se déplacer lattéralement de y à gauche
  • bk(x,y) : reculer de x et se déplacer lattéralement de y à droite

Par exemple, pour dessiner le triangle rectangle ci-dessous qui a des sommets aux coordonnées (0, 0), (60, 0) et (60, 80), on peut dessiner l’hypothénuse avec fd(60, 80) au lieu de calculer l’angle et la distance.

fd(60, 80)
bk(0, 80)
bk(60)

Positionner la tortue

<sodipodi:namedview id="namedview2901_7" bordercolor="#666666" inkscape:pageshadow="2" inkscape:window-y="-8" pagecolor="#ffffff" inkscape:window-height="838" inkscape:window-maximized="1" inkscape:zoom="0.50911688" inkscape:window-x="-8" showgrid="false" borderopacity="1.0" inkscape:current-layer="layer1_7" inkscape:cx="-8.2961304" inkscape:cy="385.29921" inkscape:window-width="1600" inkscape:pageopacity="0.0" inkscape:document-units="in" /> <rdf:RDF > <cc:Work > <dc:format >image/svg+xml</dc:format > <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <cc:license rdf:resource="http://creativecommons.org/licenses/publicdomain/" /> <dc:publisher > <cc:Agent rdf:about="http://openclipart.org/" > <dc:title >Openclipart</dc:title > </cc:Agent > </dc:publisher > <dc:title >Frog</dc:title > <dc:date >2010-08-02T15:18:44</dc:date > <dc:description /> <dc:source >https://openclipart.org/detail/76105/frog-by-gammillian</dc:source > <dc:creator > <cc:Agent > <dc:title >gammillian</dc:title > </cc:Agent > </dc:creator > <dc:subject > <rdf:Bag > <rdf:li >amphibian</rdf:li > <rdf:li >animal</rdf:li > <rdf:li >frog</rdf:li > <rdf:li >green</rdf:li > </rdf:Bag > </dc:subject > </cc:Work > <cc:License rdf:about="http://creativecommons.org/licenses/publicdomain/" > <cc:permits rdf:resource="http://creativecommons.org/ns#Reproduction" /> <cc:permits rdf:resource="http://creativecommons.org/ns#Distribution" /> <cc:permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks" /> </cc:License > </rdf:RDF >


Pour se déplacer sans laisser de trait on utilise hop(). Le déplacement qui vient après hop() se fera sans laisser de trait.

Par exemple, on peut utiliser hop() suivi d’un déplacement pour positionner la tortue au bon endroit au début d’un dessin ou pour faire des dessins composés de plusieurs parties disjointes comme celui-ci :

hop(); fd(140, 40)

fd(0, -80); bk(80); fd(0, 80); fd(80)

hop(); bk(200)

fd(0, -80); bk(80); fd(0, 80); fd(80)

ht()

Exercice 4


Utilisez la tortue pour dessiner un hexagone régulier dont chaque côté mesure 40 pixels. L’hexagone doit être centré à la position (0, 0).

Solution

Pour centrer l’hexagone, on utilise hop() pour positionner la tortue avant de commencer le dessin. On pourrait commencer à n’importe quel sommet de l’hexagone, mais dans cette solution on se déplace au sommet (0, 40).

# Positionner la tortue
hop()
fd(0, 40)

# Dessiner le côté #1
rt(30)
fd(40)

# Dessiner le côté #2
rt(60)
fd(40)

# Dessiner le côté #3
rt(60)
fd(40)

# Dessiner le côté #4
rt(60)
fd(40)

# Dessiner le côté #5
rt(60)
fd(40)

# Dessiner le côté #6
rt(60)
fd(40)

ht()

Couleur de la tortue avancée

On a vu qu’on peut changer la couleur du trait avec pencolor(nom). On peut donner une couleur plus précise en utilisant trois nombres entre 0 et 1 qui représentent les proportions de rouge, vert et bleu. Voici quelques exemples.

pencolor(1, 0, 0)pencolor(0, 1, 0)pencolor(0, 0, 1)pencolor(1, 0, 0.6)pencolor(1, 1, 0)pencolor(0, 0, 0)

On peut aussi spécifier une couleur avec un code de trois caractères qu’on appelle un code hexadécimal. Chaque caractère représente la proportion de rouge, vert et bleu en utilisant une échelle de 0 (0%) à 15 (100%) et où les chiffres de 10 à 15 sont représentés par les lettres a à f. Par exemple, pour 100% de rouge et 0% de vert et bleu, on peut écrire "#f00". Voici quelques exemples.

pencolor("#f00")pencolor("#0f0")pencolor("#00f")pencolor("#f0a")pencolor("#ff0")pencolor("#000")

Les exemples et exercices de ce manuel donnent parfois le code hexadécimal d’une couleur plutôt que ses proportions de rouge, vert et bleu, car c’est un format plus concis.

Exercice 5

À quelle couleur correspond l’instruction pencolor(1, 0, 1) ?

Solution

L'appel pencolor(r, g, b) donne les proportions de rouge, vert et bleu. Le mélange de rouge et de bleu donne la couleur magenta.

Pour en être certain, on peut aussi exécuter pencolor(1, 0, 1) dans la console, puis fd(100) pour voir la couleur du trait.

Exercice 6


Utilisez la tortue pour faire des carrés superposés comme ci-dessus.

Les couleurs des carrés sont 1,0,0, "darkred" et "#400". Pour le carré intermédiaire vous pouvez tourner la tortue ou utiliser l’image "diamond".

Solution

Bien que les couleurs des carrés soient données dans des format différents, ce sont tous des format reconnus par pencolor.

pencolor(1, 0, 0)
image("square")

hop()
pencolor("darkred")
image("diamond")

hop()
pencolor("#400")
image("square", 0.5)

ht()

Les commentaires


Les commentaires sont des parties de code ignorés par l’ordinateur, mais qui contiennent du texte qui aide à comprendre le code. Un commentaire commence avec le symbole #. Tout ce qui suit le # jusqu’à la fin de la ligne est un commentaire.

Voici un programme où on utilise des commentaires pour expliquer les différentes étapes pour faire un dessin.

# Ce programme dessine un carré

# Positionner la tortue dans le coin en bas à gauche
hop()
fd(-50, -50)

# Dessiner le carré
fd(100)
lt(90)
fd(100)
lt(90)
fd(100)
lt(90)
fd(100)
lt(90)

Exercice 7


Le programme dans votre environnement de développement dessine une petite maison comme ci-dessus. Ne modifiez pas les instructions du programme, mais ajoutez des commentaires pour expliquer chaque étape du programme.

hop()
lt(90)
bk(30)

pencolor("#f40")
pensize(50)
fd(50)

pencolor("#840")
pensize(60)
fd(10)
pensize(40)
fd(10)
pensize(20)
fd(10)

ht()

Solution

On ajoute un commentaire en haut du programme pour expliquer sa tâche.

On divise ensuite le programme en trois parties : positionner la tortue, dessiner le mur de la maison, et dessiner le toit de la maison. Juste avant chaque partie on utilise # pour ajouter un commentaire expliquant ce qu’elle fait.

# Ce programme dessine une petite maison

# Positionner la tortue
hop()
lt(90)
bk(30)

# Dessiner le mur de la maison
pencolor("#f40")
pensize(50)
fd(50)

# Dessiner le toit de la maison
pencolor("#840")
pensize(60)
fd(10)
pensize(40)
fd(10)
pensize(20)
fd(10)

ht()

Les commentaires doivent être clairs et concis. Ils doivent expliquer le fonctionnement du programme, pas ce que chaque instruction fait. Par exemple, voici une solution avec des commentaires trop détaillés :

# Ce programme dessine une petite maison

# Positionner la tortue
hop()  # Sauter
lt(90) # Tourner à gauche de 90 degrés
bk(30) # Reculer de 30 unités

# Dessiner le mur de la maison
pencolor("#f40")   # Changer la couleur du trait à orange
pensize(50)        # Changer la taille du trait à 50
fd(50)             # Avancer de 50 unités

# Dessiner le toit de la maison
pencolor("#840") # Changer la couleur du trait à brun
pensize(60)      # Changer la taille du trait à 60
fd(10)           # Avancer de 10 unités
pensize(40)      # Changer la taille du trait à 40
fd(10)           # Avancer de 10 unités
pensize(20)      # Changer la taille du trait à 20
fd(10)           # Avancer de 10 unités

ht()              # Cacher la tortue

Les commentaires multilignes

Si on veut écrire un commentaire qui s’étend sur plusieurs lignes, on peut utiliser plusieurs #.

# Auteure : Ada Lovelace
# Date : 10 décembre 1832
#
# Ce programme dessine un crabe rouge avec un
# contour noir afin de donner un effet de relief.

image("crab")
pencolor("red")
image("crab", 0.95)

Une autre façon est d’utiliser un texte sur plusieurs lignes entouré de triples guillemets """.

"""
Auteure : Ada Lovelace
Date : 10 décembre 1832

Ce programme dessine un crabe rouge avec un
contour noir afin de donner un effet de relief.

"""

image("crab")
pencolor("red")
image("crab", 0.95)

Les triples guillemets """ peuvent servir à plusieurs choses. On peut les utiliser pour écrire un commentaire multiligne, mais aussi pour écrire un texte de plusieurs lignes qui sera affiché à l’écran avec print. Il faut garder en tête que le même symbole peut servir à différentes choses selon le contexte.

Résumé

Messages d’erreurs et console.

Terme Définition
Message d’erreur Texte affiché par l’environnement de développement lors d’une erreur dans le programme. Il est important de lire les messages d’erreurs!
Console Fenêtre contenant l’invite de commande (>>>) au haut de l’environnement de développement. La console permet de tester de petits fragments de code.

Tortue avancée.

Instruction Description Exemple
fd(xy) Avancer de x et se déplacer lattéralement de y à gauche. fd(3040)
bk(xy) Reculer de x et se déplacer lattéralement de y à droite. bk(2010)
hop() Faire sauter la tortue pour que le prochain déplacment se fasse sans laisser de trait. hop(); fd(100)
pencolor(r,g,b) Changer la couleur du trait à la proportion donnée de rouge, vert et bleu (entre 0 et 1). pencolor(1,0,0) changera la couleur au rouge
pencolor("#rgb") Changer la couleur du trait en utilisant un code hexadécimal. pencolor("#00f") changera la couleur au bleu

Commentaires.

Symbole Description Exemple
# Tout ce qui suit le # jusqu’à la fin de la ligne est un commentaire qui sert à expliquer le fonctionnement du programme. # …
""" On peut utiliser un texte sur plusieurs lignes entouré de triples guillemets pour écrire un commentaire multilignes.
"""
Ceci est un
long commentaire.
"""

Exercice 8

7


Le programme dans votre environnement de développement doit calculer et afficher la circonférence et l’aire d’un cercle de rayon 7, mais contient des erreurs. Corrigez les erreurs jusqu’à ce que le programme affiche le bon résultat.

print("Le rayon du cercle est de 7)
print("Circonférence :", 2 * pi * 7)
print("Aire :", 3.1416 x 7 x 7)

Solution

Le programme contient trois erreurs :

  • Il manque une guillemet fermante à la première ligne.
  • pi n’est pas défini. Il faut utiliser 3.1416 à la deuxième ligne.
  • Le symbole de multiplication est * et non x à la troisième ligne.
print("Le rayon du cercle est de 7")
print("Circonférence :", 2 * 3.1416 * 7)
print("Aire :", 3.1416 * 7 * 7)

Exercice 9

12090

Utilisez la tortue pour dessiner un triangle rectangle dont la longueur de la base est 120 pixels et la hauteur est 90 pixels comme ci-dessus.

Solution

On décide de placer les coins de notre triangle comme sur le dessin aux coordonnées (0, 0), (120, 0) et (120, 90), et on utilise fd pour tracer les traits entre ces coins.

fd(120)
fd(0, 90)
bk(120, 90)
ht()

Exercice 10

?


La vitesse de la lumière est d’exactement 299 972 458 m/s.

Depuis la Terre, on dirige un laser vers un miroir réfléchissant se trouvant sur la Lune. On calcule que la faisceau laser prend 2,6 secondes pour faire l’aller-retour Terre-Lune.

À l’aide de la console, calculez la distance entre la Terre et la Lune.

Quelle est la distance entre la Terre et la Lune en kilomètres arrondie au kilomètre près ?

389964

Solution

On fait le calcul 299972458 / 1000 * 2.6 / 2. Il ne faut pas oublier de diviser par 2, puisque le faisceau parcourt la distance Terre-Lune deux fois.

>>> 299972458 / 1000 * 2.6 / 2
389964.19539999997

La réponse est donc 389964 kilomètres.

Exercice 11


Utilisez la tortue pour dessiner trois carrés de couleurs différentes comme ci-dessus.

Dessinez les carrées en utilisant image("square") et centrez les aux positions (-110, -40), (0, 0) et (110, 40). Les couleurs des carrés sont "#f0a", 1,1,0 et "green".

Solution

Pour chaque carré, on positionne la tortue avec hop() suivi d’un déplacement avec fd ou bk. Les couleurs sont données dans trois formats différents, mais qui sont tous reconnus par pencolor.

hop()
bk(110, 40)
pencolor("#f0a")
image("square")

hop()
fd(110, 40)
pencolor(1, 1, 0)
image("square")

hop()
fd(110, 40)
pencolor("green")
image("square")

ht()

Exercice 12


Le programme dans votre environnement de développement doit dessiner le drapeau de la Suède, mais contient des erreurs. Corrigez les erreurs jusqu’à ce que le programme complète son dessin.

# Positionner la tortue
hop()
bk(80)

# Fond bleu
pensize(0, 0.29, 0.53)
pencolor(100)
fd(160)

# Barre jaune horizontale
pencolor(1, 0.8, 0)
pensize(20)
bk(160

# Barre jaune verticale
hop()
fd(60, -50)
fd(0 100)

ht()

Solution

Le programme contient trois erreurs :

  • Les noms pencolor et pensize ont été inversés lors du dessin du fond bleu.
  • Il manque une parenthèse au deuxième bk.
  • Une virgule a été oubliée au dernier fd.
# Positionner la tortue
hop()
bk(80)

# Fond bleu
pencolor(0, 0.29, 0.53)
pensize(100)
fd(160)

# Barre jaune horizontale
pencolor(1, 0.8, 0)
pensize(20)
bk(160)

# Barre jaune verticale
hop()
fd(60, -50)
fd(0, 100)

ht()

Lorsqu’on oublie une parenthèse, la parenthèse fermante sera cherchée sur la ligne suivante et l’erreur sera donc signalée sur cette ligne. C’est ce qui est arrivé ici lorsqu’on a oublié la parenthèse fermante de bk(160). Il est donc aussi important de vérifier si l’erreur est en fait survenue sur la ligne précédente.

Exercice 13

4560601059090


Utilisez la tortue pour dessiner le drapeau du Groenland ci-dessus.

Les couleurs utilisées sont le rouge ("#c13"), le blanc ("white"), et un gris clair ("#aaa") pour le contour. Pour dessiner les demi-cercles, utilisez la fonction image avec le nom d’image "disk180".

Divisez votre programme en sections séparées par des sauts de ligne et ajoutez des commentaires pour expliquer chaque section du code.

Solution

On divise le code en sections : une pour chaque bande horizontale, une pour chaque demi-cercle, et une section pour le contour gris. En ajoutant des sauts de lignes et des commentaires, ça permet de rapidement comprendre ce que fait chaque section du code.

clear()

# Dessiner la bande rouge du bas
hop(); bk(135, 45)
pencolor("#c13")
pensize(90)
fd(270)

# Dessiner la bande blanche du haut
hop()
bk(270, -90)
pencolor("white")
fd(270)

# Dessiner le demi-cercle rouge du haut
hop()
bk(165, 45)
pencolor("#c13")
image("disk180", 1.2)

# Dessiner le demi-cercle blanc du bas
rt(180)
pencolor("white")
image("disk180", 1.2)

# Dessiner un contour au drapeau pour la visibilité
pensize(1)
pencolor("#aaa")
hop()
fd(105)
fd(0, 90)
bk(270)
fd(0, -180)
fd(270)
fd(0, 90)

ht()

Exercice 14


Le programme dans l’environnement de développement dessine un drapeau de l’Islande comme ci-dessus.

Cependant, il est difficile de comprendre ce que chaque ligne fait puisque le programme ne contient pas de divisions ou de commentaires.

Sans modifier les instructions, ajoutez des sauts de ligne pour diviser le code en sections et ajoutez des commentaires pour expliquer ce que fait chaque section.

hop()
bk(125)
pencolor("#04a")
pensize(180)
fd(250)
pencolor("white")
pensize(40)
bk(250)
fd(90)
lt(90)
fd(90)
bk(180)
fd(90)
rt(90)
pencolor("#f03")
pensize(20)
fd(160)
bk(250)
fd(90)
lt(90)
fd(90)
bk(180)
ht()

Indice

Ce drapeau est dessiné en trois étapes: le fond bleu, la croix blanche, puis la croix rouge.

Pour identifier quelle partie du code exécute chaque étape, débutez l’exécution en cliquant sur (Exécuter le premier pas), puis continuez avec (Exécuter le prochain pas).

Solution

# Positionner la tortue
hop()
bk(125)

# Dessiner le fond bleu
pencolor("#04a")
pensize(180)
fd(250)

# Dessiner la croix blanche
pencolor("white")
pensize(40)
bk(250)
fd(90)
lt(90)
fd(90)
bk(180)
fd(90)
rt(90)

# Dessiner la croix rouge
pencolor("#f03")
pensize(20)
fd(160)
bk(250)
fd(90)
lt(90)
fd(90)
bk(180)

ht()

Exercice 15

Dial Thermometer (Fahrenheit and Celsius)<sodipodi:namedview id="namedview7_9" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:showpageshadow="2" inkscape:pageopacity="0.0" inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1" inkscape:document-units="px" showgrid="true" inkscape:zoom="0.5" inkscape:cx="314" inkscape:cy="444" inkscape:window-width="1366" inkscape:window-height="704" inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="1" inkscape:current-layer="layer7_9"><inkscape:grid id="grid1_9" units="px" originx="-229.84141" originy="-27.642373" spacingx="0.26458333" spacingy="0.26458333" empcolor="#3f3fff" empopacity="0.25098039" color="#3f3fff" opacity="0.1254902" empspacing="5" enabled="true" visible="true" /></sodipodi:namedview> rdf:RDF<cc:Work rdf:about="">dc:titleDial Thermometer (Fahrenheit and Celsius)</dc:title>dc:creatorcc:Agentdc:titleAlgot Runeman</dc:title></cc:Agent></dc:creator>dc:rightscc:Agentdc:titleAlgot Runeman</dc:title></cc:Agent></dc:rights>dc:publishercc:Agentdc:titlehttp://runeman.org</dc:title></cc:Agent></dc:publisher>dc:sourcehttp://runeman.org/clipart/2025/</dc:source>dc:languageen-US</dc:language>dc:coverageworldwide</dc:coverage>dc:date2025-07-29</dc:date>dc:identifierthermometer-dual.svg</dc:identifier>dc:descriptionAn adjustable dial thermometer. The arrow rotates as needed. Fahrenheit and Celsius degrees.</dc:description><cc:license rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />dc:subjectrdf:Bagrdf:lithermometer</rdf:li>rdf:litemperature</rdf:li><rdf:li /></rdf:Bag></dc:subject></cc:Work><cc:License rdf:about="http://creativecommons.org/publicdomain/zero/1.0/"><cc:permits rdf:resource="http://creativecommons.org/ns#Reproduction" /><cc:permits rdf:resource="http://creativecommons.org/ns#Distribution" /><cc:permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks" /></cc:License></rdf:RDF>


Pour convertir une température de Celsius à Fahrenheit, on utilise la formule suivante.

°F = (°C × 9/5) + 32

Avec la tortue, dessinez le graphique de cette fonction dans le plan cartésien. L’axe des x doit représenter la température en Celsius et l’axe des y, les Fahrenheit. Vous devez dessiner l’axe des x et l’axe des y en noir, et la courbe de la fonction en rouge pour l’intervalle allant de -100°C à 100°C comme ceci :

Solution

On résout le problème en deux étapes.

  1. On trace les axes x et y.
  2. On utilise l’équation de la fonction pour calculer les coordonnées de deux points avec x = -100 et x = 100, puis on utilise fd pour tracer un trait rouge entre ces points.

N’oubliez pas d’utiliser le bouton Exécuter le prochain pas pour observer chaque étape de la solution.

# Tracer les axes
hop()
fd(-100, 0)
fd(200)
hop()
fd(-100, -100)
fd(0, 200)

# Tracer la fonction °F = (°C × 9/5) + 32

# On place la tortue à l'origine de la fonction (y=32)
hop()
fd(0, -100)
hop()
fd(0, 32)

# Tracer la ligne de la fonction
pencolor("red")
fd(100, 9 / 5 * 100)
bk(200, 9 / 5 * 200)

ht()

Introduction


Un programme peut faire des calculs en utilisant les opérations mathématiques comme + et -. On utilise le symbole / pour la division, * pour la multiplication et ** pour les exposants. On peut aussi utiliser des parenthèses pour regrouper des expressions.

L’ordre des opérations est l’ordre habituel :

  1. parenthèses : ( et )
  2. exposants : **
  3. multiplication/division : * et /
  4. addition/soustraction : + et -

Par exemple, voici un programme qui calcule les fonds dans un compte d’épargne avec un taux d’intérêt annuel nominal de 7% composé mensuellement.

012345678910Année050100150200Montant

print("Montant initial :", 100)
print("Taux d'intérêt annuel nominal :", 0.07)
print("Périodes composant une année :", 12)
print("Nombre d'années écoulées :", 10)
print("Montant actuel :", 100 * (1 + 0.07 / 12) ** (10 * 12))

Le terme taux d’intérêt annuel nominal a un sens précis pour les banques. Cherchez la définition de ce terme sur le Web pour en savoir plus.

Les types de nombres

3.89964e8


Pour faire des calculs, on peut utiliser des nombres entiers (par exemple 42, ou 2026) ou des nombres décimaux (3.14, ou 9.81), aussi appelés nombres flottants.

Dans le code on utilise un point (.) dans un nombre flottant pour séparer la partie entière et les décimales, donc 3.14 c’est la valeur qui s’écrit normalement 3,14 en français.

Pour rendre les calculs plus lisibles, on peut utiliser le séparateur _ pour écrire de grands entiers. Par exemple, la valeur 1000000 peut être écrite 1_000_000 dans le code.

On peut aussi écrire des nombres flottants avec la notation scientifique. Par exemple, pour représenter 3,89964×108 dans le code (la distance entre la terre et la lune) on peut écrire 3.89964e8 ou 3.89964e+8.

print("Masse de la Lune :", 7.3e22)
print("Masse de la Terre :", 6e24)
print("Distance :", 3.89964e8)
print("Constante gravitationnelle :", 6.67e-11)
print("Force d'attraction en Newtons :")
print(6.67e-11 * 7.3e22 * 6e24 / 3.89964e8 ** 2)

Exercice 1


Utilisez la console pour calculer le nombre de grains de sable sur les plages à travers le monde.

On suppose les faits suivants :

  • Il y a 500 000 kilomètres de rivages.
  • Un tier des rivages est couvert de sable.
  • Un rivage sablonneux a en moyenne 30 mètres de largeur et 2 mètres de profondeur.
  • Il y a environ 10 milliards de grains de sable par mètre cube.

Quel est le nombre de grains de sable sur les plages du monde ? Inscrivez ici le résultat de votre calcul tel qu’affiché à la console.

1e+20

Indice

Utilisez le symbole / pour la division.

Le résultat sera un très grand nombre! L’affichage des grands nombres décimaux se fait avec la notation scientifique, par exemple 3.4e+21 signifie 3,4×1021 .

Solution

On peut faire le calcul suivant dans la console. La partie 500000 * 1000 / 3 calcule la longueur de rivages sablonneux en mètres. On multiplie par 30 * 2 pour obtenir le volume de sable en mètres cube. Finalement, on multiplie par 10000000000 qui est le nombre de grains par mètre cube.

>>> 500000 * 1000 / 3 * 30 * 2 * 10000000000
    1e+20

Le résultat du calcul est 1e+20 qui signifie 1020 .

Exercice 2


La masse d’un proton est d’environ 1,672×1027 kg, celle d’un électron est environ 9,109×1031 kg.

On peut approximer la masse d’un atome d’hydrogène en additionnant la masse d’un proton et d’un électron.

En se rappellant qu’une mole contient 6,02×1023 particules, écrivez un programme estimant la masse d’une mole d’atomes d’hydrogène.

Le programme doit utiliser print pour afficher les masses d’un proton, d’un électron, d’un atome d’hydrogène et d’une mole d’atomes d’hydrogène.

Solution

1,672×1027 est écrit 1.672e-27.

9,109×1031 est écrit 9.109e-31.

6,02×1023 est écrit 6.02e23.

print("Masse d'un proton :", 1.672e-27)
print("Masse d'un électron :", 9.109e-31)
print("Masse d'un atome d'hydrogène :", 1.672e-27 + 9.109e-31)
print("Masse d'une mole d'hydrogène :", (1.672e-27 + 9.109e-31) * 6.02e23)

Les variables

------++++++


Dans le code on a souvent besoin d’utiliser plus d’une fois une valeur ou le résultat d’un calcul. Pour éviter d’avoir à réécrire le calcul plusieurs fois, on peut mémoriser la valeur dans une variable.

Pour affecter une valeur à une variable on utilise le symbole =.

x = 10 + 2
print(x * x)

En plus de permettre de réutiliser des résultats, les variables aident à organiser le code et à le rendre plus lisible.

proton = 1.672e-27
neutron = 1.675e-27

# carbone-12 (6 protons, 6 neutrons)
numero_atomique = 6
isotope = 12
nombre_neutrons = isotope - numero_atomique
mole = 6.02e23

masse_atome = numero_atomique * proton + nombre_neutrons * neutron
masse_molaire = mole * masse_atome

print("Masse d'un atome :", masse_atome)
print("Masse d'une mole d'atomes :", masse_molaire)

Les variables rendent le code facile à modifier. Par exemple, pour calculer la masse molaire du carbone-13, il suffit de remplacer isotope = 12 par isotope = 13. Cette modification entrainera que le nombre de neutrons sera 7, ce qui correspond bien à la situation du carbone-13.

Noms de variables

Le nom d’une variable peut être composé de lettres, de chiffres, et du caractère _. Il ne peut pas commencer par un chiffre.

Par exemple, ces noms sont valides :

temperature_exterieure = 23.5
prix_en_2026 = 299
distance_terre_lune = 389_964

Mais ceux-ci sont invalides :

3_petits_chats = 3
prix_en_$ = 2.99

Puisque les espaces ne sont pas permis dans les noms de variables, on utilise souvent le caractère _ pour séparer les mots. Ce style de nom s’appelle le snake_case.

Utilisez des noms clairs et descriptifs pour nommer les variables et évitez les abbréviations et les noms d’une seule lettre. Par exemple utilisez temperature et non t.

Exercice 3

Parmi les noms de variable suivants, lesquels sont valides ?

Solution

Bien que d’utiliser des noms d’une seule lettre comme x et T ne soit par recommandés, il s’agit quand même de noms valides.

Exercice 4

Parmi les noms de variable suivants, lesquels sont invalides ?

Solution

Le nom _ respecte la règle de n’être composé que de lettres, chiffres et du caractère _.

Les accents sont permis, comme dans température. Ils sont cependant déconseillés, car certains environnements de développement ne les supportent pas.

Les lettres majuscules sont permises. PROPORTION_DES_COTES est donc valide.

10degres_celsius est invalide, car il commence par un chiffre.

Répéter un calcul avec différentes valeurs

En plus de faciliter la modification d’un paramètre dans un programme, les variables permettent de répéter un même calcul avec différentes valeurs.

Par exemple, ce programme affiche les nombres de 1 à 5.

print(1)
print(2)
print(3)
print(4)
print(5)
print("fin!")

On peut simplifier le programme en répétant la même instruction print(nombre) où la variable nombre prend les valeurs de 1 à 5.

for nombre in 1, 2, 3, 4, 5:
    print(nombre)
print("fin!")

C’est ce qu’on appelle une boucle. Une boucle indique un nom de variable (après le mot-clé for) et les valeurs que prendra cette variable (après le in). Le code à répéter est indenté, c’est à dire qu’on utilise quatre espaces avant chaque instruction à répéter.

Les boucles sont très importantes en programmation. Nous en apprendrons plus sur les boucles dans les prochains chapitres.

Exercice 5


Utilisez une boucle for pour dessiner un rectangle avec la tortue. Le programme doit commencer par deux variables qui permettent de facilement modifier la largeur et la hauteur du rectangle.

Par exemple, pour une largeur de 150 et un hauteur de 100, votre programme doit faire le dessin ci-dessus.

Solution

Si on voulait seulement dessiner un rectangle 150×100 , on pourrait utiliser la boucle suivante :

for cote in 150, 100, 150, 100:
    fd(cote)
    rt(90)

On peut faire mieux en utilisant des variables pour paramétrer la largeur et la hauteur. Ça évite de les répéter et les rend facile à modifier.

largeur = 150
hauteur = 100

hop()
bk(largeur / 2, -hauteur / 2)

for cote in largeur, hauteur, largeur, hauteur:
    fd(cote)
    rt(90)

ht()

La fonction d’arrondissement

Pour arrondir un nombre on utilise round, qui arrondit à l’entier le plus proche.

print(round(3.14))
print(round(9.81))

On peut aussi ajouter un deuxième paramètre à round pour choisir à quelle précision arrondir. Par exemple, arrondir à trois décimales après la virgule :

print(round(3.14159265, 3))

Exercice 6


Pour une expérience, une boîte de Petri contient une population initiale de 2000 bactéries. À chaque heure, la population de bactéries augmente de 75%.

Écrivez un programme qui affiche la population à chaque heure lors des cinq premières heures de l’expérience. Puisqu’il ne peut y avoir qu’un nombre entier de bactéries, assurez-vous que la valeur affichée soit un entier.

Indice

Pour calculer le nombre de bactéries, utilisez la formule suivante :

P(t)=Pinitiale1,75t

P(t) est la population à t heures et Pinitiale est la population initiale.

Solution

On calcule la population avec l’équation :

population = population_initiale * 1.75 ** heures

Ensuite, on utilise round(population), qui arrondit à l’entier le plus près, pour afficher une valeur entière.

population_initiale = 2_000

for heures in 0, 1, 2, 3, 4, 5:
    population = population_initiale * 1.75 ** heures
    print("Après", heures, "h, la population est de", round(population))

Tel que le montre le graphique ci-dessous de la population en fonction du temps, la croissance des bactéries est très rapide!

012345heure010,00020,00030,000population

La valeur absolue

La valeur absolue d’un nombre est sa valeur sans tenir compte de son signe. Pour trouver la valeur absolue d’un nombre, on utilise la fonction abs.

print(abs(-123))
print(abs(-3.14))
print(abs(2026))

Exercice 7

La fonction valeur absolue est fréquemment utilisée en statistiques pour calculer l’écart moyen. L’écart moyen mesure à quel point des données sont dispersées autour de la moyenne.

Dans un ensemble de données, on peut calculer l’écart d’un seul point x à la moyenne x avec :

|xx|

|...| est la fonction valeur absolue.

L’écart moyen est la moyenne de tous les écarts.

Par exemple, on peut regarder la moyenne d’un groupe d’étudiants pour savoir si un examen a été bien réussi. On peut également regarder l’écart moyen pour savoir si les notes varient beaucoup d’une personne à l’autre.

Écrivez un programme qui calcule la moyenne et l’écart moyen des notes d’examen d’un petit groupe ayant obtenu les notes 93, 67, 87 et 71.

note1 = 93
note2 = 67
note3 = 87
note4 = 71

# Complétez le programme

Solution

On doit d’abord calculer la moyenne du groupe, car il faut la moyenne pour calculer un écart de chaque étudiant. Ensuite, on additionne les écarts et on en prend la moyenne.

note1 = 93
note2 = 67
note3 = 87
note4 = 71

moyenne = (note1 + note2 + note3 + note4) / 4

ecart_moyen = (abs(note1 - moyenne) +
               abs(note2 - moyenne) +
               abs(note3 - moyenne) +
               abs(note4 - moyenne)) / 4

print("Moyenne :", moyenne)
print("Écart moyen :", ecart_moyen)

On aurait également pu utiliser une boucle pour éviter de répéter l’expression abs(note - moyenne).

note1 = 93
note2 = 67
note3 = 87
note4 = 71

moyenne = (note1 + note2 + note3 + note4) / 4

ecart_moyen = 0
for note in note1, note2, note3, note4:
    ecart_moyen = ecart_moyen + abs(note - moyenne) / 4

print("Moyenne :", moyenne)
print("Écart moyen :", ecart_moyen)

Les minimum et maximum

On utilise min et max pour trouver le minimum ou le maximum de deux valeurs.

print(min(2.71, 3.14))
print(max(2**3, 3**2))

On utilise souvent min et max pour borner le résultat d’un calcul. Si, par exemple, on veut que le résultat d’un calcul soit borné entre 0 et 100, on peut écrire max(0, min(100, resultat)).

resultat1 = 3 * 25 + 40
print("Résultat #1 :", resultat1)
print("Résultat #1 borné :", max(0, min(100, resultat1)))

resultat2 = -3 * 25 + 15
print("Résultat #2 :", resultat2)
print("Résultat #2 borné :", max(0, min(100, resultat2)))

Exercice 8


La batterie d’un téléphone cellulaire est initialement chargée à 10%. On branche le téléphone qui commence à se recharger de 2% chaque minute. Lorsqu’elle atteint 100%, la batterie est pleine et sa charge ne change plus.

Écrivez un programme qui affiche la charge de la batterie après un certain temps de recharge. Le programme doit commencer par la définition d’une variable temps qui représente le nombre de minutes de recharge.

temps = 0

# Complétez le programme

Solution

# Paramètres
temps = 0
charge_initial = 10
taux_de_chargement = 2

# Calcul et affichage du chargement
charge = min(100, taux_de_chargement * temps + charge_initial)
print("Charge :", charge, "%")

Les fonctions mathématiques

On peut calculer avec des fonctions mathématiques en utilisant la bibliothèque mathématique. Une bibliothèque, c’est un ensemble de fonctions qui portent sur un même sujet.

La bibliothèque mathématique s’appelle math. On écrit math.fonction pour utiliser une de ses fonctions. Voici quelques exemples :

Fonction Description
math.sqrt(x) racine carrée
math.sin(angle) sinus (en radians)
math.cos(angle) cosinus (en radians)
math.tan(angle) tangente (en radians)
math.asin(x) arc-sinus (en radians)
math.acos(x) arc-cosinus (en radians)
math.atan(x) arc-tangente (en radians)
math.ceil(x) arrondir vers le haut
math.floor(x) arrondir vers le bas
math.log(x) logarithme en base e
math.log10(x) logarithme en base 10

Les fonctions trigonométriques prennent des angles en radians. Un angle de π radians correspond à 180°.

Exercice 9


Une boîte orange de 10 kg repose sur un plan incliné.

La gravité exerce une force vers le bas sur la boîte (en rouge dans le dessin).

En réponse à la gravité, le plan exerce une force perpendiculaire à sa surface appelée la force normale (en bleu).

La force résultante est une force parallèle au plan qui fait glisser la boîte vers le bas (en vert).

Écrivez un programme qui dessine le diagramme de forces du plan incliné avec la tortue. Le programme doit commencer par déclarer deux variables pour paramétrer l’angle du plan et la masse de la boîte.

Dessinez la force gravitationnelle en rouge, la force normale en bleu, et la force résultante en vert. Utilisez l’amplitude de la force (en Newtons) comme longueur des flèches représentant chaque force, centrées au milieu de la boîte. Utilisez l’image "arrowhead" pour la pointe des flèches et tenez compte de la taille de cette image dans la longueur du trait.

Indice

On peut calculer les forces gravitationnelle ( Fg ), normale ( Fn ) et résultante ( Fr ) avec ces formules :

Fg=9,81Nkg×mFn=Fg×cos(θ)Fr=Fg×sin(θ)

m est la masse de l’objet (en kg), et θ est l’angle du plan incliné.

Attention! Les fonctions math.sin et math.cos sont en radians, mais la tortue utilise des degrés. Il faut convertir avec cette formule :

θrad=π180θdeg

Solution

On utilise force * math.cos(angle_radian) pour calculer la force normale.

On utilise force * math.sin(angle_radian) pour calculer la force résultante.

Une fois qu’on a les forces, tous les calculs sont faits et il ne reste qu’à dessiner. Les pointes de flèches sont rétrécies à 20% de leur taille normale et il faut donc soustraire 10 pixels de la distance de déplacement de la tortue.

On peut changer la valeur de la variable angle, relancer le programme, et observer comment les composantes réagissent.

# Paramètres
angle = 30
masse = 10
cote_boite = 40
acceleration_gravitationnelle = 9.81
angle_radian = angle / 180 * math.pi

# Calcul des composantes de la force
force_gravitationnelle = masse * acceleration_gravitationnelle
force_normale = force_gravitationnelle * math.cos(angle_radian)
force_resultante = force_gravitationnelle * math.sin(angle_radian)

# Dessin de la pente
lt(angle-180)
pencolor("beige")
image("disk180", 200)
rt(90)

# Dessin de la boite
pensize(cote_boite)
pencolor("orange")
fd(cote_boite)
bk(cote_boite / 2)

# Dessin force gravitationnelle
pensize(2)
pencolor("red")
rt(angle-180)
fd(force_gravitationnelle - 10); image("arrowhead", 0.2)
hop(); bk(force_gravitationnelle - 10)

# Dessin force normale
pencolor("blue")
lt(angle-180)
fd(force_normale - 10); image("arrowhead", 0.2)
hop(); bk(force_normale - 10)

# Dessin force résultante parallèle au plan
pencolor("green")
lt(90)
fd(force_resultante - 10); image("arrowhead", 0.2)

ht()

La division entière et le modulo

Une division peut être décomposée en une partie entière et un reste. Par exemple, dans la division 13÷5 , la partie entière est 2 et le reste est 3 , parce que 13=2×5+3 .

La division entière calcule la partie entière d’une division. Elle est aussi appelée quotient. La division entière s’écrit avec le symbole //.

Le modulo est une opération qui calcule le reste d’une division. Le modulo s’écrit avec le symbole %.

dividende = 13
diviseur = 5

print(dividende, "÷", diviseur)
print("partie entière :", dividende // diviseur)
print("reste :", dividende % diviseur)
print("division :", dividende / diviseur)

Exercice 10


Si aujourd’hui est un lundi, quel jour sera-t-il dans 100 jours ?

Utilisez la console ou écrivez un programme faisant les calculs nécessaires pour obtenir la réponse.

Indice

Le modulo (%) est utile pour faire des calculs sur des valeurs cycliques.

Par exemple les jours de la semaine forment un cycle. On peut associer chaque jour à un nombre allant de 0 à 6 : dimanche=0, lundi=1, ..., samedi=6. Après le jour 6, samedi, on recommence au jour 0, dimanche.

On peut faire le calcul (aujourdhui + N) % 7 pour obtenir un nombre de 0 à 6 qui correspond au jour qu’il sera dans N jours.

Solution

On associe chaque jour à un nombre de 0 à 6 : dimanche=0, lundi=1, ..., samedi=6. Le calcul suivant à la console nous amène au jour 3, un mercredi.

>>> (1 + 100) % 7
    3

On peut écrire un programme plus complet qui permet de reproduire ce calcul pour n’importe quel jour de départ et nombre de jours écoulés.

dimanche = 0
lundi = 1
mardi = 2
mercredi = 3
jeudi = 4
vendredi = 5
samedi = 6

aujourdhui = lundi
nombre_de_jours = 100

print((aujourdhui + nombre_de_jours) % 7)

Les fonctions de hasard


Certains programmes ont besoin de générer des nombres aléatoires, par exemple un jeu vidéo, une simulation de mutations génétiques, ou un programme de cryptographie.

Pour générer un nombre flottant aléatoire entre 0 (inclus) et 1 (exclus), on utilise random().

print("Trois nombres flottants aléatoires de 0 à 1")
for nombre in 1, 2, 3:
    print(random())

On peut aussi générer un nombre entier aléatoire avec randint(a,b) qui génère un nombre de a à b (inclus).

print("Cinq entiers aléatoires de 1 à 6")
for nombre in 1, 2, 3, 4, 5:
    print(randint(1, 6))

Exercice 11

<sodipodi:namedview id="base_17" bordercolor="#666666" inkscape:pageshadow="2" inkscape:window-y="24" pagecolor="#ffffff" inkscape:window-height="949" inkscape:window-maximized="1" inkscape:zoom="0.5" inkscape:window-x="0" showgrid="false" borderopacity="1.0" inkscape:current-layer="layer2_17" inkscape:cx="173.79666" inkscape:cy="165.24249" showguides="true" inkscape:guide-bbox="true" inkscape:window-width="1280" inkscape:pageopacity="0.0" inkscape:document-units="px" > <sodipodi:guide id="guide2858_17" position="-158.04501,-158.04502" orientation="744.09,0" /> <sodipodi:guide id="guide2860_17" position="27.977489,-158.04502" orientation="744.09,0" /> <sodipodi:guide id="guide2862_17" position="213.99999,-158.04502" orientation="744.09,0" /> <sodipodi:guide id="guide2864_17" position="400.02249,-158.04502" orientation="744.09,0" /> <sodipodi:guide id="guide2866_17" position="586.04499,-158.04502" orientation="744.09,0" /> <sodipodi:guide id="guide2868_17" position="-158.04501,-158.04502" orientation="0,744.09" /> <sodipodi:guide id="guide2870_17" position="-158.04501,27.977481" orientation="0,744.09" /> <sodipodi:guide id="guide2872_17" position="-158.04501,213.99998" orientation="0,744.09" /> <sodipodi:guide id="guide2874_17" position="-158.04501,400.02248" orientation="0,744.09" /> <sodipodi:guide id="guide2876_17" position="-158.04501,586.04498" orientation="0,744.09" /> </sodipodi:namedview > <rdf:RDF > <cc:Work > <dc:format >image/svg+xml</dc:format > <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <cc:license rdf:resource="http://creativecommons.org/licenses/publicdomain/" /> <dc:publisher > <cc:Agent rdf:about="http://openclipart.org/" > <dc:title >Openclipart</dc:title > </cc:Agent > </dc:publisher > <dc:title >compass</dc:title > <dc:date >2010-11-10T22:55:50</dc:date > <dc:description /> <dc:source >https://openclipart.org/detail/95047/compass-by-rg1024</dc:source > <dc:creator > <cc:Agent > <dc:title >rg1024</dc:title > </cc:Agent > </dc:creator > <dc:subject > <rdf:Bag > <rdf:li >brujula</rdf:li > <rdf:li >compass</rdf:li > <rdf:li >east</rdf:li > <rdf:li >north</rdf:li > <rdf:li >south</rdf:li > <rdf:li >west</rdf:li > </rdf:Bag > </dc:subject > </cc:Work > <cc:License rdf:about="http://creativecommons.org/licenses/publicdomain/" > <cc:permits rdf:resource="http://creativecommons.org/ns#Reproduction" /> <cc:permits rdf:resource="http://creativecommons.org/ns#Distribution" /> <cc:permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks" /> </cc:License > </rdf:RDF >


Écrivez un programme qui affiche un nombre flottant entre 0 (inclus) et 360 (exclus) au hasard.

Solution

Puisque random() génère un nombre flottant entre 0 et 1, on peut multiplier le résultat par 360 pour que le nombre soit entre 0 et 360.

nombre = random() * 360
print(nombre)

Exercice 12


Écrivez un programme qui affiche un nombre entier impair entre 1 (inclus) et 35 (inclus) au hasard.

Solution

Puisque randint(a,b) génère un nombre entre a et b, on peut multiplier le résulat par 2 et additionner 1 pour que le nombre soit entre 1 + 2 × a et 1 + 2 × b. Si on choisit a = 0 et b = 17 on obtient le bon intervalle.

nombre = 1 + 2 * randint(0, 17)
print(nombre)

Résumé

Les opérations arithmétiques.

Opérateur Description Exemple Résultat
+ addition 10 + 3 13
- soustraction 10 - 3 7
* multiplication 10 * 3 30
/ division 25 / 10 2.5
** exposant (xy) 10 ** 3 1000
// division entière 25 // 10 2
% modulo (reste de la division) 25 % 10 5
abs(x) valeur absolue abs(-7) 7
min(ab) minimum min(-7, -6) -7
max(ab) maximum max(0, -5) 0
round(x) arrondir à l’entier round(3.1416) 3
round(xn) arrondir à la précision de n décimales round(3.14163) 3.142

Les fonctions de la bibliothèque math.

Fonction ou valeur Description Exemple
math.sqrt(x) racine carrée math.sqrt(100)
math.sin(angle) sinus math.sin(0)
math.cos(angle) cosinus math.cos(3.1416)
math.tan(angle) tangente math.tan(3.1416 / 4)
math.asin(x) arc-sinus math.asin(1)
math.acos(x) arc-cosinus math.acos(0)
math.atan(x) arc-tangente math.atan(1)
math.ceil(x) arrondir vers le haut math.ceil(10.1)
math.floor(x) arrondir vers le bas math.floor(10.9)
math.log(x) logarithme en base e math.log(2.71 ** 3)
math.log2(x) logarithme en base 2 math.log2(16)
math.log10(x) logarithme en base 10 math.log10(0.001)
math.pi 3.141592653589793
math.e 2.718281828459045

Les fonctions trigonométriques prennent des angles en radians. Un angle de π radians correspond à 180°.

Normalement il faut faire import math en haut du programme pour utiliser les fonctions de la bibliothèque math. Cependant, dans l’environnement de développement utilisé dans ce manuel le import math est optionnel.

Les fonctions de hasard.

Fonction Description Exemple Exemple de résultat
random() nombre flottant aléatoire entre 0 et 1 random() 0.7354
randint(ab) entier aléatoire entre a et b (inclus) randint(16) 4

Normalement il faut faire import random en haut du programme pour utiliser les fonctions de la bibliothèque random, puis utiliser random.random() et random.randint(ab). Cependant, dans ce manuel on peut faire directement random() et randint(ab).

La boucle for simple.

Fonction Description Exemple
for var in valeurs: Exécuter des instructions pour chaque valeur indiquée
for x in 123:
    print(x)

affiche
1
2
3

Exercice 13

Le programme dans votre environnement de développement doit calculer la moyenne des trois nombres 1,5 et 2,3 et 3,7.

Il contient toutefois des erreurs subtiles. Trouvez les erreurs et corrigez-les pour que le programme fonctionne correctement et imprime le bon résultat.

a = 1,5
b = 2,3
c = 3,7
moyenne = (a + b + c) / 3
print(moyenne)

Solution

L’erreur dans le programme est que tous les nombres flottants ont été écrits avec une virgule (,) alors que dans le code ils doivent être écrits avec un point (.).

Cette erreur peut être difficile à repérer, car écrire 1,5 dans le code a un sens pour l’ordinateur qui n’est pas le même que le nombre flottant 1.5 ; ça signifie plutôt une paire des nombres 1 et 5. C’est seulement plus tard dans le programme, lors du calcul de la moyenne, que l’erreur apparaît car c’est invalide de faire des calculs entre des paires et des nombres.

a = 1.5
b = 2.3
c = 3.7
moyenne = (a + b + c) / 3
print(moyenne)

Exercice 14


Un contenant de 150 litres se fait remplir à un débit de 2 litres par seconde. Puisque le contenant peut contenir au maximum 150 litres, la quantité d’eau dans le contenant sera toujours de 0 à 150.

Écrivez un programme calculant la quantité d’eau dans ce contenant après un certain nombre de secondes.

Le programme doit commencer par une variable temps qui est le temps en secondes depuis qu’on a commencé le remplissage. Ce temps peut prendre une valeur négative, représentant la période avant que le remplissage commence.

Votre programme doit afficher le niveau d’eau dans la console et dessiner le contenant et son niveau d’eau avec la tortue.

Utilisez votre créativité pour le dessin! Par exemple le dessin ci-dessus correspond à un temps écoulé de 30 secondes.

Indice

Si quantite_eau est la quantité d’eau totale s’étant écoulée et taille_contenant est la taille du contenant, le niveau d’eau dans le contenant peut être calculé avec :

max(0, min(taille_contenant, quantite_eau))

Solution

# Modifiez le temps et relancez le programme
temps = 30 # secondes

# Paramètres de la simulation
hauteur_contenant = 150 # 1 pixel = 1L
debit_eau = 2 # L / seconde

# Calcul d'un niveau d'eau
quantite_eau = debit_eau * temps
niveau_eau = max(0, min(hauteur_contenant, quantite_eau))

print("Après", temps, "secondes, le niveau d'eau est de", niveau_eau, "L")

# Dessin du contenant
hop()
lt(90)
bk(hauteur_contenant / 2)
pensize(104)
fd(hauteur_contenant + 2); bk(hauteur_contenant)
pensize(100)
pencolor(1, 1, 1)
fd(hauteur_contenant); bk(hauteur_contenant)

# Dessin du niveau d'eau
pencolor(0.72, 0.83, 1)
fd(niveau_eau)

ht()

Exercice 15


La loi de Snell permet de calculer l’angle de réfraction d’un rayon de lumière changeant de milieu.

n1sinθ1=n2sinθ2

n1 et n2 sont les indices de réfraction des milieux dans lesquels se propage les rayons initial et réfracté, et θ1 et θ2 sont les angles de réfraction de ces rayons.

Vous devez utiliser la loi de Snell pour simuler et dessiner un rayon réfracté par un panneau de verre en utilisant la tortue.

Pour pouvoir paramétrer la simulation, le programme doit commencer par la déclaration de trois variables qui représentent :

  1. l’indice de réfraction du milieu initial
  2. l’indice de réfraction du panneau
  3. l’angle d’incidence du rayon entrant dans le panneau

Dessinez un panneau de verre allant de x = 0 à x = 100 dans le plan de la tortue. Dessinez ensuite la trajectoire du rayon traversant le panneau.

Le dessin ci-dessus correspond à n1=1 , n2=3 et θ1=30 et c’est ce que votre programme doit dessiner pour ces valeurs.

Indice

Pour calculer l’angle θ2 , on peut utiliser la formule

θ2=arcsinn1sinθ1n2

Attention! Les fonction trigonométriques math.sin et math.asin utilisent des radians, mais la tortue utilise des degrés. Il faudra convertir les angles avec la formule suivante.

θrad=π180θdeg

Solution

On commence par déclarer trois variables : indice_refract1, indice_refract2 et angle1_degre. En modifiant leurs valeurs, on pourra facilement paramétrer la simulation.

On utilise ensuite la loi de Snell pour calculer l’angle réfracté.

Une fois que toutes les angles et distances ont été calculés, on utilise la tortue pour faire le dessin. Séparer le code en deux partie (une pour les calculs et une pour le dessin) aide à rendre le programme plus lisible.

# Changez ces variables pour paramétrer le dessin
# Les indices de réfraction doivent être plus grands ou égaux à 1.0
indice_refract1 = 1.0 
indice_refract2 = 3.0
angle1_degre = 30
profondeur_milieu2 = 100

# === CALCULS ===

# Calcul des angles
angle1_radian = angle1_degre / 180 * math.pi
angle2_radian = math.asin(indice_refract1 * math.sin(angle1_radian) / indice_refract2)
angle2_degre = angle2_radian / math.pi * 180

# Calcul de la distance parcourue par le rayon dans le milieu
distance_milieu2 = profondeur_milieu2 / math.cos(angle2_radian)

# === DESSIN ===

# Dessin du panneau de verre
pencolor(0.72, 0.83, 0.91)
pensize(500)
fd(profondeur_milieu2); bk(profondeur_milieu2)

# Dessin du rayon avant le panneau de verre
pencolor(1, 0, 0)
pensize(1)
rt(angle1_degre)
bk(100); fd(100)

# Dessin du rayon dans le panneau de verre
lt(angle1_degre); rt(angle2_degre)
fd(distance_milieu2)

# Dessin du rayon sortant du panneau de verre
lt(angle2_degre); rt(angle1_degre)
fd(100)

ht()

Exercice 16

Une année commune (qui n’est pas bissextile) contient 31536000 secondes.

Écrivez un programme qui commence par définir une variable seconde qui contiendra un entier de 0 à 31536000 (exclus).

Le programme doit calculer le jour, et l’heure (incluant les minutes) correspondant à cette seconde précise de l’année.

Par exemple, si seconde = 31_535_999 (dernière seconde de l’année), alors le programme affichera :

Jour : 365
Heure : 23 : 59
seconde = 31_535_999

# Complétez le programme

Indice

Commencez par utiliser la division entière pour trouver combien de jours se sont écoulés. Utilisez le modulo pour calculer nombre de secondes écoulées dans cette journée.

Les calculs pour trouver le jour, l’heure et la minute sont très similaires.

Solution

On peut utiliser la division entière pour savoir combien de jours complets se sont écoulés depuis le début de l’année. On utilise le modulo pour calculer le reste, qui est le nombre de secondes dans la journée actuelle.

On peut répéter ce processus pour trouver l’heure de la journée actuelle, puis la minute de l’heure actuelle.

seconde = 31_535_999

# Calcul du nombre de secondes par intervalles
sec_par_minute = 60
sec_par_heure = 60 * sec_par_minute
sec_par_jour = 24 * sec_par_heure

# Nombre de jours complets écoulés
jour = seconde // sec_par_jour + 1 # On compte les jours à partir de 1

# Nombre d'heures complètes écoulées
heure = (seconde // sec_par_heure) % 24

# Nombre de minutes écoulées dans cette heure
minute = (seconde // sec_par_minute) % 60

print("Jour :", jour)
print("Heure :", heure, ":", minute)

Exercice 17

Écrivez un programme qui commence par déclarer une variable nombre qui contient un nombre entier plus grand que zéro.

Le programme doit afficher au hasard un multiple du nombre entre 0 et 100 (inclus).

Par exemple, si on a nombre = 24, le programme génèrera un nombre au hasard parmi 0, 24, 48, 72 et 96.

nombre = 24

# Complétez le programme

Solution

L’expression randint(0, N) * nombre génèrera aléatoirement un multiple entre 0 et N * nombre. Pour trouver le plus grand entier N tel que N * nombre est plus petit ou égal à 100, on utilise la division entière N = 100 // nombre.

nombre = 24
multiple = 100 // nombre
resultat = randint(0, multiple) * nombre
print(resultat)

Exercice 18


Utilisez la tortue pour dessiner le drapeau de la République d’Artsakh.

Les dimensions de ce drapeau sont de 240 pixels de large par 120 pixels de haut. Chacun des neufs rectangles blancs mesure un sixième de la largeur du drapeau.

Les couleurs exactes de ce drapeau peuvent être dessinées avec pencolor(0.83, 0, 0.06) (rouge), pencolor(0.15, 0.19, 0.63) (bleu), et pencolor(0.99, 0.66, 0) (orange).

Indice

Pour dessiner le motif de rectangles blancs en zig-zag, on peut utiliser un boucle for.

Voici la position du point milieu du côté gauche de chaque rectangle. La position en x peut être calculée avec une fonction valeur absolue. La position en y peut être calculée avec une fonction linéaire.

Rectangle (de haut en bas) x y
1 80,0 53,3
2 60,0 40,0
3 40,0 26,7
4 20,0 13,3
5 0,0 0,0
6 20,0 -13,3
7 40,0 -26,7
8 60,0 -40,0
9 80,0 -53,3

Solution

La position du point milieu du côté gauche d’un petit rectangle blanc peut être calculée avec les formules suivantes :

x=12×|5n|×largeury=(5n)×hauteur

n est le numéro du rectangle à partir du haut, et largeur et hauteur sont les dimensions des rectangles blancs.

On peut donc utiliser une boucle for pour calculer la position de chaque rectangle et le dessiner.

# Paramètres du drapeau
largeur = 240
hauteur = 120
largeur_blanc = largeur / 6
hauteur_blanc = hauteur / 9

# Positionner la tortue
hop()
rt(90)
bk(hauteur / 2)

# Bande rouge
pensize(largeur)
pencolor(0.83, 0, 0.06)
fd(hauteur / 3)

# Bande bleue
pencolor(0.15, 0.19, 0.63)
fd(hauteur / 3)

# Bande jaune
pencolor(0.99, 0.66, 0)
fd(hauteur / 3)

# Repositionner la tortue au centre
hop()
bk(hauteur / 2)
lt(90)

# Rectangles blancs
pencolor(1, 1, 1)
pensize(math.ceil(hauteur_blanc)) # On arrondit le nb de pixels vers le haut

for rectangle in 1, 2, 3, 4, 5, 6, 7, 8, 9:
    y = (5 - rectangle) * hauteur_blanc
    x = abs(5 - rectangle) * largeur_blanc / 2

    # Déplacement à la position du rectangle
    hop(); fd(x, y)
    fd(largeur_blanc)

    # Retour au centre
    hop(); bk(x + largeur_blanc, y)

ht()

Les entrées avec input

On peut utiliser la fonction input pour demander à l’utilisateur de fournir des informations au programme.

nom = input("Quel est votre nom ? ")

print("Bonjour", nom, "!")

La fonction input affichera la question indiquée en paramètre et attendra que l’utilisateur réponde. Le texte entré par l’utilisateur sera le résultat retourné par la fonction input.

Dans ce manuel, input affiche une boîte de dialogue pour demander une entrée à l’utilisateur. Dans d’autres environnements de développement, input attendra que l’utilisateur tape une réponse dans la console.

Conversion de type avec int() et float()

42.0"42"42

La fonction input retourne toujours un texte, même si l’utilisateur entre un nombre.

Si le programme a besoin d’une valeur numérique, on doit convertir le texte en valeur numérique avec int(x) pour un nombre entier ou float(x) pour un nombre flottant.

Lors de la mise au point d’un programme, il est souvent utile d’afficher le type d’une valeur avec la fonction type.

valeur_texte = input("Entrez un nombre : ")
print("Valeur et type avant conversion :", valeur_texte, type(valeur_texte))

valeur_int = int(valeur_texte)
print("Valeur et type après int() :", valeur_int, type(valeur_int))

valeur_float = float(valeur_texte)
print("Valeur et type après float() :", valeur_float, type(valeur_float))

En programmation le terme classe est souvent synonyme du terme type et c’est le terme classe qui est utilisé par la fonction type. Ainsi type(42) sera <class 'int'>, indiquant que 42 est un nombre entier (integer en anglais).

Exercice 1

Écrivez un programme qui demande à l’utilisateur d’entrer son nom et son âge. Le programme doit afficher un message du type "Bonjour <nom>, vous avez <âge> ans."

Solution

Puisqu’on ne fait qu’afficher le nom et l’âge, on n’a pas besoin de convertir l’entrée en nombre.

nom = input("Quel est votre nom ? ")
age = input("Quel est votre âge ? ")
print("Bonjour", nom, "! Vous avez", age, "ans.")

Exercice 2

Écrivez un programme qui demande à l’utilisateur d’entrer deux nombres entiers.

Le programme doit afficher la somme, et le produit des deux nombres.

Solution

On utilise int(input(...)) pour demander un entrée et la convertir en entier. On répète cette opération pour les deux nombres.

nombre1 = int(input("Entrez le premier nombre entier : "))
nombre2 = int(input("Entrez le deuxième nombre entier : "))

somme = nombre1 + nombre2
produit = nombre1 * nombre2 
print("Somme :", somme)
print("Produit :", produit)

Exercice 3

Le programme dans votre environnement de développement demande à l’utilisateur d’entrer deux nombres flottants et affiche leur moyenne.

Il contient toutefois des erreurs. Corrigez le programme pour qu’il fonctionne correctement.

nombre1 = input("Entrez le premier nombre : ")
nombre2 = input("Entrez le deuxième nombre : ")
moyenne = (nombre1 + nombre2) / 2
print("Moyenne :", moyenne)

Solution

Le texte entré par l’utilisateur doit être converti en nombre flottant avec float(input(...)).

nombre1 = float(input("Entrez le premier nombre : "))
nombre2 = float(input("Entrez le deuxième nombre : "))
moyenne = (nombre1 + nombre2) / 2
print("Moyenne :", moyenne)

Les opérations de comparaison

Les opérations de comparaison permettent de comparer deux valeurs pour savoir si l’une est plus grande, plus petite, égale, ou différente de l’autre. Les opérateurs de comparaison retournent un booléen qui est soit True si la comparaison est vraie, soit False si elle est fausse.

print("Est-ce que 10 est plus petit que 3x4 ?", 10 < 3 * 4)
print("Est-ce que 999 est égal 11x99 ?", 999 == 11 * 99)
print("Est-ce que 3x2 est différent de 2x3 ?", 3*2 != 2*3)

Voici les opérateurs de comparaison :

Opération Description
x < y Plus petit que
x > y Plus grand que
x <= y Plus petit ou égal à
x >= y Plus grand ou égal à
x == y Égal à
x != y Différent de

Les opérateurs de comparaison peuvent comparer des nombres ou des textes. Si les valeurs sont des textes, c’est l’ordre alphabétique qui est utilisé pour les comparer.

Exercice 4

Utilisez la console pour déterminer laquelle de ces expressions est la plus grande: πe ou eπ .

Solution

Dans la console, on peut exécuter math.pi ** math.e < math.e ** math.pi pour comparer les deux valeurs. Puisque l’expression retourne True, on sait que πe est plus petit que eπ . La réponse est donc que la plus grande valeur est eπ .

Instructions conditionnelles

Un programme peut prendre des décisions et exécuter des instructions seulement si une condition est remplie.

On utilise le mot-clé if pour indiquer une condition à tester. Si la condition est vraie, les instructions sous le if sont exécutées.

Par exemple, on peut demander à l’utilisateur d’entrer oui ou non pour confirmer une action.

solde = 1000
retrait = 200

confirmer = input("Confirmer ? : ")

if confirmer == "oui":
    solde = solde - retrait
    print("Retrait effectué, il reste", solde, "$ dans le compte.")

if confirmer == "non":
    print("Retrait annulé, il reste", solde, "$ dans le compte.")

Il y a un problème avec cet exemple! Si l’utilisateur entre autre chose que oui ou non, le programme ne fait rien!

Exercice 5

Écrivez un programme qui commence par définir une variable nombre qui peut contenir un nombre entier entre -100 et 100. Le programme doit afficher "positif" si le nombre est strictement supérieur à zéro, "négatif" si le nombre est strictement inférieur à zéro, et "zéro" si le nombre est égal à zéro.

Si on change la valeur de la variable nombre, le programme doit afficher le message correspondant au nombre défini.

Solution

On utilise trois instructions if pour tester les trois cas possibles qui sont nombre == 0, nombre < 0, et nombre > 0.

Si on change la valeur de nombre, le programme affichera le message correspondant à la condition qui est vraie.

nombre = 50 # Essayez de modifier ce nombre
            # pour tester les trois cas possibles

if nombre > 0:
    print("positif")

if nombre < 0:
    print("négatif")

if nombre == 0:
    print("zéro")

Exercice 6

Écrivez un programme qui demande à l’utilisateur d’entrer son nom.

Si l’utilisateur entre son nom, le programme doit afficher "Bonjour <nom> !"<nom> est le nom entré.

Si l’utilisateur n’entre rien (ou appuie sur Annuler), le programme doit afficher "Bonjour personne inconnue!".

Solution

nom = input("Entrez votre nom : ")

if nom != "":
    print("Bonjour", nom, "!")

if nom == "":
    print("Bonjour personne inconnue!")

Ce programme fonctionne, mais il teste deux fois une condition très similaire. La section suivante explique comment améliorer ce programme en utilisant else.

Instructions conditionnelles avec else

On peut aussi utiliser le mot-clé else pour indiquer des instructions à exécuter si la condition d’un if est fausse.

Par exemple, on peut demander à l’utilisateur de confirmer une action, et exécuter l’action seulement s’il répond oui. Sinon, on annule l’action.

solde = 1000
retrait = 200

confirmer = input("Confirmer ? : ")

if confirmer == "oui":
    solde = solde - retrait
    print("Retrait effectué, il reste", solde, "$ dans le compte.")
else:
    print("Retrait annulé, il reste", solde, "$ dans le compte.")

Exercice 7

Écrivez un programme qui demande à l’utilisateur d’entrer un nombre entier.

Le programme doit afficher "pair" si le nombre est pair, et "impair" sinon.

Indice

Un nombre est pair si le reste de sa division par 2 est égal à 0. On peut utiliser l’opérateur modulo % pour obtenir le reste d’une division.

Solution

nombre = int(input("Entrez un nombre entier : "))

if nombre % 2 == 0:
    print("pair")
else:
    print("impair")

Exercice 8

Écrivez un programme qui demande à l’utilisateur d’entrer un mot de passe. Si le mot de passe est correct, le programme doit afficher "Accès accordé!". Sinon, le programme doit afficher "Accès refusé...".

Le mot de passe est "piton123", gardez le secret!

Solution

mot_de_passe = input("Entrez le mot de passe: ")

if mot_de_passe == "piton123":
    print("Accès accordé!")
else:
    print("Accès refusé...")

Bien entendu, ce programme n’est pas sécurisé. Un vrai système de mot de passe ne devrait jamais stocker le mot de passe en texte clair dans le code!

Instructions conditionnelles avec elif

Si la condition d’un if est fausse, on peut utiliser le mot-clé elif (contraction de else if) pour tester une autre condition.

Seul les instructions sous le premier if ou elif dont la condition est vraie seront exécutées.

Par exemple, on peut demander à l’utilisateur de confirmer une action et exécuter des instructions différentes si la réponse est oui, non, ou une réponse invalide.

solde = 1000
retrait = 200

confirmer = input("Confirmer ? : ")

if confirmer == "oui":
    solde = solde - retrait
    print("Retrait effectué, il reste", solde, "$ dans le compte.")
elif confirmer == "non":
    print("Retrait annulé, il reste", solde, "$ dans le compte.")
else:
    print("Entrée invalide, le retrait est annulé.")

Exercice 9

Écrivez un programme qui demande à l’utilisateur d’entrer un notes en pourcentage (entre 0 et 100).

Le programme doit afficher la lettre correspondante selon l’échelle suivante :

Pourcentage Lettre
100 A+
90 - 99 A
80 - 89 B
70 - 79 C
60 - 69 D
0 - 59 E

Solution

En utilisant if, elif, et else, on peut tester chaque intervalle de pourcentage en ordre décroissant.

note = int(input("Entrez votre note (0-100) : "))

if note == 100:
    print("A+")
elif note >= 90:
    print("A")
elif note >= 80:
    print("B")
elif note >= 70:
    print("C")
elif note >= 60:
    print("D")
else:
    print("E")

Les opérations logiques : and et or

Les opérateurs logiques or (ou) et and (et) permettent de combiner des expressions booléennes.

L’opération test1 or test2 retourne True si au moins une des expressions est vraie.

print("True  or True  =", True or True)   # True
print("True  or False =", True or False)  # True
print("False or True  =", False or True)  # True
print("False or False =", False or False) # False

L’opération test1 and test2 retourne True si les deux expressions sont vraies.

print("True  and True  =", True and True)   # True
print("True  and False =", True and False)  # False
print("False and True  =", False and True)  # False
print("False and False =", False and False) # False

Les opérations logiques : not

L’opérateur logique not (non) retourne True si l’expression est fausse, et False si l’expression est vraie.

print("not True  =", not True)   # False
print("not False =", not False)  # True

Exercice 10

Dans une ville, le transport en commun est gratuit pour les enfants de moins de 12 ans et pour les aînés de 65 ans et plus. Les autres personnes doivent payer le tarif régulier de 2.50$.

Écrivez un programme qui demande à l’utilisateur d’entrer son âge. Le programme doit afficher "Gratuit!" si l’utilisateur peut utiliser le transport en commun gratuitement, et "Tarif régulier : 2.50$" sinon.

Solution

age = int(input("Entrez votre âge : "))

if age < 12 or age >= 65:
    print("Gratuit!")
else:
    print("Tarif régulier : 2.50$")

Exercice 11

Écrivez une intelligence artificielle très simple qui conseille à un humain s’il doit prendre un parapluie.

Le programme doit poser deux questions à l’utilisateur :

  • Est-ce qu’il pleut ?
  • Est-ce que tu veux rester au sec ?

Si l’utilisateur répond non à l’une des deux questions, le programme doit afficher "Pas besoin de parapluie.".

Si l’utilisateur répond oui aux deux questions, le programme doit afficher "Prends un parapluie.".

Par exemple, si l’utilisateur répond non à la première question, le programme doit afficher "Pas besoin de parapluie." sans poser la deuxième question.

Solution

Il y a deux façons de résoudre cet exercice. Voici une solution utilisant if, elif, et else. Dès que l’utilisateur répond non à une question, le programme affiche le message et s’arrête.

if input("Est-ce qu'il pleut ?") == "non":
    print("Pas besoin de parapluie.")
elif input("Est-ce que tu veux rester au sec ?") == "non":
    print("Pas besoin de parapluie.")
else:
    print("Prends un parapluie.")

On peut utiliser and pour être plus concis. L’opérateur and est spécial, car il évalue la deuxième condition seulement si la première est vraie.

if (input("Est-ce qu'il pleut ?") == "oui" and
    input("Est-ce que tu veux rester au sec ?") == "oui"):
    print("Prends un parapluie.")
else:
    print("Pas besoin de parapluie.")

Ce comportement de and qui arrête l’évaluation à la première expression fausse est appelé court-circuitage. L’opérateur or est similaire, mais arrête l’évaluation à la première expression vraie.

Résumé

Entrées avec input.

Instruction Description Exemple
input(message) Demander une entrée à l’utilisateur en affichant un message nom = input("Entrez votre nom : ")
input() Demander une entrée à l’utilisateur sans afficher de message entree = input()

Conversion de type.

Instruction Description Exemple
int(x) Convertir un texte en entier n = int("5")
float(x) Convertir un texte en flottant p = float("3.14")
type(valeur) Obtenir le type d’une valeur type(42)<class 'int'>

Opérateurs de comparaison.

Opérateur Description Exemple
x < y Plus petit que 3 < 5True
x > y Plus grand que 3 > 5False
x <= y Plus petit ou égal à 3 <= 3True
x >= y Plus grand ou égal à 4 >= 5False
x == y Égal à 2 == 3False
x != y Différent de 2 != 3True

Opérateurs logiques.

Opérateur Description Exemple
and Vrai si les deux conditions sont vraies a > 0 and b > 0
or Vrai si au moins une condition est vraie age < 12 or age >= 65
not Inverse la valeur booléenne not x == y

Instructions conditionnelles.

Mot-clé Description Exemple
if Exécuter si la condition est vraie
if note >= 90:
    print("A")
elif Tester une autre condition si le if précédent est faux
elif note >= 80:
    print("B")
else Exécuter si aucune condition n’est vraie
else:
    print("C")

Exercice 12

Écrivez un programme qui commence par définir une variable angle qui contient un nombre entier entre 0 et 180.

Le programme doit afficher "angle aigu" si l’angle est strictement inférieur à 90, "angle droit" si l’angle est égal à 90, et "angle obtus" si l’angle est strictement supérieur à 90.

Si vous changez la valeur de la variable angle, le programme doit afficher le message correspondant à l’angle défini.

Solution

On utilise trois instructions if pour tester les trois cas possibles qui sont angle == 90, angle < 90, et angle > 90.

Si on change la valeur de angle, le programme affichera le message correspondant à la condition qui est vraie.

angle = 90

if angle == 90:
    print("angle droit")

if angle < 90:
    print("angle aigu")

if angle > 90:
    print("angle obtus")

Exercice 13

Si un nombre se trouve entre 8 et 120 inclusivement, alors il est toujours premier s’il n’est pas divisible par 2, 3, 5, ou 7.

Écrivez un programme qui demande à l’utilisateur d’entrer un nombre entier entre 8 et 120.

Le programme doit afficher "Premier" si le nombre est premier. Sinon, le programme doit afficher "Divisible par <n>", où n est le plus petit des nombres 2, 3, 5, ou 7 par lequel le nombre est divisible.

Si le nombre entré n’est pas entre 8 et 120, le programme doit afficher "Je ne sais pas...".

Solution

On teste chacun des diviseurs possibles avec des instructions if et elif. Si un diviseur est trouvé, on affiche le message correspondant.

nombre = int(input("Entrez un nombre entier entre 8 et 120 : "))

if nombre < 8 or nombre > 120:
    print("Je ne sais pas...")
elif nombre % 2 == 0:
    print("Divisible par 2")
elif nombre % 3 == 0:
    print("Divisible par 3")
elif nombre % 5 == 0:
    print("Divisible par 5")
elif nombre % 7 == 0:
    print("Divisible par 7")
else:
    print("Premier")

Exercice 14

Écrivez un programme qui demande trois entrées à l’utilisateur : une opération (+, -, *, ou /), et deux nombres flottants.

Le programme doit effectuer l’opération demandée sur les deux nombres et afficher le résultat. Si l’opération n’est pas reconnue, le programme doit afficher "Opération invalide".

Solution

On utilise if, elif, et else pour tester chaque opération possible. Il ne faut pas oublier de convertir les entrées en nombres flottants avec float(input(...)).

operation = input("Entrez une opération (+, -, *, /) : ")
nombre1 = float(input("Entrez le premier nombre : "))
nombre2 = float(input("Entrez le deuxième nombre : "))

if operation == "+":
    resultat = nombre1 + nombre2
    print("Résultat :", resultat)
elif operation == "-":
    resultat = nombre1 - nombre2
    print("Résultat :", resultat)
elif operation == "*":
    resultat = nombre1 * nombre2
    print("Résultat :", resultat)
elif operation == "/":
    resultat = nombre1 / nombre2
    print("Résultat :", resultat)
else:
    print("Opération invalide")

Exercice 15

Un programme de virement bancaire vérifie si le solde du compte est suffisant pour effectuer un virement et s’assure que le montant entré est valide, c’est-à-dire un nombre positif.

Écrivez un programme qui commence par la définition d’une variable solde contenant le solde du compte (par exemple 1000$ ).

Le programme doit demander à l’utilisateur d’entrer le montant du virement.

Si le montant est négatif, le programme doit afficher "Montant invalide.".

Si le montant est supérieur au solde, le programme doit afficher "Fonds insuffisants.".

Autrement le programme affiche "Virement effectué." et met à jour le solde du compte.

Dans tous les cas, le programme doit afficher le solde restant après la tentative de virement.

Solution

On utilise float(input(...)) pour demander le montant du virement et if, elif, et else pour vérifier les conditions.

Puisque le solde doit être affiché dans tous les cas, on place l’instruction d’affichage du solde à la fin du programme, en dehors du if.

solde = 1000
montant = float(input("Entrez le montant du virement : "))

if montant < 0:
    print("Montant invalide.")
elif montant > solde:
    print("Fonds insuffisants.")
else:
    solde = solde - montant
    print("Virement effectué.")

print("Solde restant :", solde, "$")

Utilise des flottants pour un montant monétaire n’est pas idéal, notamment parce qu’on ne peut pas retirer 0,001 d’un compte bancaire. Cependant, c’est acceptable pour le moment.

Exercice 16

On peut trouver les zéro de ax2+bx+c avec l’équation des zéros d’une fonction quadratique.

x=b±b24ac2a

Il y a trois possibilités selon le signe du terme (b24ac) , appelé le discriminant :

  1. Positif : il y a deux zéros réels distincts.
  2. Égal à zéro : il y a un seul zéro réel.
  3. Négatif : il n’y a pas de zéro réel.

Écrivez un programme qui commence par la définition des variables a, b, et c. Le programme doit afficher le ou les zéros réels de l’équation quadratique, ou "aucun" s’il n’y en a pas.

a = 1
b = -3
c = 2

# Complétez le programme

Solution

On calcule d’abord le discriminant avec b**2 - 4 * a * c. On utilise ensuite if, elif, et else pour gérer les trois cas possibles.

a = 1
b = -3
c = 2

discriminant = b**2 - 4 * a * c

if discriminant > 0:
    racine1 = (-b + math.sqrt(discriminant)) / (2 * a)
    racine2 = (-b - math.sqrt(discriminant)) / (2 * a)
    print(racine1, racine2)
elif discriminant == 0:
    racine = -b / (2 * a)
    print(racine)
else:
    print("aucun")

Exercice 17

Écrivez un programme qui dessine le drapeau du Libéria en utilisant la tortue.

Les dimensions de ce drapeau sont de 285 de largeur et 150 de hauteur.

La taille de l’étoile est 2/3 de la taille du carré bleu.

Les couleurs utilisées sont pencolor(0.68, 0.18, 0.21) (rouge), et pencolor(0.06, 0.15, 0.4) (bleu).

Indice

Pour dessiner les onze lignes horizontales, utilisez une boucle for. Les lignes impaires sont rouges et les lignes paires sont blanches.

Solution

Pour dessiner les lignes, on utilise une boucle for qui répète pour les lignes 1, 2, ..., 11. Si le numéro de la ligne est impair (ligne % 2 == 1), on utilise la couleur rouge, sinon on utilise la couleur blanche.

# dimensions du drapeau
largeur = 285
hauteur = 150

hauteur_ligne = hauteur / 11

# dessiner les 11 lignes
rt(90)
hop()
bk(hauteur / 2)
pensize(largeur)

for ligne in 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11:
    if ligne % 2 == 1:
        pencolor(0.68, 0.18, 0.21)
    else:
        pencolor(1, 1, 1)
        
    fd(hauteur_ligne)

# dessiner le carré bleu
hop()
bk(hauteur_ligne * 8.5, largeur / 2)

lt(90)
carre = 5 * hauteur_ligne
pencolor(0.06, 0.15, 0.4)
pensize(5 * hauteur_ligne)
fd(carre)
bk(carre / 2)

# dessiner l'étoile blanche
pencolor(1, 1, 1)
image("star", 2/3 * carre / 100)

ht()

Exercice 18

Une année bissextile contient un jour supplémentaire (29 février) pour compenser le fait que la Terre ne prend pas exactement 365 jours pour faire le tour du Soleil.

Une année est bissextile si :

  • elle est divisible par 4 (bissextile)
  • sauf si elle est divisible par 100 (non bissextile)
  • à moins qu’elle soit divisible par 400 (bissextile)

Voici quelques exemples :

  • 2026 n’est pas bissextile (non divisible par 4)
  • 2028 est bissextile (divisible par 4)
  • 2100 n’est pas bissextile (divisible par 100)
  • 2000 est bissextile (divisible par 100, mais aussi par 400)

Écrivez un programme qui demande à l’utilisateur d’entrer une année (un entier), puis affiche "Année bissextile" si l’année est bissextile, et "Année non bissextile" sinon.

Indice

Une année est bissextile si elle est divisible par 4 ET pas divisible par 100, OU si elle est divisible par 400.

Pouvez-vous transformer cette phrase en expression booléenne en utilisant les opérateurs and, or ?

Solution

annee = int(input("Entrez une année : "))

if (annee % 4 == 0 and annee % 100 != 0) or (annee % 400 == 0):
    print("Année bissextile")
else:
    print("Année non bissextile")

Exercice 19

La vitesse de libération d’un corps céleste, par exemple une planète comme la Terre, est la vitesse minimale qu’un objet doit atteindre pour s’échapper de son attraction gravitationnelle. On utilise l’équation suivante pour calculer la vitesse de libération en mètres par seconde :

v=2GMR+h

G est la constante gravitationnelle, M est la masse du corps céleste, R est son rayon (en mètres), et h est l’altitude de l’objet (en mètres). Le résultat v est la vitesse de libération en mètres par seconde.

La constante gravitationnelle est 6.674×1011 . La masse de la Terre est 5.972×1024 kg et son rayon est d’environ 6.378×106 m.

Écrivez un programme qui servira de système de bord à une fusée. Le programme doit demander deux entrées à l’astronaute aux commandes :

  • l’altitude de la fusée en kilomètres
  • la vitesse de la fusée en km/s

Le système de bord doit déterminer si la fusée peut s’échapper de l’attraction gravitationnelle de la Terre. Il doit afficher "C'est parti!" si la fusée peut s’échapper, et "Encore un peu de puissance..." sinon.

G = 6.674e-11
masse_terre = 5.972e24 # kg
rayon_terre = 6.378e6 # m

# Complétez le programme

Indice

Afin de tester votre système de bord, la vitesse de libération à 100km d’altitude est d’environ 11.9 km/s.

N’oubliez pas de convertir l’altitude de kilomètres en mètres (1 km = 1000 m) et la vitesse de km/s en m/s (1 km/s = 1000 m/s)!

Solution

Après avoir calculé la vitesse de libération, on utilise >= pour vérifier si la fusée peut s’échapper de l’attraction gravitationnelle de la Terre.

G = 6.674e-11
masse_terre = 5.972e24 # kg
rayon_terre = 6.378e6 # m

altitude = float(input("Altitude de la fusée (km) : ")) * 1000  # m
vitesse_fusee = float(input("Vitesse de la fusée (km/s) : ")) * 1000  # m/s

liberation = math.sqrt((2 * G * masse_terre) / (rayon_terre + altitude)) # m/s

if vitesse_fusee >= liberation:
    print("C'est parti!")
else:
    print("Encore un peu de puissance...")

Exercice 20

Simple Farm Crops

Un robot botanique arrose automatiquement les plantes dans un champs. Le robot possède trois senseurs :

  • un capteur d’humidité du sol (0 à 100%)
  • un capteur de température (en °C)
  • un capteur de lumière (en lux, une unité de luminosité)

Pour s’assurer que les plantes poussent bien, le robot doit arroser si :

  • l’humidité du sol est inférieure à 30%
  • la température est supérieure à 20°C
  • la lumière ambiante est supérieure à 50 000 lux

Toutefois, si l’humidité du sol tombe sous 10%, le robot doit arroser peu importe la température et la lumière.

Écrivez un programme qui commence par la définition de trois variables : humidite, temperature, et lumiere. Le programme doit afficher "Arroser les plantes" si le robot doit arroser, et "Ne pas arroser" sinon.

humidite = 25
temperature = 22
lumiere = 25000

# Complétez le programme

Solution

Le robot doit arroser si l’humidité est inférieure à 30% et la température est supérieure à 20°C et la lumière est supérieure à 50 000 lux, ou si l’humidité est inférieure à 10%.

On peut traduire cette logique avec les opérateurs and et or en "humidite < 10 or (humidite < 30 and temperature > 20 and lumiere > 50000)".

humidite = 25
temperature = 22
lumiere = 25000

if (humidite < 30 and temperature > 20 and lumiere > 50_000) or humidite < 10:
    print("Arroser les plantes")
else:
    print("Ne pas arroser")

Les parenthèses autour des conditions combinées avec and ne sont pas strictement nécessaires car l’opérateur and a une priorité plus élevée que l’opérateur or (de la même manière que la multiplication a une priorité plus élevée que l’addition). Cependant, les inclure améliore la lisibilité du code.

Exercice 21

Écrivez un programme qui choisit un nombre entier aléatoire de 1 à 6 représentant le lancer d’un dé.

Utilisez la tortue pour dessiner la face du dé correspondant au nombre choisi.

Par exemple, si le nombre est 3, le programme doit dessiner ce dé :

Indice

On pourrait utiliser une série d’instructions if pour dessiner chaque face possible du dé.

if nombre == 1:
    # dessiner la face 1
elif nombre == 2:
    # dessiner la face 2
elif nombre == 3:
    # dessiner la face 3
...

Cette solution serait très longue! Un meilleur moyen est d’utiliser des conditions pour dessiner chaque point du dé. Par exemple, le point au centre doit être dessiné seulement si le nombre est 1, 3, ou 5

Les points en haut à gauche et en bas à droite doivent être dessinés seulement si le nombre est 2, 3, 4, 5, ou 6.

Et ainsi de suite, on peut déterminer les conditions pour chaque point du dé pour écrire un programme plus court.

Solution

On peut écrire un programme concis en ne testant que quatre conditions.

Si le nombre est 1, 3, ou 5, on dessine le point au centre.

Si le nombre est 2, 3, 4, 5, ou 6, on dessine les points en haut à gauche et en bas à droite.

Si le nombre est 4, 5, ou 6, on dessine les points en haut à droite et en bas à gauche.

Si le nombre est 6, on dessine les points au milieu à gauche et au milieu à droite.

nombre = randint(1, 6)

cote = 160
coord_point = cote / 4
point = cote / 800

image("square", cote/100)
pencolor("white")
image("square", 0.99 * cote/100)

pencolor("black")

# point au centre
if nombre == 1 or nombre == 3 or nombre == 5:
    image("disk", point)

if nombre >= 2:
    # points en haut à gauche
    hop(); bk(coord_point, -coord_point)
    image("disk", point)

    # points en bas à droite
    hop(); fd(2*coord_point, -2*coord_point)
    image("disk", point)
    hop(); bk(coord_point, -coord_point)

if nombre >= 4:
    # points en haut à droite
    hop(); fd(coord_point, coord_point)
    image("disk", point)
    hop(); bk(2*coord_point, 2*coord_point)

    # points en bas à gauche
    image("disk", point)
    hop(); fd(coord_point, coord_point)

if nombre == 6:
    # points au milieu à gauche
    hop(); bk(coord_point)
    image("disk", point)

    # points au milieu à droite
    hop(); fd(2*coord_point, 0)
    image("disk", point)
    hop(); bk(2*coord_point, 0)

ht()

Chaque bloc if ramène la tortue au centre du dé après avoir dessiné ses points. C’est important, autrement les prochains points ne seraient pas correctement centrés.

Exercice 22

Utilisez la tortue pour dessiner le drapeau de la Grèce.

Les dimensions de ce drapeau sont de 240 pixels de large par 160 pixels de haut. La teinte de bleue utilisée est obtenue avec pencolor(0.18, 0.36, 0.66).

Indice

Pour dessiner les neuf lignes horizontales, utilisez une boucle for. Les lignes impaires sont bleues et les lignes paires sont blanches. On peut utiliser un if avec l’opérateur modulo % pour déterminer si une ligne est paire ou impaire.

Solution

largeur = 240
hauteur = 160

hauteur_ligne = hauteur / 9

rt(90)
hop(); bk(hauteur / 2)
pensize(largeur)

# Dessin des neuf lignes
for ligne in 1, 2, 3, 4, 5, 6, 7, 8, 9:
    if ligne % 2 == 0:
        pencolor(1, 1, 1)
    else:
        pencolor(0.18, 0.36, 0.66)
    
    fd(hauteur_ligne)

# Placement pour le carré
hop()
bk(hauteur_ligne * 6.5,  largeur / 2)
lt(90)

cote_carre = 5 * hauteur_ligne

# Dessin du carré
pencolor(0.18, 0.36, 0.66)
pensize(cote_carre)
fd(cote_carre)

# Dessin de la croix blanche
pencolor(1, 1, 1)
pensize(hauteur_ligne)
bk(cote_carre)
fd(cote_carre / 2)
rt(90)
fd(cote_carre / 2)
bk(cote_carre)

ht()

Introduction

Un programme doit souvent effectuer la même tâche plusieurs fois. Si, par exemple, on a un programme qui dessine une maison avec la tortue :

pencolor("#f40")
image("square", 0.5)
hop(); fd(0, 43.3)
pencolor("#840")
image("triangle", 0.75)
hop(); bk(0, 43.3)
ht()

Ce n’est pas pratique d’avoir à copier ce code trois fois si on veut dessiner cette image d’un village :

La solution est de regrouper les instructions dans une fonction qui peut être réutilisée autant de fois que nécessaire.

# Ceci est une fonction qui dessine une maison quand on écrit maison()
def maison():
    pencolor("#f40")
    image("square", 0.5)
    hop(); fd(0, 43.3)
    pencolor("#840")
    image("triangle", 0.75)
    hop(); bk(0, 43.3)

hop(); bk(100, 50)
maison()
hop(); fd(100, 40)
maison()
hop(); fd(90, -25)
maison()

Exercice 1

Écrivez un programme qui dessine le dessin ci-dessus.

On remarque que ce dessin est composé d’une image d’une personne entourée d’un cadre orange sur fond jaune répétée trois fois.

Écrivez tout d’abord une fonction photo qui va dessiner l’image "person" encadrée. L’intérieur du cadre est 100 × 100 et l’épaisseur du cadre est 5 pixels. Ensuite utilisez cette fonction trois fois dans votre programme pour faire le dessin complet.

L’instruction photo() doit donc donner ce dessin :

Solution

Une personne encadrée peut se dessiner en superposant trois images. Le cadre peut se dessiner avec un carré orange de taille 110 × 110 sur lequel on superpose un carré jaune de taille 100 × 100. Il reste ensuite à dessiner en noir l’image d’une personne.

def photo():
    pencolor("orange")
    image("square", 1.1)
    pencolor("yellow")
    image("square")
    pencolor("black")
    image("person")

hop(); fd(-125)
photo()

hop(); fd(125)
photo()

hop(); fd(125)
photo()

ht()

Les fonctions

Une fonction est un morceau de code qui effectue une tâche spécifique. On a déjà vu des fonctions, comme print("Bonjour") qui affiche du texte, ou fd(100) qui fait avancer la tortue de 100 pixels.

C’est grâce aux paramètres que l’on peut modifier le comportement d’une fonction. Un paramètre est une valeur utilisée par la fonction dans sa logique. Par exemple, print prend comme paramètre le texte à afficher, et fd prend comme paramètre la distance à parcourir. L’effet obtenu dépend des paramètres fournis à la fonction.

En plus des fonctions qui sont prédéfinies, on peut aussi créer nos propres fonctions en utilisant le mot-clé def.

def accueillir(etudiant, cours):
    print("Bonjour", etudiant, "!")
    print("  Bienvenue au cours de", cours, "!")

accueillir("Alice", "chimie")
accueillir("Bob", "mathématiques")
accueillir("Charlie", "programmation")

Dans cet exemple accueillir est le nom de la fonction, et etudiant et cours sont ses paramètres. Utiliser une fonction en écrivant accueillir("Alice", "chimie") est appelé un appel de fonction.

Les instructions à l’intérieur d’une fonction sont indentées (décalées vers la droite). C’est similaire aux if, elif et else pour lesquels la fin des instructions est aussi indiquée par la fin de l’indentation.

Exercice 2

Écrivez une fonction appelée afficher_note qui prend comme paramètres le nom d’un étudiant et sa note (un nombre entre 0 et 100), et qui affiche un message dans le format "La note de Alice est 85 sur 100".

Utilisez ensuite cette fonction pour afficher le rapport suivant :

La note de Alice est 85 sur 100
La note de Bob est 92 sur 100
La note de Charlie est 78 sur 100

Solution

def afficher_note(etudiant, note):
    print("La note de", etudiant, "est", note, "sur 100")

afficher_note("Alice", 85)
afficher_note("Bob", 92)
afficher_note("Charlie", 78)

Exercice 3

Écrivez un programme qui dessine le dessin ci-dessus.

On remarque que ce dessin est similaire à celui du premier exercice. C’est l’image à l’intérieur du cadre qui change. La fonction qui fait une image encadrée doit donc avoir un paramètre qui est le nom de l’image à encadrer.

Écrivez tout d’abord une fonction encadrer qui prend comme paramètre le nom d’une image et qui la dessine dans un cadre. L’intérieur du cadre est 100 × 100 et l’épaisseur du cadre est 5 pixels. Ensuite utilisez cette fonction trois fois dans votre programme pour faire le dessin complet.

L’instruction encadrer("star") doit donc donner ce dessin :

Solution

Comme pour le premier exercice chaque image encadrée peut se dessiner en superposant trois images. Le cadre peut se dessiner avec un carré orange de taille 110 × 110 sur lequel on superpose un carré jaune de taille 100 × 100. Il reste ensuite à dessiner en noir l’image dont le nom a été donné en paramètre.

Il faut définir la fonction encadrer avec def encadrer(nom): et dans le programme on retrouvera les appels de fonction encadrer("ant"), encadrer("spider") et encadrer("crab").

def encadrer(nom):
    pencolor("orange")
    image("square", 1.1)
    pencolor("yellow")
    image("square")
    pencolor("black")
    image(nom)

hop(); fd(-125)
encadrer("ant")

hop(); fd(125)
encadrer("spider")

hop(); fd(125)
encadrer("crab")

ht()

Retourner une valeur

(14, 3)(10, 0)

Une fonction peut retourner une valeur. Par exemple, math.sqrt(x) est une fonction qui retourne la racine carrée de x.

On peut écrire des fonctions qui retournent des valeurs en utilisant le mot-clé return. Quand on utilise return, la fonction s’arrête immédiatement et passe la valeur à l’endroit où la fonction a été appelée.

Par exemple, on peut écrire une fonction qui calcule la distance entre deux points dans un plan cartésien en utilisant le théorème de Pythagore.

def distance(x1, y1, x2, y2):
    # Calcul de la distance entre (x1, y1) et (x2, y2)
    return math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)

print("La distance entre les points est de", distance(10, 0, 14, 3))

Les variables et les noms de paramètres utilisés à l’intérieur d’une fonction ne sont pas accessibles à l’extérieur de la fonction. On dit que la portée de ces variables est limitée à l’intérieur de la fonction. Ça permet d’utiliser les mêmes noms de variables dans différentes fonctions sans risque de conflit.

Exercice 4

Écrivez une fonction appelée montant_apres_taxes qui prend en paramètre le montant d’un achat avant taxes, et qui retourne le montant après avoir ajouté les taxes. Il y a deux taxes à ajouter sur le montant initial : la TPS (5%) et la TVQ (9.975%). Le total retourné est donc l’addition du montant initial, de la TPS et de la TVQ.

Terminez votre programme avec trois exemples d’utilisation de la fonction.

Solution

On définit la fonction avec def montant_apres_taxes(montant): et on calcule la tps, et la tvq. Pour retourner le résultat de l’addition du montant et des taxes, on utilise return montant + tps + tvq.

def montant_apres_taxes(montant):
    tps = montant * 0.05
    tvq = montant * 0.09975
    return montant + tps + tvq

# Exemple 1
print("Le montant après taxes est de", montant_apres_taxes(5))

# Exemple 2
print("Le montant après taxes est de", montant_apres_taxes(10))

# Exemple 3
print("Le montant après taxes est de", montant_apres_taxes(500))

Exercice 5

1 radRR

Les fonctions mathématiques math.sin et math.cos prennent comme paramètre un angle en radians. Il est souvent pratique de pouvoir utiliser des angles en degrés. Écrivez deux fonctions appelées sin_degres et cos_degres qui prennent comme paramètre un angle en degrés, et qui retournent respectivement le sinus et le cosinus de cet angle.

On peut convertir un angle de degrés vers radians en utilisant la formule suivante :

rad=deg×π180

Solution

On définit d’abord la fonction def sin_degres(angle_degres): qui commence par calculer l’angle en radians, puis retourne le sinus de cet angle en utilisant math.sin.

On fait ensuite la même chose pour la fonction cos_degres.

def sin_degres(angle_degres):
    angle_radians = angle_degres * math.pi / 180
    return math.sin(angle_radians)

def cos_degres(angle_degres):
    angle_radians = angle_degres * math.pi / 180
    return math.cos(angle_radians)

print("Le sinus de 30 degrés est de", sin_degres(30))
print("Le cosinus de 30 degrés est de", cos_degres(30))

Différence entre retourner et afficher

Parfois, le rôle d’une fonction est de retourner une valeur, parfois c’est d’afficher quelque chose (du texte dans la console, ou un dessin avec la tortue).

Quand une fonctionne retourne une valeur, cette valeur peut être utilisée dans d’autres calculs.

Quand une fonction affiche une valeur sans la retourner, elle est uniquement visible à l’écran et on ne peut pas utiliser cette valeur dans d’autres calculs.

Si on se trompe et qu’on affiche une valeur au lieu de la retourner, le programme ne fonctionnera pas comme prévu. Voici un exemple où la fonction rabais affiche le montant d’un rabais de 10% au lieu de le retourner, ce qui empêche de calculer le prix après rabais.

def rabais(prix):
    print(prix * 0.1)

prix = 100
prix_apres_rabais = prix - rabais(prix)

print("Le prix après rabais est de", prix_apres_rabais)

Voici la version correcte qui retourne la valeur au lieu de l’afficher.

def rabais(prix):
    return prix * 0.1

prix = 100
prix_apres_rabais = prix - rabais(prix)

print("Le prix après rabais est de", prix_apres_rabais)

Exercice 6

300100120

Écrivez une fonction appelée aire_trapeze qui prend comme paramètres la petite base, la grande base et la hauteur d’un trapèze, et qui retourne son aire.

Utilisez ensuite cette fonction pour afficher l’aire d’un trapèze de petite base 100, grande base 300 et hauteur 120, comme ci-dessus.

Indice

La formule pour l’aire d’un trapèze est :

A=hauteur×petite base+grande base2

Solution

On utilise la formule pour l’aire d’un trapèze pour écrire la fonction aire_trapeze. Il est important d’utilise return pour que la fonction retourne la valeur de l’aire.

def aire_trapeze(petite_base, grande_base, hauteur):
    return hauteur * (petite_base + grande_base) / 2

print("L'aire du trapèze est de", aire_trapeze(100, 300, 120))

Exercice 7

150100

Écrivez une fonction appelée afficher_aire_parallelogramme qui prend comme paramètres la base et la hauteur d’un parallélogramme, et qui affiche son aire.

Utilisez ensuite cette fonction pour afficher l’aire d’un parallélogramme de base 150 et hauteur 100, comme ci-dessus.

Solution

Une astuce pour avoir du code lisible et réutilisable est de créer une fonction qui retourne l’aire du parallélogramme, puis d’utiliser cette fonction dans afficher_aire_parallelogramme pour afficher l’aire.

L’une des deux fonction retourne et l’autre affiche, ce qui évite de confondre les deux rôles. On appelle cette manière de faire le principe de séparation des préoccupations.

def aire_parallelogramme(base, hauteur):
    return base * hauteur

def afficher_aire_parallelogramme(base, hauteur):
    print("L'aire du parallélogramme est de", aire_parallelogramme(base, hauteur))

afficher_aire_parallelogramme(150, 100)

Les effets secondaires d’une fonction

Certaines fonctions modifient l’état du programme. On dit que ces fonctions ont des effets secondaires. Par exemple, si la position de la tortue avant et après l’appel de fonction est différente, c’est un effet secondaire de la fonction.

Écrire des fonctions sans effets secondaires aide à rendre le code plus facile à comprendre. Autant que possible, écrivez des fonctions qui évitent les effets secondaires. Par exemple, après une fonction qui fait un dessin, ramenez la tortue à sa position initiale.

def drapeau_japon():
    pensize(67)
    pencolor("#eee")
    fd(100)
    bk(50)
    pencolor("#b33")
    pensize(3 / 5 * 67)
    regpoly()

    # Rétablir la position initiale
    hop()
    bk(50)

# Avant le dessin du drapeau, la tortue est à gauche
drapeau_japon()

# Après le dessin, la tortue est encore à gauche
# On en profite pour dessiner un mât au drapeau
pencolor("brown")
pensize(2)
rt(90)
bk(67/2)
fd(100)
ht()

Exercice 8

Écrivez une fonction appelée rectangle qui dessine une rectangle de couleur centré à la position de la tortue.

La fonction doit prendre comme paramètres la largeur, la hauteur et la couleur du rectangle. Quand la fonction retourne, elle doit laisser la tortue à la même position qu’au début.

Par exemple, rectangle(200, 100, "yellow") doit dessiner un rectangle en utilisant le tracé suivant pour ramener la tortue au centre du rectangle après le dessin :

Solution

On sait déjà dessiner un rectangle. Il suffit donc d’ajouter un mouvement à la fin du dessin pour ramener la tortue à sa position initiale.

def rectangle(largeur, hauteur, couleur):
    pensize(hauteur)
    pencolor(couleur)

    # Dessiner le rectangle
    bk(largeur / 2)
    fd(largeur)

    # Rétablir la position initiale de la tortue
    bk(largeur / 2)

rectangle(200, 100, "yellow")

Exercice 9

Réutilisez la fonction rectangle écrite dans le dernier exercice pour dessiner le drapeau de la Suède.

Les dimensions du drapeau sont de 160 pixels de largeur et 100 pixels de hauteur. Les couleurs utilisées sont "#058" (bleu) et "#fc0" (jaune).

Indice

Une fois la fonction rectangle écrite, on peut dessiner ce drapeau avec trois rectangles.

Solution

Ce drapeau peut être dessiné en trois rectangle :

  1. Un grand rectangle bleu de 160×100 centré à (0, 0)
  2. Un rectangle jaune horizontal de 160×20 centré à (0, 0)
  3. Un rectangle jaune vertical de 20×100 centré à (-25, 0)
def rectangle(largeur, hauteur, couleur):
    pensize(hauteur)
    pencolor(couleur)

    # Dessiner le rectangle
    bk(largeur / 2)
    fd(largeur)

    # Rétablir la position initiale de la tortue
    bk(largeur / 2)

rectangle(160, 100, "#058")
rectangle(160, 20, "#fc0")
hop(); bk(25)
rectangle(20, 100, "#fc0")
ht()

Résumé

Les fonctions.

Instruction Description Exemple
def fn(param): Définir une fonction
def saluer(nom):
    print("Bonjour", nom)
return valeur Retourner une valeur depuis une fonction
def carre(x):
    return x * x
Appel de fonction Exécute la fonction avec des paramètres
saluer("Alice")
print(carre(10))

Exercice 10

Écrivez un fonction aire_rectangle qui prend comme paramètres la largeur et la hauteur d’un rectangle, et qui retourne son aire.

Utilisez cette fonction pour calculer l’aire d’un rectangle de 12 unités de largeur et 5 unités de hauteur, puis affichez le résultat.

125

Solution

Pour définir une fonction, on utilise def. Puisque la fonction doit calculer l’aire d’un rectangle, on choisit le nom aire_rectangle et on déclare deux paramètres largeur et hauteur.

def aire_rectangle(largeur, hauteur):
    return largeur * hauteur

# Calcul de l'aire d'un rectangle de 12 x 5
aire = aire_rectangle(12, 5)
print("L'aire du rectangle est de", aire)

Exercice 11

°C

Écrivez une fonction qui prend une température en degrés Celsius et qui retourne la température correspondante en degrés Fahrenheit. La formule de conversion est la suivante :

Fahrenheit=Celsius×95+32

Utilisez cette fonction pour trouver les températures de congélation et d’ébullition de l’eau en degrés Fahrenheit, puis affichez les résultats.

Solution

On doit créer une fonction qui prend un paramètre, la température en celsius. On déclare donc une fonction avec def celsius_vers_fahrenheit(celsius) qui retourne le résultat celsius * 9 / 5 + 32 avec return.

def celsius_vers_fahrenheit(celsius):
    return celsius * 9 / 5 + 32

# Température de congélation de l'eau
temp_congelation_c = 0
temp_congelation_f = celsius_vers_fahrenheit(temp_congelation_c)
print("La température de congélation de l'eau est de", temp_congelation_f, "F")

# Température d'ébullition de l'eau
temp_ebullition_c = 100
temp_ebullition_f = celsius_vers_fahrenheit(temp_ebullition_c)
print("La température d'ébullition de l'eau est de", temp_ebullition_f, "F")

Exercice 12

Le programme dans votre environnement de développement doit calculer la vitesse d’un objet en chute libre qui tombe pendant un certain nombre de secondes à partir d’une vitesse initiale donnée.

En ce moment, ce programme ne fonctionne pas correctement. Trouvez l’erreur et corrigez-la.

def vitesse_chute(v_init, acc, temps):
    print(v_init + acc * temps)

def deplacement_chute(v_init, acc, temps):
    return (v_init + vitesse_chute(v_init, acc, temps)) / 2 * temps

# Paramètres de la chute
temps = 5  # secondes
acceleration = 9.8  # m/s² vers le bas
vitesse = 5  # m/s vers le bas
dist = deplacement_chute(vitesse, acceleration, temps)

print("Le déplacement après", temps, "secondes est de", dist, "mètres.")

Solution

L’erreur dans ce programme est que la fonction vitesse_chute affiche la vitesse au lieu de la retourner. Pour corriger cette erreur, il faut remplacer print par return dans cette fonction.

def vitesse_chute(v_init, acc, temps):
    return v_init + acc * temps

def deplacement_chute(v_init, acc, temps):
    return (v_init + vitesse_chute(v_init, acc, temps)) / 2 * temps

# Paramètres de la chute
temps = 5  # secondes
acceleration = 9.8  # m/s² vers le bas
vitesse = 5  # m/s vers le bas
dist = deplacement_chute(vitesse, acceleration, temps)

print("Le déplacement après", temps, "secondes est de", dist, "mètres.")

Exercice 13

Écrivez une fonction identifier_substance qui prend comme paramètre la masse et le volume d’une substance. La fonction doit afficher "Plus dense que l'eau" si la densité de la substance est supérieure à 1 g/cm³, et "Moins dense que l'eau" sinon. Si la masse volumique est exactement égale à 1 g/cm³, la fonction doit afficher "C'est de l'eau!".

Utilisez votre fonction pour identifier une substance de 10 cm³ de volume et dont la masse est 7,89 g.

Indice

La densité d’une substance est calculée en divisant sa masse par son volume. Vous pouvez donc utiliser cette fonction, ainsi qu’une condition if pour déterminer si la substance est plus ou moins dense que l’eau.

def masse_volumique(masse, volume):
    return masse / volume

Solution

On sépare le programme en deux fonctions : une qui calcule la masse volumique, et une qui utilise cette fonction pour identifier la substance.

def masse_volumique(masse, volume):
    # Formule pour calculer la masse volumique
    return masse / volume

def identifier_substance(masse, volume):
    densite = masse_volumique(masse, volume)
    if densite > 1:
        print("Plus dense que l'eau")
    elif densite == 1:
        print("C'est de l'eau!")
    else:
        print("Moins dense que l'eau")

# Identifier la substance
identifier_substance(7.89, 10)

Exercice 14

Écrivez une fonction appelée drapeau_canada qui dessine le drapeau du Canada et appelez cette fonction pour dessiner un drapeau centré comme celui-ci :

Le drapeau a une largeur de 200 pixels et une hauteur de 100 pixels. Les deux bandes rouges ont une largeur de 50 pixels chacune. Utilisez image("maple leaf") pour dessiner la feuille d’érable. Les dimensions de l’image sont appropriées pour le drapeau. La couleur de l’image peut être changée avec pencolor. Utilisez la couleur "#f34" pour le rouge du drapeau. Assurez-vous que la tortue soit à la même position avant et après l’appel de la fonction.

Solution

def drapeau_canada():
    pensize(100)
    pencolor("#f34")

    # Dessin du drapeau
    fd(50)
    pencolor("white")
    fd(100)
    pencolor("#f34")
    fd(50)
    hop(); bk(100)
    image("maple leaf")
    hop(); bk(100)

    # Réinitialiser la tortue à son état initial
    hop(); bk(200)

hop(); bk(100)
drapeau_canada()
ht()

Exercice 15

Pour dessiner une image avec une certaine couleur et position, il faut positionner la tortue, puis appeler pencolor(couleur) et image(nom). Il serait pratique d’avoir une seule fonction qui fait tout ça en un seul appel.

Écrivez une fonction appelée dessiner_image qui prend comme paramètres la position x et y, la couleur, et le nom de l’image. La fonction doit dessiner l’image à la position donnée avec la couleur donnée, puis ramener la tortue à sa position initiale.

Utilisez ensuite votre fonction pour faire les appels suivants.

dessiner_image(50, 50, "red", "crab")
dessiner_image(50, -50, "purple", "spider")
dessiner_image(-50, -50, "green", "rocket")
dessiner_image(-50, 50, "blue", "ant")

Votre programme devrait alors faire ce dessin.

Solution

Si on souhaitait dessiner une image d’une couleur donnée à un position, alors on pourrait écrire le code suivant :

x = 50
y = 50
couleur = "red"
nom_image = "crab"

# Placer la tortue
hop()
fd(x, y)

# Dessiner l'image avec la bonne couleur
pencolor(couleur)
image(nom_image)

# Ramener la tortue à sa position initiale
hop()
bk(x, y)

Pour réutiliser ce code avec une fonction, on place le code dans un bloc def dessiner_image(...) et on remplace les valeurs fixes par des paramètres de la fonction.

def dessiner_image(x, y, couleur, nom_image):
    # Placer la tortue
    hop()
    fd(x, y)

    # Dessiner l'image avec la bonne couleur
    pencolor(couleur)
    image(nom_image)

    # Ramener la tortue à sa position initiale
    hop()
    bk(x, y)

dessiner_image(50, 50, "red", "crab")
dessiner_image(50, -50, "purple", "spider")
dessiner_image(-50, -50, "green", "rocket")
dessiner_image(-50, 50, "blue", "ant")
ht()

Exercice 16

(0, 3)(10, 1)(4, 6)

Écrivez une fonction appelée perimetre_triangle qui prend comme paramètres les coordonnées des trois sommets d’un triangle, donc six paramètres au total.

La fonction doit retourner le périmètre du triangle ci-dessus.

Solution

On peut réutiliser la fonction distance définie précédemment pour calculer la longueur de chaque côté du triangle.

On écrit une fonction perimetre_triangle qui calcule la longueur des trois côtés en appelant distance trois fois et en additionnant les côtés.

def distance(x1, y1, x2, y2):
    return math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)

def perimetre_triangle(x1, y1, x2, y2, x3, y3):
    cote1 = distance(x1, y1, x2, y2)
    cote2 = distance(x2, y2, x3, y3)
    cote3 = distance(x3, y3, x1, y1)
    return cote1 + cote2 + cote3

# Exemple d'utilisation de la fonction

print("Le périmètre du triangle est de", perimetre_triangle(0, 3, 4, 6, 10, 1))

Exercice 17

Écrivez une fonction appelée drapeau_quebec qui dessine le drapeau du Québec et appelez cette fonction pour dessiner un drapeau centré comme celui-ci :

Le drapeau a une largeur de 240 pixels et une hauteur de 160 pixels. Il y a une croix blanche de 40 pixels de largeur qui divise le drapeau en quatre rectangles bleus. Dans chaque rectangle bleu, il y a une fleur de lis blanche dessinée avec image("fleur-de-lis", 0.5). Assurez-vous que la tortue soit à la même position avant et après l’appel de la fonction.

Solution

Le corps du drapeau peut être dessiné avec trois rectangles : un grand rectangle bleu, un rectangle blanc horizontal et un rectangle blanc vertical. On écrit donc une fonction rectangle(largeur, hauteur, couleur) pour dessiner ces trois rectangles.

On peut aussi simplifier le code en écrivant une fonction fleur_de_lis(x, y) qui dessine une fleur de lis à la position (x, y) et qui ramène la tortue à sa position initiale. Il n’est pas obligatoire d’écrire cette fonction, mais ça rend le code de drapeau_quebec plus concis.

def rectangle(largeur, hauteur, couleur):
    pensize(hauteur)
    pencolor(couleur)

    # Dessiner le rectangle
    bk(largeur / 2)
    fd(largeur)

    # Rétablir la position initiale de la tortue
    bk(largeur / 2)

def fleur_de_lis(x, y):
    hop(); fd(x, y)
    pencolor("white")
    image("fleur-de-lis", 0.5)
    hop(); bk(x, y)

def drapeau_quebec():
    largeur = 240
    hauteur = 2 * largeur // 3
    largeur_bande = largeur // 6

    bleu = "#21a"

    x_fleur = largeur * 7 // 24
    y_fleur = largeur_bande // 2 + largeur // 8

    rectangle(largeur, hauteur, bleu)
    rectangle(largeur, largeur_bande, "white")
    rectangle(largeur_bande, hauteur, "white")
    
    fleur_de_lis(x_fleur, y_fleur)
    fleur_de_lis(-x_fleur, y_fleur)
    fleur_de_lis(x_fleur, -y_fleur)
    fleur_de_lis(-x_fleur, -y_fleur)

drapeau_quebec()
ht()

Exercice 18

La forme suivante est construite à partir d’un carré de côté c dont les coins inférieurs, ainsi qu’un triangle formé par le centre du carré et ses sommets supérieurs, ont été enlevés.

cc

Écrivez un programme qui fait les trois choses suivantes :

  • Dessiner la forme suivante de dimension 150;
  • Calculer l’aire de cette forme;
  • Afficher l’aire calculée dans la console.

Pour ce faire, écrivez trois fonctions : dessiner_forme(c) qui dessine la forme de dimension c, aire_forme(c) qui calcule et retourne l’aire de la forme, et afficher_aire_forme(c) qui affiche l’aire calculée dans la console. Le message affichée dans le cas de c = 150 devrait être :

L'aire est de 11250.0

Indice

Si on réarrange la forme, on peut voir qu’elle correspond en fait à un carré dont on a retiré la moitié de son aire. Pour une forme de dimensions c, l’aire du carré est c ** 2, donc l’aire de la forme est c ** 2 / 2.

Solution

Puisque le problème nous demande de faire trois choses différentes, une bonne première étape est de déclarer trois fonctions vides qu’on remplira une à la fois.

def dessiner_forme(c):
    ... # À faire plus tard

def aire_forme(c):
    ... # À faire plus tard

def afficher_aire_forme(c):
    ... # À faire plus tard

Bien sûr, il faut maintenant remplir ces fonctions, mais séparer le travail en trois parties nous permet de nous concentrer sur une tâche à la fois.

def dessiner_forme(c):
    hop()
    bk(0, c/2)
    fd(c/2, c/2)
    fd(0, c/2)
    bk(c/2, c/2)
    bk(c/2,-c/2)
    fd(0, -c/2)
    fd(c/2, -c/2)

def aire_forme(c):
    return c ** 2 / 2

def afficher_aire_forme(c):
    print("L'aire est de", aire_forme(c))

cote = 150

ht()
dessiner_forme(cote)
afficher_aire_forme(cote)

Exercice 19

De nombreux drapeaux nationaux sont formés de trois bandes verticales de couleurs différentes. On peut utiliser une même fonction pour dessiner ces drapeaux en changeant simplement les couleurs.

Écrivez une fonction appelée drapeau_tricolore qui dessine un drapeau tricolore de 100 pixels de largeur et 67 pixels de hauteur. La fonction doit prendre trois paramètres représentant les couleurs des bandes de gauche à droite.

Utilisez cette fonction pour faire le dessin suivant contenant six drapeaux tricolores, espacés de 10 pixels.

Les couleurs utilisées pour chaque drapeau sont indiquées dans le tableau suivant.

Pays Drapeau Couleur 1 Couleur 2 Couleur 3
France "#125" "#fff" "#c33"
Chad "#026" "#fd0" "#d13"
Guinée "#c33" "#fd4" "#496"
Italie "#094" "#fff" "#d33"
Mali "#1b4" "#fd1" "#d12"
Côte d’Ivoire "#f80" "#fff" "#0a6"

Solution

En plus d’utiliser def pour définir la fonction drapeau_tricolore, on crée aussi une fonction deplacer pour déplacer la tortue sans dessiner. Cela permet d’éviter de répéter le code de déplacement plusieurs fois.

Une fois les fonctions écrites, on déplace la tortue, puis on appelle drapeau_tricolore six fois avec les bonnes couleurs.

def drapeau_tricolor(couleur1, couleur2, couleur3):
    largeur = 100
    hauteur = 67

    largeur_bande = largeur / 3

    pensize(hauteur)

    for couleur in couleur1, couleur2, couleur3:
        pencolor(couleur)
        fd(largeur_bande)

def deplacer(x, y):
    hop()
    fd(x, y)

clear()

# Première rangée de drapeaux
deplacer(-160, 39)
drapeau_tricolor("#125", "#fff", "#c33")
deplacer(10, 0)
drapeau_tricolor("#026", "#fd0", "#d13")
deplacer(10, 0)
drapeau_tricolor("#c33", "#fd4", "#496")

# Deuxième rangée de drapeaux
deplacer(-320, -77)
drapeau_tricolor("#094", "#fff", "#d33")
deplacer(10, 0)
drapeau_tricolor("#1b4", "#fd1", "#d12")
deplacer(10, 0)
drapeau_tricolor("#f80", "#fff", "#0a6")

ht()

Exercice 20

Écrivez un programme qui fait le dessin d’un cube 3D comme ci-dessus. Ce dessin est composé de trois losanges avec des teintes de gris légèrement différentes. Un losange c’est deux images "triangle" dos-à-dos. Le losange du haut a la couleur "#ddd", celui de gauche a la couleur "#ccc" et celui de droite a la couleur "#aaa".

Commencez votre programme avec la définition d’une fonction nommée losange qui dessine un losange d’une certaine couleur au dessus de la tortue. Donc l’instruction losange("#ddd") doit donner ce dessin :

Solution

La définition de la fonction losange doit positionner deux images "triangle" pour qu’elles soient dans la bonne orientation et position. Le positionnement peut se faire sans calculs trigonométriques si on tient compte que le sommet de l’image du triangle est à une distance de 50 pixels au dessus du centre de l’image. Un déplacement de la tortue avec bk(0, 50) suivi de image("triangle") va donc placer le sommet du triangle à l’endroit où était la tortue avant le déplacement. L’orientation du triangle est déterminée par une rotation de la tortue avant le déplacement de la tortue.

def losange(couleur):
    pencolor(couleur)
    lt(150)
    hop(); bk(0, 50)
    image("triangle")
    hop(); fd(0, 50)
    lt(60)
    hop(); bk(0, 50)
    image("triangle")
    hop(); fd(0, 50)
    rt(210)

losange("#ddd")

rt(120)
losange("#aaa")

rt(120)
losange("#ccc")

ht()

Exercice 21

Le dessin du yin et yang ci-dessus peut être fait avec une composition de cercles et de demi-cercles de différentes tailles, couleurs et à différents angles de rotation.

Écrivez une fonction permettant de dessiner une image à une position, avec une couleur, une échelle et un angle de rotation donnés.

Utilisez ensuite cette fonction pour composer des cercles (image "disk") et des demi-cercles (image "disk180") de différentes couleurs (utilisez les couleurs "black", "white" et "gray"), échelles et angles pour faire le dessin.

Indice

Écrivez une fonction dessiner_image(x, y, nom, couleur, echelle, angle) qui dessine une image à la position (x, y), avec le nom nom, la couleur couleur, l’échelle echelle et l’angle de rotation angle.

def dessiner_image(x, y, nom, couleur, echelle, angle):
    ... # Complétez cette fonction

Une fois cette fonction écrite, il est possible de faire le dessin demandé avec cinq cercles et deux demi-cercles.

Solution

def dessiner_image(x, y, nom, couleur, echelle, angle):
    hop(); fd(x, y)
    pencolor(couleur)
    lt(angle); image(nom, echelle); rt(angle)
    hop(); bk(x, y)

dessiner_image(0,   0, "disk",    "gray",  2.01, 0)
dessiner_image(0,   0, "disk180", "black", 2,    90)
dessiner_image(0,   0, "disk180", "white", 2,   -90)
dessiner_image(0,  50, "disk",    "black", 1,   -90)
dessiner_image(0, -50, "disk",    "white", 1,    90)
dessiner_image(0,  50, "disk",    "white", 0.25, 0)
dessiner_image(0, -50, "disk",    "black", 0.25, 0)

ht()

Retour sur les boucles

On a vu comment exécuter une séquence d’instructions plusieurs fois avec une boucle for.

for x in 1, 2, 3, 4, 5:
    print("x=", x)

Le problème avec les boucles for est qu’on doit connaître à l’avance le nombre d’itérations à effectuer. Si on ne le connaît pas, on peut utiliser une boucle while.

Par exemple, voici un programme qui imprime la première puissance de 2 supérieure à 1000. Puisqu’on ne sait pas à l’avance combien de fois il faudra multiplier par 2 pour dépasser 1000, on doit répéter la multiplication tant que le nombre est inférieur ou égal à 1000.

nombre = 1

while nombre <= 1000:
    nombre = nombre * 2

print("La première puissance de 2 supérieure à 1000 est", nombre)

On aurait pu quand même utiliser une boucle while pour faire l’équivalent de la boucle for ci-dessus. Par exemple :

x = 1
while x <= 5:
    print("x=", x)
    x = x + 1

Les boucles while

Un programme peut répéter une séquence d’instructions autant de fois que nécessaire en utilisant une boucle conditionnelle, ou boucle while.

On utilise le mot-clé while pour créer une boucle conditionnelle. Le mot-clé while est suivi d’une condition, comme un if. Si la condition est vraie, les instructions indentées sous le while sont exécutées.

À la fin d’une exécution de la boucle, appelée une itération, la condition est évaluée à nouveau et la boucle se répète si la condition est encore vraie.

iteration = 1

while iteration <= 5:
    print("La boucle a fait", iteration, "itération(s).")
    iteration = iteration + 1

print("La boucle est terminée.")

Les boucles peuvent servir à toutes sortes de choses. Par exemple, créer des animations, redemander une entrée utilisateur jusqu’à ce qu’elle soit valide, ou traiter une liste de données.

Exercice 1

Écrivez un programme qui affiche les nombres pairs de 2 à 20 inclusivement.

Solution

On initialise une variable nombre qui commence à 2 et qui changera à la fin de chaque itération de la boucle.

Après avoir ajouté 2 à la variable nombre, la boucle vérifie si nombre est toujours inférieur ou égal à 20 et démarre une nouvelle itération si c’est le cas.

nombre = 2
while nombre <= 20:
    print(nombre)
    nombre = nombre + 2

Exercice 2

Écrivez un programme qui dessine un escalier avec la tortue, comme ci-dessus.

Dans cet exemple, l’escalier a 8 marches de 20 pixels de hauteur chacune, mais il doit être facile de changer le nombre de marches et la taille des marches.

Solution

Pour qu’il soit facile de changer la taille et le nombre de marche, on écrit une fonction marche qui dessine une marche d’une taille donnée. On écrit aussi une fonction escalier qui utilise une boucle while pour dessiner le nombre de marches désiré.

Un truc utile pour rendre le code plus court est de décrémenter le nombre de marche restant à dessiner à chaque itération avec n = n - 1 et d’itérer tant qu’il reste des marches à dessiner, c’est-à-dire que n > 0. Ça évite d’avoir à utiliser une seconde variable pour compter les marches déjà dessinées.

def marche(taille):
    fd(0, taille)
    fd(taille)

def escalier(n, taille_marche):

    demi_taille = taille_marche * n / 2
    hop(); bk(demi_taille, demi_taille)

    while n > 0:
        marche(taille_marche)
        n = n - 1

escalier(8, 20)

ht()

Les opérateur accumulants

On termine souvent une boucle en modifiant une valeur pour la prochaine itération.

compteur = 0
while compteur < 10:
    print(compteur)
    compteur = compteur + 1

On peut utiliser les opérateurs accumulants pour simplifier ce genre de modification.

compteur = 0
while compteur < 10:
    print(compteur)
    compteur += 1  # Même chose que compteur = compteur + 1

Chaque opérateur arithmétique a un équivalent accumulant.

Opérateur Opérateur accumulant Exemple Équivalent à
+ += x += 5 x = x + 5
- -= x -= 3 x = x - 3
* *= x *= 2 x = x * 2
/ /= x /= 4 x = x / 4
// //= x //= 3 x = x // 3
% %= x %= 7 x = x % 7
** **= x **= 2 x = x ** 2

Exercice 3

Écrivez un programme qui affiche les puissances de 2 de 1 à 1024 inclusivement.

Solution

On initialise une variable nombre qui commence à 1. À la fin de chaque itération, on utilise l’opérateur accumulant *= pour multiplier nombre par 2.

nombre = 1
while nombre <= 1024:
    print(nombre)
    nombre *= 2

Boucles infinies

Une boucle while peut itérer indéfiniment si la condition est toujours vraie. Par exemple, si on écrit while True:, la boucle ne s’arrêtera jamais. On peut utiliser une boucle infinie pour créer des programmes qui tournent jusqu’à ce qu’on les arrête manuellement.

secondes = 0
while True:
    print("Le programme tourne depuis", secondes, "seconde(s).")
    sleep(1)  # ceci fera une pause de 1 seconde
    secondes += 1

Ce programme utilise l’instruction sleep(1) pour que le programme fasse une pause de une seconde, d’une itération de la boucle à la suivante.

Pour arrêter un programme qui tourne dans une boucle infinie, vous pouvez appuyer sur le bouton (Arrêter) ou utiliser la touche du clavier ESC.

Exercice 4

Écrivez un programme qui utilise la tortue pour dessiner un compteur numérique qui affiche les secondes écoulées depuis le début du programme.

Vous pouvez utiliser write(x) pour afficher le texte ou nombre x avec la tortue. La taille du texte peut être modifiée en donnant un facteur d’agrandissement en deuxième paramètre, similairement à image(nomfacteur). Utilisez un facteur d’agrandissement de 20 pour cet exercice.

Solution

On utilise une boucle infinie pour afficher le nombre de secondes écoulées. À chaque itération, on efface le dessin précédent avec clear().

secondes = 0
while True:
    clear(); ht()
    write(secondes, 20)
    sleep(1)
    secondes += 1

Créer des animations avec sleep

On peut créer des animations en affichant une séquence d’images avec une boucle. Au début de chaque itération, on efface le dessin précédent avec clear() et on dessine la nouvelle image. On utilise la fonction sleep(secondes) pour faire une courte pause entre chaque image.

def dessiner_engrenages(x, angle):
    hop(); fd(x)
    rt(angle); image("gear8", 10); lt(angle)
    hop(); fd(-x)

angle = 0

while True:
    # On efface le dessin précédent
    clear()
    ht()

    # On dessine la nouvelle image
    dessiner_engrenages(-40, angle)
    dessiner_engrenages(40, -angle + 22.5)

    # On fait une courte pause avant de passer à l'image suivante
    sleep(0.03)
    angle += 2.5

Plus le temps de pause donnée à sleep(secondes) est petit, plus l’animation sera rapide. Essayez de modifier cette valeur pour voir l’effet sur la vitesse de l’animation!

Exercice 5

Écrivez un programme qui affiche une animation de la Lune qui orbite autour de la Terre comme celle ci-dessus.

Utilisez un disque bleu de 50 pixels de diamètre pour représenter la Terre et un disque gris de 15 pixels de diamètre pour la Lune. La Lune doit orbiter autour de la Terre à une distance constante de 75 pixels.

Solution

Puisqu’on souhaite dessiner plus d’un corps céleste, on crée une fonction corps qui dessine un corps à un angle et une distance donnés. À chaque itération de la boucle, on efface l’image précédente et on dessine la Terre au centre, puis la Lune à un angle qui augmente à chaque itération.

Pour cette solution, on utilise le fait que rt et lt peuvent prendre un angle supérieur à 360 degrés. Par exemple, rt(450) fait tourner la tortue de 450 degrés vers la droite, ce qui est équivalent à une rotation de 90 degrés. Ça permet d’incrémenter l’angle indéfiniement sans jamais le remettre à zéro.

def corps(angle, distance, taille):
    hop(); lt(angle); fd(distance)
    image("disk", taille/100)
    hop(); bk(distance); rt(angle)

angle = 0

while True:
    clear()
    ht()
    pencolor("blue")
    corps(0, 0, 50)

    pencolor("grey")
    corps(angle, 75, 15)

    angle += 1
    sleep(0.01)

Exercice 6

Écrivez un programme qui affiche une animation d’un carré de 100 pixels de côté et dont la couleur passe graduellement du noir au jaune, puis du jaune au noir, et ainsi de suite, comme ci-dessus.

Indice

Il est utile de se rappeler que la couleur jaune est obtenue avec pencolor(1, 1, 0). Si on fait pencolor(0.5, 0.5, 0) on obtiendra un jaune plus foncé et pencolor(0.25, 0.25, 0) sera un jaune presque noir.

On peut utiliser une variable qui oscille entre 0 et 1 pour représenter la proportion de jaune dans la couleur, c’est-à-dire la valeur du premier et du deuxième paramètre de pencolor.

Solution

On garde une variable proportion_de_jaune qui commence à 0 (noir) et qui augmentera jusqu’à 1 (jaune). On utilise une variable direction pour indiquer si proportion_de_jaune doit augmenter ou diminuer. Quand la proportion de jaune dépasse l’intervalle de 0 à 1, on inverse la direction.

Pour cette solution, on utilise une direction de 0,01 et un délai de 0,01 secondes entre chaque image, mais vous pouvez essayer d’autres valeurs pour voir l’effet sur l’animation!

proportion_de_jaune = 0.0
direction = 0.01

while True:
    clear()
    ht()
    pencolor(proportion_de_jaune, proportion_de_jaune, 0.0)
    image("square")

    proportion_de_jaune += direction

    if proportion_de_jaune >= 1.0 or proportion_de_jaune <= 0.0:
        direction = -direction
        proportion_de_jaune += 2 * direction

    sleep(0.01)

Sortir d’une boucle avec break

Si on veut sortir d’une boucle while immédiatement, sans attendre que la condition devienne fausse, on peut utiliser le mot-clé break. Quand l’instruction break est exécutée, la boucle se termine et l’exécution du programme continue après la boucle.

nombre = 1
while True:
    if nombre == 5:
        print("On a atteint le nombre 5, on sort de la boucle.")
        break
    print("Nombre:", nombre)
    nombre += 1

print("La boucle est terminée.")

Exercice 7

Écrivez un programme qui demande à l’utilisateur d’entrer son âge. Si l’âge entré est inférieur à 0 ou supérieur à 120, le programme doit afficher "Âge invalide..." et redemander l’âge jusqu’à ce qu’un âge valide soit entré.

Utilisez la fonction alert(texte) pour afficher le message d’erreur au lieu de print(texte), ce qui affichera une boîte de dialogue avec le message.

Quand un âge valide est entré, le programme doit afficher "Vous avez <âge> ans.", où <âge> est l’âge entré par l’utilisateur.

Solution

On utilise une boucle infinie pour redemander l’âge jusqu’à ce qu’un âge valide soit entré. À chaque itération, on vérifie si l’âge est valide. Si l’âge est invalide, on affiche le message et on laisse la boucle continuer. Si l’âge est valide, on utilise break pour sortir de la boucle.

while True:
    age = int(input("Entrez votre âge : "))
    if age < 0 or age > 120:
        alert("Âge invalide...")
    else:
        break

print("Vous avez", age, "ans.")

Passer à l’itération suivante avec continue

Si on veut sauter le reste du code dans une itération de la boucle et passer directement à l’itération suivante, on peut utiliser le mot-clé continue.

nombre = 0
while nombre < 10:
    nombre += 1
    if nombre % 2 == 0:
        continue # On saute les nombres pairs
    print("Nombre impair:", nombre)

print("La boucle est terminée.")

Exercice 8

Écrivez un programme qui affiche les nombres de 1 à 100, mais saute tous les nombres multiples de 2, 3, ou 5

Solution

On utilise une boucle while pour compter de 1 à 100. À chaque itération, on vérifie si le nombre est un multiple de 2, 3, ou 5 et on saute cette itération avec continue si c’est le cas.

nombre = 0
while nombre < 100:
    nombre += 1
    if nombre % 2 == 0 or nombre % 3 == 0 or nombre % 5 == 0:
        continue
    print( nombre)

Contrôler le comportement de la boucle

Le mot-clé break nous permet de contrôler le moment où est évaluée la condition d'arrêt d'une boucle. Selon l'endroit où on place la condition d'arrêt, la boucle se comporte différemment. Considérons trois façons de dessiner une spirale carrée avec la tortue.

Condition dans le while: La condition est vérifiée avant chaque itération. Si elle est fausse dès le départ, le corps de la boucle ne s'exécute jamais.

taille = 10
while taille <= 50:
    fd(taille)
    rt(90)
    taille += 5
ht()

Condition au début du corps (break au début): Équivalent au cas précédent, mais en utilisant while True avec un break. La condition est vérifiée avant le reste du corps.

taille = 10
while True:
    if taille > 50:
        break
    fd(taille)
    rt(90)
    taille += 5
ht()

Condition à la fin du corps (break à la fin): Le corps s'exécute au moins une fois avant que la condition soit vérifiée. C'est l'équivalent d'une boucle «faire ... tant que» (do-while) qu'on retrouve dans d'autres langages.

taille = 10
while True:
    fd(taille)
    rt(90)
    taille += 5
    if taille > 50:
        break
ht()

Les deux premiers exemples sont équivalents: si taille commençait à 60, la tortue ne dessinerait rien. Le troisième exemple dessinerait toujours au moins un segment, puisque la condition n'est testée qu'après le dessin. Essayez-le!

Résumé

Boucle while.

Instruction Description Exemple
while condition: Répèter tant que la condition est vraie
while n < 10:
    n = n + 5
while True: Répéter indéfiniment
while True:
    print("∞")
break Sortir d’une boucle break
continue Passer à l’itération suivante continue

Opérateurs accumulants.

Opérateur Opérateur accumulant Exemple Équivalent à
+ += x += 5 x = x + 5
- -= x -= 3 x = x - 3
* *= x *= 2 x = x * 2
/ /= x /= 4 x = x / 4
// //= x //= 3 x = x // 3
% %= x %= 7 x = x % 7
** **= x **= 2 x = x ** 2

Attendre pour faire une animation.

Instruction Description Exemple
sleep(x) Mettre en pause pendant x secondes sleep(0.1)

Afficher du texte.

Instruction Description Exemple
alert(texte) Afficher le texte dans une boîte de dialogue alert("Bonjour")
write(x) Dessiner le texte ou nombre x à la position et orientation de la tortue write(123)
write(xf) Dessiner x agrandi d’un facteur f write("Bonjour"1.5)
dessinera le texte agrandi de 50%

Exercice 9

Écrivez un programme qui affiche toutes les puissances de 3 de 1 à 1000. C’est à dire 1, 3, 9, 27, ...

Solution

On initialise une variable nombre qui commence à 1.

Après avoir multiplié nombre par 3, la boucle vérifie si nombre est toujours inférieur ou égal à 1000 et démarre une nouvelle itération si c’est le cas.

nombre = 1
while nombre <= 1000:
    print(nombre)
    nombre *= 3

Exercice 10

Écrivez un programme qui dessine un escalier plein avec la tortue, comme ci-dessus.

Dans cet exemple, l’escalier a 8 marches de 20 pixels de hauteur chacune, mais il doit être facile de changer le nombre de marches et la taille des marches.

Solution

Puisqu’un escalier peut être décomposé en une série de rectangles pleins, on crée une fonction rectangle. On peut ensuite écrire une fonction escalier qui utilise une boucle while pour dessiner des rectangles de plus en plus courts pour former un escalier plein.

def rectangle(largeur, hauteur):
    pensize(hauteur)
    fd(largeur)
    bk(largeur)

def escalier(n, taille_marche):

    demi_taille = taille_marche * n / 2
    hop(); bk(demi_taille, demi_taille - taille_marche / 2)

    compteur = 0
    while compteur < n:
        largeur = taille_marche * (n - compteur)
        rectangle(largeur, taille_marche)
        hop(); fd(taille_marche, taille_marche)
        compteur += 1

escalier(8, 20)

ht()

Exercice 11

Écrivez un programme qui dessine une spirale carrée composée de segments de plus en plus longs comme ci-dessus.

Le premier segment au centre de la spirale a une longueur de 5 pixels. Chaque segment suivant est plus long de 5 pixels que le précédent.

On arrête le dessin de la spirale lorsque la longueur du segment dépasse 200 pixels.

Solution

longueur_maximale = 200
longueur_segment = 5

while longueur_segment <= longueur_maximale:
    fd(longueur_segment)
    rt(90)
    longueur_segment += 5

ht()

Exercice 12

Une suite de Syracuse est une séquence de nombres entiers définie de la façon suivante :

  • On commence avec un nombre entier positif n .
  • Si n est pair, le nombre suivant dans la suite est n/2 .
  • Si n est impair, le nombre suivant dans la suite est 3n+1 .
  • La suite se termine lorsque le nombre 1 est atteint.

Par exemple, la suite de Syracuse de 10 est 10, 5, 16, 8, 4, 2, 1. Cette suite a une longueur de 7 termes.

Quel est la longueur de la suite de Syracuse de 27?

112

La conjecture de Syracuse, aussi appelé conjecture de Collatz, affirme que la suite de Syracuse se termine toujours quel que soit le nombre entier positif de départ. Par contre, personne ne sait si cette conjecture est vraie ou fausse!

Solution

On utilise une boucle while qui continue tant que le nombre courant n n’est pas égal à 1. À chaque itération, on applique la règle de Syracuse pour obtenir le nombre suivant.

On utilise un compteur pour le nombres d’itérations effectuées, ce qui correspond à la longueur de la suite. On initialise le compteur à 1, car le nombre de départ compte comme terme de la suite.

n = 27
compteur = 1

while n != 1:
    if n % 2 == 0:
        n = n // 2
    else:
        n = 3 * n + 1
    compteur += 1

print("La longueur de la suite est :", compteur)

Exercice 13

Un nombre entier est un nombre premier s’il est supérieur à 1 et s’il n’a pas d’autres diviseurs que 1 et lui-même. Par exemple, le nombre 5 est premier parce qu’il n’est pas divisible par 2, 3 ou 4. Le nombre 9 n’est pas premier parce qu’il est divisible par 3.

On peut vérifier si un nombre n est premier en essayant de le diviser par tous les entiers de 2 à n-1.

Écrivez un programme qui demande à l’utilisateur d’entrer un nombre entier positif n et qui affiche "<n> est un nombre premier." si n est un nombre premier, ou "<n> n'est pas premier." sinon.

Indice

On peut vérifier si une variable n contient un nombre qui est divisible par un autre nombre d en utilisant l’opérateur modulo : n % d == 0. On peut écrire une fonction est_premier(n) qui utilise une boucle while pour tester tous les diviseurs possibles de 2 à n-1 et qui retourne un booléen (True ou False) indiquant si n est premier ou non.

La fonction est_premier peut ensuite être utilisée dans un if pour faire une exécution conditionnelle avec : if est_premier(n):.

Solution

On écrit une fonction est_premier(n) qui vérifie si n est premier. Cette fonction va retourner un booléen (True ou False).

La fonction est_premier(n) utilise une boucle while pour tester tous les diviseurs possibles de 2 à n-1. Dès qu’un diviseur est trouvé, on exécute return False, ce qui a pour effet de sortir immédiatement de la fonction. Si la boucle se termine sans trouver de diviseur, on exécute return True pour indiquer que n est premier.

def est_premier(n):
    diviseur = 2
    while diviseur < n:
        if n % diviseur == 0:
            return False
        diviseur += 1
    return True

n = int(input("Entrez un nombre entier positif : "))

if est_premier(n):
    print(n, "est un nombre premier.")
else:
    print(n, "n'est pas premier.")

Exercice 14

Le nombre 46523 est un nombre premier. Utilisez votre solution de l’exercice précédent pour trouver la somme des dix prochains nombres premiers après 46523.

Quelle est la somme des dix prochains nombres premiers après 46523?

465920

Solution

On utilise la fonction est_premier(n) de l’exercice précédent pour vérifier si un nombre est premier. On commence par tester le nombre 46524 et on continue à tester les nombres suivants jusqu’à ce qu’on trouve dix nombres premiers.

def est_premier(n):
    diviseur = 2
    while diviseur < n:
        if n % diviseur == 0:
            return False
        diviseur += 1
    return True

nombre = 46524
compteur_premiers = 0
somme_premiers = 0

while compteur_premiers < 10:
    if est_premier(nombre):
        somme_premiers += nombre
        compteur_premiers += 1
    nombre += 1

print(somme_premiers)

Exercice 15

123456789101112

Écrivez un programme qui dessine une horloge à aiguilles avec la tortue comme celle ci-dessus. Cette horloge a une aiguille des secondes et des minutes, mais pas une aiguille des heures.

L’aiguille des secondes a une longueur de 70 pixels, l’aiguille des minutes une longueur de 60 pixels et une épaisseur de 2 pixels. L’horloge a un rayon de 100 pixels. Utilisez write(n) pour écrire les chiffres du cadran à la position de la tortue.

Votre programme doit définir une fonction horloge(minutes, secondes) qui démarre l’animation au temps donné. Par exemple horloge(10, 45) démarre l’horloge à 10 minutes et 45 secondes comme dans l’animation ci-dessus.

Indice

Pour tester un programme qui utilise de longues pauses comme sleep(1), on peut remplacer temporairement le temps de pause par une valeur plus petite, par exemple sleep(0.1). Ainsi, on peut vérifier que le programme fonctionne correctement sans attendre trop longtemps.

Solution

def aiguille(longueur, angle, epaisseur):
    pensize(epaisseur)
    rt(angle)
    fd(longueur)
    bk(longueur)
    lt(angle)

def cadran(rayon):
    image("disk", 2 * rayon / 100)
    pencolor("white")
    image("disk", (2 * rayon - 4) / 100)
    pencolor("black")

    for h in 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12:
        rt(30)
        hop(); fd(rayon - 20)
        lt((h - 3) * 30); write(h); rt((h - 3) * 30)
        hop(); bk(rayon - 20)

def horloge(minutes, secondes):
    secondes = minutes * 60 + secondes

    while True:
        clear(); ht(); lt(90)

        # Dessin du cadran
        cadran(100)

        # Calcul de l'angle des aiguilles
        angle_minutes = secondes / 60 * 6
        angle_secondes = (secondes % 60) * 6

        # Dessin des aiguilles
        aiguille(60, angle_minutes, 2)
        aiguille(70, angle_secondes, 1)

        # Incrémentation du temps
        secondes += 1
        sleep(1)

horloge(10, 45)

Exercice 16

Écrivez un programme qui dessine un moulin à vent avec la tortue, comme ci-dessus.

Votre programme doit permettre de facilement changer la forme du moulin à vent, c’est-à-dire sa hauteur, son nombre d’ailes, l’angle de rotation des ailes, et sa couleur. Écrivez donc une fonction qui prend ces quatre paramètres. Le moulin ci-dessus a une hauteur de 120 pixels, 4 ailes ayant une rotation de 30 degrés et la couleur utilisée est pencolor(0, 0.8, 0.5).

Solution

La meilleure manière de permettre de facilement changer la forme du moulin à vent est d’écrire une fonction moulin qui prend comme arguments la hauteur, le nombre d’ailes, l’angle de rotation des ailes, et les proportions de rouge, vert et bleu de la couleur.

def aile(longueur):
    # dessiner une aile du moulin à vent
    fd(longueur)
    fd(0, -longueur / 2)
    bk(longueur, -longueur / 2)

def ailes(longueur, nb_ailes):
    # dessiner les ailes du moulin à vent
    angle = 360 / nb_ailes
    while nb_ailes > 0:
        lt(angle)
        aile(longueur)
        nb_ailes -= 1

def moulin(hauteur, nb_ailes, rotation, r, g, b):
    # dessiner un moulin à vent avec une certaine rotation de ses ailes
    pensize(50)
    pencolor(r, g, b)
    fd(hauteur)
    hop(); bk(hauteur*0.1)
    pensize(2)
    pencolor("black")
    rt(rotation)
    ailes(hauteur*2/3, nb_ailes)
    rt(-rotation)
    hop(); bk(hauteur*0.9)

hop()
lt(90)
bk(100)
moulin(120, 4, 30, 0.0, 0.8, 0.5)
ht()

Exercice 17

Utilisez votre solution à l’exercice précédent pour dessiner cette animation de deux moulins à vent, comme ci-dessus.

Vous pouvez user de votre créativité pour choisir les dimensions et les couleurs des moulins. Remarquez toutefois que les ailes du moulin de droite tournent deux fois plus vite que celles du moulin de gauche. Cette différence doit se retrouver dans votre animation

Solution

def aile(longueur):
    # dessiner une aile du moulin à vent
    fd(longueur)
    fd(0, -longueur / 2)
    bk(longueur, -longueur / 2)

def ailes(longueur, nb_ailes):
    # dessiner les ailes du moulin à vent
    angle = 360 / nb_ailes
    while nb_ailes > 0:
        lt(angle)
        aile(longueur)
        nb_ailes -= 1

def moulin(hauteur, nb_ailes, rotation, r, g, b):
    # dessiner un moulin à vent avec une certaine rotation de ses ailes
    pensize(50)
    pencolor(r, g, b)
    fd(hauteur)
    hop(); bk(hauteur*0.1)
    pensize(2)
    pencolor("black")
    rt(rotation)
    ailes(hauteur*2/3, nb_ailes)
    rt(-rotation)
    hop(); bk(hauteur*0.9)

angle = 0
while True:
    clear(); ht()
    hop()
    lt(90)

    # moulin de droite
    bk(100, 100)
    moulin(90, 3, angle, 0.7, 0.5, 0.5)

    # moulin de gauche
    hop()
    fd(0, 200)
    moulin(120, 6, angle / 2, 0.5, 0.5, 0.9)

    angle += 1
    sleep(0.01)

Exercice 18

Écrivez un jeu de devinette où l’utilisateur doit jouer contre l’ordinateur. L’ordinateur choisit un nombre aléatoire entre 1 et 100, et demande à l’utilisateur de deviner ce nombre en appelant input.

Après chaque tentative, l’ordinateur doit indiquer si le nombre deviné est trop petit ou trop grand à l’aide d’un message affiché avec alert(message).

Lorsque le nombre est trouvé, l’ordinateur doit afficher à la console un message de félicitations et le nombre d’essais effectués.

Solution

Puisque le jeu peut continuer indéfiniment si l’utilisateur n’est pas très malin, on doit utiliser une boucle infinie avec while True:.

À chaque itération de la boucle, on demande un nombre, on incrémente le compteur d’essais et on affiche le message selon si le nombre est trop petit, trop grand, ou correct.

nombre_a_deviner = randint(1, 100)
essais = 0

while True:
    entree = int(input("Devinez le nombre (entre 1 et 100) : "))
    essais += 1

    if entree < nombre_a_deviner:
        alert("Trop petit!")
    elif entree > nombre_a_deviner:
        alert("Trop grand!")
    else:
        print("Félicitations! Vous avez deviné en", essais, "essais.")
        break

Il existe une stratégie qui permet de deviner n’importe quel nombre entre 1 et 100 en au plus 7 essais. Pouvez-vous trouver cette stratégie ?

Exercice 19

Un ordinateur représente une couleur par ses proportions de rouge, vert et bleu, comme le fait pencolor(r, g, b). En réalité la lumière est une onde dont la couleur est déterminée par sa longueur d’onde. Par exemple une onde de 650 nanomètres est perçue comme rouge.

On peut convertir une longeur d’onde λ (en nanomètres) de lumière visible en couleur rgb (rouge-vert-bleu) approximative avec l’équation suivante :

r= borner(|λ470|120)g= borner(2|λ540|50)b= borner(4|λ430|20)

borner(x) est une fonction qui retourne 0 si x < 0, 1 si x > 1, et x sinon. Puisque cette fonction n’est pas prédéfinie vous devez l’écrire.

Écrivez une fonction appelée pencolor_onde qui prend une longueur d’onde en nanomètres et change la couleur du trait de la tortue avec la couleur correspondante. Si la longueur d’onde est en dehors de l’intervalle de la lumière visible (entre 380 et 780 nanomètres), utilisez la couleur noire.

Utilisez ensuite cette fonction pour dessiner une bande de couleurs comme ci-dessus représentant le spectre visible de la lumière, allant de 350 à 810 nanomètres (on utilise un spectre un peu plus large pour bien voir la transition entre lumière visible et invisible à l’oeil). Dessinez une bande centrée de 400 pixels de large et 50 pixels de haut, où chaque pixel horizontal correspond à une longueur d’onde différente.

Solution

On peut d’abord écrire la fonction borner qui borne une valeur entre 0 et 1 qui sera réutilisée dans la fonction pencolor_onde.

La fonction pencolor_onde commence par un clause de garde qui utilise la couleur noire si la longueur d’onde est en dehors de l’intervalle de la lumière visible.

On utilise ensuite les formules données pour calculer les valeurs de r, g et b, puis on appelle pencolor(r, g, b).

Une fois la fonction définie, on peut dessiner la bande de couleur en utilisant une boucle while qui décrémente la longueur d’onde à chaque itération. À chaque itération, on avance de 1 pixel et on doit donc décrémenter la longueur d’onde de (810 - 350) / 400 nm.

def borner(x):
    if x < 0:
        return 0
    elif x > 1:
        return 1
    else:
        return x

def pencolor_onde(nm):
    if nm < 380 or nm > 780:
        pencolor(0, 0, 0)
    else:
        r = borner(abs(nm - 470) / 120)
        g = borner(2 - abs(nm - 540) / 50)
        b = borner(4 - abs(nm - 430) / 20)
        pencolor(r, g, b)

# Paramètres de la bande de couleur
largeur_bande = 400
longueur_onde_min = 350
longueur_onde_max = 810

# Dessiner la bande de couleur
clear()
pensize(50)
hop(); bk(largeur_bande / 2)

# Boucle pour dessiner la bande de 810 à 350 nm
longueur_onde = longueur_onde_max
while longueur_onde >= longueur_onde_min:
    pencolor_onde(longueur_onde)
    fd(1)
    longueur_onde -= (longueur_onde_max - longueur_onde_min) / largeur_bande

ht()

Exercice 20

On peut utiliser une boucle infinie pour programmer une simulation physique. Par exemple, on peut simuler et animer une balle qui rebondit sur le sol en utilisant les lois de la physique, comme ci-dessus.

La balle est initialement à une distance de 80 cm du sol et a une vitesse initiale de 0 m/s. On considère qu’un pixel équivaut à 1 cm et donc que l’accélération due à la gravité est de g = -981 pixels/s² (soit -9.81 m/s²).

On peut écrire une simulation en séparant le temps en petits intervalles de 0,01 secondes. À chaque intervalle de temps, on met à jour la position et la vitesse de la balle en utilisant les formules suivantes :

v=v0+gdty=y0+vdt

v0 et y0 sont la vitesse et la position à l’intervalle précédent, v et y sont la vitesse et la position pour ce nouvel intervalle, et dt est l’intervalle de temps (0,01 secondes).

Lorsque la balle touche le sol (c’est-à-dire lorsque y <= 0), elle rebondit. Sa vitesse, qui était négative (vers le bas) juste avant le rebond, devient positive. Par contre, la balle perd de l’énergie à chaque rebond. On peut modéliser cette perte d’énergie en multipliant la vitesse par un nombre entre 0 et 1 appelé le coefficient de restitution. Par exemple, si le coefficient de restitution est 0,8, la vitesse après le rebond sera calculée avec v = -v * 0.8 (la balle ne conserve que 80% de sa vitesse avant le rebond).

À chaque itération de la boucle infinie, on peut dessiner le sol et la balle à sa position actuelle pour visualiser la simulation.

Programmez cette simulation en utilisant une boucle infinie. Il doit être facile de modifier la position initiale, le coefficient de restitution, ou l’intervalle de temps pour observer leur effet sur la simulation.

Solution

y = 80  # Position initiale
v = 0    # Vitesse initiale
g = -981  # Accélération due à la gravité (pixels/s²)
dt = 0.01   # Intervalle de temps (s)
coeff_rebond = 0.8  # Coefficient de restitution

while True:
    # Mettre à jour la position et la vitesse
    v += g * dt
    y += v * dt

    # Vérifier si la balle touche le sol
    if y <= 0:
        y = -y
        v = -v * coeff_rebond

    clear(); ht()

    # Dessiner le sol
    fd(100); bk(200); fd(100)

    # Dessiner la balle
    pencolor("red")
    hop(); fd(0, y + 5) # on ajoute 5 pixels, car la balle a un rayon de 5 pixels
    image("disk", 0.1)

    # Attendre un court instant
    sleep(dt)

Les boucles for

Dans les chapitres précédents, on a vu une forme simple de boucle for.

for i in 0, 1, 2, 3, 4, 5:
    print(i)

Cette boucle permet d'itérer sur une séquence de valeurs, mais elle n'est pas pratique si la séquence est très longue. Par exemple, si on veut afficher les nombres de 1 à 100, il faudrait tous les écrire dans la boucle for.

On pourrait utiliser une boucle while, mais il y a une manière plus simple.

for i in range(101):
    print(i)

La fonction range

La fonction range retourne une séquence de nombres sur lesquels on peut itérer avec une boucle for. Il y a trois façons de l'utiliser range.

Fonction Description Exemple
range(n) Séquence de nombres de 0 à n-1 range(3)0, 1, 2
range(ab) Séquence de nombres de a à b-1 range(25)2, 3, 4
range(abc) Séquence de nombres de a à b-1 par saut de c range(282)2, 4, 6

Par exemple, pour calculer la somme de tous les nombres paires de 1 à 100 inclusivement, on peut écrire:

somme = 0

for nombre in range(2, 101, 2):
    somme = somme + nombre

print("La somme des nombres pairs de 1 à 100 est:", somme)

À chaque itération, la variable nombre prend la prochaine valeur de la séquence.

Quand on crée une séquence, que ce soit avec range(fin), range(debut, fin) ou range(debut, fin, pas), la valeur fin est toujours exclue de la séquence.

Exercice 1

Écrivez une boucle for qui imprime tous les nombres de 0 à 10 inclusivement.

Solution

La séquence range(11) commence à 0 et exclut 11, donc elle inclut les nombres de 0 à 10.

for n in range(11):
    print(n)

Exercice 2

Écrivez une boucle for qui imprime tous les nombres de 5 à 15 inclusivement.

Solution

Pour commencer à 5, on utilise range avec deux arguments. La séquence range(5, 16) commence à 5 et exclut 16, donc elle va de de 5 à 15.

for n in range(5, 16):
    print(n)

Exercice 3

Écrivez une boucle for qui imprime tous les nombres impairs de 1 à 19 inclusivement.

Solution

Pour avoir un bond de 2 entre les éléments de la séquence pour n'avoir que les nombres impairs, on utilise range avec trois arguments. La séquence range(1, 20, 2) commence à 1 et exclut 20, donc elle inclut les nombres impairs de 1 à 19.

for n in range(1, 20, 2):
    print(n)

Boucle for décroissante

On peut utiliser la fonction range avec un pas négatif pour créer une boucle for décroissante. Par exemple, pour afficher les nombres de 10 à 1, on peut écrire:

for valeur in range(10, 0, -1):
    print(valeur)

Comme pour les boucles croissantes avec range, la valeur de fin est exclue de la séquence. Donc, dans l'exemple ci-dessus, la boucle s'arrête à 1 et n'inclut pas 0.

Exercice 4

Écrivez un programme qui affiche un compte à rebours de 10 secondes avec la tortues. Lorsque le compte à rebours est terminé, le programme doit afficher une animation de fusée qui décolle du centre de la fenêtre vers le haut.

Utilisez write(n, 10) pour écrire le nombre n en grand dans le fenêtre de la tortue pour le compte à rebours.

Utilisez image("rocket") pour afficher une image de fusée. Laissez aller votre imagination pour l'animation de décollage!

Vous pouvez modéliser l'accélération de la fusée à l'aide d'une fontion quadratique.

Solution

# Compte à rebours
for secondes in range(10, 0, -1):
    clear(); ht()
    write(secondes, 10)
    sleep(1)


# Animation de décollage
for x in range(500):
    clear(); ht()
    hop(); fd(0, -50)
    
    # On utilise une fonction quadratique pour l'effet d'accélération
    hop(); fd(0, x ** 2 / 500)
    image("rocket")    
    sleep(0.01)

Sortir d'une boucle for avec break

De la même manière qu'avec une boucle while, on peut utiliser l'instruction break pour arrêter immédiatement une boucle for avant qu'elle n'ait terminé toutes ses itérations.

for valeur in range(100):
    if valeur == 10:
        print("On arrête la boucle à valeur =", valeur)
        break
    print(valeur)

Exercice 5

Écrivez un boucle for qui itère sur les nombres n de 1 à 1000 et affiche la première valeur de n telle que 1 / n est inférieure à 0.067.

Solution

L'instruction break peut servir à recherche une valeur dans un intervale. Lorsque la valeur est trouvée, on peut arrêter la recherche en appelant break.

for n in range(1, 1001):
    if 1 / n < 0.067:
        print("La première valeur de n telle que 1 / n < 0.067 est:", n)
        break

Passer à l'itération suivante avec continue

De la même manière qu'avoir une boucle while, on peut sauter le reste du code dans une itération de la boucle et passer directement à l'itération suivante avec l'instruction continue.

for valeur in range(10):
    if valeur % 2 == 0:
        continue # on saute les nombres pairs
    print(valeur)

Exercice 6

Écrivez une boucle for qui affiche tous les nombres de 1 à 50 à l'exception de ceux qui sont des multiples de 3, 7 ou 11.

Solution

Il y a plusieurs façon de résoudre cet exercice. Une approche est d'utiliser continue pour sauter les itérations correspondant aux multiples de 3, 7 ou 11.

for n in range(1, 51):
    if n % 3 == 0 or n % 7 == 0 or n % 11 == 0:
        continue

    print(n)

Les boucles imbriquées

Certaines tâches s'expriment naturellement en tant qu'une combinaison de processus répétitifs. Prenons par exemple un camelot livrant les journaux dans un quartier. Sa méthode de travail pourrait s'exprimer de la manière suivante:

nombre_rues = 3
nombre_maisons_par_rue = 5

# Pour chaque rue dans le quartier
for i in range(nombre_rues):
    # Pour chaque maison dans la rue
    for j in range(nombre_maisons_par_rue):
        print("Déposer un journal (", i, ",", j, ")")

Les boucles ci-haut sont dites imbriquées.

Exercice 7

Écrivez la fonction dessiner_carre(couleur, longueur) qui dessine un carré plein aux côtés de longueur longueur pixels avec la tortue, en utilisant la couleur couleur. Vous devez uniquement effectuer des mouvements de 1 pixel à la fois lors du tracé des lignes. Une fois le carré dessiné, votre tortue doit revenir à son point de départ.

Par exemple, l'appel dessiner_carre("red", 50) dessinera un carré rouge plein de 50 pixels de côté, et l'appel dessiner_carre("blue", 100) dessinera un carré bleu plein de 100 pixels de côté.

Solution

On utilise deux boucles for imbriquées. La boucle extérieure itère sur les lignes du carré et la boucle intérieure dessine chaque pixel de la ligne en avançant de 1 pixel à la fois. Après chaque ligne, on fait demi-tour et on retrace la ligne pour revenir au début, puis on monte d'un pixel.

def dessiner_carre(couleur, longueur):
    # On établit d'abord les paramètres du dessin
    pencolor(couleur)
    pensize(1)

    # Puis on trace le carré ligne par ligne
    for ligne in range(longueur):
        # Et colonne par colonne
        for colonne in range(longueur):
            # En effectuant des mouvements de 1px
            fd(1)

        # Puis, on vient déplacer la tortue sur la prochaine ligne à tracer
        hop(); bk(longueur)
        lt(90); hop(); fd(1); rt(90)

    # Et enfin on retourne au point de départ
    hop(); rt(90); hop(); fd(longueur); hop(); lt(90)

dessiner_carre("red", 50)

Exercice 8

En vous inspirant de dessiner_carre, dessinez un carré de 100×100 pixels avec un dégradé de couleur allant du rouge au bleu, à la fois verticalement (de bas en haut) et horizontalement (de gauche à droite). Le coin en bas à gauche doit être rouge, le coin en haut à droite doit être bleu, et chaque pixel intermédiaire doit progresser graduellement entre les deux selon sa position en x et en y . Rappel: pencolor(r, g, b) accepte des valeurs réelles entre 0 et 1.

Pour créer un dégradé dans les deux directions, on calcule deux proportions: une pour la ligne (t_ligne) et une pour la colonne (t_colonne), chacune variant de 0.0 à 1.0. On les combine en faisant leur moyenne: t = (t_ligne + t_colonne)/2

Pour la ligne et la colonne parmi n lignes et colonnes:

t_ligne = ligne / (n - 1)
t_colonne = colonne / (n - 1)
t = (t_ligne + t_colonne) / 2

Ensuite, on interpole chaque composante de couleur:

valeur = début + t * (fin - début)

Par exemple, la composante rouge vaut 1.0 au début et 0.0 à la fin:

r = 1.0 + t * (0.0 - 1.0)

Quand t = 0 (coin bas-gauche), on obtient du rouge pur. Quand t = 1 (coin haut-droit), on obtient du bleu pur. Les pixels intermédiaires se calculent selon les formules ci-haut.

Solution

On dessine le carré pixel par pixel. Pour chaque pixel, on calcule une proportion combinée à partir de sa position horizontale et verticale, puis on interpole entre les composantes de la couleur de départ et celles de la couleur d'arrivée. Le programme suivant est court et précis:

taille = 100
pensize(1)

# On recentre le carré
hop(); bk(50, 50)

# Couleurs de départ et d'arrivée (essayez d'autres valeurs!)
r1 = 1; g1 = 0; b1 = 0  # rouge
r2 = 0; g2 = 0; b2 = 1  # bleu

for ligne in range(taille):
    # Proportion verticale: 0.0 en bas, 1.0 en haut
    t_ligne = ligne / (taille - 1)

    # On trace une ligne horizontale pixel par pixel
    for colonne in range(taille):
        # Proportion horizontale: 0.0 à gauche, 1.0 à droite
        t_colonne = colonne / (taille - 1)

        # On combine les deux proportions
        t = (t_ligne + t_colonne) / 2

        # Interpolation de chaque composante rgb
        r = r1 + t * (r2 - r1)
        g = g1 + t * (g2 - g1)
        b = b1 + t * (b2 - b1)

        # Puis on change la couleur du trait
        pencolor(r, g, b)
        fd(1)

    # Puis on revient au début et on monte d'une ligne,
    # comme dans l'exercice précédent
    hop(); bk(taille)
    lt(90); fd(1); rt(90)

ht()

For vs While

La boucle for et la boucle while permettent toutes deux de répéter des instructions, mais elles sont adaptées à des situations différentes.

La boucle for est idéale quand on connaît à l'avance le nombre d'itérations ou qu'on itère sur une séquence:

for i in range(5):
    fd(20)
    rt(72)
ht()

La boucle while est idéale quand on ne connaît pas à l'avance le nombre d'itérations et qu'on attend qu'une condition devienne fausse:

n = 1
while n < 1000:
    n = n * 2
print(n)

En général, si vous pouvez écrire for i in range(...), préférez for. Utilisez while lorsque la condition d'arrêt dépend de ce qui se passe dans la boucle. Retournez au chapitre précédent, section "Contrôle", pour voir des exemples de cas.

Résumé

Créer une séquence de nombres.

Fonction Description Exemple
range(n) Séquence de nombres de 0 à n-1 range(3)0, 1, 2
range(ab) Séquence de nombres de a à b-1 range(25)2, 3, 4
range(abc) Séquence de nombres de a à b-1 par saut de c range(282)2, 4, 6

Boucle for.

Instruction Description Exemple
for var in ...: Itérer sur chaque élément d'une séquence
for i in range(5):
    print(i)
break Sortir immédiatement de la boucle break
continue Passer à l'itération suivante de la boucle continue

Exercice 9

Écrivez une fonction somme_multiples(k, n) qui calcule la somme de tous les multiples de k inférieurs à n. Par exemple, somme_multiples(3, 10) doit retourner 3 + 6 + 9 = 18.

Utilisez cette fonction pour afficher la somme des multiples de 12 inférieurs à 10000.

Solution

Pour itérer sur les multiples k,2k,3k, inférieurs à n, on peut utiliser range(k, n, k) qui commence à k et ajoute k à chaque itération jusqu'à ce que la valeur atteigne ou dépasse n.

On peut accumuler la somme dans une variable somme initialisée à 0.

def somme_multiples(k, n):
    somme = 0
    for nombre in range(k, n, k):
        somme = somme + nombre
    return somme

print(somme_multiples(12, 10000))

Exercice 10

L'opération mathématique factoriel de n, noté n! , est le produit des entiers de 1 à n. Par exemple, 5!=1×2×3×4×5=120 . De plus, on définit que 0!=1 .

Écrivez une fonction factoriel(n) qui calcule le factoriel de n. Utilisez votre fonction pour écrire un programme qui affiche les factoriels de 0 à 10.

Solution

On utilise une boucle for pour multiplier les entiers de 1 à n. Pour que n soit inclus dans la boucle, on utilise range(1, n + 1).

Remarquez que si n vaut 0, la séquence range(1, 1) est vide et le résultat retourné est 1, comme demandé.

def factoriel(n):
    resultat = 1
    for x in range(1, n + 1):
        resultat = resultat * x
    return resultat

for n in range(11):
    print("factoriel de", n, "est", factoriel(n))

Exercice 11

Écrivez un programme qui affiche le drapeau de la Catalogne avec la tortue, comme celui-ci-dessous.

Le rapport hauteur/largeur du drapeau est de 2:3. Les bandes horizontales sont de même hauteur. Les couleurs utilisées sont "#f01" (rouge) et "#fe0" (jaune).

Tâchez à décomposer le problème en plusieurs fonctions. Par exemple, remarquez que le drapeau de la Catalogne est composé de bandes. Cela vous donne un indice sur les fonctions à écrire!

Solution

On décompose le problème en deux fonctions: bande qui dessine une seule bande horizontale, et drapeau_catalogne qui assemble les 9 bandes. Cette décomposition rend le code plus lisible et chaque fonction a une responsabilité claire.

Les bandes paires (0, 2, 4, 6, 8) sont jaunes et les bandes impaires (1, 3, 5, 7) sont rouges. On peut utiliser l'opérateur modulo % pour déterminer si le numéro de la bande est pair ou impair.

def bande(couleur, largeur, hauteur):
    pencolor(couleur)
    pensize(largeur)
    fd(hauteur)

def drapeau_catalogne(largeur):
    hauteur = largeur * 2 / 3
    hauteur_bande = hauteur / 9

    rt(90)
    hop(); bk(hauteur / 2)

    for i in range(9):
        if i % 2 == 0:
            bande("#fe0", largeur, hauteur_bande)
        else:
            bande("#f01", largeur, hauteur_bande)

    hop(); bk(hauteur / 2)
    lt(90)

drapeau_catalogne(300)
ht()

Exercice 12

Écrivez une fonction table_de_multiplication(m, n) qui affiche la table de multiplication de m jusqu'à n. Par exemple, table_de_multiplication(3, 5) doit afficher:

3 x 1 = 3
3 x 2 = 6
3 x 3 = 9
3 x 4 = 12
3 x 5 = 15

Utilisez cette fonction pour afficher la table de multiplication de 12 pour les nombres de 1 à 12.

Solution

def table_de_multiplication(m, n):
    for i in range(1, n + 1):
        print(m, "x", i, "=", i * m)

table_de_multiplication(12, 12)

Exercice 13

On cherche la plus grande valeur entière x entre 0 et 100 (inclusivement) telle que x×(x+1)×(x+2) modulo 7452 donne 6900.

Quelle est cette valeur de x?

92

Solution

On peut utiliser une boucle for avec range(100, -1, -1) pour itérer de 100 à 0 en ordre décroissant. La première valeur trouvée sera la plus grande.

for x in range(100, -1, -1):
    if (x * (x + 1) * (x + 2)) % 7452 == 6900:
        print("La plus grande valeur de x est:", x)
        break

Exercice 14

Écrivez un programme qui affiche le drapeau de l'Union Européenne avec la tortue, comme celui-ci-dessous.

Le drapeau a des dimensions de 300 pixels de largeur par 200 pixels de hauteur. Les étoiles jaunes sont disposées sur un cercle de rayon d'un tiers de la hauteur du drapeau, centré au milieu.

Le diamètre des étoiles est de 1/8 de la hauteur du drapeau. L'image "star" a un diamètre par défaut de 100 pixels. Pour obtenir un diamètre de d pixels, on utilise image("star", d / 100).

Les couleurs utilisées sont "#20a" (bleu) et "#fd0" (jaune).

Solution

def drapeau_ue():
    largeur = 300
    hauteur = 200

    # Fond bleu
    pencolor("#20a")
    pensize(hauteur)
    fd(largeur / 2)
    bk(largeur)
    fd(largeur / 2)

    # Étoiles jaunes
    pencolor("#fd0")
    rayon_cercle = hauteur / 3
    diametre_etoile = hauteur / 8
    taille_etoile = diametre_etoile / 100
    for i in range(12):
        rt(i * 30)
        hop(); fd(rayon_cercle)
        lt(i * 30)
        image("star", taille_etoile)
        rt(i * 30)
        hop(); bk(rayon_cercle)
        lt(i * 30)

drapeau_ue()
ht()

Exercice 15

Écrivez un programme qui affiche un plateau d'échecs de 8x8 avec la tortue, comme celui-ci-dessous. Chaque case doit être un carré de 20 pixels de côté.

Solution

Puisqu'un plateau d'échecs est une grille de 8x8 cases, on peut utiliser deux boucles for imbriquées pour dessiner chaque case. La boucle extérieur itère sur les lignes et la boucle intérieur itère sur les colonnes. Au total, ça permet de dessiner 64 cases (8 lignes x 8 colonnes).

Il y a plusieurs manières de choisir la couleur d'une case. Une astuce est d'utiliser le fait que les cases noires se trouvent là où la somme du numéro de la ligne et du numéro de la colonne est paire ( 0+0=0 , 0+2=2 , 1+1=2 , etc.). On peut utiliser l'opérateur modulo % pour déterminer si cette somme est paire ou impaire.

def carre(x, y, taille):
    hop(); fd(x, y)
    pensize(taille)
    rt(90)
    fd(taille)
    hop(); bk(taille)
    lt(90)
    hop(); fd(-x, -y)

def grille(taille_case):
    for ligne in range(8):
        for colonne in range(8):
            # Calcul de la position de la case
            x = colonne * taille_case
            y = ligne * taille_case

            # Calcul de la couleur de la case
            if (ligne + colonne) % 2 == 0:
                pencolor("black")
            else:
                pencolor("white")

            carre(x, y, taille_case)

hop(); bk(70, 70)
grille(20)
ht()

Exercice 16

Un triplet de Pythagore est un ensemble de trois entiers positifs supérieurs à zéro (a, b, c) tels que a2+b2=c2 . Par exemple, (3, 4, 5), (4, 3, 5), et (5, 12, 13) sont des triplets de Pythagore. Cependant, (3, 4, 5) et (4, 3, 5) sont équivalents. Votre code ne doit pas compter les doublons.

Combien y a-t-il de triplets de Pythagore avec des valeurs inférieures ou égales à 100?

52

Solution

On peut utiliser trois boucles imbriqués qui itèrent chacune sur range(1, limite + 1), où limite est la valeur maximale (ici 100). Ensembles, ces trois boucles vont parcourir toutes les combinaisons possibles de valeurs pour a, b et c. À chaque itération, on vérifie si la condition a2+b2=c2 est satisfaite. Si c'est le cas, on incrémente un compteur.

Cette technique qui consiste à tester toutes les combinaisons possibles d'un problème pour trouver une réponse s'appelle la méthode force brute. Elle fonctionne pour les petites valeurs, mais devient rapidement inefficace pour des valeurs plus grandes à cause du grand nombre de combinaisons à tester.

Notez que les doublons sont évités car b commence à a et c commence à b, ce qui garantit que a <= b <= c.

limite = 100

compteur = 0

for a in range(1, limite + 1):
    for b in range(a, limite + 1):
        for c in range(b, limite + 1):
            if a * a + b * b == c * c:
                compteur += 1

print("Il y a", compteur, "triplets de Pythagore")

Exercice 17

La séquence de Fibonacci est une suite de nombres où chaque nombre est la somme des deux précédents. La séquence commence par 0 et 1, donc les premiers nombres de la séquence sont: 0, 1, 1, 2, 3, 5, 8, ...

Écrivez une fonction fibonacci(n) qui retourne le n-ième nombre de la suite de Fibonacci et utilisez-la pour afficher le 100-ième nombre de Fibonacci.

Solution

def fibonacci(n):
    a = 0
    b = 1
    
    # Le caractère '_' est un identifiant valide.
    # Il est utilisé ici pour indiquer qu'on ne se soucie pas de la valeur de
    # la variable d'itération - on souhaite uniquemnet exécuter le code n fois.
    for _ in range(n):
        somme = a + b
        a = b
        b = somme

    return a

print(fibonacci(100))

Les listes de données

012345

Lorsqu'on souhaite traiter un grand nombre de données apparentées, il est pratique de les regrouper dans un objet qu'on appèle une liste . Comme dans la vie de tous les jours, une liste est une suite d'éléments ordonnés. On peut écrire une liste en utilisant les crochets [] et en séparant les éléments par des virgules.

animaux = ["crabe", "tortue", "serpent", "fourmi", "araignée", "fusée"]

print(animaux)

Chaque élément d'une liste a une position, appelée son index. Le premier élément d'une liste a l'index 0, le deuxième élément a l'index 1, et ainsi de suite. On peut accéder à un élément d'une liste en utilisant son index entre crochets.

animaux = ["crabe", "tortue", "serpent", "fourmi", "araignée", "fusée"]

print("Le premier animal est :", animaux[0])
print("Le troisième animal est :", animaux[2])
print("Le dernier animal est :", animaux[5])
print("Hey! Une", animaux[5], "n'est pas un animal!")

Lorsqu'on accède à un index qui n'est pas dans la liste, par exemple si la liste est trop courte, l'ordinateur signale une erreur appelée IndexError. Il faut donc faire attention de s'assurer que les index utilisés sont valides pour la liste.

Le contenu des listes

True0-619923.143"ABC"4

Une liste peut contenir n'importe quel type de données : des nombres, des textes, des booléens, et même d'autres listes!

Voici quelques exemples de listes contenant différents types de données :

liste_de_nombres = [1, 2, 3, 4, 5]

liste_de_mots = ["pomme", "banane", "cerise"]

liste_mixte = [True, -6, 99, 3.14, "ABC"]

print("Les premiers éléments de chaque liste sont :")
print(liste_de_nombres[0])
print(liste_de_mots[0])
print(liste_mixte[0])

Une liste de listes peut être utilisée pour représenter des données plus complexes en deux dimensions, comme une grille ou une matrice. Chaque index de la liste principale peut, par exemple, contenir une autre liste qui représente une rangée de la grille ou de la matrice.

Exercice 1

12345678910111213141516171819202122232425262728293031

Écrivez une liste qui contient les noms des jours de la semaine sous forme de texte. Accédez ensuite aux éléments de la liste pour afficher tous les jours de la semaine du lundi au dimanche.

Solution

Pour créer une liste, on utilise des crochets [] et on sépare les éléments par des virgules.

Puisqu'on souhaite réutiliser la liste pour accéder aux jours de la semaine, on stocke la liste dans une variable jours_de_la_semaine.

jours_de_la_semaine = ["lundi", "mardi", "mercredi", "jeudi",
                       "vendredi", "samedi", "dimanche"]

print(jours_de_la_semaine[0])
print(jours_de_la_semaine[1])
print(jours_de_la_semaine[2])
print(jours_de_la_semaine[3])
print(jours_de_la_semaine[4])
print(jours_de_la_semaine[5])
print(jours_de_la_semaine[6])

Puisqu'on sait que la liste contient sept éléments, dont les index vont de 0 à 6, on peut également utiliser une boucle for.

jours_de_la_semaine = ["lundi", "mardi", "mercredi", "jeudi",
                       "vendredi", "samedi", "dimanche"]

for index in range(7):
    print(jours_de_la_semaine[index])

Exercice 2

Écrivez une liste qui contient les nombres de 1 à 10. Accédez ensuite aux éléments de la liste pour faire la somme de tous ces nombres et afficher cette somme.

Solution

Pour créer une liste de nombres de 1 à 10, on peut les écrire directement entre crochets [].

nombres = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

total = 0

for index in range(10):
    total += nombres[index]

print("La somme des nombres de 1 à 10 est :", total)

Pour le moment, on écrit manuellement la liste. Nous verrons très bientôt comment créer de longues listes sans avoir à écrire chaque élément.

Ajouter un élément à la fin d'une liste

11111111111111111111111111111111111111111111111111222222222222222222222222222222222222222222222222223333333333333333333333333333333333333333333333333

Il est possible d'ajouter et retirer des éléments d'une liste.

Pour ajouter un élément x à la fin d'une liste, on écrit liste.append(x).

Pour construire une liste, on définit souvent une liste vide et on ajoute les éléments un par un avec la méthode .append.

pays = [] # Ceci est une liste vide

pays.append("France")
pays.append("Italie")
pays.append("Mali")

print(pays) # La liste contient maintenant les pays

Construire une liste avec la méthode .append est utile pour éviter d'avoir à écrire manuellement de longues listes. Par exemple, ce programme construit une liste qui contient tous les nombres pairs de 0 à 20.

nombres_pairs = [] # La liste est vide

for nombre in range(21):
    nombres_pairs.append(nombre)

print(nombres_pairs) # Elle contient maintenant les nombres pairs de 0 à 20

Les fonctions auquelles on accède en écrivant liste.append(x) sont appelées des méthodes. Il s'agit de fonctions qui sont associées à un type de données, comme les listes.

Exercice 3

Créez une liste qui contient tous les nombres impairs de 1 à 99. Accédez ensuite aux éléments de la liste pour faire la somme de tous ces nombres et afficher cette somme.

Solution

Puisqu'il serait trop long d'écrire les nombres 1, 3, 5, ..., 99 manuellement, on peut construire la liste avec une boucle for et la méthode .append.

nombres = []

for nombre in range(1, 100, 2):
    nombres.append(nombre)

total = 0
for index in range(50): # Il y a 50 nombre impairs de 1 à 99
    total += nombres[index]

print("La somme des nombres impairs de 1 à 99 est :", total)

Obtenir la longueur d'une liste

Puisque les listes peuvent changer de taille, il est utile de pouvoir connaître leur longueur. On peut utiliser la fonction len pour obtenir le nombre d'éléments dans une liste.

animaux = ["crabe", "tortue", "serpent", "fourmi", "araignée", "fusée"]

taille_de_la_liste = len(animaux)

print("Il y a", taille_de_la_liste, "animaux dans la liste.")

Par exemple, la fonction len permet de découvrir la longueur d'une liste lorsqu'on veut itérer sur tous ses éléments avec une boucle for. Les index d'une liste vont toujours de 0 à len(liste) - 1. Ainsi, pour accéder à tous les éléments d'une liste, on peut utiliser une boucle for avec range(len(liste)).

liste_de_notes = ['A', 'A', 'C+', 'B', 'A-', 'C', 'B+', 'A']

for index in range(len(liste_de_notes)):
    print("La note numéro", index, "est :", liste_de_notes[index])

Il est important de pouvoir découvrir la longueur d'une liste, car on vous demandera souvent d'écrire des fonctions qui prennent en paramètre une liste de n'importe quelle longueur. En utilisant len, votre fonction pourra traiter des listes de différentes tailles sans que vous ayez à modifier votre code.

Pour accéder au dernier élément d'une liste, on peut utiliser l'index len(liste) - 1. Pour être un peu plus concis, on peut aussi utiliser l'index -1 pour accéder au dernier élément, -2 pour accéder à l'avant-dernier élément, et ainsi de suite. Testez des index négatifs dans votre console pour voir comment cela fonctionne!

Exercice 4

Créez une liste qui contient tous les nombres impairs de 1 à 10,000 . Utilisez ensuite la fonction len pour afficher le nombre d'éléments dans la liste et affichez le dernier élément de la liste.

Solution

On crée d'abord la liste de nombres impairs de 1 à 10,000 en utilisant une boucle for et la méthode .append.

Ensuite, on peut utiliser len pour afficher le nombre d'éléments dans la liste.

Pour accéder au dernier élément, on peut utiliser l'index len(nombres) - 1 ou simplement l'index -1.

nombres = []

for nombre in range(1, 10001, 2):
    nombres.append(nombre)

print("Il y a", len(nombres), "nombres impairs de 1 à 10,000.")
print("Le dernier nombre impair de 1 à 10,000 est :", nombres[-1])

Exercice 5

Écrivez une fonction appelée calculer_moyenne qui prend en paramètre une liste de nombres non-vide. Votre fonction doit calculer et retourner la moyenne de ces nombres. Elle doit donc calculer la somme des nombres et la diviser par le nombre d'éléments dans la liste.

Utilisez ensuite votre fonction pour calculer la moyenne des 10 premières décimales de π : 3 , 1 , 4 , 1 , 5 , 9 , 2 , 6 , 5 et 3 .

Solution

On définit une fonction avec def calculer_moyenne(nombres):. Puisque la fonction peut recevoir une liste non-vide de n'importe quelle longueur, on utilise len(nombres) pour connaître le nombre d'éléments dans la liste. Ça nous permet d'itérer sur tous les index de la liste, et de diviser leur total par len(nombres) pour calculer la moyenne.

On retourne ensuite la moyenne calculée.

def calculer_moyenne(nombres):
    total = 0
    for index in range(len(nombres)):
        total += nombres[index]

    moyenne = total / len(nombres)

    return moyenne

decimales_de_pi = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3]
moyenne_pi = calculer_moyenne(decimales_de_pi)
print(moyenne_pi)

Qu'arrive-t-il à votre fonction si vous lui passez une liste vide? Essayez de l'appeler avec une liste vide pour voir ce qui se passe. La moyenne d'un ensemble ne contentant aucun nombre n'est pas défini mathématiquement, est-ce que le comportement de votre fonction est raisonnable dans ce cas?

Pour teste si une liste est vide, on peut utiliser la fonction len et vérifier si la valeur retournée est 0.

ma_liste = []

if len(ma_liste) == 0:
    print("La liste est vide.")
else:
    print("La liste n'est pas vide.")

On peut également utiliser la liste comme condition d'un if. Une liste vide est considérée comme False, tandis qu'une liste non-vide est considérée comme True.

ma_liste = []

if ma_liste:
    print("La liste n'est pas vide.")
else:
    print("La liste est vide.")

Cette notion se génalise : on peut utiliser n'importe quelle expression comme condition d'un if, pas seulement un booléen. La valeur de vérité sera déterminée par la valeur de l'expression : les nombres 0 et 0.0, le texte vide "", et la liste vide [] sont considérés comme False, tandis que les autres valeurs sont considérées comme True.

Exercice 6

Écrivez une fonction est_vide qui prend en paramètre une liste et retourne True si la liste est vide, et False sinon.

Solution

On peut utiliser la fonction len pour vérifier si la liste est vide.

def est_vide(liste):
    return len(liste) == 0

# Quelques tests
print(est_vide([])) # True
print(est_vide([1, 2, 3])) # False

Itérer sur les éléments d'une liste

On a vu qu'il est possible d'itérer sur les éléments d'une liste en utilisant une boucle for avec range(len(liste)). Cependant, si ce qui nous intéresse est le contenu de la liste plutôt que les index, on peut itérer directement sur les éléments de la liste avec for element in liste:.

jours_de_la_semaine = ["lundi", "mardi", "mercredi", "jeudi",
                       "vendredi", "samedi", "dimanche"]

for jour in jours_de_la_semaine:
    print(jour)

Exercice 7

Écrivez une fonction contient qui prend deux paramètre: une liste de nombres et un nombre. La fonction doit retourner True si le nombre est dans la liste, et False sinon.

Testez votre fonction avec au moins trois listes et nombres à chercher différents.

Solution

On pourrait utiliser range(len(liste)) pour itérer sur les index de la liste et retourner True dès qu'on trouve l'élément recherché. En faisant return True, l'itération arrête immédiatement, et la fonction ne retourne True.

def contient(liste, nombre):
    for index in range(len(liste)):
        if liste[index] == nombre:
            return True

    return False

# Quelques tests
print(contient([1, 2, 3], 2)) # True
print(contient([1, 2, 3], 4)) # False
print(contient([], 1)) # False

Cependant, il est plus simple d'itérer directement sur les éléments de la liste avec for element in liste:.

def contient(liste, nombre):
    for element in liste:
        if element == nombre:
            return True

    return False

# Quelques tests
print(contient([1, 2, 3], 2)) # True
print(contient([1, 2, 3], 4)) # False
print(contient([], 1)) # False

Résumé

Créer une liste.

Instruction Description Exemple
[a...z] Crée une liste avec des éléments ma_liste = [123]
[] Crée une liste vide ma_liste = []

Contenu d'une liste.

Instruction Description Exemple
liste[index] Retourne l'élément à la position index dans la liste ma_liste[0] retourne le premier élément de ma_liste
len(liste) Retourne le nombre d'éléments dans la liste len([112233])3

Modifier une liste.

Instruction Description Exemple
liste.append(x) Ajoute un élément x à la fin de la liste ma_liste.append(4) ajoute 4 à ma_liste

Itérer sur une liste.

Instruction Description Exemple
for var in liste: Parcourt chaque élément de la liste
for n in ma_liste:
    print(n)

Exercice 8

HHydrogen1.0081  HeHelium4.00262  LiLithium6.943  BeBeryllium9.01224  BBoron10.815  CCarbon12.0116  NNitrogen14.0077  OOxygen15.9998  FFluorine18.9989  NeNeon20.1810 NaSodium22.9911 MgMagnesium24.30512 AlAluminium26.98213 SiSilicon28.08514 PPhosphorus30.97415 SSulfur32.0616 ClChlorine35.4517 ArArgon39.94818 KPotassium39.098319 CaCalcium40.07820 ScScandium44.95621 TiTitanium47.86722 VVanadium50.94223 CrChromium51.99624 MnManganese54.93825 FeIron55.84526 CoCobalt58.93327 NiNickel58.69328 CuCopper63.54629 ZnZinc65.3830 GaGallium69.72331 GeGermanium72.6332 AsArsenic74.92233 SeSelenium78.97134 BrBromine79.90435 KrKrypton83.79836 RbRubidium85.46837 SrStrontium87.6238 YYttrium88.90639 ZrZirconium91.22440 NbNiobium92.90641 MoMolybdenum95.9542 TcTechnetium9843 RuRuthenium101.0744 RhRhodium102.9145 PdPalladium106.4246 AgSilver107.8747 CdCadmium112.4148 InIndium114.8249 SnTin118.7150 SbAntimony121.7651 TeTellurium127.652 IIodine126.953 XeXenon131.2954 CsCesium132.9155 BaBarium137.3356 LaLanthanum138.9157 CeCerium140.1258 PrPraseodymium140.9159 NdNeodymium144.2460 PmPromethium14561 SmSamarium150.3662 EuEuropium151.9663 GdGadolinium157.2564 TbTerbium158.9365 DyDysprosium162.566 HoHolmium164.9367 ErErbium167.2668 TmThulium168.9369 YbYtterbium173.0570 LuLutetium174.9771 HfHafnium178.4972 TaTantalum180.9573 WTungsten183.8474 ReRhenium186.2175 OsOsmium190.2376 IrIridium192.2277 PtPlatinum195.0878 AuGold196.9779 HgMercury200.5980 TlThallium204.3881 PbLead207.282 BiBismuth208.9883 PoPolonium20984 AtAstatine21085 RnRadon22286 FrFrancium22387 RaRadium22688 AcActinium22789 ThThorium232.0490 PaProtactinium231.0491 UUranium238.0392 NpNeptunium23793 PuPlutonium24494 AmAmericium24395 CmCurium24796 BkBerkelium24797 CfCalifornium25198 EsEinsteinium25299 FmFermium257100MdMendelevium258101NoNobelium259102LrLawrencium266103RfRutherfordium267104DbDubnium268105SgSeaborgium269106BhBohrium270107HsHassium277108MtMeitnerium278109DsDarmstadtium281110RgRoentgenium282111CnCopernicium285112NhNihonium286113FlFlerovium289114McMoscovium290115LvLivermorium293116TsTennessine294117OgOganesson294118

Dans votre environnement de développement, vous trouverez la définition d'une liste contenant les dix premiers éléments du tableau périodique. Écrivez un programme qui itére sur cette liste et affiche le nom de chaque élément précédé de son numéro atomique comme ceci:

1 Hydrogène
2 Hélium
3 Lithium
4 Béryllium
5 Bore
6 Carbone
7 Azote
8 Oxygène
9 Fluor
10 Néon
elements = ["Hydrogène", "Hélium", "Lithium", "Béryllium", "Bore",
            "Carbone", "Azote", "Oxygène", "Fluor", "Néon"]

Solution

Puisque les éléments de la liste sont déjà ordonnées, on peut calculer leur numéro atomique à partir de leur index dans la liste. Par exemple, l'hydrogène est à l'index 0 dans la liste, mais son numéro atomique est 1, donc on peut calculer le numéro atomique en ajoutant 1 à l'index de l'élément.

elements = ["Hydrogène", "Hélium", "Lithium", "Béryllium", "Bore",
            "Carbone", "Azote", "Oxygène", "Fluor", "Néon"]

for index in range(len(elements)):
    numero_atomique = index + 1
    nom_element = elements[index]
    print(numero_atomique, nom_element)

Exercice 9

Écrivez une fonction trouver qui prend deux paramètre: une liste de nombres et un nombre. Si le nombre se trouve dans la liste, la fonction doit retourner l'index à laquelle il se trouve. Si le nombre se trouve plusieurs fois dans la liste, la fonction doit retourner l'index de sa première position dans la liste. Si le nombre ne se trouve pas dans la liste, la fonction doit retourner 1 .

Solution

Puisqu'il faut retourner l'index d'un élément, on doit itérer sur les index de la liste avec range(len(liste)). À chaque index, on vérifie si l'élément à cet index est égal au nombre recherché. Si c'est le cas, on retourne cet index. Si on arrive à la fin de la liste sans trouver le nombre, on retourne -1.

def trouver(liste, nombre):
    for index in range(len(liste)):
        if liste[index] == nombre:
            return index

    return -1

# Quelques tests
print(trouver([1, 2, 3], 3)) # 2
print(trouver([1, 2, 3], 4)) # -1
print(trouver([1, 2, 2, 3], 2)) # 1
print(trouver([], 999)) # -1

Exercice 10

Écrivez un fonction position_maximum qui prend en paramètre une liste non-vide de nombres et retourne l'index du plus grand nombre dans la liste. Si le plus grand nombre se trouve plusieurs fois dans la liste, la fonction doit retourner l'index de sa première position dans la liste.

Solution

Pour trouver l'index du plus grand nombre, il faut itérer sur les index. À chaque index, on vérifie si le nombre est plus grand que le plus grand nombre trouvé jusqu'à présent. Si c'est le cas, on met à jour l'index du maximum trouvé jusqu'à présent.

Au début de la fonction, on peut initialiser l'index du maximum à 0 pour commencer la comparaison à partir du premier élément de la liste.

def position_maximum(liste):
    index_max = 0

    for index in range(1, len(liste)):
        if liste[index] > liste[index_max]:
            index_max = index

    return index_max

# Quelques tests
print(position_maximum([1, 2, 3])) # 2
print(position_maximum([3, 2, 1])) # 0
print(position_maximum([1, 3, 2, 3])) # 1
print(position_maximum([-1, -2, -3])) # 0

Modifier les éléments d'une liste

Il est possible de modifier les éléments d'une liste en accédant à leur index et en leur assignant une nouvelle valeur.

mes_animaux_favoris = ["tortue", "crocodile", "toucan"]

print("Aujourd'hui mes animaux favoris sont :", mes_animaux_favoris)

mes_animaux_favoris[0] = "ornithorynque"
mes_animaux_favoris[1] = "panda"

print("Demain, ils seront :", mes_animaux_favoris)

Il faut être prudent lorsqu'on modifie une liste, car si plusieurs variables font référence à la même liste, alors les modifications affecteront toutes ces variables.

mes_animaux_favoris = ["tortue", "crocodile", "toucan"]
tes_animaux_favoris = mes_animaux_favoris # Référence à la même liste

mes_animaux_favoris[0] = "araignée"

# Observez que les modifications affectent les deux variables,
# car elles font référence à la même liste
print("Mes animaux favoris sont :", mes_animaux_favoris)
print("Tes animaux favoris sont :", tes_animaux_favoris)

Ce comportement peut causer des bogues très difficiles à trouver. En général, on évite donc de modifier une liste à moins que ce soit explicitement ce qui est demandé par la tâche ou l'exercice à accomplir.

La méthode .append, que nous avons déjà vue, modifie une liste. Si plusieurs variables font référence à la même liste, alors l'utilisation de la méthode .append sur une de ces variables affectera toutes les variables qui font référence à cette liste. Il faut donc faire attention à ne pas utiliser la méthode .append sur une liste partagée à moins que ce soit explicitement ce qui est demandé.

Exercice 1

Écrivez une fonction retirer_negatif qui prend en paramètre une liste de nombre et modifie la liste pour remplacer tous les nombres négatifs qu'elle contient par zéro.

Votre fonction ne doit rien retourner. Par convention, une fonction qui modifie une liste ne retourne rien pour bien indiquer que la modification se fait sur la liste passée en paramètre et que la fonction ne retourne pas une nouvelle liste. La fonction ne devrait donc contenir aucun return.

Solution

Lorsqu'on modifie une liste, on n'a pas le choix d'itérer sur ses index avec range(len(liste)), car il faut connaître la position des éléments à modifier dans la liste.

À chaque index, on vérifie si l'élément à cet index est négatif. Si c'est le cas, on lui assigne la valeur 0 pour le remplacer.

def retirer_negatif(nombres):
    for index in range(len(nombres)):
        if nombres[index] < 0:
            nombres[index] = 0

liste_test = [3, -1, 4, -2, 5]
retirer_negatif(liste_test)
print(liste_test) # Affiche [3, 0, 4, 0, 5]

Ajouter des élément à un index précis

012"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c"2"b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""b""c""a""a""a""a""a""a""a""a""a""a""a""a""a""a""a""a""a""a""a""a""a""a""a""a""a""a""a""a""a""a""a""a""a""a""a""a""a""a""a""a""a""a""a""a""a""a""a""a""a""a"

On peut ajouter une valeur à n'importe quelle position dans un liste avec la méthode .insert. Cette méthode prend deux paramètre : l'index où insérer la valeur, et la valeur à insérer. Après l'appel à la méthode .insert(index, x), les éléments à partir de l'index index seront décalés d'une position vers la droite et la valeur x se trouvera à l'index index,

Par exemple, on utilise souvent liste.insert(0, x) pour ajouter un élément x au début d'une liste.

liste_de_nombre = []

liste_de_nombre.insert(0, "a")
liste_de_nombre.insert(0, "b")
liste_de_nombre.insert(0, "c")

print(liste_de_nombre) # Affiche ["c", "b", "a"]

Retirer des éléments d'une liste

On peut retirer un élément d'une liste avec la méthode liste.pop(). Cette méthode fait l'inverse de la méthode .append : elle retire le dernier élément de la liste. En plus de retirer l'élément, la méthode .pop retourne la valeur de l'élément retiré afin qu'il puisse être utilisé pour d'autres calculs.

liste_de_taches = [
    "Collecter les données",
    "Démarrer l'accélérateur de particules",
    "Vérifier l'état des appareils",
    "Prendre un café"
]

tache = liste_de_taches.pop()
print("Tâche accomplie :", tache)
print("Il reste à faire :")
for tache in liste_de_taches:
    print(" -", tache)

Lorsqu'on souhaite retirer un élément à un index précis, on peut utiliser liste.pop(index) avec l'index de l'élément à retirer.

# liste de données avec un nombre erroné
liste_de_nombres = [10, 20, -999, 40, 50]

nombre_retiré = liste_de_nombres.pop(2)
print("Le nombre retiré est :", nombre_retiré)
print("Il reste dans la liste :", liste_de_nombres)

Exercice 2

Écrivez une fonction vider qui prend en paramètre une liste et modifie la liste pour la vider de tous ses éléments. Votre fonction ne doit rien retourner.

Indice

La méthode liste.pop() retire un élément de la liste. Il faut toutefois retirer des élément autant de fois que nécessaire pour vider complètement la liste en utilisant un boucle.

Solution

Pour retirer un élément, on peut utiliser la méthode .pop(). Puisqu'il faut vider complètement la liste, on appelle la méthode .pop() tant que la liste n'est pas vide. On peut donc utiliser une boucle while qui teste si la liste n'est pas vide.

def vider(liste):
    while len(liste) > 0: # Tant que la liste n'est pas vide
        liste.pop() # Retire le dernier élément

liste_de_mots = ["pomme", "banane", "cerise"]
vider(liste_de_mots)
print(liste_de_mots) # La liste est maintenant vide

On peut même utiliser la valeur de vérité de la liste pour écrire du code légèrement plus concis.

def vider(liste):
    while liste: # Tant que la liste n'est pas vide
        liste.pop() # Retire le dernier élément

Exercice 3

Écrivez une fonction rotation_droite qui prend en paramètre une liste et modifie la liste pour prendre le dernier élément de la liste et le mettre au début de la liste, tandis que tous les autres éléments sont décalés d'une position vers la droite.

La fonction modifie la liste en place et ne retourne rien (il ne doit y avoir aucun return dans la fonction).

En informatique, l'opération qui prend le dernier élément d'une liste et le met au début de la liste s'appelle une rotation de la liste vers la droite. Il existe aussi une rotation vers la gauche, qui prend le premier élément d'une liste et le met à la fin de la liste.

Solution

Pour faire une rotation de la liste, on peut utiliser la méthode .pop pour retirer le dernier élément de la liste et le stocker dans une variable. Ensuite, on utilise la méthode .insert pour insérer cet élément au début de la liste.

def rotation_droite(liste):
    dernier_element = liste.pop() # Retire dernier
    liste.insert(0, dernier_element) # Insère au début

ma_liste = [1, 2, 3, 4, 5]
rotation_droite(ma_liste)
print(ma_liste) # Affiche [5, 1, 2, 3, 4]

Exercice 4

Écrivez une fonction rotation_gauche qui prend en paramètre une liste et modifie la liste pour prendre le premier élément de la liste et le mettre à la fin de la liste, tandis que tous les autres éléments sont décalés d'une position vers la gauche.

La fonction modifie la liste en place et ne retourne rien (il ne doit y avoir aucun return dans la fonction).

Solution

Pour faire une rotation de la liste vers la gauche, on peut utiliser la méthode .pop(0) pour retirer le premier élément de la liste et le stocker dans une variable. Ensuite, on utilise la méthode .append pour ajouter cet élément à la fin de la liste.

def rotation_gauche(liste):
    premier_element = liste.pop(0) # Retire premier
    liste.append(premier_element) # Ajoute à la fin

ma_liste = [1, 2, 3, 4, 5]
rotation_gauche(ma_liste)
print(ma_liste) # Affiche [2, 3, 4, 5, 1]

Concaténer des listes

L'action de prendre deux listes et de les combiner pour en faire une seule liste est appelée concaténation de listes. La concaténation de listes se fait avec l'opérateur +.

La concaténation de listes crée une nouvelle liste qui contient tous les éléments des listes d'origine. Les listes d'origine ne sont donc pas modifiées.

liste1 = [1, 2, 3]
liste2 = [4, 5, 6]

nouvelle_liste = liste1 + liste2

# La nouvelle liste
print(nouvelle_liste)

# Les listes originales n'ont pas été modifiées
print(liste1)
print(liste2)

Attention, l'opérateur += a un comportement subtil. Si les variables liste1 et liste2 contiennent des listes alors liste1 += liste2 ne fait pas exactement la même chose que liste1 = liste1+liste2. La liste liste1 est plutôt modifiée comme si on avait utilisé la méthode .append pour ajouter un par un les éléments de la liste liste2 à la liste liste1.

Exercice 5

Écrivez un programme qui crée deux listes : une liste de tous les nombres pairs de 0 à 18, et une liste de tous les nombres impairs de 1 à 19.

Utilisez ces deux listes pour construire une nouvelle liste qui commence par tous les nombres pairs de 0 à 18, suivis de tous les nombres impairs de 1 à 19. Affichez cette nouvelle liste.

Solution

On peut construire les listes de nombres pairs et impairs avec des boucles for et la méthode .append. Ensuite, on utilise l'opérateur + pour concaténer les deux listes et en faire une nouvelle liste.

nombres_pairs = []
for nombre in range(0, 20, 2):
    nombres_pairs.append(nombre)

nombres_impairs = []
for nombre in range(1, 20, 2):
    nombres_impairs.append(nombre)

nombres_concatenés = nombres_pairs + nombres_impairs
print(nombres_concatenés)

Extraire une partie d'une liste (tranche)

Une tranche est un sous-section d'une liste. Par exemple, le code suivant utilise range pour créer une tranche ne contenant que les éléments aux index pairs d'une liste.

liste = ["crabe", "tortue", "serpent", "fourmi", "araignée", "fusée"]
nouvelle_liste = []

for index in range(0, len(liste), 2):
    nouvelle_liste.append(liste[index])

print("Les index pairs de la liste contenaient :", nouvelle_liste)

Il y a une syntaxe plus concise pour créer des tranches. Récurérer les index correspondants à range(debut, fin) peut être fait en écrivant liste[debut:fin]. Si on souhaite ajouter un pas comme dans range(debut, fin, pas), on peut écrire liste[debut:fin:pas]. Par exemple, le code précédent peut être réécrit de manière plus consise comme ceci :

liste = ["crabe", "tortue", "serpent", "fourmi", "araignée", "fusée"]
nouvelle_liste = liste[0:len(liste):2]
print("Les index pairs de la liste contenaient :", nouvelle_liste)

Dans les exemples ci-dessous, la variable lst contient la liste [11, 22, 33, 44].

Exemple Description Exemple Résultat
liste[a:b] Créer une liste avec des éléments de a à b-1 lst[1:3] [22,33]
liste[a:] Créer une liste avec des éléments de a à la fin de la liste lst[1:] [22,33,44]
liste[:b] Créer une liste avec des éléments de a à b-1 lst[:3] [11,22,33]
liste[:] Créer une copie de la liste lst[:] [11,22,33,44]
liste[a:b:c] Créer une liste avec des éléments de a à b-1 par sauts de c lst[1:5:2] [22,44]
liste[::-1] Créer une liste avec les éléments dans l'ordre inverse lst[::-1] [44,33,22,11]

L'extraction d'une tranche ne peut jamais causer une erreur IndexError, même si les index de la tranche sont en dehors des limites de la liste. Si les limites de la liste sont dépassées, alors ces portion de la tranche sont simplement ignorées.

Exercice 6

Écrivez une fonction positions_pairs qui prend en paramètre une liste et retourne une tranche de la liste contenant les éléments aux positions paires de la liste d'origine (c'est à dire les éléments aux index 0, 2, 4, etc.).

Solution

On peut utiliser une tranche avec un pas de 2 pour extraire les éléments aux positions paires de la liste.

def positions_pairs(liste):
    return liste[0:len(liste):2]

# Quelques tests
print(positions_pairs([1, 2, 3, 4, 5, 6])) # Affiche [1, 3, 5]
print(positions_pairs(["a", "b", "c", "d", "e"])) # Affiche ["a", "c", "e"]
print(positions_pairs([])) # Affiche []

Puisque'on souhaite extraire les éléments du début à la fin, on peut omettre les limites de la tranche et écrire une version plus concise de la fonction.

def positions_pairs(liste):
    return liste[::2]

# Quelques tests
print(positions_pairs([1, 2, 3, 4, 5, 6])) # Affiche [1, 3, 5]
print(positions_pairs(["a", "b", "c", "d", "e"])) # Affiche ["a", "c", "e"]
print(positions_pairs([])) # Affiche []

Exercice 7

Écrivez une fonction trois_derniers qui prend en paramètre une liste et retourne une nouvelle liste contenant les trois derniers éléments de la liste d'origine. Si la liste contient moins de trois élément, alors une copie de la liste entière doit être retournée.

Solution

On peut utiliser une tranche allant de len(liste) - 3 à la fin de la liste pour extraire les trois derniers éléments, à moins que la liste contienne moins de trois éléments, auquel cas on retourne une copie de la liste entière.

def trois_derniers(liste):
    if len(liste) < 3:
        return liste[:] # copie de la liste entière
    else:
        return liste[len(liste) - 3:]

# Quelques tests
print(trois_derniers([1, 2, 3, 4, 5])) # Affiche [3, 4, 5]
print(trois_derniers([1, 2])) # Affiche [1, 2]
print(trois_derniers([])) # Affiche []

On peut utiliser également utiliser un index négatif pour écrire du code plus concis. Puisque les tranches ne causent jamais d'erreur IndexError, cette tranche retournera automatiquement la liste entière si elle contient moins de trois éléments.

def trois_derniers(liste):
    return liste[-3:]

# Quelques tests
print(trois_derniers([1, 2, 3, 4, 5])) # Affiche [3, 4, 5]
print(trois_derniers([1, 2])) # Affiche [1, 2]
print(trois_derniers([])) # Affiche []

Exercice 8

11111111111222222222223333333333344444444444555555555551111111111122222222222333333333334444444444455555555555111111111112222222222233333333333444444444445555555555511111111111222222222223333333333344444444444555555555551111111111122222222222333333333334444444444455555555555111111111112222222222233333333333444444444445555555555511111111111222222222223333333333344444444444555555555551111111111122222222222333333333334444444444455555555555111111111112222222222233333333333444444444445555555555511111111111222222222223333333333344444444444555555555551111111111122222222222333333333334444444444455555555555111111111112222222222233333333333444444444445555555555511111111111222222222223333333333344444444444555555555551111111111122222222222333333333334444444444455555555555111111111112222222222233333333333444444444445555555555511111111111222222222223333333333344444444444555555555551111111111122222222222333333333334444444444455555555555111111111112222222222233333333333444444444445555555555511111111111222222222223333333333344444444444555555555551111111111122222222222333333333334444444444455555555555111111111112222222222233333333333444444444445555555555511111111111222222222223333333333344444444444555555555551111111111122222222222333333333334444444444455555555555111111111112222222222233333333333444444444445555555555511111111111222222222223333333333344444444444555555555551111111111122222222222333333333334444444444455555555555111111111112222222222233333333333444444444445555555555511111111111222222222223333333333344444444444555555555551111111111122222222222333333333334444444444455555555555111111111112222222222233333333333444444444445555555555511111111111222222222223333333333344444444444555555555551111111111122222222222333333333334444444444455555555555111111111112222222222233333333333444444444445555555555511111111111222222222223333333333344444444444555555555551111111111122222222222333333333334444444444455555555555111111111112222222222233333333333444444444445555555555511111111111222222222223333333333344444444444555555555551111111111122222222222333333333334444444444455555555555111111111112222222222233333333333444444444445555555555511111111111222222222223333333333344444444444555555555551111111111122222222222333333333334444444444455555555555111111111112222222222233333333333444444444445555555555511111111111222222222223333333333344444444444555555555551111111111122222222222333333333334444444444455555555555111111111112222222222233333333333444444444445555555555511111111111222222222223333333333344444444444555555555551111111111122222222222333333333334444444444455555555555111111111112222222222233333333333444444444445555555555511111111111222222222223333333333344444444444555555555551111111111122222222222333333333334444444444455555555555111111111112222222222233333333333444444444445555555555511111111111222222222223333333333344444444444555555555551111111111122222222222333333333334444444444455555555555111111111112222222222233333333333444444444445555555555511111111111222222222223333333333344444444444555555555551111111111122222222222333333333334444444444455555555555111111111112222222222233333333333444444444445555555555511111111111222222222223333333333344444444444555555555551111111111122222222222333333333334444444444455555555555111111111112222222222233333333333444444444445555555555511111111111222222222223333333333344444444444555555555551111111111122222222222333333333334444444444455555555555111111111112222222222233333333333444444444445555555555511111111111222222222223333333333344444444444555555555551111111111122222222222333333333334444444444455555555555111111111112222222222233333333333444444444445555555555511111111111222222222223333333333344444444444555555555551111111111122222222222333333333334444444444455555555555111111111112222222222233333333333444444444445555555555511111111111222222222223333333333344444444444555555555551111111111122222222222333333333334444444444455555555555111111111112222222222233333333333444444444445555555555511111111111222222222223333333333344444444444555555555551111111111122222222222333333333334444444444455555555555111111111112222222222233333333333444444444445555555555511111111111222222222223333333333344444444444555555555551111111111122222222222333333333334444444444455555555555111111111112222222222233333333333444444444445555555555511111111111222222222223333333333344444444444555555555551111111111122222222222333333333334444444444455555555555111111111112222222222233333333333444444444445555555555511111111111222222222223333333333344444444444555555555551111111111122222222222333333333334444444444455555555555111111111112222222222233333333333444444444445555555555511111111111222222222223333333333344444444444555555555551111111111122222222222333333333334444444444455555555555111111111112222222222233333333333444444444445555555555511111111111222222222223333333333344444444444555555555551111111111122222222222333333333334444444444455555555555111111111112222222222233333333333444444444445555555555511111111111222222222223333333333344444444444555555555551111111111122222222222333333333334444444444455555555555111111111112222222222233333333333444444444445555555555511111111111222222222223333333333344444444444555555555551111111111122222222222333333333334444444444455555555555111111111112222222222233333333333444444444445555555555511111111111222222222223333333333344444444444555555555551111111111122222222222333333333334444444444455555555555111111111112222222222233333333333444444444445555555555511111111111222222222223333333333344444444444555555555551111111111122222222222333333333334444444444455555555555

Écrivez une fonction inverser qui prend en paramètre une liste et retourne une nouvelle liste contenant les éléments de la liste d'origine dans l'ordre inverse.

Solution

On peut utiliser une tranche avec un pas de -1 pour créer une nouvelle liste avec les éléments dans l'ordre inverse.

def inverser(liste):
    return liste[::-1]

# Quelques tests
print(inverser([1, 2, 3, 4, 5]))
print(inverser(["a", "b", "c"]))
print(inverser([]))

Résumé

Modifier une liste.

Instruction Description Exemple
liste[i] = x Change la position i de la liste pour y mettre la valeur x ma_liste[0] = 10
change le premier élément de ma_liste à la valeur 10
liste.append(x) Ajoute un élément x à la fin de la liste ma_liste.append(4)
ajoute 4 à la fin de ma_liste
liste.insert(ix) Insère un élément x à la position i dans la liste ma_liste.insert(0, 99)
insère 99 au début de ma_liste
liste.pop() Retire le dernier élément de la liste et retourne sa valeur ma_liste.pop()
retire le dernier élément de ma_liste et retourne sa valeur
liste.pop(i) Retire l'élément à la position i dans la liste et retourne sa valeur ma_liste.pop(0)
retire le premier élément de ma_liste et retourne sa valeur

Concaténer des listes.

Instruction Description Exemple
liste1 + liste2 Concatène les listes liste1 et liste2 pour en faire une nouvelle liste [1,2] + [3,4]
retourne la nouvelle liste [1,2,3,4]
liste1 += liste2 Modifie la liste liste1 en y ajoutant les éléments de liste2 ma_liste += [5,6]
ajoute les éléments 5 et 6 à la fin de ma_liste

Les tranches (Slices).

Dans les exemples ci-dessous, la variable lst contient la liste [11, 22, 33, 44].

Exemple Description Exemple Résultat
liste[a:b] Créer une liste avec des éléments de a à b-1 lst[1:3] [22,33]
liste[a:] Créer une liste avec des éléments de a à la fin de la liste lst[1:] [22,33,44]
liste[:b] Créer une liste avec des éléments de a à b-1 lst[:3] [11,22,33]
liste[:] Créer une copie de la liste lst[:] [11,22,33,44]
liste[a:b:c] Créer une liste avec des éléments de a à b-1 par sauts de c lst[1:5:2] [22,44]
liste[::-1] Créer une liste avec les éléments dans l'ordre inverse lst[::-1] [44,33,22,11]

Exercice 9

Écrivez une fonction ma_tranche qui prend une liste en paramètre et retourne une tranche contenant les éléments aux index 1 , 4 , 7 , et 10 de cette liste. Si la liste ne contient pas d'élément à l'un de ces index, alors les éléments correspondants sont simplement ignorés.

Solution

On peut utiliser une tranche avec un pas de 3 pour extraire les éléments aux index 1, 4, 7, et 10. Si la liste ne contient pas d'élément à l'un de ces index, alors la tranche retournera simplement les éléments qui existent.

def ma_tranche(liste):
    return liste[1:11:3]

# Quelques tests
print(ma_tranche([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])) # Affiche [1, 4, 7, 10]
print(ma_tranche([0, 1, 2, 3, 4, 5])) # Affiche [1, 4]
print(ma_tranche([0])) # Affiche []

Exercice 10

Écrivez un fonction positions_impaires qui prend en paramètre une liste de nombres et retourne une nouvelle liste contenant les éléments de la liste d'origine qui se trouvent à des positions impaires (c'est-à-dire aux index 1 , 3 , 5 , 7 , 9 , etc.).

Solution

On peut utiliser une tranche avec un pas de 2 pour extraire les éléments aux positions impaires. En commençant la tranche à l'index 1 , on s'assure d'extraire les éléments aux index 1 , 3 , 5 , etc. Puisqu'on souhaite extraire les éléments jusqu'à la fin de la liste, on peut omettre l'index de fin dans la tranche.

def positions_impaires(liste):
    return liste[1::2]

# Quelques tests
print(positions_impaires([0, 1, 2, 3, 4, 5])) # Affiche [1, 3, 5]
print(positions_impaires([0, 1, 2, 3, 4])) # Affiche [1, 3]
print(positions_impaires([0])) # Affiche []

Exercice 11

Écrivez une fonction somme_listes qui prend en paramètre deux listes de nombres et retourne une nouvelle liste contenant la somme des éléments correspondants des deux listes. Si les listes n'ont pas la même longueur, alors les éléments manquants dans la liste la plus courte sont considérés comme étant égaux à 0 .

Voici quelques exemples de ce que doit retourner somme_listes:

  • somme_listes([1, 2, 3], [4, 5, 6]) [5, 7, 9]
  • somme_listes([1, 2], [3, 4, 5]) [4, 6, 5]
  • somme_listes([1, 2, 3], []) [1, 2, 3]

Solution

On écrit une fonction qui fait d'abord la somme des éléments commun. On peut trouver le dernier index commun aux deux listes avec min(len(liste1), len(liste2)). Après avoir fait la somme des éléments communs, on ajoute le reste des éléments de la liste la plus longue.

def somme_listes(liste1, liste2):
    longueur_min = min(len(liste1), len(liste2))
    resultat = []

    # On fait la somme des éléments communs
    for index in range(longueur_min):
        resultat.append(liste1[index] + liste2[index])

    # On ajoute les éléments restants
    # On utilise un truc pour éviter d'utiliser un if pour savoir
    # quelle liste est plus longue en remarquant que la tranche
    # [longueur_min:] de la liste la plus courte sera toujours vide
    resultat += liste1[longueur_min:] + liste2[longueur_min:]

    return resultat

# Quelques tests
print(somme_listes([1, 2, 3], [4, 5, 6])) # Affiche [5, 7, 9]
print(somme_listes([1, 2], [3, 4, 5])) # Affiche [4, 6, 5]
print(somme_listes([1, 2, 3], [])) # Affiche [1, 2, 3]

Exercice 12

Écrivez une fonction melanger qui prend en paramètre une liste (pouvant contenir n'importe quel type d'éléments) et retourne une nouvelle liste contenant les mêmes éléments que la liste d'origine, mais dans un ordre aléatoire.

Indice

N'oubliex pas que vous pouvez utiliser la fonction randint(a, b) pour générer un nombre aléatoire entre a et b (inclusivement). Par exemple, vous pouvez utiliser cette fonction pour sélectionner un élément aléatoire d'une liste. Il faut toutefois faire attention à ne pas sélectionner le même élément deux fois!

Solution

On peut utiliser randint(0, len(liste) - 1) pour sélectionner un index aléatoire dans une liste. Pour s'assurer de ne pas sélectionner deux fois le même élément, on commence par créer une copie de la liste d'origine. À chaque fois qu'on sélectionne un élément aléatoirement, on le retire de la copie. On continue jusqu'à ce que la copie soit vide.

def melanger(liste):
    copie = liste[:]

    resultat = []

    while copie:
        index_aleatoire = randint(0, len(copie) - 1)
        element_aleatoire = copie.pop(index_aleatoire)
        resultat.append(element_aleatoire)

    return resultat

# Quelques tests (notez que les résultats seront différents à chaque fois!)
print(melanger([1, 2, 3, 4, 5]))
print(melanger(['a', 'b', 'c', 'd']))
print(melanger([]))

Exercice 13

Une liste de nombre est triée si les nombres de la liste sont en ordre croissant. Par exemple, la liste [1, 2, 3] est triée, alors que la liste [1, 3, 2] ne l'est pas.

Pour cet exercice, on souhaite modifier une liste afin qu'elle soit triée. Écrivez une fonction trier qui prend une liste de nombres en paramètre et modifie la liste pour qu'elle soit triée.

On peut écrire liste.sort() pour trier une liste. Pour cet exercice, vous n'avez toutefois par le droit d'utiliser la méthode .sort !

Indice

Une manière simple de trier une liste consiste à trouver son plus petit élément et à le placer à l'index 0 , puis trouver son deuxième plus petit élément et à le placer à l'index 1 , etc. Après avoir répété ce processus autant de fois qu'il y a d'éléments dans la liste, la liste sera triée.

Cette méthode de tri s'appelle le tri par sélection. Ce n'est pas un algorithme de tri très efficace, mais il est facile à comprendre et à implémenter.

Solution

On écrit d'abord une fonction position_minimum qui retourne l'index du plus petit nombre dans une liste. On va ensuite itérer sur la liste et, à chaque index, trouver le plus petit élément de la tranche de la liste qui commence à cet index. On retire ensuite le plus petit élément de la liste et on le place à l'index courant.

def position_minimum(liste):
    index_min = 0

    for index in range(len(liste)):
        if liste[index] < liste[index_min]:
            index_min = index

    return index_min

def trier(liste):
    for index in range(len(liste)):
        # Trouver le plus petit élément de la tranche commençant à index
        index_min = position_minimum(liste[index:])

        # On retire le plus petit élément de la liste
        plus_petit = liste.pop(index + index_min)

        # On place le plus petit élément à l'index courant
        liste.insert(index, plus_petit)

liste = [5, 2, 4, 1, 3]

print("Avant le tri:", liste)
trier(liste)
print("Après le tri:", liste)

Exercice 14

816357492

Un carré magique est un carré de nombre où la somme des nombres de chaque ligne, de chaque colonne et de chaque diagonale est la même. Par exemple, le carré ci-dessus est magique puisque la somme de chaque ligne, de chaque colonne et de chaque diagonale est égale à 15 .

On peut représenter un carré de nombre avec un liste de listes. Chaque élément de la liste principale représente donc une rangée dans le carrée. Voici un le carré de nombre ci-haut représentée par une liste de listes :

carre_magique = [
    [8, 1, 6],
    [3, 5, 7],
    [4, 9, 2]
]

Par contre, tous les carrées de nombres ne sont pas magiques (ils sont même plutôt rares!). Par exemple, le carré ci-dessous n'est pas magique puisque la somme de la première ligne est égale à 6 , alors que la somme de la deuxième ligne est égale à 15 .

carre_non_magique = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

Écrivez une fonction est_magique qui prend en paramètre un carré de nombre représenté par une liste de listes ecomme celles ci-haut et retourne True si le carré est magique, ou False sinon.

Solution

Pour vérifier si un carré est magique, il est pratique d'écrire quelques fonctions pour s'aider.

On écrit premièrement une fonction ligne(carre, index) qui retourne la ligne d'un carré à un index donné.

On écrit une fonction similaire colonne(carre, index) qui retourne la colonne d'un carré à un index donné.

On écrit aussi une fonction diagonale(carre, direction) qui retourne la diagonale d'un carré dans une direction donnée. La direction peut être 1 ou 1 pour indiquer la diagonale qui va du coin supérieur gauche au coin inférieur droit, ou la diagonale qui va du coin supérieur droit au coin inférieur gauche.

On écrit finalement une fonction somme(liste) qui retourne la somme des éléments d'une liste.

On peut ainsi vérifier si un carré est magique en calculant la somme de la première ligne du carré, puis en vérifiant que la somme de chaque ligne, de chaque colonne et de chaque diagonale est égale à cette somme.

def ligne(carre, index):
    return carre[index][:] # copie pour éviter une modification du carré original

def colonne(carre, index):
    col = []
    for i in range(len(carre)):
        col.append(carre[i][index])
    return col

def diagonale(carre, direction):
    diag = []
    if direction == 1:
        for i in range(len(carre)):
            diag.append(carre[i][i])
    elif direction == -1:
        for i in range(len(carre)):
            diag.append(carre[i][-1 - i])
    return diag

def somme(liste):
    total = 0
    for nombre in liste:
        total += nombre
    return total

def est_magique(carre):
    taille_carre = len(carre)
    somme_magique = somme(ligne(carre, 0))

    for i in range(taille_carre):
        # Vérifier les lignes et les colonnes
        if somme(ligne(carre, i)) != somme_magique:
            return False
        if somme(colonne(carre, i)) != somme_magique:
            return False

    # Vérifier les diagonales
    if somme(diagonale(carre, 1)) != somme_magique:
        return False
    if somme(diagonale(carre, -1)) != somme_magique:
        return False

    return True

# Quelques tests
carre_magique = [
    [16, 2, 3, 13],
    [5, 11, 10, 8],
    [9, 7, 6, 12],
    [4, 14, 15, 1]
]

carre_non_magique = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

print(est_magique(carre_magique)) # True
print(est_magique(carre_non_magique)) # False

Exercice 15

Une liste peut être utilisée pour stocker des données du monde réel. Par exemple, votre environnement de développement contient une liste représentant la population estimée de truites dans un lac de 2000 à 2024. Cette population s'est presque éteinte en 2006, mais des efforts de conservation ont permis à la population de se rétablir au fil des années. En particulier, de nouvelles techniques d'analyse de l'eau découvertes en 2012 ont permis de mieux comprendre les besoins des truites et d'améliorer les efforts de conservation.

population_truites = [
    500, 700, 800, 600, 300,     # 2000-2004
    50, 20, 90, 150, 200,        # 2005-2009
    180, 250, 350, 400, 700,     # 2010-2014
    900, 1200, 1100, 1150, 1250, # 2015-2019
    1150, 1100, 1200, 1250, 1200 # 2020-2024
]

On souhaite représenter cette population de truites à l'aide d'un diagramme à bandes comme celui ci-dessous. Vous devez écrire un programme qui utilise la tortue pour tracer les axes du diagramme et les bandes représentant la population de truites pour chaque année comme dans le diagramme ci-dessous. Vous pouvez choisir les couleurs et les dimensions du diagramme à votre guise.

20002005201020152020Annéespopulation02505007501000

Bonus : Le diagramme ci-dessus contient des titres pour les axes x et y . Vous pouvez utiliser la fonction write de la tortue pour afficher du texte à la position de la tortue. Tout comme la fonction image, la fonction write prend un second argument optionnel qui permet de spécifier la taille du texte. Si vous le souhaitez, vous pouvez même ajouter des graduation aux axes du diagramme.

Tracer un diagramme avec des axes bien dimensionnées et graduées est un problème difficile, car il faut bien aligner les éléments et ajuster leur taille en fonction des données à représenter. Il est normal que votre dession soit différent du diagramme ci-dessus, ou qu'il contienne des imperfections.

Solution

population_truites = [
    500, 700, 800, 600, 300,     # 2000-2004
    50, 20, 90, 150, 200,        # 2005-2009
    180, 250, 350, 400, 700,     # 2010-2014
    900, 1200, 1100, 1150, 1250, # 2015-2019
    1150, 1100, 1200, 1250, 1200 # 2020-2024
]

def maximum(liste):
    max_val = liste[0]
    for i in range(1, len(liste)):
        if liste[i] > max_val:
            max_val = liste[i]
    return max_val

def trait(x, y):
    fd(x, y)
    hop(); bk(x, y)

def diagramme(donnees, largeur, hauteur, couleur_bande):
    
    # Calculer les dimensions des bandes
    max_donnee = maximum(donnees)
    largeur_bande = (largeur - 5) / len(donnees)

    pencolor(couleur_bande)
    pensize(largeur_bande - 2)

    for index in range(len(donnees)):
        y = donnees[index]
        # Placer tortue au centre de la bande
        hop(); fd(largeur_bande/2)

        # Tracer la bande
        hauteur_bande = hauteur * y / max_donnee
        trait(0, hauteur_bande)

        # BONUS: graduation des années
        if index % 5 == 0:
            
            angle_graduation_x = 45
            pencolor("black")
            pensize(1)
            
            # graduation
            trait(0, -2)
            
            # valeur
            hop(); lt(angle_graduation_x); bk(8, 3)
            write(2000 + index, 0.5)
            hop(); fd(8, 3); rt(angle_graduation_x)
            
            pencolor(couleur_bande)
            pensize(largeur_bande - 2)
        # FIN DU BONUS: graduation des années
            
        # Placer la tortue à la fin de la bande
        hop(); fd(largeur_bande/2)

    hop(); bk(len(donnees) * largeur_bande)
        
    # Tracer les axes
    pencolor("black")
    pensize(1)

    # x
    distance_titre_x = 20
    fd(largeur / 2); 
    hop(); fd(0, -distance_titre_x)
    write("Années")
    hop(); bk(0, -distance_titre_x)
    fd(largeur / 2)
    image("arrowhead", 0.2); bk(largeur)

    # y 
    distance_titre_y = 25
    lt(90); fd(hauteur / 2)
    hop(); fd(0, distance_titre_y)
    write("population")
    hop(); bk(0, distance_titre_y)
    fd(hauteur / 2)
    image("arrowhead", 0.2); bk(hauteur) # y

    # BONUS: graduation des y
    graduations = 250
    nombre_graduations_y = (max_donnee // graduations)
    espaces_entre_graduations = hauteur / nombre_graduations_y
    distance_titre_y = 10

    for graduation in range(nombre_graduations_y):
        trait(0, 2)
        rt(90);
        hop(); bk(10)
        write(graduation * graduations, 0.5)
        hop(); fd(10);
        lt(90)
        hop(); fd(espaces_entre_graduations)

    # Ramener la tortue à l'origine
    bk(nombre_graduations_y * espaces_entre_graduations); rt(90)
    # FIN DU BONUS: graduation des années

clear()
hop(); bk(100, 50)
diagramme(population_truites, 200, 100, 'lightblue')
ht()

Introduction

Une chaîne de caractères, ou tout simplement chaîne, est une suite de caractères (lettres, chiffres, symboles, espaces, etc.) représentant du texte.

Les guillemets

Dans le code, une chaîne s'écrit en plaçant du texte entre des délimiteurs. Il existe une variété de délimiteurs :

  • Les apostrophes simples '...' ou guillemets "..." sont utilisés pour écrire des chaînes simples devant débuter et se terminer sur une même ligne;
  • Les apostrophes triples '''...''' ou guillemets triples """...""" sont utilisés pour écrire des chaînes sur plusieurs lignes.
texte1 = 'Bonjour'
texte2 = "Bonsoir"
texte3 = """Ceci est
un texte sur
plusieurs lignes"""

print(texte1)
print(texte2)
print(texte3)

Les chaînes sont des données de type str, un nom qui vient de l'anglais string.

Exercice 1

Écrivez un programme qui affiche les phrases suivantes :

Alice s'est rendue à son rendez-vous.
Elle a lancé un petit "Salut !" en entrant.
Bernard lui a répondu "Content de te voir, Alice !" avec un sourire.

Solution

Il y a deux façons d'afficher les phrases, de ne faire qu'un seul print avec des guillements (ou apostrophes) triples :

# Façon 1 : print multi-lignes

print("""Alice s'est rendue à son rendez-vous.
Elle a lancé un petit "Salut !" en entrant.
Bernard lui a répondu "Content de te voir, Alice !" avec un sourire.""")

Il est possible d'écrire des chaînes contenant des apostrophes et/ou des guillemets : dans ce cas, ils ne servent pas de délimiteurs. Pour y parvenir, on utilise le délimiteur opposé : si la chaîne contient des apostrophes, on choisit des guillemets, et inversement. Il est donc possible de faire plusieurs print en utilisant des guillements (ou apostrophes) simples :

# Façon 2 : plusieurs print

print("Alice s'est rendue à son rendez-vous.")
print('Elle a lancé un petit "Salut !" en entrant.')
print('Bernard lui a répondu "Content de te voir, Alice !" avec un sourire.')

Caractères d'échappement

Le texte

Il a dit : "J'ai faim!".

contient à la fois des apostrophes et des guillemets à l'intérieur de la chaîne elle-même. En affichant le contenu de cette chaîne, on devrait préserver les apostrophes et guillemets présents.

Il est nécessaire de distinguer entre les apostrophes et guillemets agissant en tant que délimiteurs de ceux ayant une présence dite littérale dans la chaîne. Pour ce faire, nous utiliserons des séquences d'échappement composées du caractère d'échappement \ et d'autres caractères tels que ' et ". Une séquence d'échappement permet d'insérer un ou des caractères de manière littérale dans la chaîne.

Voici comment afficher le texte ci-haut en utilisant un échappement :

print('Il a dit : "J\'ai faim!".')

Nous avons fait usage de la séquence d'échappement \' pour insérer un apostrophe de manière littérale. Sans l'utilisation du caractère d'échappement \, l'apostrophe aurait signifié la fin de la chaîne. Essayez de l'enlever!

On peut aussi utiliser la séquence d'échappement \" afin d'utiliser les guillements comme délimiteurs :

print("Il a dit : \"J'ai faim!\".")

Quand on utilise des triples guillemets ("""...""") ou les triples apostrophes ('''...'''), on peut inclure à l'intérieur de la chaîne des apostrophes (') et des guillemets (") sans avoir besoin d'un caractère d'échappement, tant qu'il n'y en a pas trois consécutifs.

Exercice 2

Pour chaque ligne, dire si elle est valide ou invalide :

  1. texte = "Bonjour"
  2. texte = 'Bonjour"
  3. texte = "J'aime programmer"
  4. texte = 'J'aime programmer'
  5. texte = "Il a dit : \"Salut\""
  6. texte = """
    Bonjour,
    Je m'appelle Alice.
    J'ai "39 ans".
    """

Solution

La deuxième chaîne est invalide à cause de délimiteurs incohérents.

La quatrième chaîne est invalide à cause d'une apostrophe qui casse la chaîne.

Toutes les autres chaînes sont valides.

Caractères spéciaux

Il existe plusieurs types de caractères spéciaux tels que le retour à la ligne \n, qui insère un retour à la ligne littéral, ainsi que l'antislash (backslash) \\ qui insère le caractère \ dans la chaîne. Ainsi, nous pouvons écrire le texte

Il fait
beau!

soit avec les triples guillemets

"""Il fait
beau!"""

ou de simples guillemets avec retour à la ligne

"Il fait\nbeau!"

Ces deux chaînes sont équivalentes, les triples guillemets n'étant qu'une manière plus simple d'insérer des retours à la ligne :

texte1 = """Il fait
beau!"""
texte2 = "Il fait\nbeau!"

print(texte1 == texte2) # Affiche True

Opérations de base sur les chaînes

Les chaînes ont des similarités avec les listes. Ceci se comprends car une liste c'est une séquence d'éléments et une chaîne c'est une séquence de caractères. Ainsi, plusieurs opérations sur les chaînes sont inspirées des opérations correspondantes sur les listes.

Longueur

Une chaîne a une longueur, qui est le nombre de caractères qu'elle contient. La fonction len permet d'obtenir la longueur d'une chaîne :

print(len("12345")) # 5
print(len("abc")) # 3
print(len("")) # 0

Accès par index

L'accès aux caractères d'une chaîne peut se faire en utilisant la notation d'indexation et de tranches :

texte = "abcdef"

print(texte[0])  # "a"
print(texte[-1]) # "f"

print(texte[0:2])  # "ab"
print(texte[:4])   # "abcd"
print(texte[::2])  # "ace"
print(texte[::-1]) # "fedcba"

Une différence importante entre les listes et les chaînes est que les chaînes sont immuables, c'est-à-dire qu'on ne peut pas modifier le contenu d'une chaîne. Il n'est pas possible de modifier un caractère dans une chaîne. On doit plutôt créer une nouvelle chaîne.

Ceci donnera donc une erreur :

mot = "rouge"
mot[0] = "b" # erreur

Concaténation

Nous pouvons construire des chaînes à partir d'autres chaînes en effectuant une concaténation. L'opérateur de concaténation des chaînes est l'addition (+) :

debut = "Je pense,"
fin = " donc je suis."

print(debut + fin) # "Je pense, donc je suis."

Exercice 3

Créez une chaîne contenant votre prénom, puis affichez :

  • la première lettre
  • la dernière lettre
  • la longueur du prénom
prenom = "Alice"

Solution

prenom = "Alice"

print(prenom[0])      # première lettre
print(prenom[-1])     # dernière lettre
print(len(prenom))    # longueur du prénom

Découper une chaîne

La méthode .split permet de découper une chaîne en plusieurs morceaux et de les extraire dans une liste.

Syntaxe

texte.split(separateur)
  • texte : la chaîne à découper
  • separateur : ce qui sert de marqueur pour le découpage

Si on ne donne aucun separateur, on va utiliser tous les espaces (espaces, double espaces, tabulations, retours à la ligne, ...) comme séparateur.

Exemple

texte = "\nBonjour tout le  monde,\nJ'ai 32 ans."

print(texte.split(" ")) # découper par les espaces simples

print(texte.split("o")) # découper par la lettre o

print(texte.split())    # découper par tous type d'espacement

Si dans la chaîne le séparateur est immédiatement suivi du séparateur, comme on a un double espace dans l'exemple, cela va nous créer une chaîne vide dans notre liste, car entre ces deux séparateurs, nous n'avons rien (une chaîne vide).

Exercice 4

On considère le texte

Pauline programme de mieux en mieux et plus rapidement

Écrivez un programme qui affiche le nombre de mots dans ce texte.

texte = "Pauline programme de mieux en mieux et plus rapidement"

Solution

texte = "Pauline programme de mieux en mieux et plus rapidement"

# On découpe le texte en mots
mots = texte.split(" ")

# On affiche le nombre de mots
print(len(mots))

Exercice 5

On considère le texte

Pauline programme de mieux en mieux et plus rapidement

Écrivez un programme capable d'identifier tous les mots qui commencent par la lettre p.

texte = "Pauline programme de mieux en mieux et plus rapidement"

Solution

texte = "Pauline programme de mieux en mieux et plus rapidement"

# On découpe en mots
mots = texte.split(" ")

# On filtre les mots qui commencent par "p" ou "P"
resultat = []

for i in range(len(mots)):
    mot = mots[i]
    if mot[0] == "p" or mot[0] == "P":
        resultat.append(mot)

print(resultat)

Les fichiers textuels

Lorsqu'on a beaucoup de texte à traiter il est souvent plus pratique de stocker le texte dans un fichier. On peut ensuite accéder le contenu du fichier en utilisant la fonction prédéfinie read_file(nom_du_fichier) qui retourne une chaîne correspondant au contenu du fichier. Dans cette chaîne on retrouve le caractère \n à chaque retour à la ligne dans le texte. Par exemple ce programme va compter le nombre de mots dans le fichier bateau.txt :

fichier = "bateau.txt"

contenu = read_file(fichier)

mots = contenu.split()

print("Le fichier", fichier, "contient", len(mots), "mots.")
print("Voici le contenu du fichier :")
print(contenu)
Si tu veux construire un bateau, ne rassemble pas tes hommes et femmes
pour leur donner des ordres, pour expliquer chaque détail, pour leur
dire où trouver chaque chose... Si tu veux construire un bateau, fais
naître dans le coeur de tes hommes et femmes le désir de la mer.

Exercice 6

Écrivez un programme qui lit le contenu du fichier nombres.txt contenant des nombres et qui affiche la somme de tous ces nombres.

Par exemple si le fichier nombres.txt contient :

10
50 15
5

le programme doit afficher 80.

contenu = read_file("nombres.txt")

42
7 89 13
55 21 0 100
3 18
90 44 12 6 77

Solution

Après avoir obtenu le contenu du fichier avec la fonction read_file il faut en extraire les nombres avec la méthode .split puis il faut faire la somme des nombres dans une boucle, en n'oubliant pas de convertir chaque chaîne en valeur numérique avec la fonction float.

contenu = read_file("nombres.txt")

nombres = contenu.split()

somme = 0

for i in range(len(nombres)):
    somme += float(nombres[i])

print('La somme des nombres est :', somme)
42
7 89 13
55 21 0 100
3 18
90 44 12 6 77

Joindre des chaînes

À l'inverse de .split, la méthode .join permet de construire une chaîne à partir d'une liste de chaînes. La chaîne finale sera la concaténation des chaînes de chaque chaîne de la liste à un séparateur donné.

Syntaxe

separateur.join(liste)
  • separateur : ce qu'on ajoute entre les éléments
  • liste : liste de chaînes

Exemple

mots = ["Bonjour", "tout", "le", "monde,", "j'ai", "32", "ans."]

texte = " ".join(mots) # ajoute un espace entre chaque élément
print(texte)

texte = "-".join(mots) # ajoute un tiret entre chaque élément
print(texte)

caracteres = ["B", "o", "n", "j", "o", "u", "r"]

print("".join(caracteres)) # on concatène tous les caractères ensemble

Tous les éléments doivent être des chaînes, sinon on aura une erreur :

mots = ["Bonjour", "tout", "le", "monde,", "j'ai", 32, "ans."]

texte = " ".join(mots) # ajoute un espace entre chaque élément
print(texte)

Exercice 7

image/svg+xml Le chocolat est la réponse...peu importe la question.

Écrivez un programme qui crée une liste de citations et affiche les citations dans le format, en utilisant la méthode .join :

Le crabe a dit : ...

Exemples :

Le crabe a dit : Si le plan A ne fonctionne pas, il reste 25 lettres dans l’alphabet.
Le crabe a dit : Le chocolat est la réponse... peu importe la question.

Solution

citations = [
    "Je ne suis pas paresseux, je suis en mode économie d’énergie.",
    "Si le plan A ne fonctionne pas, il reste 25 lettres dans l’alphabet.",
    "Le chocolat est la réponse... peu importe la question.",
    "L’ordinateur est incroyablement rapide, précis et stupide. L’homme est incroyablement lent, imprécis et brillant.",
    "L’ordinateur ne fait jamais d’erreurs... sauf quand il le fait.",
    "Programmer, c’est comme écrire un roman... sauf que si tu fais une faute, le lecteur ne rit pas, il pleure.",
    "Si ça ne plante pas, ce n’est pas un bug, c’est une fonctionnalité.",
    "Mon code est parfait, c’est ton ordinateur qui a un problème",
]

# On concatène avec "\nLe crabe a dit : "
texte = "\nLe crabe a dit : ".join(citations)
# Pour que la première citation est bien affiché
texte = "Le crabe a dit : " + texte

print(texte)

Exercice 8

Écrivez une fonction adn_complementaire qui transforme une séquence d'ADN (en majuscule) en sa séquence complémentaire (A T, C G).

Exemples

print(adn_complementaire("ATCG")) # "TAGC"
def adn_complementaire(seq):
    ...

print(adn_complementaire("ATCG"))

Solution

À l'aide d'une boucle on examine les caractères de la séquence d'ADN un caractère à la fois. On fait ensuite la conversion de ce caractère et on les accumule dans une seconde chaîne.

def adn_complementaire(seq):
    new_seq = ""

    for i in range(len(seq)):
        c = seq[i]
        if c == "A":
            new_seq += "T"
        elif c == "C":
            new_seq += "G"
        elif c == "G":
            new_seq += "C"
        elif c == "T":
            new_seq += "A"

    return new_seq

print(adn_complementaire("ATCG")) # "TAGC"

Majuscules et minuscules

On peut facilement transformer un texte soit en majuscules soit en minuscules avec les méthodes .upper et .lower, respectivement :

texte = "Bonjour"

print(texte.upper())
print(texte.lower())

Exercice 9

Demandez un texte à l'utilisateur et affichez :

  • "MAJUSCULES" si tout est en majuscules
  • "minuscules" si tout est en minuscules
  • "mixte" sinon

Solution

texte = input("Entrez un texte : ")

if texte == texte.upper():   # test si toutes les lettres sont en majuscules
    print("MAJUSCULES")
elif texte == texte.lower(): # test si toutes les lettres sont en minuscules
    print("minuscules")
else:
    print("mixte")

Exercice 10

<sodipodi:namedview id="base_20" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="1.3563859" inkscape:cx="213.40454" inkscape:cy="319.23069" inkscape:document-units="px" inkscape:current-layer="layer1_20" showgrid="false" fit-margin-top="0" fit-margin-left="0" fit-margin-right="0" fit-margin-bottom="0" showborder="false" inkscape:window-width="1920" inkscape:window-height="1017" inkscape:window-x="-4" inkscape:window-y="9" inkscape:window-maximized="1" /> rdf:RDF <cc:Work rdf:about=""> dc:formatimage/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> dc:title</dc:title> </cc:Work> </rdf:RDF>

Poser une question simple de oui/non (en ignorant la casse), et afficher un message différent selon la réponse.

Ignorer la casse veut dire qu'on accepte le mot peu importe s'il contient des majuscules ou minuscles, par exemple : oui, OUI, oUI, ... seront accepté.

Solution

reponse = input("Aimez-vous les crèmes glacées ?")

# On ignore la casse en convertissant en majuscules
if reponse.upper() == "OUI":
    print("Laquelle préférez-vous ?")
elif reponse.upper() == "NON":
    print("Comment cela vous n'aimez pas les crèmes glacées ?")
else:
    print("Vous n'avez pas répondu à ma question par oui ou non !")

Tester le contenu d'une chaîne

Il y a plusieurs méthodes utiles pour vérifier le type de contenu, notamment : .isalpha qui permet de vérifier si tous les caratères sont alphabétiques (si ce sont que des lettres), il va retourner True si c'est le cas. Cependant si un seul caractère (ou plus) n'est pas une lettre, il va retourner False. De manière équivalente il existe aussi ces méthodes :

Méthode Description
.isalpha() lettres seulement
.isdigit() chiffres seulement
.isalnum() lettres et chiffres seulement
.islower() toutes les lettres sont des minuscules
.isupper() toutes les lettres sont des majuscules
texte = "adam123"

print(texte.isalpha())  # lettres seulement
print(texte.isdigit())  # chiffres seulement
print(texte.isalnum())  # lettres et chiffres seulement
print(texte.islower())  # toutes les lettres sont des minuscules
print(texte.isupper())  # toutes les lettres sont des majuscules

Exercice 11

Écrivez une fonction compter_lettres qui compte le nombre de lettres dans une chaîne (ignore les espaces et chiffres).

Exemples

print(compter_lettres("abc 123")) # 3
print(compter_lettres("Bonjour tout le monde!"))  # 18
def compter_lettres(texte):
    ...

print(compter_lettres("abc 123"))
print(compter_lettres("Bonjour tout le monde!"))

Solution

def compter_lettres(texte):
    total = 0
    for i in range(len(texte)):
        # on regarde si le caractère est une lettre, si c'est
        # le cas on augmente notre compteur
        if texte[i].isalpha():
            total += 1
    return total

print(compter_lettres("abc 123")) # 3
print(compter_lettres("Bonjour tout le monde!"))  # 18

Conversion en chaîne

La fonction str permet de convertir un nombre en chaîne :

age = 25
texte = "J'ai " + str(age) + " ans"
print(texte)

mots = ["Bonjour", "tout", "le", "monde,", "j'ai", 32, "ans."]
mots[5] = str(mots[5])
texte = " ".join(mots) # ajoute un espace entre chaque élément
print(texte)

F-string

Outre la conversion classique via la fonction str, il existe une façon plus élégante et concise pour intégrer des variables ou des expressions au sein d'une chaîne : les f-strings (ou chaînes formatées).

Une f-string se définit en préfixant le délimiteur de la chaîne par la lettre f ou F. On peut alors insérer une variable ou un calcul directement à l'intérieur de la chaîne en utilisant des accolades { }.

Voici comment simplifier l'assemblage de texte et de variables :

age = 25

# Concaténation classique (nécessite str)
texte1 = "J'ai " + str(age) + " ans"

# Utilisation des f-strings
texte2 = f"J'ai {age} ans"
texte3 = f"J'ai {25} ans"
texte4 = F'J\'ai {20 + 5} ans'

print(texte1 == texte2) # Affiche True
print(texte1 == texte3) # Affiche True
print(texte1 == texte4) # Affiche True

Dans cet exemple, les accolades agissent comme des balises d'insertion : Le code situé entre { et } est évalué et injecté dans la chaîne.

Pour obtenir une accolade littérale, lorsqu'on utilise des f-strings, il faut doubler le caractère ({{ ou }}). On distingue ainsi l'accolade utilisée pour le formatage de celle ayant une présence textuelle.

Exercice 12

Écrivez une fonction quiz_multiplication(a, b) qui prend deux nombres en paramètre, puis demande à l'utilisateur le résultat de leur multiplication.

La fonction doit ensuite indiquer si la réponse est correcte ou non, et afficher la bonne réponse, en utilisant des f-strings.

Solution

def quiz_multiplication(a, b):

    reponse = int(input(f"Combien font {a} * {b} ? "))

    bon = a * b

    if reponse == bon:
        print("Correct !")
    else:
        print("Incorrect.")
        print(f"La bonne réponse était {a} * {b} = {bon}, et non {reponse}.")

quiz_multiplication(3, 4)

Résumé

Contrairement aux listes (type list), les chaînes de caractères (type str) sont immuables. Les méthodes ci-dessous ne modifient jamais la chaîne originale, elles en retournent une nouvelle.

Manipulation et transformation.

Méthode / Syntaxe Description Exemple
len(s) Le nombre de caractères dans la chaîne *s* len("Chat")4
s[i] Accède au caractère à l'index i "abc"[0]"a"
s1 + s2 Concatène deux chaînes "A" + "B""AB"
s.split(sep) Découpe la chaîne en liste selon un séparateur "1,2".split(",")["1", "2"]
sep.join(liste) Joint une liste de chaînes avec un séparateur "-".join(["A", "B"])"A-B"
s.upper() / s.lower() Met tout en majuscules ou en minuscules "Ab".upper()"AB"

Tests et vérifications.

Méthode Description Résultat pour s="Ab1"
s.isalpha() True si uniquement des lettres False (contient 1)
s.isdigit() True si uniquement des chiffres False (contient A)
s.isalnum() True si lettres ou chiffres (pas de symboles) True
s.isupper() True si toutes les lettres sont des majuscules False
s.islower() True si toutes les lettres sont des minuscules False

Formatage et échappement.

Syntaxe Usage Exemple
f"{var}" f-string : Insère une variable ou un calcul f"2+2={2+2}""2+2=4"
\' ou \" Insère un guillemet littéral sans fermer la chaîne 'D\'accord'"D'accord"
\n Insère un retour à la ligne "A\nB"
\\ Insère un antislash littéral "C:\\"
{{ / }} Affiche une accolade littérale dans une f-string f"{{x}}""{x}"

Les tranches (Slices).

Les tranches fonctionnent aussi sur les chaînes (type str), similairement aux listes (type list).

Syntaxe Description Résultat pour s="abcdef"
s[0:3] Caractères de l'index 0 à 2 "abc"
s[:4] Du début jusqu'à l'index 3 "abcd"
s[2:] De l'index 2 jusqu'à la fin "cdef"
s[::-1] Inverse la chaîne complète "fedcba"

Exercice 13

Écrivez une fonction contient_voyelle(chaine) qui retourne True si la chaîne contient au moins une voyelle (a, e, i, o, u, y) et False sinon. La fonction doit être insensible à la casse (majuscules/minuscules).

Exemples

print(contient_voyelle("Bonjour"))  # True
print(contient_voyelle("psst"))     # False

Solution

On peut procéder caractère par caractère et vérifier si le caractère est dans la liste des voyelles.

def contient_voyelle(chaine):

    # On parcourt chaque caractère de la chaîne
    for i in range(len(chaine)):
        c = chaine[i].upper()
        if c=="A" or c=="E" or c=="I" or c=="O" or c=="U" or c=="Y":
            # Dès qu'on trouve une voyelle, on peut retourner True
            return True

    # Si aucune voyelle n'a été trouvée, on retourne False
    return False

print(contient_voyelle("Bonjour"))  # True
print(contient_voyelle("psst"))     # False
print(contient_voyelle("EVE"))      # True

Exercice 14

Écrivez un programme pour composer une liste de courses.

  • Demander le nom et la quantité des articles jusqu'à ce que l'utilisateur entre une ligne vide.
  • À la fin, afficher la liste complète.

Solution

liste_courses = []

while True:
    article = input("Article à ajouter ? (ou entrée vide pour arrêter) ")
    if article == "":
        break
    quantite = input(f"Quelle quantité de {article} ? ")
    liste_courses.append([article, quantite])

print("\nVotre liste de courses :")
for i in range(len(liste_courses)):
    print(f"article {i+1}/{len(liste_courses)} : {liste_courses[i][1]}"+
          f" de {liste_courses[i][0]}")

Exercice 15

Écrivez une fonction frequence_lettres(texte) qui retourne le nombre de fois que chaque lettre apparaît dans un texte.

Exemples

print(frequence_lettres("un ananas hawaien"))

Doit afficher :

[5, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 4, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0]

Solution

alphabet = "abcdefghijklmnopqrstuvwxyz"

def indice_lettre(lettre):
    # permet de déterminer l'indice d'une lettre (a=0, b=1, ...)
    for i in range(len(alphabet)):
        if alphabet[i] == lettre:
            return i

def frequence_lettres(texte):
    freq = [0] * len(alphabet)
    for j in range(len(texte)):
        c = texte[j]
        if c.isalpha():
            c = c.lower()
            freq[indice_lettre(c)] += 1

    return freq

print(frequence_lettres("un ananas hawaien"))

L'affichage de la fréquence des lettres sous forme d'une liste de nombres n'est pas idéal car il est difficile de comprendre rapidement quelle lettres sont les plus fréquentes.

Si on remplace l'appel final de print par la fonction prédéfinie chart, les fréquences seront affichées sous la forme d'un diagramme à barres permettant de voir plus aisément que les lettres a (index=0) et n (index=13) sont de loin les plus fréquentes.

alphabet = "abcdefghijklmnopqrstuvwxyz"

def indice_lettre(lettre):
    # permet de déterminer l'indice d'une lettre (a=0, b=1, ...)
    for i in range(len(alphabet)):
        if alphabet[i] == lettre:
            return i

def frequence_lettres(texte):
    freq = [0] * len(alphabet)
    for j in range(len(texte)):
        c = texte[j]
        if c.isalpha():
            c = c.lower()
            freq[indice_lettre(c)] += 1

    return freq

chart(frequence_lettres("un ananas hawaien"))

Exercice 16

Écrivez une fonction dessin_images(instructions) qui prend en entrée une chaîne contenant des instructions. Chaque instruction est constituée d'une couleur et d'une image à afficher, séparés par un espace. Les différentes instructions sont séparées par une virgule suivie d'un espace (, ). Par exemple, les instructions suivantes :

red crab, blue rocket, green star

doivent afficher les images correspondantes (avec un facteur de 0.5), chacune dans la couleur spécifiée, à une distance de 50px les unes des autres et centré sur l'image du milieu.

Ainsi, pour les instructions ci-dessus, le résultat attendu serait :

Solution

def dessin_images(instructions):
    clear()
    list_instructions = instructions.split(", ") # Récupère chaque instruction
    hop(); bk(50*((len(list_instructions)-1) / 2)) # on centre les images

    for i in range(len(list_instructions)):  # Pour chaque instruction
        instruction = list_instructions[i]
        arguments = instruction.split(" ") # on recupère la couleur et l'image
        pencolor(arguments[0])     # la couleur
        image(arguments[1], 0.5)   # l'image à dessiner
        hop(); fd(50)

dessin_images("red crab, blue rocket, green star")

Exercice 17

Écrivez une fonction verifier_mot_de_passe qui vérifie qu'un mot de passe :

  • contient au moins 8 caractères
  • contient au moins 2 lettre
  • contient au moins 3 chiffre
  • contient au moins une majuscule
  • contient un caractère special (qui n'est pas un tiret)
  • ne contient pas d'espace

Exemples

print(verifier_mot_de_passe("Secret")) # False
print(verifier_mot_de_passe("Secret123!")) # Vrai

Solution

def verifier_mot_de_passe(mdp):

    # des compteurs de classes de caractères
    num_lettre = 0
    num_chiffre = 0
    num_majuscule = 0
    num_special = 0

    # on regarde quel type de caractère il s'agit, pour augmenter son compteur
    for i in range(len(mdp)):
        c = mdp[i]
        if c.isalpha():
            num_lettre +=1
            if c.isupper():
                num_majuscule += 1
        elif c.isdigit():
            num_chiffre += 1
        elif c != "-":
            num_special += 1
        elif c == " ":
            return False

    # verifie toutes les contraintes (autre que les espaces)
    return (len(mdp) >= 8 and num_lettre >= 2 and num_chiffre >= 3 and
            num_majuscule >= 1 and num_special == 1)

mdp = input("Mot de passe : ")

if verifier_mot_de_passe(mdp):
    print("Valide")
else:
    print("Invalide")

Exercice 18

Écrivez une fonction afficher_calendrier(nombre_de_jours, jour_de_la_semaine) qui va afficher un calendrier d'un mois ayant un certain nombre de jours et dont le premier jour est un certain jour de la semaine. Le paramètre jour_de_la_semaine est un nombre de 0 à 6, avec 0 qui signifie lundi, 1 signifie mardi, ...

Le format ci-dessous doit être respecté pour que toutes les colonnes soient bien alignées. Les jours de la semaine en entête sont des abbréviations de 3 lettres.

L'appel de fonction afficher_calendrier(31, 4) doit donc afficher :

+-----+-----+-----+-----+-----+-----+-----+
| Lun | Mar | Mer | Jeu | Ven | Sam | Dim |
+-----+-----+-----+-----+-----+-----+-----+
|     |     |     |     | 1   | 2   | 3   |
+-----+-----+-----+-----+-----+-----+-----+
| 4   | 5   | 6   | 7   | 8   | 9   | 10  |
+-----+-----+-----+-----+-----+-----+-----+
| 11  | 12  | 13  | 14  | 15  | 16  | 17  |
+-----+-----+-----+-----+-----+-----+-----+
| 18  | 19  | 20  | 21  | 22  | 23  | 24  |
+-----+-----+-----+-----+-----+-----+-----+
| 25  | 26  | 27  | 28  | 29  | 30  | 31  |
+-----+-----+-----+-----+-----+-----+-----+

Solution

def separateur():
    print("+-----+-----+-----+-----+-----+-----+-----+")

def afficher_calendrier(nombre_de_jours, jour_de_la_semaine):

    jour = 1 - jour_de_la_semaine

    separateur()

    print("| Lun | Mar | Mer | Jeu | Ven | Sam | Dim |")

    separateur()

    while jour <= nombre_de_jours:
        rangee = "|"
        for colonne in range(7):
            if jour < 1 or jour > nombre_de_jours:
                rangee += "     |"
            elif jour <= 9:
                rangee += " " + str(jour) + "   |"
            else:
                rangee += " " + str(jour) + "  |"
            jour += 1
        print(rangee)
        separateur()

afficher_calendrier(31, 4)

Introduction

villepayslatitudelongitudepopulation
1DelhiInde28.660077.230029617000
2MiamiÉtats-Unis25.7839-80.21026445545
3ParisFrance48.85662.352211020000
4PerthAustralie-31.9522115.85892059484
5SeoulCorée du sud37.5600126.990021794000
6TokyoJapon35.6897139.692237977000

Les données traitées par les programmes et les résultats produits par les programmes sont souvent stockées dans des fichiers. Cela permet de les organiser et les entreposer afin de les consulter à nouveau dans le futur.

Chaque fichier a un nom dans le format nom_du_fichier.ext, où ext désigne le type du fichier. Il existe de nombreux types importants :

  • Les fichiers texte, contenu textuel sans format précis (.txt)
  • Les fichiers d'images, contenant des images (.png, .jpg, ...)
  • Les fichiers vidéos, contenant des vidéos (.mp4, .avi, ...)
  • Les fichiers de code, contenant du code (.py, .java, ...)
  • Les fichiers CSV, données structurées en grille comme ci-dessus (.csv)
  • etc.

Dans ce chapitre, nous allons nous pencher sur le format CSV (Comma-Separated Values) qui permet de stocker des grilles de données sous forme textuelle.

Chaque ligne d'un fichier CSV correspond à une rangée de la grille, les colonnes sont séparées par des séparateurs (généralement des virgules), et les lignes sont séparées par des retours à la ligne (caractère \n).

Voici un exemple d'un fichier CSV contenant une liste de grandes villes du monde, le pays qui les contient, leur position (latitude et longitude) et leur population :

ville,pays,latitude,longitude,population
Delhi,Inde,28.6600,77.2300,29617000
Miami,États-Unis,25.7839,-80.2102,6445545
Paris,France,48.8566,2.3522,11020000
Perth,Australie,-31.9522,115.8589,2059484
Seoul,Corée du sud,37.5600,126.9900,21794000
Tokyo,Japon,35.6897,139.6922,37977000

Ce fichier CSV a une première ligne spéciale appelée en-tête qui contient le nom de chaque colonne. C'est une bonne pratique d'avoir une en-tête, pour bien comprendre ce que chaque colonne représente. Cependant, certains fichiers CSV n'en ont pas, ce qui fait que la première ligne contient des données.

Lire un fichier

On a vu qu'on peut accéder au contenu d'un fichier avec la fonction read_file(nom_du_fichier) qui retourne tout le contenu du fichier sous forme d'une chaîne de caractères.

Pour lire les données d'un fichier CSV il y a la fonction read_csv_file(nom_du_fichier_CSV). La valeur retournée sera une liste de liste de chaîne de caractères. Chaque chaîne de caractères correspond au contenu d'une des cellules de la grille et chaque liste dans la liste principale est une des rangées de la grille.

donnees = read_csv_file("personnes.csv")

for rangee in donnees:
    print(rangee)
nom,age,ville
Alice,25,Paris
Bob,30,Islamabad
Charlie,22,Tehran
David,28,Vancouver
Eve,35,Kharkiv

Bien que la colonne d'age correspond à une valeur numérique, les données lues seront toujours des chaînes de caractères.

On peut ignorer l'en-tête d'un fichier CSV en utilisant la notation des tranches :

donnees = read_csv_file("personnes.csv")

for rangee in donnees[1:]:  # ignorer l'en-tête
    print(rangee)
nom,age,ville
Alice,25,Paris
Bob,30,Islamabad
Charlie,22,Tehran
David,28,Vancouver
Eve,35,Kharkiv

Exercice 1

Écrivez un programme qui affiche uniquement la première colonne d’un fichier CSV nommé dino.csv contenant des données sur des dinosaures.


nom,type,taille
Tyrannosaurus Rex,Carnivore,12
Triceratops,Herbivore,9
Velociraptor,Carnivore,2
Brachiosaurus,Herbivore,22
Stegosaurus,Herbivore,7

Solution

# Lecture du CSV
donnees = read_csv_file("dino.csv")

# Affichage de la première colonne
for rangee in donnees:
    print(rangee[0])
nom,type,taille
Tyrannosaurus Rex,Carnivore,12
Triceratops,Herbivore,9
Velociraptor,Carnivore,2
Brachiosaurus,Herbivore,22
Stegosaurus,Herbivore,7

Exercice 2

Écrivez une fonction converti_type_colonne qui transforme le type d’une colonne dans un fichier CSV.

Pour ensuite, convertir la colonne age en nombre entier (int) et la colonne salaire en nombre flottant (float).

def converti_type_colonne(grille, index_col, new_type):
    ...

...
nom,age,salaire
Alice,25,3000.5
Bob,30,4000
Charlie,22,2500

Solution

def converti_type_colonne(grille, index_col, convertir):
    # on separe l'en-tête du reste
    entete = grille[0]
    rangees = grille[1:]

    for rangee in rangees:
        # pour chaque rangee, transformer l'element dans
        # la colonne selectionne
        rangee[index_col] = convertir(rangee[index_col])
    return [entete] + rangees

grille = read_csv_file("salaires.csv")

# Convertir l'âge en int
grille = converti_type_colonne(grille, 1, int)

# Convertir le salaire en float
grille = converti_type_colonne(grille, 2, float)

for rangee in grille:
    print(rangee)
nom,age,salaire
Alice,25,3000.5
Bob,30,4000
Charlie,22,2500

Exercice 3

Les fichiers CSV peuvent aussi se retrouver sur le Web. Par exemple, une liste des villes du monde avec une population de plus de 50 000 habitants est disponible à cette adresse Web :

https://raw.githubusercontent.com/codeboot-org/data/main/geoloc/villes.csv

Les fonctions read_file et read_csv_file peuvent lire directement ces fichiers simplement en précisant leur adresse Web.

Écrivez un programme qui affiche toutes les villes du Canada qui ont plus de 50 000 habitants, et la population de ces villes.

villes = read_csv_file("https://raw.githubusercontent.com/codeboot-org/data/main/geoloc/villes.csv")

...

Solution

villes = read_csv_file("https://raw.githubusercontent.com/codeboot-org/data/main/geoloc/villes.csv")

for rangee in villes[1:]:
    ville = rangee[0]
    pays = rangee[1]
    population = rangee[4]
    if pays == "Canada":
        print(f"{ville} a une population de {population} habitants")

Exercice 4

Écrivez un programme qui fait l'affichage de chaque personne dans le fichier CSV personnes.csv et qui indique le pays de résidence. Cela doit se faire en combinant les données du fichier CSV personnes.csv avec les données du fichier CSV de l'exercice précédent.

personnes = read_csv_file("personnes.csv")

villes = read_csv_file("https://raw.githubusercontent.com/codeboot-org/data/main/geoloc/villes.csv")

...
nom,age,ville
Alice,25,Paris
Bob,30,Islamabad
Charlie,22,Tehran
David,28,Vancouver
Eve,35,Kharkiv

Solution

personnes = read_csv_file("personnes.csv")

villes = read_csv_file("https://raw.githubusercontent.com/codeboot-org/data/main/geoloc/villes.csv")

def trouver_pays(ville):
    for rangee in villes[1:]:
        if rangee[0] == ville:
            return rangee[1]
    return "inconnu"

for rangee in personnes[1:]:
    nom = rangee[0]
    ville = rangee[2]
    pays = trouver_pays(ville)
    print(f"le pays de résidence de {nom} est {pays}")
nom,age,ville
Alice,25,Paris
Bob,30,Islamabad
Charlie,22,Tehran
David,28,Vancouver
Eve,35,Kharkiv

Écrire dans un fichier

La fonction prédéfinie write_file(nom_du_fichier,contenu) permet de créer des fichiers avec un certain contenu textuel (une chaîne de caractères). Cette fonction va soit créer le fichier s'il n'existe pas, ou va remplacer le contenu du fichier s'il existe.

Voici un exemple :

texte = "La princesse et\nla grenouille furent\nheureux pour toujours!\n"

write_file("roman.txt", texte)

print(read_file("roman.txt"))  # afficher le contenu du fichier créé

Similairement, la fonction prédéfinie write_csv_file(nom_du_fichier_CSV,contenu) permet de créer des fichiers CSV avec un certain contenu sous forme de grille (une liste de liste de chaînes de caractères).

Voici un exemple :

grille = [
    ["nom", "prenom", "age"],
    ["Alice", "Dupont", "30"],
    ["Bob", "Martin", "25"]
]

write_csv_file("personnes.csv", grille)

print(read_file("personnes.csv"))  # afficher le contenu du fichier créé

Graphique

0123index0102030value

La fonction prédéfinie chart permet d'afficher des données sous forme graphique.

Lorsque le paramètre de la fonction chart est une liste de nombres les données seront affichées sous la forme d'un diagramme à barres :

donnees = [10, 20, 15, 30]

chart(donnees)

Courbe

4681012141618x0510152025y

Lorsque le paramètre de la fonction chart est une liste de paires de 2 nombres, on obtiendra plutôt une courbe où chaque paire de nombres représente un point (x,y) sur le plan cartésien :

donnees = [[3, 10], [4, 15], [7, 5], [8, 18], [19, 25]]

chart(donnees)

Comme la fonction prend une liste en paramètre, on peut faire ce même graphique à partir des données lues d’un fichier CSV :

donnees = read_csv_file("donnees.csv")

chart(donnees)
temps,valeur
3,10
4,15
7,5
8,18
19,25

Comme on le voit dans ce dernier exemple, la fonction chart est assez intelligente pour reconnaître quand la première rangee est une en-tête. Les noms dans l'en-tête détermineront les noms des axes horizontal et vertical.

Options

ABCLettre010515ValeurvaleurMes données

On peut personnaliser le graphique avec différentes options passées en paramètre à la fonction chart :

  • mark=type : type de graphique ("line", "bar", ...)
  • x_axis=nom : nom de l’axe horizontal
  • y_axis=nom : nom de l’axe vertical
  • x_type="nominal" : indique que les valeurs de l’axe des X sont des chaînes de caractères, au lieu de valeurs numériques continues
  • legend=titre : titre de la légende
donnees = [
    ["lettre", "valeur"],
    ["A", 10],
    ["B", 15],
    ["C", 12]
]

chart(donnees,
      mark="line",
      x_axis="Lettre",
      x_type="nominal",
      y_axis="Valeur",
      legend="Mes données")

Exercice 5

12345jour0204060valeurtemperaturehumiditeDonnées Environnementales

Écrivez un programme qui affiche un seul graphique combinant la température et l’humidité.


jour,temperature,humidite
1,20,55
2,22,50
3,19,60
4,23,52
5,21,58

Solution

grille = read_csv_file("temp_hum.csv")

chart(grille, mark="line", x_axis="jour", y_axis="valeur",
      legend="Données Environnementales")
jour,temperature,humidite
1,20,55
2,22,50
3,19,60
4,23,52
5,21,58

Exercice 6

12345index0102030value

Écrivez un programme qui affiche un diagramme à barres des âges des personnes dans le CSV.


nom,age,ville
Alice,25,Paris
Bob,30,Islamabad
Charlie,22,Tehran
David,28,Vancouver
Eve,35,Kharkiv

Solution

def obtenir_colonne(grille, id_colonne):
    donnees = []

    for rangee in grille:
        donnees.append(rangee[id_colonne])

    return donnees

donnees = read_csv_file("personnes.csv")
chart(obtenir_colonne(donnees, 1), mark="bar")
nom,age,ville
Alice,25,Paris
Bob,30,Islamabad
Charlie,22,Tehran
David,28,Vancouver
Eve,35,Kharkiv

Résumé

Les fichiers textuels et CSV.

Méthode / Syntaxe Description Exemple
read_file(nom_du_fichier) Lit le contenu complet d'un fichier textuel contenu = read_file("roman.txt")
read_csv_file(nom_du_fichier_CSV) Lit un fichier CSV et retourne une liste de liste de chaînes de caractères grille = read_csv_file("donnees.csv")
write_file(nom_du_fichierchaîne) Écrit une chaîne dans un fichier write_file("sortie.txt", texte)
write_csv_file(nom_du_fichier_CSVliste) Écrit une liste de liste de chaînes de caractères dans un fichier write_csv_file("resultats.csv", grille)

Les graphiques.

Méthode / Syntaxe Description Exemple
chart(donneesoptions) Crée un graphique à partir de donnees chart([1853], mark="line")
Options Description
mark=type Type de graphique : "line", "bar", ...
x_axis=nom Nom de l’axe horizontal
y_axis=nom Nom de l’axe vertical
x_type="nominal" Signifie qu'il y a des noms (chaînes) sur l’axe des X
legend=titre Titre de la légende

Exercice 7

Écrivez un programme qui affiche uniquement les personnes de plus de 25 ans.


nom,age,ville
Alice,25,Paris
Bob,30,Islamabad
Charlie,22,Tehran
David,28,Vancouver
Eve,35,Kharkiv

Solution

donnees = read_csv_file("personnes.csv")
entete = donnees[0]
rangees = donnees[1:]

filtered = []
for rangee in rangees:
    if int(rangee[1]) > 25:
        filtered.append(rangee)
csv_result = [entete] + filtered

write_csv_file("personnes_plus_25.csv", csv_result)

for rangee in filtered:
    print(rangee)
nom,age,ville
Alice,25,Paris
Bob,30,Islamabad
Charlie,22,Tehran
David,28,Vancouver
Eve,35,Kharkiv

Exercice 8

Écrivez un programme qui affiche la ville la plus peuplée de Cuba et sa population.

Utilisez cette liste de villes :

https://raw.githubusercontent.com/codeboot-org/data/main/geoloc/villes.csv

villes = read_csv_file("https://raw.githubusercontent.com/codeboot-org/data/main/geoloc/villes.csv")

...

Solution

villes = read_csv_file("https://raw.githubusercontent.com/codeboot-org/data/main/geoloc/villes.csv")

max_ville = None
max_pop = 0

for rangee in villes[1:]:
    ville = rangee[0]
    pays = rangee[1]
    population = int(rangee[4])

    if pays == "Cuba":
        if population > max_pop:
            max_pop = population
            max_ville = ville

print(f"Ville la plus peuplée du Cuba est {max_ville} avec {max_pop} habitants.")

Exercice 9

Écrivez un programme qui lit un fichier CSV contenant des concentrations et volumes, et calcule la molarité.


solution,volume_ml,moles
A,50,0.01
B,75,0.015
C,100,0.02
D,60,0.012
E,80,0.018

Solution

grille = read_csv_file("chimie.csv")

def converti_type_colonne(grille, index_col, convertir):
    # on separe l'en-tete du reste
    entete = grille[0]
    rangees = grille[1:]

    for rangee in rangees:
        # pour chaque rangee on va transformer l'element dans la colonne selectionne
        rangee[index_col] = convertir(rangee[index_col])
    return [entete] + rangees

grille = converti_type_colonne(grille, 1, float)
grille = converti_type_colonne(grille, 2, float)

csv_molarity = [["solution","molarite"]]
for rangee in grille[1:]:
    volume_l = rangee[1]/1000
    molarite = rangee[2]/volume_l
    csv_molarity.append([rangee[0], str(round(molarite,2))])

write_csv_file("chimie_molarite.csv", csv_molarity)
solution,volume_ml,moles
A,50,0.01
B,75,0.015
C,100,0.02
D,60,0.012
E,80,0.018

Exercice 10

2,018.02,018.52,019.02,019.52,020.02,020.52,021.02,021.52,022.0annee020406080100populationlapinrenardaigleEspèces

Écrivez un programme qui lit un fichier CSV contenant les populations d'espèces sur plusieurs années et crée un graphique de tendance.


annee,lapin,renard,aigle
2018,90,30,10
2019,95,25,5
2020,60,20,7
2021,45,25,7
2022,47,35,9

Solution

donnees = read_csv_file("biologie.csv")

# Création d'un graphique linéaire pour toutes les espèces
chart(donnees,
      mark="line",
      x_axis="annee",
      y_axis="population",
      legend="Espèces")
annee,lapin,renard,aigle
2018,90,30,10
2019,95,25,5
2020,60,20,7
2021,45,25,7
2022,47,35,9

Exercice 11

0.00.51.01.52.02.53.03.54.04.55.0temps en seconde0246810position en metre

Écrivez un programme qui lit un fichier CSV contenant temps et position, qui calcule la vitesse moyenne et qui affiche un graphique qui indique la position en fonction du temps.


temps_s,position_m
0,0
1,2
2,4.1
3,6.2
4,8.5
5,10.1

Solution

def converti_extraire_colonne(grille, index_col, convertir):
    rangees = []
    for rangee in grille[1:]:
        rangees.append(convertir(rangee[index_col]))
    return rangees

grille = read_csv_file("physique.csv")

# Extraire colonnes converties en float
temps = converti_extraire_colonne(grille, 0, float)
position = converti_extraire_colonne(grille, 1, float)

# Calcul de la vitesse moyenne
vitesse_moyenne = round((position[-1] - position[0]) / (temps[-1] - temps[0]), 2)
print(f"Vitesse moyenne: {vitesse_moyenne}m/s")

chart(grille,
      mark="line",
      x_axis="temps en seconde",
      y_axis="position en metre")
temps_s,position_m
0,0
1,2
2,4.1
3,6.2
4,8.5
5,10.1

Exercice 12

bonjourlemondeestbeauàtouscodeamusantmot0123frequence

Écrivez un programme qui calcule la fréquence des mots d'un fichier texte, en enlevant les signes de ponctuations : .,!?;. Le programme doit afficher un diagramme à barres de la fréquence, et sauvegarder le résultat dans un fichier CSV.

Utilisez ce texte :


Bonjour le monde. Le monde est beau. Bonjour à tous. Le code est amusant.

Solution

def enleve_caracteres_speciaux(mot):
    # Supprime les caractères ponctuation
    for c in [".", ",", "!", "?", ";"]:
        mot = mot.replace(c, "")
    return mot.lower() # met tout en minuscule pour uniformiser

def indice_mot(liste_mots, mot):
    # permet de déterminer l'indice du mot et s'il n'existe pas retour -1
    for i in range(len(liste_mots)):
        if liste_mots[i] == mot:
            return i
    return -1

def converti_type_colonne(grille, index_col, convertir):
    # on separe l'en-tete du reste
    entete = grille[0]
    rangees = grille[1:]

    for rangee in rangees:
        # pour chaque rangee on va transformer l'element dans la colonne selectionne
        rangee[index_col] = convertir(rangee[index_col])
    return [entete] + rangees

texte = read_file("texte.txt")
mots = texte.split()

# Comptage manuel
liste_mots = []
frequences = []

for mot in mots:
    mot = enleve_caracteres_speciaux(mot)
    index = indice_mot(liste_mots, mot)

    if index == -1:
        # c'est la premiere fois qu'on voit le mot:
        # ajoute le mot et le conteur a notre liste csv
        frequences.append([mot, 1])
        liste_mots.append(mot)
    else:
        # ajout 1 au conteur du mot
        frequences[index][1] += 1

grille = [["mot","frequence"]] # notre en-tete
grille += frequences

# Graphique
chart(converti_type_colonne(grille, 1, str), mark="bar", x_type="nominal")

# Sauvegarde CSV
grille = converti_type_colonne(grille, 1, str)
write_csv_file("freq_mots.csv", grille)
Bonjour le monde. Le monde est beau. Bonjour à tous. Le code est amusant.

Exercice 13

FEDCBAA+grade0.00.51.01.52.0compte

Écrivez un programme qui lit un fichier de notes, calcule la moyenne et l'écart-type, et attribue un grade et affiche un graphique de la distribution des grades.

Voici le tableau des grades :

Grade Note Minimum Note Maximum
A+ 91 100
A 81 90
B 74 80
C 65 73
D 59 64
E 50 58
F 0 49
liste_grades = ["F", "E", "D", "C", "B", "A", "A+"]

nom,note
Alice,78
Bob,45
Charlie,60
David,92
Eve,55
Frank,37
Grace,88

Solution

def converti_extraire_colonne(grille, index_col, convertir):
    rangees = []
    for rangee in grille[1:]:
        rangees.append(convertir(rangee[index_col]))
    return rangees

def grade(note):
    # Fonction pour attribuer un grade
    if note < 50:
        return "F"
    elif note <= 58:
        return "E"
    elif note <= 64:
        return "D"
    elif note <= 73:
        return "C"
    elif note <= 80:
        return "B"
    elif note <= 90:
        return "A"
    return "A+"

def ajoute_colonne(grille, nom_colonne, valeur_default):
    for index in range(len(grille)):
        valeur = valeur_default
        if index == 0:
            valeur = nom_colonne
        grille[index].append(valeur)

def indice_grade(frequences_grades, mot):
    # permet de déterminer l'indice du mot et s'il n'existe pas retour -1
    for i in range(len(frequences_grades)):
        if frequences_grades[i][0] == mot:
            return i
    return None

def converti_type_colonne(grille, index_col, convertir):
    # on separe l'en-tete du reste
    entete = grille[0]
    rangees = grille[1:]

    for rangee in rangees:
        # pour chaque rangee on va transformer l'element dans la colonne selectionne
        rangee[index_col] = convertir(rangee[index_col])
    return [entete] + rangees

grille = read_csv_file("notes.csv")
notes = converti_extraire_colonne(grille, 1, int)

# Calcul des statistiques
moyenne = sum(notes)/len(notes)
sum_ecart_type = 0
for n in notes:
    sum_ecart_type += (n - moyenne)**2
ecart_type = math.sqrt(sum_ecart_type/len(notes))
print("Moyenne:", round(moyenne,2))
print("Écart-type:", round(ecart_type,2))


# Ajouter une colonne "grade"
ajoute_colonne(grille, "grade", 0)

# Et comptage des fréquences des grades
frequences_grades = [["F", 0], ["E",  0], ["D",  0], ["C",  0], ["B",  0], ["A",  0], ["A+", 0]]
for index in range(1, len(grille)): # on ne parcours pas l'en-tete
    g = grade(notes[index-1])
    grille[index][-1] = g # on ajoute le grade à la note associé
    index_g = indice_grade(frequences_grades, g)

    frequences_grades[index_g][1] += 1 # ajout 1 au conteur du grade

# Sauvegarde CSV
write_csv_file("notes_graded.csv", grille)

frequences_grades = [["Grade", "Nombre"]] + frequences_grades

# Graphique des grades
chart(converti_type_colonne(frequences_grades,1,str), mark="bar", x_axis="grade", x_type="nominal", y_axis="compte")
nom,note
Alice,78
Bob,45
Charlie,60
David,92
Eve,55
Frank,37
Grace,88

Exercice 14

Un supermarché enregistre les achats de ses clients dans un fichier CSV. Chaque rangee correspond à un produit acheté par un client.

Le magasin possède aussi un deuxième fichier contenant le prix d'achat des produits (combien le magasin paye ses fournisseurs).

Le directeur veut analyser :

  1. le montant moyen d’un panier client
  2. le produit le plus acheté
  3. le profit total du magasin

Il vous faut donc afficher ces différents éléments.

client,produit,prix_vente
Alice,Pomme,2
Alice,Banane,1
Bob,Pomme,2
Bob,Pomme,2
Charlie,Banane,1
Charlie,Orange,3
produit,prix_achat
Pomme,1
Banane,0.5
Orange,2

Solution


def prix_produit(achats, produit):
    # permet de déterminer le prix du produit
    for achat in achats:
        if achat[0] == produit:
            return float(achat[1])

def obtient_indice(liste_mot, mot):
    # permet de déterminer l'indice du mot et s'il n'existe pas retour -1
    for i in range(len(liste_mot)):
        if liste_mot[i][0] == mot:
            return i
    return -1

ventes = read_csv_file("ventes.csv")
achats = read_csv_file("prix_achat.csv")

# Total par client
total_clients = []

# Comptage produits
compte_produits = []

profit_total = 0
vente_total = 0

for rangee in ventes[1:]:
    client = rangee[0]
    produit = rangee[1]
    prix_vente = float(rangee[2])

    # Total client
    idx = obtient_indice(total_clients, client)
    if idx == -1:
        total_clients.append([client, prix_vente])
    else:
        total_clients[idx][1] += prix_vente

    # Comptage produit
    idx = obtient_indice(compte_produits, produit)
    if idx == -1:
        compte_produits.append([produit, 1])
    else:
        compte_produits[idx][1] += 1

    # Profit
    profit_total += prix_vente - prix_produit(achats, produit)
    vente_total += prix_vente

# Moyenne des caddies
moyenne = vente_total / len(total_clients)

# Produit le plus acheté
produit_max = None
max_count = 0

for produit in compte_produits:
    if produit[1] > max_count:
        produit_max = produit[0]
        max_count = produit[1]

print("Moyenne des caddies:", round(moyenne, 2))
print("Produit le plus acheté:", produit_max)
print("Profit total:", round(profit_total, 2))
client,produit,prix_vente
Alice,Pomme,2
Alice,Banane,1
Bob,Pomme,2
Bob,Pomme,2
Charlie,Banane,1
Charlie,Orange,3
produit,prix_achat
Pomme,1
Banane,0.5
Orange,2

Exercice 15

Un professeur a un fichier CSV contenant les notes de ses élèves :

  • H1
  • H2
  • ...
  • moyenne

Cependant, à cause d’un bug, une valeur a disparu dans chaque ligne.

Il veut que vous reconstruisiez les valeurs manquantes et sauvegardiez le fichier corrigé.

Nom,Prenom,H1,H2,H3,H4,H5,H6,H7,moyenne
Branson,Lucie,43,47,53,,60,57,65,52.71
Davenport,Gabriel,,78,42,42,41,67,64,56.71
Dubois,Maxime,39,61,44,66,58,47,74,
Garcia,Clara,66,78,67,61,84,,64,71.71
Johnson,Emma,48,58,,67,71,70,61,63.29
Miller,Noah,92,84,77,77,90,86,,86.29
Moore,William,37,53,66,69,52,,58,54.0
Robinson,Mia,82,100,93,100,100,71,81,
Rodriguez,Emily,91,80,97,92,,98,100,94.0
Smith,James,82,,93,81,76,69,81,79.43
Taylor,Charlotte,61,63,51,48,72,49,51,
Wilson,Sophia,,50,52,56,68,46,75,60.43

Solution

grille = read_csv_file("notes.csv")

entete = grille[0]
lignes = grille[1:]
num_colone = len(entete)
num_devoir = num_colone - 2 - 1

for ligne in lignes:
    # recupere toutes les notes de devoir en float, et leur somme
    sum_note = 0
    for i in range(2, num_colone-1):
        if ligne[i] != "":
            ligne[i] = float(ligne[i])
            sum_note += ligne[i]

    # s'il manque la moyenne calcul la, sinon regarde quel note il manque et on la trouve
    if ligne[num_colone-1] == "":
        ligne[num_colone-1] = round(sum_note / num_devoir, 2)
    else:
        ligne[num_colone-1] = float(ligne[num_colone-1])
        for i in range(2, num_colone-1):
            if ligne[i] == "":
                ligne[i] = round(num_devoir * ligne[num_colone-1] - sum_note, 2)
                break

    # remet tout en string pour pouvoir sauvegarder le resultat
    for i in range(2, num_colone):
        ligne[i] = str(ligne[i])

write_csv_file("notes_corrigees.csv", [entete] + lignes)
Nom,Prenom,H1,H2,H3,H4,H5,H6,H7,moyenne
Branson,Lucie,43,47,53,,60,57,65,52.71
Davenport,Gabriel,,78,42,42,41,67,64,56.71
Dubois,Maxime,39,61,44,66,58,47,74,
Garcia,Clara,66,78,67,61,84,,64,71.71
Johnson,Emma,48,58,,67,71,70,61,63.29
Miller,Noah,92,84,77,77,90,86,,86.29
Moore,William,37,53,66,69,52,,58,54.0
Robinson,Mia,82,100,93,100,100,71,81,
Rodriguez,Emily,91,80,97,92,,98,100,94.0
Smith,James,82,,93,81,76,69,81,79.43
Taylor,Charlotte,61,63,51,48,72,49,51,
Wilson,Sophia,,50,52,56,68,46,75,60.43