Cours & exercices de Python

Introduction

Manuel de Python

Tu peux télécharger le manuel de python encliquant ici.

Présentation

  • Prénom
  • As-tu déjà programmé ? Si oui, avec quel langage de programmation ?
  • Motivation : pourquoi t'es-tu inscrit à ce cours ?

Notions de base

  • Programmation ?
  • Programme ?
  • Langage de programmation ?
  • Instruction ?
  • Compilation ?
  • Exécution ?
  • Syntaxe ?

Pourquoi Python ?

  • Langage interprété : versatilité (le fonctionnement ne dépend pas du système d'exploitation)
  • Syntaxe simple
  • Très utilisé dans pleins de domaines différents

Fonctionnement du cours

Les notions dont tu auras besoin dans ce cours se trouvent dans le manuel de python. Dans chaque cours, les chapitres que tu dois lire sont indiqués au début dans la section Manuel. Une fois que tu as lu les chapitres demandés, tu devras faire les exercices de la section Exercices.

Pour quasiment chaque exercice, on te demande de créer un nouveau programme, c'est à dire un nouveau fichier. Retiens-bien ça : Un programme = un fichier.

Une fois les exercices d'un cours terminés, appelle le professeur pour qu'il vienne vérifier que ce que tu as fait est correct. N'oublie pas d'essayer ton programme avant pour être sûr que tu as terminé l'exercice et qu'il n'y a pas d'erreur.

Introduction à IDLE

  • Sauvegarder un programme (p.18 du manuel)
  • Premier programme : Crée un premier programme nommé bonjour.py qui affiche le texte "Bonjour tout le monde !"

Chapitre 1 : Calculs et variables

Cours 1 : Opérateurs arithmétiques

Manuel

  • "Calculer avec Python", p.22-23
  • "Les opérateurs de Python", p.23
  • "L'ordre des opérateurs", p.24-25

Exercices

Pour chaque exercice, il faut créer un nouveau programme.

  1. Dans un programme nommé cours1.py :
    • Affiche le résultat d'une addition.
    • Affiche le résultat d'une soustraction.
    • Affiche le résultat d'une multiplication.
    • Affiche le résultat d'une division.
    • Affiche le résultat d'un calcul utilisant tous les opérateurs.
    • Affiche le résultat d'une opération qui illustre l'ordre des opérateurs et l'utilisation des parenthèses.

Cours 2 : Variables

Manuel

  • "Les variables sont comme des étiquettes", p.25-26
  • "Utiliser les variables", p.26-29

Exercices

  1. Dans un programme nommé variables.py :
    • Crée une variable nommée mon_age égale à ton âge, puis afficher le contenu de cette variable.
    • Crée une variable nommée annee_actuelle égale à l'année actuelle.
    • Affiche le résultat de annee_actuelle moins mon_age.

Chapitre 2 : Chaînes, listes, tuples, dictionnaires

Cours 3 : Chaînes de caractères 1

Manuel

  • "Les chaînes", p.32
  • "Créer des chaînes", p.32-33
  • "Gérer les problèmes de chaînes", p.33-36

Exercices

  1. Dans un programme nommé prenom_nom.py :
    • Crée une variable prenom contenant une chaîne de caractères correspondant à ton prénom.
    • Crée une variable nom contenant une chaîne de caractères correspondant à ton nom de famille.
    • Affiche "Bonjour ! Je m'appelle " suivi du contenu de prenom, puis d'un espace, puis du contenu de nom.
  2. Dans un programme nommé multiligne.py :
    • Crée une variable ma_journee contenant une chaîne de caractères de plusieurs lignes racontant ta journée.
    • Affiche ma_journee.
  3. Dans un programme nommé guillemets.py :
    • Crée une variable guillemets qui contient la phrase C'est vraiment compliqué de dire "mon prof de python est le meilleur" sans provoquer d'erreur..
    • Affiche cette variable.

Cours 4 : Chaînes de caractères 2

Manuel

  • "Insérer des valeurs dans des chaînes", p.36-37
  • "Multiplier des chaînes", p.37-38

Exercices

  1. Dans un programme nommé prenom_nom_mieux.py :
    • Crée une variable prenom contenant une chaîne de caractères correspondant à ton prénom.
    • Crée une variable nom contenant une chaîne de caractères correspondant à ton nom de famille.
    • Affiche "Bonjour ! Je m'appelle <prénom> <nom>" en remplaçant <prénom> et <nom> par les variables créées plus tôt et en utilisant %s.
  2. Dans un programme nommé mon_salaire.py :
    • Crée une variable pieces_par_jour contenant le nombre de pièces d'or que tu gagnes par jour.
    • Crée une variable jours_de_travail contenant le nombre de jours où tu as travaillé.
    • Affiche "En travaillant <jours_de_travail> jours et avec un salaire quotidien de <pieces_par_jour> pièces, j'ai gagné un total de <jours_de_travail * pieces_par_jour> pièces. Je suis riche !" en utilisant %s. Il faudra bien sûr remplacer les parties entre chevrons (<…>) par le contenu des variables.
  3. Dans un programme nommé perroquet.py :
    • Crée une variable phrase contenant la phrase de ton choix.
    • Affiche "Le perroquet répète : ".
    • Affiche 10 fois la phrase contenue dans phrase sans te répéter.
  4. Dans un programme nommé mur_de_caractères.py :
    • Crée une variable caractere qui contient un caractère de ton choix. Par exemple "#" ou "-" ou ce que tu veux.
    • Crée une variable repetition et assigne-lui un nombre entier de ton choix.
    • Affiche autant de fois ton caractere que le nombre dans repetition.

Cours 5 : Listes 1

Manuel

  • "Plus puissantes que les chaînes : les listes", p.38-41

Exercices

  1. Dans un programme nommé liste_courses.py :
    • Crée une variable courses contenant une liste d'au moins 5 choses à acheter. Chaque élément sera une chaîne de caractères.
    • Affiche la liste de courses.
    • Affiche le 1er élément de la liste en utilisant son indice.
    • Affiche le 3ème élément de la liste en utilisant son indice.
    • Modifie le 2ème élément de la liste et l'afficher après modification.
    • Modifie le dernier élément de la liste et l'afficher après modification.
    • Affiche d'un seul coup le sous-ensemble de la liste contenant les 2ème, 3ème et 4ème éléments de la liste.
  2. Dans un programme nommé liste_de_listes.py :
    • Crée une variable legumes contenant une liste de 3 légumes à acheter.
    • Crée une variable fruits contenant une liste de 3 fruits à acheter.
    • Crée une variable divers contenant une liste de 3 autres choses à acheter.
    • Crée une varibale listes qui sera une liste contenant les 3 listes créées précédemment. Attention, il ne faut pas réécrire les listes, mais seulement les réutiliser.
    • En utilisant uniquement la varibale listes :
      • Affiche le 3ème élément de la liste legumes.
      • Affiche le 1er élément de la liste fruits.
      • Affiche le 2ème élément de la liste divers.

Cours 6 : Listes 2

Manuel

  • "Ajouter des éléments à une liste", p.41-42
  • "Supprimer des éléments à une liste", p.42
  • "Arithmétique de liste", p.42-44

Exercices

  1. Dans un programme nommé liste_eleves.py :
    • Crée une variable eleves contenant la liste des prénoms des personnes présentes à l'atelier Python en omettant le tient.
    • Affiche la liste.
    • Ajoute ton prénom et celui du professeur dans la liste.
    • Affiche la liste modifiée.
    • Supprime le prénom du professeur.
    • Place ton prénom au début de la liste.
    • Affiche la liste finale.
  2. Dans un programme nommé encore_plus_de_listes.py :
    • Crée une liste liste_1 avec au moins 3 éléments de ton choix.
    • Crée une liste liste_2 avec au moins 2 élements de ton choix.
    • Crée une liste des_listes qui est la concaténation des deux autres.
    • Affiche la liste des_listes.
    • Fais en sorte que la liste des_listes ait 5 fois plus de contenu.
    • Affiche la liste des_listes.

Cours 7 : Tuples et dictionnaires

Manuel

  • "Tuples", p.45
  • "Dictionnaires", p.45-47

Indication complémentaire sur les dictionnaires

Comme vu dans le manuel, tu peux modifier une valeur dans un dictionnaire simplement en utilisant sa clef :

fortunes = {'Elon Musk': 180000000000, 'Jeff Bezos': 114000000000, 'Bill Gates': 104000000000, 'Mark Zuckerberg': 64400000000, 'Moi': 0}
print(fortunes)
fortunes['Moi'] = 100
print(fortunes)

Résultat :

{'Elon Musk': 180000000000, 'Jeff Bezos': 114000000000, 'Bill Gates': 104000000000, 'Mark Zuckerberg': 64400000000, 'Moi': 0}
{'Elon Musk': 180000000000, 'Jeff Bezos': 114000000000, 'Bill Gates': 104000000000, 'Mark Zuckerberg': 64400000000, 'Moi': 100}

Si tu veux ajouter un élément, c'est-à-dire une clef et une valeur, il faut faire comme si on modifiait la valeur de la nouvelle clef :

fortunes = {'Elon Musk': 180000000000, 'Jeff Bezos': 114000000000, 'Bill Gates': 104000000000, 'Mark Zuckerberg': 64400000000, 'Moi': 0}
print(fortunes)
fortunes['Mon chat'] = 100
print(fortunes)

Résulat :

{'Elon Musk': 180000000000, 'Jeff Bezos': 114000000000, 'Bill Gates': 104000000000, 'Mark Zuckerberg': 64400000000, 'Moi': 0}
{'Elon Musk': 180000000000, 'Jeff Bezos': 114000000000, 'Bill Gates': 104000000000, 'Mark Zuckerberg': 64400000000, 'Moi': 0, 'Mon chat': 100}

Exercices

  1. Dans un programme nommé mon_tuple.py :
    • Crée un tuple un_tuple avec au moins 3 éléments.
    • Affiche le tuple.
    • Modifie la première valeur du tuple.
    • Affiche le tuple modifié.
  2. Dans un programme nommé courses_dictionnaire.py :
    • Crée un dictionnaire courses contenant 3 éléments à acheter comme clef avec comme valeur la quantité à acheter.
    • Affiche le dictionnaire.
    • Ajoute un élément que tu aurais oublié.
    • Supprime le premier élément du dictionnaire.
    • Modifie la deuxième entrée du dictionnaire.
    • Affiche le dictionnaire.

Cours 8 : Input

Cours

Jusqu'ici, nous avons donné à nos variables des valeurs directement dans le code python. Comment fait-on si l'on souhaite demander une information à l'utilisateur et qu'il puisse la donner sans qu'il ait besoin de modifier le code ?

La méthode la plus simple, c'est d'utiliser la fonction input(). Nous utilisons déjà la fonction print() pour afficher du texte à l'écran mais nous verrons plus tard et en détail ce qu'est une fonction en programmation.

En anglais, "input" signifie "entrée". La fonction input() sert à récupérer une "entrée utilisateur", c'est-à-dire les informations que l'utilisateur (celui qui utilise le programme) donne à l'ordinateur. Pour le moment, les informations seront seulement des caractères que l'utilisateur tapera au clavier. Lorsque nous utiliserons input(), l'utilisateur pourra entrer des caractères au clavier et terminer par la touche <Enter> ou <Entrée> pour terminer. Dans le programme, nous pourrons récupérer ce que l'utilisateur a entré dans une variable pour le réutiliser.

On peut utiliser la fonction input() en laissant les parenthèses vides. On peut aussi y placer un message explicatif destiné à l'utilisateur. Par exemple :

prenom = input("Entrez votre prénom : ")
print("Bonjour %s !" % prenom)

Résultat :

exemple prenom1

L'utilisateur peut entrer son prénom et appuyer sur la touche <Entrée> :

exemple prenom2

La variable dans laquelle nous récupérons l'entrée utilisateur sera une chaîne de caractères. Si nous essayons de faire des opérations arithmétiques avec la valeur récupérée, cela va générer une erreur "TypeError":

age = input("Entrez votre âge : ")
print(age + 10)

Résultat :

TypeError: can only concatenate str (not "int") to str

Ou encore :

age = input("Entrez votre âge : ")
print("Tu es né en %s !" % (2022 - age))

Résultat :

TypeError: unsupported operand type(s) for -: 'int' and 'str'

Python génère une erreur car la variable age est une chaîne de caractères et non pas un nombre avec lequel on peut faire une opération. Pour résoudre ce problème, il nous suffit de convertir la valeur de retour de input() en nombre. Si nous voulons un nombre entier (sans virgule), il faut utiliser int(). Si nous souhaitons récupérer un nombre décimal (à virgule), nous devons utiliser float(). Exemple pour convertir en un nombre entier :

age = int(input("Entrez votre âge : "))
print("Tu es né en %s !" % (2022 - age))

Pour le moment, cela suffira pour créer des programmes plus intéractifs, mais nous reverrons plus en détail les conversions en python dans le chapitre 4 (cours 13).

Exercices

  1. Dans un programme nommé carte_identite.py :
    • Pour chaque information à demander à l'utilisateur, il faudra utiliser input() avec une question appropriée.
    • Récupère dans une variable prenom le prénom de l'utilisateur.
    • Récupère dans une variable nom le nom de l'utilisateur.
    • Récupère dans une variable age l'âge de l'utilisateur.
    • Récupère dans une variable taille la taille de l'utilisateur.
    • Récupère dans une variable nationalite la nationalité de l'utilisateur.
    • Affiche "Je m'appelle <prenom> <nom>, j'ai <age> ans, je fais <taille>cm et mon pays d'origine est <nationalite>."

Chapitre 3 : Turtle

Cours 9 : Turtle

Manuel

  • "Dessiner avec une tortue", p.49-56

Exercices

  1. Dans un programme nommé carré.py, fais dessiner un carré à une tortue.
  2. Dans un programme nommé hexagone.py, fais dessiner un hexagone à une tortue.
  3. Dans un programme nommé etoile.py, fais dessiner une étoile à une tortue.
  4. Dans un programme nommé etoile_variable.py, fais dessiner une étoile à 5 branches à une tortue. Cependant, cette fois-ci il doit y avoir une variable nommée taille_cote qui doit être utilisée pour déterminer la taille des côtés de l'étoile. Par exemple, si taille_cote vaut 1, l'étoile sera composée de segments de 1 pixel de long. Si taille_cote vaut 100, l'étoile sera composée de segments de 100 pixels.
  5. Dans un programme nommé visage.py, fais dessiner un visage à une tortue. Le visage doit contenir au moins deux yeux, un nez et une bouche.

Chapitre 4 : Les conditions

Cours 10 : if

Manuel

  • "Poser des questions avec if et else", p. 59
  • "Intructions if", p.60
  • "Un bloc est un groupe d'instructions", p.60-62
  • "Des conditions pour comparer des choses", p.62-64

Exercices

  1. Dans un programme nommé boutique.py :
    • Demande à l'utilisateur un nombre entier correspondant à la somme d'argent qu'il a et stocke sa réponse dans une variable euros.
    • Si euros est supérieure à 2, le programme doit afficher "Tu peux t'acheter des chewing-gums" puis enlever 2 à euros.
    • Si euros est supérieure à 30, le programme devra aussi afficher "Tu peux t'acheter des légos" puis enlever 30 à euros.
    • Si euros est supérieure à 350, le programme devra aussi afficher "Tu peux t'acheter une playstation" puis enlever 350 à euros.
    • Si euros est supérieure à 5000000, le programme devra aussi afficher "Tu es trop riche et tu donnes toute ta fortune !" puis euros devra être mise à 0.
    • Enfin, affiche "Il te reste <euros>" en remplaçant euros par ce qu'il y a dans la variable.
  2. Dans un programme nommé montagnes_russes.py :
    • Demande à l'utilisateur son âge puis sa taille et stocke ses réponses dans des variables age et taille.
    • Crée une condition qui affiche "Tu es trop jeune pour faire les montagnes russes." si age est strictement inférieure à 7 ans.
    • Crée une condition qui affiche "Tu as le bon âge pour faire les montagnes russes." si age est supérieure ou égale à 7 ans.
    • Crée une condition qui affiche "Tu es trop petit pour faire les montagnes russes." si taille est strictement inférieure à 60cm.
    • Crée une condition qui affiche "Tu es trop petit pour faire les montagnes russes sans être accompagné." si taille est entre 60cm inclus et 80cm exclus.
    • Crée une condition qui affiche "Tu as la bonne taille pour faire les montagnes russes sans être accompagné." si taille est supérieure ou égale à 80cm.
  3. Dans un programme nommé formes.py :
    • Demande à l'utilisateur un nombre entier que tu stockeras dans une variable nb_cotes.
    • Demande à l'utilisateur un autre nombre entier que tu stockeras dans une variable taille_cote.
    • Si nb_cotes est égale à 3, une tortue doit dessiner un triangle dont les côtés sont égaux à taille_cote.
    • Si nb_cotes est égale à 4, une tortue doit dessiner un carré dont les côtés sont égaux à taille_cote.
    • Si nb_cotes est égale à 5, une tortue doit dessiner un pentagone dont les côtés doivent être égaux à taille_cote.
    • Si nb_cotes est strictement inférieure à 3, affiche "Nombre de côtés trop petit.".
    • Si nb_cotes est strictement supérieure à 5, affiche "Nombre de côtés trop grand.".

Cours 11 : if, elif, else

Manuel

  • "Instructions si-alors-sinon", p.64-65
  • "Instructions if et elif", p.65-66

Exercices

  1. Dans un programme nommé dragon.py :
    • Affiche "Tu te trouves dans une pièce obscure d'un mystérieux château.".
    • Affiche "Tu dois choisir entre trois portes. Choisis 1, 2 ou 3… " et récupère la réponse de l'utilisateur dans une variable choix.
    • Si le joueur a choisi la porte 1, affiche "Tu as trouvé un trésor, tu es riche !".
    • Si le joueur a choisi la porte 2, affiche "La porte s'ouvre et un ogre affamé te donne un coup de massue. Perdu !".
    • Si le joueur a choisi la porte 3, affiche "Il y a un dragon dans cette pièce. Le dragon se réveille et te mange. Il te trouve délicieux… Perdu !".
    • Si le joueur a choisi autre chose, affiche "Désolé, il faut entrer 1, 2 ou 3.".
  2. Dans un programme nommé endroit_secret.py :
    • Crée une variable mot_secret égale au mot de ton choix.
    • Crée une variable humeur_gardien égale à un entier entre 0 et 10.
    • Demande à l'utilisateur d'entrer son mot secret et stocke-le dans une variable mot_utilisateur.
    • En utilisant if, elif et else, implémente les conditions suivantes :
      • Si le mot_utilisateur est égal au mot_secret, affiche "Bienvenue, vous êtes VIP !".
      • Si le mot_utilisateur est différent de mot_secret, il y a 3 possibilités :
        • Soit le gardien est de mauvaise humeur (humeur_gardien inférieure à 3). Dans ce cas, affiche "Veuillez procéder à une vérification des papiers.".
        • Soit le gardien est de bonne humeur (humeur_gardien supérieure à 7). Dans ce cas, affiche "Bienvenue, mais vous n'êtes pas VIP.".
        • Soit le gardien est neutre. Dans ce cas, affiche "Veuillez prendre connaissance des règles avant d'entrer.".

Cours 12 : and, or

Manuel

  • "Combiner des conditions", p.66

Exercices

  1. Dans un programme nommé montagnes_russes2.py :
    • Demande à l'utilisateur son âge puis sa taille et stocke ses réponses dans des variables age et taille.
    • En utilisant seulement deux if et en utilisant and et or, implémente les conditions suivantes :
      • Si age est supérieure ou égale à 7 et taille est supérieure ou égale à 80, affiche "Tu peux faire les montagnes russes.".
      • Si age est inférieure à 7 ou taille est inférieure à 80, affiche "Tu ne peux pas faire les montagnes russes.".

Cours 13 : Types de données et conversions

Manuel

  • "Variables sans valeur : None", p.66-67
  • "Différence entre chaînes et nombres", p.67-69

Exercices

  1. Dans un programme nommé types_donnees.py :
    • Crée une variable nb_str contenant une chaîne convertible en nombre.
    • Crée une variable nb_int contenant la conversion en nombre entier de nb_str.
    • Crée une variable nb_float contenant la conversion en nombre flottant de nb_str.
    • Crée une variable nb_int2 contenant un nombre entier de ton choix.
    • Crée une variable nb_str2 contenant la conversion en chaîne de nb_int2.
    • Affiche toutes les variables.

Chapitre 5 : Les boucles

Cours 14 : Les boucles for

Manuel

  • "Tourner en boucle", p.73
  • "Utiliser les boucles for", p.74-80

Exercices

  1. Dans un programme nommé repetition.py :
    • Demande à l'utilisateur un nombre entier et stocke-le dans une variable nombre.
    • Fais une boucle for qui affiche nombre fois "Je n'aurais plus jamais besoin de me répéter".
    • Fais une boucle for qui affiche tous les nombres de 0 à nombre inclus.
    • Fais une boucle for qui affiche tous les nombres de 0 à nombre exclus.
    • Crée une liste liste.
    • Fais une boucle for qui demande nombre fois à l'utilisateur d'entrer un mot qui s'ajoutera à la liste.
    • Fais une boucle for qui affiche chaque élément de la liste ligne par ligne.
  2. Dans un programme nommé pairs.py :
    • Affiche tous les nombres pairs de 0 à 20 en utilisant une boucle for.
  3. Dans un programme nommé repetortue.py :
    • Crée trois variables : distance, angle et repetitions et demande à l'utilisateur d'entrer leurs valeurs (nombres entiers uniquement).
    • Dans une boucle for, fais avancer repetitions fois la tortue de distance pixels et fais-la tourner (droite ou gauche, comme tu veux) de angle degrés.
    • Essaie différentes valeurs pour distance, angle et repetitions pour voir ce qu'il se passe de différent.
  4. Dans un programme nommé cercle.py :
    • Fais dessiner à une tortue un cercle à l'aide d'une boucle for. L'utilisation de la fonction circle est interdite ici.
  5. Dans un programme spirale.py :
    • Fais dessiner à une tortue une spirale à l'aide d'une boucle for.
  6. Dans un programme nommé fibonacci.py :
    • Fais un programme qui calcule les 10 premiers nombres de la suite de fibonacci en utilisant une boucle for.

      La suite de Fibonacci est : 0, 1, 1, 2, 3, 5, 8,… Les deux premiers nombres de la suite sont toujours 0 et 1, ensuite chaque nombre est égal à la somme des deux précédents.

    • (BONUS) : Fais avancer une tortue de chaque valeur de la suite de Fibonacci en la faisant tourner à chaque fois de 90°.

Cours 15 : Boucles while

Manuel

  • "Tant que nous parlons de boucles : while", p.81-83

Exercices

  1. Dans un programme nommé repetition_while.py :
    • Demande à l'utilisateur un nombre entier et stocke-le dans une variable nombre.
    • Fais une boucle while qui affiche nombre fois "Je n'aurais plus jamais besoin de me répéter".
    • Fais une boucle while qui affiche tous les nombres de 0 à nombre inclus.
    • Fais une boucle while qui affiche tous les nombres de 0 à nombre exclus.
    • Crée une liste liste.
    • Fais une boucle while qui demande nombre fois à l'utilisateur d'entrer un mot qui s'ajoutera à la liste.
    • Fais une boucle while qui affiche chaque élément de la liste ligne par ligne.
  2. Dans un programme nommé compte_a_rebours.py :
    • Demande à l'utilisateur un nombre entier de son choix et stocke-le dans une variable nombre
    • Fais une boucle while qui, tant que nombre est strictement supérieur à 0 :
      • Affiche nombre - 1
      • Demande à l'utilisateur s'il veut continuer. Si l'utilisateur tape 'non', alors le programme s'arrête.
      • Sinon, nombre prend la valeur nombre - 1

Chapitre 6 : Mise en pratique

Cours 16 : Nombre secret

Indication pour générer un nombre aléatoire

Pour générer un nombre aléatoire, tu dois d'abord importer le module random. Il faut toujours importer les modules en début de programme pour plus de clarté :

import random

Ensuite, pour générer le nombre et le stocker, tu dois utiliser la fonction random.randint(min, max). min et max sont les valeurs minimale et maximale du nombre aléatoire souhaité.

nombre = random.randint(0, 10)

Exercice

Dans un programme nommé nombre_secret.py :

  • Fais un jeu où l'ordinateur choisit un nombre aléatoire et le joueur doit le deviner.
  • Le programme doit choisir un nombre aléatoire entre 1 et 10 en utilisant la fonction vue avant.
  • Le joueur doit avoir 4 essais pour deviner le nombre.
  • Une fois qu'une partie est terminée (gagnée ou perdue), le programme doit demander à l'utilisateur s'il souhaite rejouer et relancer une partie si celui-ci répond "oui".
  • Le nombre d'essai et le minimum et maximum du nombre secret doivent être stockés dans des variables au début du programme et qui doivent être utilisées au bon endroit dans le programme afin de permettre de choisir le nombre d'essai, le minimum et le maximum en changeant seulement les variables au début du programme.
  • A chaque essai, le programme doit :
    • Demander au joueur de trouver le nombre situé entre minimum et maximum.
    • Si le nombre entré par le joueur est le bon, le jeu doit féliciter le joueur.
    • Si le nombre entré est plus petit ou plus grand, le jeu doit informer le joueur et commencer un nouvel essai s'il en reste au joueur.
    • Si le nombre n'est pas le bon est qu'il s'agissait du dernier essai, le jeu doit informer le joueur qu'il a perdu.

BONUS

  • Si le joueur a gagné, le jeu doit se relancer avec une plus grande difficulté (moins d'essais, nombre secret maximum plus grand, …)
  • Si le joueur a perdu, le jeu doit baisser la difficulté ou retourner à la difficulté originale.
  • Des messages cachés qui ne s'affichent que si l'on réussit un certain niveau ou si on trouve le nombre secret du premier coup.

Chapitre 7bis : Turtle avec les fonctions

Cours 17b : Un peu plus de turtle

Nous avons vu précédemment les bases du module turtle. En réalité, il existe encore beaucoup de fonctionnalités que nous n'avons pas encore explorées. Pour plus de détails et si tu cherches quelque-chose qui n'est pas expliqué ici, voici la documentation officielle de turtle : https://docs.python.org/fr/3/library/turtle.html#turtle-graphics-reference

Les couleurs

Pour commencer, nous pouvons changer toutes les couleurs : l'arrière-plan, le trait et même le remplissage ! Turtle propose beaucoup de couleurs et libre à toi de les essayer. En voici une liste.

colors turtle

Il existe aussi un site pour rapidement trouver le nom d'une couleur turtle : https://trinket.io/docs/colors

Changer la couleur d'arrière-plan

La fonction à utiliser pour changer la couleur d'arrière-plan est :

turtle.bgcolor("couleur") # Remplacer couleur par la couleur voulue

Changer la couleur du trait

La fonction à utiliser pour changer la couleur du trait est :

t = turtle.Pen() # Au debut du dessin
t.color("couleur") # Remplacer couleur par la couleur voulue

Changer la couleur de remplissage d'une forme

Pour changer la couleur de remplissage d'une forme, il y a plusieurs étapes à respecter.

  1. Il faut d'abord choisir la couleur à l'aide de

    t.color()
    
  2. Ensuite, lorsque l'on commence à dessiner la forme à remplir, il faut utiliser la fonction

    t.begin_fill()
    
  3. Enfin, lorsque la forme à remplir est terminée, il faut utiliser la fonction

    t.end_fill()
    

Exemple :

import turtle

t = turtle.Pen()
t.color("cyan")
t.begin_fill()
t.forward(50)
t.left(90)
t.forward(50)
t.left(90)
t.forward(50)
t.left(90)
t.forward(50)
t.end_fill()
turtle square

La vitesse

Il est possible de changer la vitesse d'exécution d'un dessin avec turtle en utilisant la fonction

t.speed(vitesse) # Remplacer vitesse par un int compris entre 0-10

La vitesse la plus rapide est… t.speed(0) !

La taille du trait

Tu peux changer la taille du trait avec la fonction

t.pensize(taille) # Remplacer taille par un int

Lever ou baisser le stylo

Par moments, tu peux avoir besoin de déplacer la tortue sans pour autant qu'elle trace des lignes sur sa trajectoire. Eh bien, il est possible de lui faire "lever" son stylo à l'aide de la fonction

t.up() # up veut dire "haut" en anglais

Une fois que tu veux que la tortue dessine à nouveau, utilise simplement la fonction

t.down() # down veut dire "bas" en anglais

Dessiner un cercle

Il est possible de dessiner un cercle rapidement a l'aide de la fonction

t.circle(rayon) # Remplacer rayon par un int correspondant au rayon du cercle

Afficher ou cacher la tortue

Si tu veux cacher la forme de la tortue, tu dois utiliser la fonction

t.hideturtle()

Pour l'afficher à nouveau, c'est à l'aide de la fonction

t.showturtle()

Se déplacer directement à des coordonnées précises

On peut définir n'importe quel point de l'écran en utilisant les coordonnées. Les abscisses x indiquent la position horizontale, tandis que les ordonnées y indiquent la position verticale.

turtle coordinates

La fonction goto() de turtle permet de "téléporter" directement la tortue à des coordonées précises. En ajoutant l'utilisation des fonctions up() et down(), le déplacement se fera sans laisser de trace.

Exemple :

import turtle
pen = turtle.Pen()
pen.up()
pen.goto(-350, 23)
pen.down()
pen.forward(100)
# etc

Connaître les coordonnées actuelles de la tortue

On peut récupérer les coordonnées de la tortue grâce à la fonction pos() de turtle. Cette fonction renvoie un tuple de la forme (abscisse x, ordonnée y).

Exemple :

import turtle
pen = turtle.Pen()
position = pen.position()
print(position[0]) # affiche l'abscisse x de la tortue
print(position[1]) # affiche l'ordonnée y de la tortue

Définir l'orientation de la tortue

Pour changer l'orientation de la tortue, nous avons vu les fonctions right(angle) et left(angle). Parfois, nous avons besoin d'orienter directement la tortue vers une direction donnée, par exemple pour pouvoir remettre l'orientation à 0. La fonction qui sert à faire cela est la fonction setheading(direction). Le paramètre direction est un nombre entier. Exemple :

import turtle
pen = turtle.Pen()
pen.setheading(90)

Exercices

Rendez-vous au cours 18b pour commencer à mettre en application toutes tes nouvelles connaissances.

Cours 18b : Exercice turtle

Mon beau sapin …

Dans un programme nommé mon_beau_sapin.py, mets en oeuvre tout ce que l'on vient de voir en reproduisant ce sapin de noël. Ce n'est pas grave s'il n'est pas exactement similaire, mais applique-toi à le faire le plus ressemblant possible.

xmas tree

Indice : les étages du sapin sont en fait des triangles superposés de tailles différentes.

Cours 19b : Turtle, mais avec des fonctions

Manuel

  • "Recycler du code avec des fonctions et des modules", p.87-88
  • "Utiliser des fonctions", p.88-89
  • "Qu'est-ce qu'une fonction ?", p.89-90
  • "Variables et portée", p.90-92

Exercice

Le but du premier exercice est de pouvoir dessiner un flocon de neige sans se répéter, grâce aux fonctions.

Voici ce qu'on veut obtenir :

snow flake

Ce dessin est très facile à réaliser si on le décompose correctement avec des fonctions. En effet, le flocon est composé de :

  • 6 fois la même branche :
snow flake branch
  • Une branche est elle-même composée d'une ligne + une forme en V le tout répété 4 fois:
snow flake fd + v
  • Et enfin, la forme en V en elle-même est une suite de plusieurs déplacements.
snow flake v

Ces 3 étapes de décomposition vont correspondent en fait aux 3 fonctions dont nous avons besoin pour créer ce flocon de neige sans se répéter et en quelques lignes seulement.

Dans un programme nommé flocon.py :

  • Configure correctement une tortue pour qu'elle dessine en blanc sur fond "turquoise" et avec une épaisseur de trait de 6.
  • Crée une fonction forme_v() qui contient les étapes pour faire le V :
    • Tourner à droite de 25°
    • Avancer de 50 pixels
    • Reculer de 50 pixels
    • Tourner à gauche de 50°
    • Avancer de 50 pixels
    • Reculer de 50 pixels
    • Tourner à droite de 25°
  • Crée une fonction branche() qui contient les étapes pour faire une branche :
    • Répéter 4 fois :
      • Avancer de 30 pixels
      • Dessiner un V
    • Reculer de 120 pixels
  • Crée une fonction flocon() qui contient les étapes pour dessiner un flocon :
    • Répéter 6 fois :
      • Dessiner une branche
      • Tourner à droite de 60°
  • Enfin, appelle la fonction flocon() et observe le flocon se dessiner !

Cours 20b : Les fonctions avec des arguments

Nous avons vu dans le chapitre précédent comment créer et utiliser des fonctions :

def nom_fonction(): #Création de la fonction
    #Le code de la fonction

nom_fonction() # Appel de la fonction pour que le code dans la fonctions soit lancé.

Si tu as bien lu les chapitres du manuel sur les fonctions, tu as probablement vu que les fonctions peuvent aussi s'utiliser avec des paramètres. Si ce n'est pas le cas, revois les chapitres du manuel indiqués dans le chapitre précédent.

Nous allons donc utiliser les fonctions et les paramètres pour améliorer notre programme de dessin de flocon et refaire le sapin du début de manière plus simple et plus rapide.

Indication sur l'utilisation du module random

Pour générer un nombre aléatoire entre 2 et 20 par exemple, voici le code qu'il faut taper :

import random # Première ligne du programme
mon_nombre = random.randint(2,20)

Exercices

Dans un programme nommé flocon2.py :

Reprends le code que tu as écris dans le programme flocon.py et copie-le dans ce nouveau programme. Nous allons y ajouter quelques fonctionnalités intéressantes.

  • Pour commencer, importe le module random au début du programme.
  • Efface la ligne de code qui définit la couleur du stylo.
  • Crée une variable couleurs qui contient une liste de couleurs de ton choix (en chaînes de caractères)
  • Dans la fonction flocon(), ajoute au début de la boucle la ligne suivante qui permet de choisir une couleur au hasard dans la liste pour chaque branche du flocon:
pen.color(random.choice(couleurs))
  • Maintenant, modifie les fonctions flocon(), branche() et forme_v() pour qu'elles prennent en paramètre une variable nommée taille. Comme son nom l'indique, ce paramètre nous permettra de modifier la taille des flocons.
  • Fais les modifications nécessaires dans ces fonctions pour que les traits tracés par la tortue soient de longueur taille.
  • Crée une nouvelle fonction tempete(nb_flocons) qui :
    • Détermine la taille d'un flocon à l'aide du module random. Je te conseille de choisir une taille entre 5 et 30.
    • Détermine la position x du début du flocon avec le module random (entre -300 et 300).
    • Détermine la position y du début du flocon avec le module random (entre -300 et 300).
    • Lève le stylo.
    • Se téléporte à la position x,y (avec la fonction goto()).
    • Baisse le stylo.
    • Dessine un flocon de taille taille (en appelant bien-sûr la fonction que l'on a créée plus tôt).
    • Toutes ces actions doivent être répétées nb_flocons fois.
  • Enfin, dans le programme (en dehors de la fonction), supprime la ligne qui appelle la fonction flocon
  • Crée une variable nb qui contient un nombre aléatoire de flocons (entre 1 et 20 par exemple)
  • Appelle la fonction tempete en lui donnant nb en paramètre.

Dans un programme nommé sapin_fonctions.py :

  • Crée une fonction nommée tronc qui prend en paramètres largeur et hauteur, qui correspondent respectivement à la largeur et la hauteur du tronc que l'on veut dessiner.
  • Cette fonction doit :
    • Orienter la tortue à 0 (voir chapitre 17b)
    • Commencer le remplissage de la forme
    • Dessiner un rectangle qui a une largeur et une hauteur correspondant aux paramètres
    • Finir le remplissage de la forme
  • Crée une fonction nommée etage_sapin qui prend en paramètre taille, qui correspond à la taille de l'étage que l'on veut dessiner.
  • Cette fonction doit permettre de dessiner un étage (un triangle):
    • Commencer le remplissage de la forme
    • Récupérer la position actuelle de la tortue (voir chapitre 17b) dans une variable position
    • Placer la tortue aux coordonnées suivantes (voir chapitre 17b) : en abscisse (x), se placer à la position x actuelle plus taille, en ordonnée (y) rester à la même position.
    • Placer la tortue aux coordonnées suivantes : position x de départ, c'est-à-dire position[0], position y de départ plus taille
    • Placer la tortue aux coordonnées suivantes : position x de départ moins taille, position y de départ.
    • Finir le remplissage de la forme
  • Maintenant que tu as préparer les fonctions, utilise-les dans ton programme avec les valeurs de ton choix et au bon moment pour dessiner un sapin. Tu peux bien-sûr t'aider du sapin du chapitre 18b pour les couleurs, les tailles, etc, mais tu dois utiliser les fonctions que tu as créées pour dessiner le tronc et les étages.

    BONUS

Ajoute dans le programme une fonction nommée etoile(taille) pour dessiner l'étoile au sommet du sapin. Utilise cette fonction à la suite du programme qui dessine le sapin.

Chapitre 7 : Les fonctions

Cours 17 : Fonctions

Manuel

  • "Recycler du code avec des fonctions et des modules", p.87-88
  • "Utiliser des fonctions", p.88-89
  • "Qu'est-ce qu'une fonction ?", p.89-90
  • "Variables et portée", p.90-92
  • "La fonction len", p.121-122

Exercices

  1. Dans un programme nommé fonctions1.py :
    • Définis une fonction ayant la signature bonjour(prenom, nom) qui doit afficher "Bonjour <prenom> <nom> !", en remplaçant <prenom> et <nom> par les arguments passés à la fonction.
    • Définis une fonction somme(nombre1, nombre2) qui retourne la somme des deux arguments.
    • Définis une fonction minimum(nombre1, nombre2) qui retourne le plus petit nombre entre les deux arguments.
    • Définis une fonction puissance(nombre1, nombre2) qui retourne nombre1 puissance nombre2.
    • Définis une fonction fibonacci(n) qui retourne le n-ième nombre de la suite de Fibonacci. Exemples : fibonacci(0)0, fibonacci(1)1, fibonacci(2)1, fibonacci(3)2, etc.
    • Appelle chaque fonction avec les paramètres de ton choix afin de vérifier qu'elles fonctionnent correctement. *Pour afficher le résultat des fonctions qui retournent quelque-chose, il suffit d'utiliser print() lors de l'appel de celles-ci.
  2. Dans un programme nommé menu.py :
    • Reprends (copie-colle) les fonctions créées dans l'exercice précédent.
    • Définis une fonction menu() qui :
      • Affiche le nom de toutes les fonctions précédemment créées et demande à l'utilisateur quelle fonction il veut utiliser.
      • Si l'utilisateur entre 'bonjour' :
        • Demande à l'utilisateur son prénom et son nom, stocke-les et appelle la fonction bonjour(prenom, nom) avec ce qu'a entré l'utilisateur
      • Si l'utilisateur entre 'somme', 'minimum' ou 'puissance' :
        • Demande à l'utilisateur deux nombres et stocke-les dans des variables.
        • Appelle la fonction somme(nombre1, nombre2), minimum(nombre1, nombre2) ou puissance(nombre1, nombre2) en fonction du choix de l'utilisateur.
      • Si l'utilisateur entre 'fibonacci' :
        • Demande à l'utilisateur un nombre et appelle la fonction fibonnaci(n) avec celui-ci
      • Tant que l'utilisateur n'entre pas 'quitter', il faut que la fonction propose les choix à nouveau à l'utilisateur.
      • Appelle la fonction menu() dans ton programme.
  3. Dans un programme nommé forme.py :
    • Définis une fonction forme(nb_cotes, taille_cotes, angle) qui dessine une forme en utilisant une tortue. La forme doit avoir nb_cotes en nombre de côtés, angle degrés de rotation et la taille des segments doit être égale à taille_cotes.
    • Appele plusieurs fois la fonction avec des arguments différents pour tout bien tester.
  4. Dans un programme nommé forme_aleatoire.py :
    • Définis une fonction ayant la signature forme_aleatoire(tortue).
    • La fonction doit définir une variable repetition égale à un nombre aléatoire entre 50 et 200.
    • La fonction doit définir une variable distance égale à un nombre aléatoire entre 10 et 200.
    • Le programme doit définir une variable angle égale à un nombre aléatoire en 0 et 360.
    • La forme aléatoire doit être dessinée par la tortue passée en argument en répétant repetition fois le fait d'avancer de distance pixels et de tourner d'angle degrés.
    • Pour tester, appelle plusieurs fois cette fonction avec des tortues différentes.
  5. Dans un programme nommé inverse.py :
    • Définis une fonction ayant la signature inverse(liste) qui doit renvoyer la liste passée en argument à l'envers. Par exemple, si on lui donne la liste [1, 5, 2, 6] en argument, elle doit renvoyer [6, 2, 5, 1].
    • Appelle la fonction plusieurs fois avec des listes différentes pour bien tester tous les cas.
    • Essaie de passer une chaîne de caractères en argument. Que se passe-t-il ?
  6. Dans un programme nommé minimum_liste.py :
    • Définis une fonction ayant la signature minimum_liste(liste_nombres) qui prend une liste de nombre en paramètre et renvoie le plus petit nombre de la liste.
    • Appeler plusieurs fois la fonction avec différentes listes de nombres pour bien tester tous les cas.
  7. Dans un programme nommé tri.py :

    • Faire une fonction ayant la signature tri(liste_nombres).
    • Le paramètre liste_nombres sera une liste de nombres.
    • La fonction doit renvoyer une liste qui contient tous les nombres de liste_nombres triés dans l'ordre croissant.
    • Appeler plusieurs fois la fonction avec différentes listes de nombres pour tester tous les cas.

    (BONUS)

    • Définis une fonction creerListe(taille) qui crée une liste de taille taille en demandant à l'utilisateur chaque nombre de la liste et renvoie la liste ainsi créée.
    • Appelle la fonction creerListe après avoir demandé la taille à l'utiliateur puis utilise la liste créée dans la fonction tri. Affiche la liste avant et après avoir utilisé tri.

Cours 18 : Les modules

Cours

Un module sert à regrouper des fonctions, des variables et d'autres choses dans des programmes plus vastes et plus puissants. Certains modules sont intégrés dans Python lui-même, tandis que tu peux en télécharger d'autres de manière séparée. Nous en avons déjà utilisé par exemple avec turtle et random.

Pour utiliser un module, il suffit d'écrire au début du fichier import nom_du_module. Dans le cas où tu voudrais utiliser un module qui n'est pas intégré à Python, il faudra d'abord le télécharger (ou le coder !).

Maintenant, si je te disais que tu peux créer tes propres modules avec tes propres fonctions, variables, classes dedans !? Ne serait-il pas pratique de pouvoir utiliser sans avoir à la réécrire une fonction qui, par exemple, permet de demander un entier à l'utilisateur et de vérifier qu'il n'y a pas d'erreur ?

Pour créer ton propre module, il suffit de :

  1. Créer un nouveau fichier et lui donner le nom de ton module, par exemple mes_fonctions.py.
  2. Écrire tes fonctions à l'intérieur du fichier, autant que tu veux. Attention, nous voulons seulement écrire les fonctions, pas les utiliser tout de suite.
  3. Une fois le fichier enregistré, il suffit de le mettre dans le même dossier que le programme dans lequel tu vas l'utiliser puis de l'importer avec import mes_fonctions dans le programme.
  4. Pour utiliser une fonction du module mes_fonctions, il faudra l'appeler en utilisant mes_fonctions.<nom_de_la_fonction>(paramètres).
  5. Pour ne plus avoir besoin d'écrire le nom du module, il faut remplacer import mes_fonctions par from mes_fonctions import *.

Exercices

Dans le chapitre suivant, nous allons mettre en pratique les modules et les fonctions ensemble en créant notre propre bibliothèque personnalisée de fonctions !

  1. Dans un fichier nommé mes_fonctions.py :
    • Crée la fonction demander_int(message) qui :
      • demande un entier à l'utilisateur en affichant le message message.
      • retourne l'entier convertit en int.
    • Crée la fonction demander_float(message) qui fonctionne comme la précédente mais avec un float.
    • Crée la fonction demander(message) qui fonctionne comme les précédentes mais avec une chaîne de caractères.
  2. Dans un programme nommé tests_fonctions.py :
    • importe ton module mes_fonctions
    • teste les 3 fonctions présentes dans ton module

Tu as maintenant créé les 3 premières fonctions de ton propre module, que tu pourras réutiliser chaque fois que tu en as besoin. Tu es libre d'y ajouter les fonctions qui te semblent intéressantes et que tu as déjà écrites, par exemple dans ce chapitre.

Chapitre 8 : Mise en pratique 2

Attention ! Pour chaque exercice, il faudra bien faire la différence entre le code à l'intérieur des fonctions et le code qui utilise les fonctions.

Nous utiliserons le fichier mes_fonctions précédemment et nous y ajouterons de nouvelles fonctions.

Niveau 1

Division euclidienne

Dans le fichier mes_fonctions.py :

  • Crée une nouvelle fonction div_euclidienne(a,b) qui retourne un tuple contenant le quotient et le reste de la division euclidienne de a par b sous la forme (quotient, reste).

Dans un programme nommé manips_nombres.py :

  • importe ton module mes_fonctions
  • Utilise la fonction div_euclidienne() dans un programme qui demande à l'utilisateur deux nombres entiers et affiche le calcul effectué ainsi que le quotient et le reste de la division euclidienne de ces nombres.

Pair ou impair

Dans le fichier mes_fonctions.py :

  • Crée une nouvelle fonction is_pair(nb) qui retourne True si nb est pair et False sinon.

Dans le programme manips_nombres.py:

  • Utilise cette fonction après avoir demandé un nombre entier à l'utilisateur et affiche un texte indiquant si le nombre est pair ou impair.

Diviseurs

Dans le fichier mes_fonctions.py :

  • Crée une fonction diviseurs(nb) qui retourne la liste de tous les diviseurs du nombre nb.

Dans le programme manips_nombres.py :

  • Utilise cette fonction après avoir demandé un nombre entier à l'utiliateur et affiche tous les diviseurs de ce nombre, séparés par des virgules et sans crochets.

Nombres premiers

Dans le fichier mes_fonctions.py :

  • Crée une fonction is_premier(nb) qui retourne True si nb est un nombre premier et False sinon.
  • Crée une fonction nb_premiers(n) qui retourne une liste contenant les n premiers nombres premiers.

Dans le programme manips_nombres.py :

  • Utilise ces fonctions après avoir demandé à l'utilisateur le nombre (entier) de nombres premiers à afficher puis affiche-les ; un par ligne.

Pour la suite, tu es libre d'ajouter et d'utiliser les fonctions que tu veux à ton module mes_fonctions pour ne plus avoir besoin de réécrire à chaque fois les fonctions que tu réutilises.

Cercle

Dans un programme nommé super_cercle.py :

  • Crée une fonction surface_cercle(rayon) qui retourne un float correspondant à la surface d'un cercle de rayon rayon.
  • Crée une fonction perimetre_cercle(rayon) qui retourne un float correspondant au périmètre d'un cercle de rayon rayon.
  • Crée une fonction creer_cercle(rayon) qui dessine avec Turtle un cercle de rayon rayon.
  • Utilise toutes ces fonctions dans un programme qui demande le rayon à l'utiliateur et affiche la surface, le périmètre et le dessin du cercle.

Lettres

Dans un programme nommé lettres.py :

  • Crée une fonction afficher_lettres(chaine) qui permet d'afficher chaque lettre d'une chaîne de caractères ; une par ligne.
  • Utilise cette fonction dans un programme qui demande à l'utilisateur un mot ou une phrase et qui affiche ensuite dans l'ordre chaque lettre une à une.

Exemple d'affichage pour chaine = "python" :

p
y
t
h
o
n

Niveau 2

Occurrences de lettres

Dans un programme nommé occurrences.py :

  • Crée une fonction occurrences(chaine) qui renvoie un dictionnaire contenant comme clefs chaque lettre présente dans la chaîne de caractères chaine et comme valeurs le nombre de fois où elle apparaît dans la chaîne.
  • Utilise cette fonction dans un programme qui demande à l'utilisateur un mot ou une phrase et qui affiche chaque lettre et le nombre de fois où elle apparaît.

Exemple d'affichage pour chaine = "Bonjour" :

Le caractère " B " apparaît 1 fois.
Le caractère " o " apparaît 2 fois.
Le caractère " n " apparaît 1 fois.
Le caractère " j " apparaît 1 fois.
Le caractère " u " apparaît 1 fois.

Le caractère " r " apparaît 1 fois.

Mot inverse

Dans un programme nommé mot_inverse.py :

  • Crée une fonction mot_inverse(mot) qui retourne une chaîne correspondant à l'inverse du mot mot. Attention, le mot original ne doit pas être modifié !
  • Utilise cette fonction dans un programme qui :
    • Demande un mot à l'utilisateur.
    • Affiche le mot original et son inverse.

Exemple pour le mot "python" :

mot original : python
inverse : nohtyp

Palindrome

Un palindrome est un mot dont l'ordre des lettres reste le même qu'on le lise de gauche à droite ou de droite à gauche.

Dans un programme nommé palindrome.py :

  • Crée une fonction est_palindrome(mot) qui retourne True si le mot mot est un palindrome et False sinon.
  • Utilise cette fonction dans un programme qui :
    • Demande un mot à l'utilisateur.
    • Affiche un texte indiquant si le mot est un palindrome ou non.

Niveau 3

Rendu de monnaie

Nous voulons créer un programme qui permet de calculer un rendu de monnaie et de dire de quels billets et pièces nous avons besoin pour former la somme à rendre. Par exemple, si la somme à payer est de 18.57€ et qu'un client donne 100€, le programme doit pouvoir :

  1. Calculer qu'il faut rendre 81.43€
  2. Afficher les billets et les pièces à utiliser pour cela. Exemple :
Prix à payer : 18.57€
Rendu : 81.43€
Décomposition :
50€ : 1
20€ : 1
10€ : 1
1€ : 1
0.20€ : 2
0.02€ : 1
0.01€ : 1

Nous considérerons les sommes suivantes pour décomposer les sommes : 500€, 100€, 50€, 20€, 10€, 5€, 2€, 1€, 0.50€, 0.20€, 0.10€, 0.05€, 0.02€, 0.01€. L'algorithme devra bien entendu utiliser le moins de pièces et billets possibles.

Dans un programme nommé rendu_monnaie.py :

  • Crée une fonction rendu_monnaie(prix, somme_payee) qui retourne la somme à rendre.
  • Crée une fonction decomposer_somme(somme) qui retourne l'ensemble des billets et pièces à utiliser et leur nombre nécessaires pour décomposer la somme d'argent somme. Tu peux par exemple retourner cette information sous forme de dictionnaire.
  • Utilise ces fonctions dans un programme qui :
    • Demande à l'utilisateur un prix (float)
    • Demande à l'utilisateur la somme qu'il donne (float)
    • Affiche la somme à rendre ainsi que les billets et pièces à utiliser.

Le pendu

Dans ce chapitre, nous allons commencer puis améliorer un jeu de pendu. Tu es libre d'organiser ton code comme tu le souhaites tant qu'il respecte des règles de base :

  • Le nom des fonctions doit être explicite
  • 1 fonction = 1 action
  • Une fonction ne doit pas faire plus de 20 lignes
  • Le nom des variables doit être explicite

Bien-sûr, ton code doit contenir uniquement des fonctions, qui peuvent faire appel à d'autres fonctions. Le seul code qui sera en dehors d'une fonction est celui qui appelle la boucle de jeu (qui est une fonction).

Fonctionnement du programme

Le programme devra :

  • Demander un mot à l'utilisateur (ce sera le mot à trouver) et l'enregistrer.
  • Limiter le nombre d'erreurs (lettres non contenues dans le mot) à un nombre inférieur à 10 (5 par exemple).
  • Tant qu'il reste des essais :
    • Afficher le mot avec les lettres trouvées et des _ à la place des lettres manquantes.
    • Afficher toutes les lettres essayées jusqu'à présent.
    • Demander une lettre à l'utilisateur.
    • Indiquer si la lettre est contenue dans le mot.
    • Si le mot est complètement trouvé, affichage de la fin de partie.
  • Si le nombre d'essais tombe à 0 et que le mot n'a pas été trouvé, affichage de la fin de partie avec le mot qu'il fallait trouver.

L'affichage peut être le même dans le cas d'une victoire ou d'une défaite mais il faudra quand même indiquer si le joueur a gagné ou perdu.

Pour t'aider, voici un exemple des fonctions que tu peux créer et utiliser :

  • afficher_mot(mot, lettres_trouvees) : Affiche le mot avec uniquement les lettres trouvées et des _ à la place des lettres à trouver.
  • demander_mot() : Demande un mot à l'utilisateur et le retourne (return)
  • afficher_statut(mot, lettres_trouvees, nb_essais) : Affiche le statut complet de la partie, c'est-à-dire :
    • le mot avec les lettres trouvées jusqu'à présent
    • toutes les lettres essayées
    • les essais restants
  • mot_trouve(mot, lettres_trouvees) : Renvoie False s'il reste encore des lettres à trouver dans mot et True si toutes les lettres ont été trouvées.
  • jeu() : la boucle de jeu.

L-systèmes

fractal_weeds.jpg

Les L-systèmes, inventés en 1968 par le biologiste hongrois Aristid Lindenmayer, sont des procédés permettant de modéliser des processus de développement et de prolifération de plantes ou bactéries.

Pour concevoir un L-système, il faut définir un ensemble de symboles et de règles qui vont permettre de modéliser un certain processus de croissance grâce à un système de réécriture.

L'algue de Lindenmayer

Nous allons étudier dans un premier temps un L-système très simple : "l'algue de Lindenmayer". Ce L-système se définit de la manière suivante :

  • Alphabet : {A,B}
  • Axiome de départ : A
  • Règles :
    • A → AB
    • B → A

Les trois points ci-dessus nous permettent de construire de manière récurrente les différentes générations de l'algue de Lindenmayer.

Explications :

  • L'alphabet : Il définit l'ensemble des caractères qui le L-système pourra utiliser.
  • L'axiome de départ : Il précise la génération 0. Dans ce cas, la génération 0 est seulement constituée d'une lettre A.
  • Les règles : Elles permettent de construire la génération n+1 en remplaçant (réécrivant) les A et les B de la génération n par, respectivement, des AB et des A.

Voici les 4 première générations de l'algue de Lindenmayer :

Génération 0 : A
Génération 1 : AB
Génération 2 : AB A
Génération 3 : AB A AB

Maintenant, essaye d'écrire ce que donnent les générations 4, 5 et 6.

Pour chaque génération d'un L-système, on obtient une chaine de caractères que l'on appelle mot. Lorsque l'alphabet du L-Système s'y prête, ce mot peut être interprété comme des "consignes d'affichage".

La courbe de Koch

Définissons maintenant un nouveau L-système : la "courbe de Koch".

  • Alphabet : {F,+,-}
  • Axiome de départ : F
  • Règles :
    • F → F + F - F - F + F
    • + → +
    • - → -

Construire les générations 0, 1 et 2 de la "courbe de Koch".

Le choix de l'alphabet pour la courbe de Koch n'est pas anodin. Les trois symboles choisis peuvent être interprétés comme des instructions de construction pour une main tenant un crayon de la manière suivante (comme avec le module Turtle) :

  • F : avancer d'un pas (= forward).
  • + : tourner à gauche de 90°.
  • - : tourner à droite de 90°.

À partir de ces informations, dessine sur une feuille en t'aidant du quadrillage les générations 1 et 2 de la "courbe de Koch".

Début de la programmation d'un L-système

Nous allons maintenant passer à la pratique.

Crée un programme nommé l-systemes.py dans lequel nous allons créer plusieurs fonctions.

  1. Crée une fonction generation(axiome, regles, n) qui prend en paramètres :
    • L'axiome de départ sous forme de chaine de caractères.
    • l'ensemble des règles sous forme d'un dictionnaire {caractère(s): remplacement}.
    • la génération désirée (0, 1, 2…).
    • La fonction doit renvoyer le mot final une fois que tous les remplacements ont été effectués.
  2. Crée une fonction tracer(mot, angle, pas) qui prend en paramètres :
    • Le mot à tracer.
    • L'angle des rotations droite et gauche.
    • Le pas (longueur) des segments (pour forward).
    • La fonction doit tracer à l'écran à l'aide du module Turtle le mot passé en paramètre.

Essaye de tracer les différentes générations de l'algue de Lendenmayer et de la courbe de Koch pour vérifier que tout fonctionne correctement.

Le cactus

Maintenant que nous avons commencé à créer les fonctions dont nous avons besoin pour obtenir le mot correspondant à une génération et tracer ce mot, nous allons introduire deux nouveaux symboles permettant de faire évoluer nos constructions de L-systèmes.

Définissons un nouveau L-Système : le "cactus" :

  • Alphabet : {F,+,-,[,]}
  • Axiome de départ : F
  • Règles :
    • F → FF[+F-F]FF[-F+F]FF
    • + → +
    • - → -
    • [ → [
    • ] → ]

Construire les générations 0, 1 et 2 du "cactus" (uniquement les mots obtenus).

Pour tracer ce L-système, nouys allons interpréter le mot obtenu avec les conventions suivantes :

  • F : avancer d'un pas.
  • + : tourner à gauche de 90°.
  • - : tourner à droite de 90°.
  • [ : mémoriser la position et l'orientation de la tortue.
  • ] : revenir à la dernière position et à la dernière orientation de la tortue mémorisée.

Tracer les générations 1 et 2 du cactus.

Suite de la programmation

Maintenant que nous avons ajouté deux symboles pour la représentations de nos L-systèmes, il va falloir les ajouter à notre fonction tracer().

  1. Ajoute la gestion du symbole [ dans la fonction tracer(). Tu devras pour cela sauvegarder la position et l'orientation de la tortue. Tu peux les obtenir à l'aide des fonctions t.pos() et t.heading() de Turtle.
  2. Ajoute ensuite la gestion du symbole ] dans la fonction tracer(). Tu pourras utiliser les fonctions t.setpos() et t.setheading() de Turtle.
    • Tu devras utiliser le principe d'une pile pour sauvegarder les positions. La fonction pop() disponible pour les listes te sera très utile. Pour savoir ce qu'est une pile en programmation, google est ton ami !
  3. Enfin, nous allons ajouter deux paramètres à notre fonction : position_initiale et orientation_initiale. Notre fonction sera désormais protypée de la sorte : tracer(mot, angle, pas, position_initiale, orienation_initiale).
    • position_initiale est un tuple de la forme (x,y). x est l'abscisse, y est l'ordonnée.
    • orientation_initiale est un entier correspondant à l'orientation.
  4. Ajoute deux lignes de code au début de la fonction tracer() permettant de placer la tortue à la position donnée dans position_initiale et à l'orientation donnée dans orientation_initiale.

Teste les nouvelles fonctionnalités en traçant quelques générations du cactus.

Nouveaux L-systèmes

Désormais, notre fonction pour tracer un L-système est complète. Nous allons donc pouvoir aborder de nouveaux L-systèmes plus intéressants et plus complexes.

La brindille

brindille

Construire graphiquement (sur l'ordinateur, avec le programme python) la génération 4 de la "brindille", dont le L-système est défini de la manière suivante :

  • Alphabet : {F,+,-,[,]}
  • Axiome de départ : F
  • Règles :
    • F → F[-F]F[+F]F
    • + → +
    • - → -
    • [ → [
    • ] → ]
  • angle = 25
  • pas = 7
  • position_initiale = (0, -250)
  • orientation_initiale = 90

Le flocon de Von Koch

flocon de Von Koch

Construire graphiquement la génération 4 du "flocon de Von Koch", dont le L-système est défini de la manière suivante :

  • Alphabet : {F,+,-,[,]}
  • Axiome de départ : F++F++F++
  • Règles :
    • F → F-F++F-F
    • + → +
    • - → -
    • [ → [
    • ] → ]
  • angle = 60
  • pas = 5
  • position_initiale = (-200, -150)
  • orientation_initiale = 0

La broussaille

broussaille

Construire graphiquement la génération 4 de la "broussaille", dont le L-système est défini de la manière suivante :

  • Alphabet : {F,+,-,[,]}
  • Axiome de départ : F
  • Règles :
    • F → FF-[-F+F+F]+[+F-F-F]
    • + → +
    • - → -
    • [ → [
    • ] → ]
  • angle = 25
  • pas = 10
  • position_initiale = (0, -250)
  • orientation_initiale = 90

Puissance 4

puissance4.jpg

Dans ce chapitre, tu vas mettre en applications tout ce que tu as appris dans les chapitres précédents. Pour cela, tu vas créer un projet de plus grande envergure que les exercices que tu as faits.

Dans cette section, nous allons créer un Puissance 4. Nous commencerons par le créer à partir des notions que nous avons vues, donc avec une interface en ligne de commande. Par la suite, quand nous étudierons comment créer des interfaces graphiques, nous pourrons revenir sur ce projet pour ajouter des visuels plus intéressants.

Les consignes qui sont données dans ce chapitre sont là pour t'aider à réaliser le projet. Le but est que tu développes le Puissance 4 en t'aidant le moins possible des consignes : dans un projet comme celui-ci, il n'y a pas "une seule bonne réponse", chacun peut avoir des idées différentes pour développer et c'est le meilleur moyen de progresser. Si tu es en trop grande difficulté, les étapes décrites dans ce chapitre sont là pour t'aider.

Si tu as des idées d'améliorations ou que tu veux faire quelque chose différemment, tu es libre de les réaliser, c'est ton projet ! Néanmoins, le professeur vérifiera que ton travail est correct et correspond aux bonnes pratiques de Python que nous avons étudiées.

Règles du Puissance 4

Le but du jeu est d'aligner une suite de 4 pions de même couleur sur une grille comptant 6 rangées et 7 colonnes. Chaque joueur dispose de 21 pions d'une couleur, en général jaune ou rouge. Tour à tour, les deux joueurs placent un pion dans la colonne de leur choix, le pion coulisse alors jusqu'à la position la plus basse possible dans la dite colonne à la suite de quoi c'est à l'adversaire de jouer. Le vainqueur est le joueur qui réalise le premier un alignement (horizontal, vertical ou diagonal) consécutif d'au moins quatre pions de sa couleur. Si, alors que toutes les cases de la grille de jeu sont remplies, aucun des deux joueurs n'a réalisé un tel alignement, la partie est déclarée nulle.

Étape 1 : Définir la structure de notre programme

Dans cette étape, tu ne vas pas encore coder. Nous allons d'abord réfléchir à la structure de notre programme et imaginer son fonctionnement général. Il faut que l'on définisse de quelles fonctions nous auront besoin pour faire fonctionner notre programme. Parfois, il est utile d'utiliser du "pseudo code". Le pseudo code, c'est une façon d'écrire un algorithme de façon presque naturelle, sans langage de programmation. Par exemple, dans un pseudo code on peu écrire :

si (utilisateur écrit "Bonjour") alors
    afficher "Bonjour"
sinon
    afficher "Au revoir"

Le pseudo code aide à déterminer quelles actions notre programme devra effectuer.

Notre programme ne comportera que des fonctions. Chaque action devra être effectuée grâce à une fonction. C'est comme ça que l'on programme : ça permet de pouvoir s'y retrouver plus facilement dans le code et de pouvoir mieux repérer nos erreurs.

La seule instruction qui ne sera pas dans une fonction sera celle qui lance le jeu !

Fonctionnement de la grille

La "grille" du jeu sera représentée par une liste à deux dimension, c'est à dire une liste de plusieurs listes. Ce sera donc une liste contenant 6 listes qui contiendront chacune 7 chiffres. Chaque sous-liste de la grille représentera une ligne de la grille. Comme le Puissance 4 contient 7 colonnes, chaque ligne aura donc 7 chiffres. La valeur d'une case de la grille a 3 possibilités :

  • 0 : la case est libre.
  • 1 : un jeton du joueur 1 est placé ici.
  • 2 : un jeton du joueur 2 est placé ici.

Au début, la grille sera remplie de 0 :

[[0,0,0,0,0,0,0],
 [0,0,0,0,0,0,0],
 [0,0,0,0,0,0,0],
 [0,0,0,0,0,0,0],
 [0,0,0,0,0,0,0],
 [0,0,0,0,0,0,0]]

Lorsqu'un joueur placera un pion, il devra choisir seulement la colonne. À nous de "simuler" le fait que le pion tombe jusqu'à la première ligne disponible. Nous aurons une fonction pour cela. Par exemple, si le joueur 1 décide de placer son pion dans la colonne 3 (en partant de 0), la grille contiendra :

[[0,0,0,0,0,0,0],
 [0,0,0,0,0,0,0],
 [0,0,0,0,0,0,0],
 [0,0,0,0,0,0,0],
 [0,0,0,0,0,0,0],
 [0,0,0,1,0,0,0]]

Si le joueur 2 décide de placer son pion dans la même colonne que le joueur 1, la grille deviendra :

[[0,0,0,0,0,0,0],
 [0,0,0,0,0,0,0],
 [0,0,0,0,0,0,0],
 [0,0,0,0,0,0,0],
 [0,0,0,2,0,0,0],
 [0,0,0,1,0,0,0]]

Et ainsi de suite.

Par exemple, si les jetons jaunes sont ceux du joueur 1 et les jetons rouges ceux du joueur 2, nous pouvons représenter la grille comme cela :

schema_liste.png

Pour parcourir une liste à deux dimensions, c'est à dire effectuer un test ou une action sur chaque case de la liste, nous utilisons une double boucle. En effet, par exemple si l'on veut ajouter un pion du joueur 1 dans la 2ème colonne de la 3ème ligne, il faut écrire :

grille[2][1] = 1
# grille[ligne][colonne]

Le premier indice correspond à la ligne et le second à la colonne. Alors pour parcourir et afficher toute la liste :

for ligne in range(len(grille)):
    for colonne in range(len(grille[ligne])):
        print(grille[ligne][colonne])

Liste des fonctions

Maintenant que nous avons une idée générale du fonctionnement de la grille de jeu, voici une liste exhaustive des fonctions dont nous aurons besoin. Tu n'as pas besoin de tout comprendre dès le début, cette section servira aussi plus tard pour t'y retrouver dans toutes les fonctions. Ne commences pas non plus à coder les fonctions ici car nous allons revenir en détail sur chacune d'elles dans les étapes suivantes.

L'important est de visualiser à peu près comment sera notre programme.

  • jeu() : c'est la fonction qui lancera le jeu et le relancera une fois la partie terminée si le joueur en a envie.
    • initialiserGrille() : cette fonction permettra d'initialiser (mettre à zéro) la grille du Puissance 4. C'est comme si elle enlevait les pions ! On utilisera cette fonction avant chaque début de partie, dans la fonction jeu().
    • boucleDeJeu() : c'est la fonction qui demandera aux joueurs de choisir où poser leurs jetons et les placera tant qu'aucun des deux joueurs n'aura gagné et que la grille n'est pas pleine. Quand le jeu est fini, elle retourne le numéro du joueur qui a gagné (ou False si c'est un match nul).
      • joueurGagne(joueur) : cette fonction détermine si le joueur passé en argument a gagné la partie. Elle sera utilisée dans la fonction boucleDejeu().
        • verifierHorizontalement(joueur) : vérifie si le joueur passé en paramètre a aligné 4 pions horizontalement dans la grille. Elle sera utilisée dans la fonction joueurGagne(joueur).
        • verifierVerticalement(joueur) : vérifie si le joueur passé en paramètre a aligné 4 pions verticalement dans la grille. Elle sera utilisée dans la fonction joueurGagne(joueur).
        • verifierDiagonale(joueur) : vérifie si le joueur passé en paramètre a aligné 4 pions en diagonale dans la grille. Elle sera utilisée dans la fonction joueurGagne(joueur).
      • verifierGrillePleine() : cette fonction devra parcourir la grille pour vérifier s'il y a encore de la place pour poser des jetons. Elle sera utilisée dans la fonction boucleDeJeu().
      • afficherGrille() : cette fonction affiche la grille actuelle. Nous formaterons la grille pour qu'elle apparaisse de manière compréhensible aux joueurs. Elle sera utilisée dans la fonction boucleDeJeu()
      • jouerLeTour(joueurActuel) : cette fonction demandera à un joueur dans quelle colonne il veut placer son jeton. Elle placera ensuite le jeton au bon endroit, c'est-à-dire à la dernière ligne disponible de la colonne demandée. Elle sera utilisée dans la fonction boucleDeJeu()
        • demanderColonne(joueur) : cette fonction permet de demander au joueur dans quelle colonne il veut placer son pion. Elle renverra le numéro de la colonne demandée. Elle sera utilisée dans la fonction remplirGrille(joueurActuel).
        • ligneLibreDeLaColonne(colonne) : cette fonction renverra le numéro de la ligne libre de la colonne choisie par le joueur. Elle sera utilisée dans la fonction remplirGrille(joueurActuel).
        • placerJeton(joueur, coordonnees) : cette fonction permet de placer le jeton du joueur passé en paramètre à l'endroit de la grille indiqué par coordonnees. coordonnees sera un tuple qui aura cette forme : (ligne, colonne). Elle sera utilisée dans la fonction remplirGrille(joueurActuel).
      • recupererSymbole(numeroJoueur) : cette fonction retourne simplement le symbole correspondant au numéro du joueur passé en paramètre. Si le numéro n'est ni 1 ni 2 alors la fonction renverra un espace ' '. Par exemple, si nous utilisons 'X' pour le joueur 1 et 'O' pour le joueur 2, la fonction recupererSymbole(1) renverra 'X'.
    • afficherFinDePartie(gagnant) : cette fonction fera l'affichage de la fin du jeu en félicitant le gagant s'il y en a un et en disant qu'il y a match nul sinon.
    • demanderRejouer() : cette fonction demandera aux joueurs s'ils veulent rejouer et retourne True ou False en fonction de leur réponse.

Étape 2 : Définir les variables globales

Une variable globale est une variable qui pourra être utilisée dans toutes les fontions d'un programme, sans avoir besoin de la passer en paramètre. Pour le Puissance 4, nous aurons besoin de 3 variables. Elles correspondront à la grille de jeu, au symbole du joueur 1 et au symbole du joueur 2 dans la grille.

Comme vu précédemment, La grille sera une liste de 6 listes qui contiendront chacune 7 chiffres. Chaque sous-liste de la grille représentera une ligne de la grille.

Pour les symboles, je te conseille d'utiliser les caractères 'X' et 'O' pour bien différencier les joueurs.

Pour créer des variables globales, c'est très simple : c'est comme des variables normales, sauf qu'elles ne sont pas dans une fonction. Pour notre cas, nous appelerons nos variables grille, symboleJoueur1 et symboleJoueur2 :

grille = [[0,0,0,0,0,0,0],
          [0,0,0,0,0,0,0],
          [0,0,0,0,0,0,0],
          [0,0,0,0,0,0,0],
          [0,0,0,0,0,0,0],
          [0,0,0,0,0,0,0]]
symboleJoueur1 = 'X'
symboleJoueur2 = 'O'

Nous n'aurons pas besoin d'autres variables globales pour le moment.

Étape 3 : Définir les fonctions d'affichage

Affichage des symboles des joueurs

  • Crée une fonction recupererSymbole(numeroJoueur). La logique de cette fonction sera :

    si numeroJoueur est égal à 1:
        renvoyer symboleJoueur1
    sinon si numeroJoueur est égal à 2:
        renvoyer symboleJoueur2
    sinon
        renvoyer le caractère 'espace'
    

Affichage de la grille

  • Crée une fonction initialiserGrille() qui utilisera la variable globale grille pour lui redonner sa valeur par défaut :

    global grille
    grille = [[0,0,0,0,0,0,0],
              [0,0,0,0,0,0,0],
              [0,0,0,0,0,0,0],
              [0,0,0,0,0,0,0],
              [0,0,0,0,0,0,0],
              [0,0,0,0,0,0,0]]
    
  • Crée une fonction afficherGrille(). Cette fonction doit simplement afficher toutes les cases de la grille grille (variable globale) pour que ce soit compréhensible pour les joueurs. Il faudra pour cela utiliser une double boucle pour parcourir chaque "case" de la liste. Pour chaque case, on doit afficher le symbole correspondant au pion du joueur placé. Dans notre cas, si c'est 1 il faudra afficher 'X'. Ensuite on peut ajouter des caractères pour bien séparer chaque case. Voici un exemple d'affichage :

Début de partie :

exemple_vide.png

Après quelques tours :

exemple_tours.png

Affichage de fin de partie

  • Crée une fonction afficherFinDePartie qui prend en paramètre une variable gagnant. Cette fonction doit :
    • Afficher la grille.
    • Afficher un texte qui dit quel joueur a gagné. Dans le cas où c'est un match nul, gagnant aura comme valeur 0. Ne pas oublier ce cas-là !

Tu peux tester tes fonctions d'affichage en les appelant dans le programme, pour être sûr que ce qui est affiché correspond bien à ce que tu voulais.

Étape 4 : Définir les fonctions pour lancer le jeu

  • Crée une fonction boucleDeJeu() qui contiendra seulement le mot clef pass. Nous coderons cette fonction à l'étape suivante mais nous avons besoin de l'appeler dans la fonction de lancement du jeu.

    def boucleDeJeu():
        pass
    
  • Crée une fonction demanderRejouer(). Elle devra :
    • Demander à l'utilisateur s'il veut rejouer tant que sa réponse n'est ni 'o' ni 'n'. Il devra taper 'o' s'il veut rejouer et 'n' s'il veut arrêter.
    • Retourner True si l'utilisateur veut rejouer et False sinon.
  • Crée une fonction jeu() :
    • Tant que l'utilisateur veut rejouer, il faut :
      • Initialiser la grille en utilisant la fonction adéquate.
      • Appeler la fonction boucleDeJeu() et recuperer son resultat.
      • Afficher le message de fin de partie en utlisant la fonction adéquate.
      • Demander à l'utilisateur s'il veut rejouer en utilisant la fonction adéquate.
    • Quand on sort de la boucle, cela veut dire que l'utilisateur ne veut plus jouer. Dans ce cas, il faudra juste afficher "Au revoir !".

Étape 5 : Déroulement d'une partie

Dans cette étape nous allons commencer la fonction principale boucleDeJeu(). Nous allons préparer la logique et nous coderons les fonctions intérmédiaires au fur et à mesure des étapes suivantes.

Fonctions intermédiaires

Pour commencer, nous allons déclarer les fonctions utilisées dans boucleDeJeu() sans pour autant en écrire le code, avec le mot-clef pass :

  • Crée une fonction joueurGagne() qui prend en paramètre joueur.
  • Crée une fonction verifierGrillePleine().
  • Crée une fonction jouerLeTour() qui prend en paramètre joueur.

Boucle du jeu

Définissons maintenant la logique de la boucle de jeu :

  • Modifie la fonction boucleDeJeu() en enlevant l'instruction pass
  • Nous avons besoin d'une variable qui contiendra le numéro du joueur qui doit jouer. Cette variable sera toujours égale à 1 au début d'un partie (le joueur 1 commence).
  • Tant que la grille n'est pas pleine (verifierGrillePleine()), il faut :
    • Afficher la grille.
    • Jouer le tour du joueur actuel (sans oublier de préciser quel joueur).
    • Si le joueur actuel gagne (joueurGagne(...)), il faut renvoyer la valeur du joueur gagnant.
    • Sinon, inverser le numéro du joueur (la variable devient 2 si on fait jouer 1 et vice-versa).
  • Quand c'est fini, cela signifie qu'il y a match nul. Dans ce cas, il faudra renvoyer 0.

Étape 6 : Déroulement d'un tour

Nous allons maintenant coder le déroulement d'un tour. Voici ce qu'il se passe à chaque tour :

  • On demande à un joueur de choisir la colonne où placer son jeton. On lui redemande tant qu'il choisi une colonne inexistante (<0 ou >6).
  • On trouve quelle ligne est la première ligne libre (en partant du bas) de la colonne choisie.
  • On place le jeton du joueur dans la grille, aux coordonnées ainsi trouvées.

Demander la colonne

Commençons par la fonction qui demande la colonne au joueur :

  • Crée une fonction demanderColonne() qui prend en paramètre joueur. Cette fonction doit :
    • Afficher un message demandant au joueur de choisir sa colonne (préciser à quel joueur on demande pour que ce soit plus clair).
    • Récupérer son choix et le convertir en entier.
    • Recommencer tant que le choix de colonne est incorrect (afficher un message précisant pourquoi on redemande au joueur un numéro de colonne).
    • Retourner le choix de l'utilisateur.

Trouver la ligne où placer le jeton

Passons maintenant à la fonction qui trouve la ligne libre d'une colonne. Nous allons devoir coder une fonction qui parcourt chaque ligne de la grille pour vérifier si la colonne choisie est libre sur cette ligne. (Voir le fonctionnement de la grille à l'étape 1 pour savoir si une case est libre).

Il faudra garder la dernière ligne libre trouvée, car le parcours de la liste se fait de haut en bas et que nous devons placer les jetons le plus bas possible.

  • Crée une fonction ligneLibreDeLaColonne() qui prend en paramètre la colonne. Cette fonction doit parcourir toutes les lignes de la colonne afin de trouver la colonne libre la plus basse. Elle devra renvoyer le numéro de la ligne libre et -1 si aucune ligne n'est libre pour cette colonne.

Placer le jeton

La dernière fonction intermédiaire pour un tour sera la fonction placerJeton(joueur, coordonnees). Cette fonction placera simplement le numéro du joueur à un l'endroit défini par le tuple coordonnees.

Jouer le tour

Enfin, nous allons pouvoir créer la fonction qui fait jouer le tour au joueur :

  • Modifie la fonction jouerLeTour() précédemment créée en supprimant le mot-clef pass. Voici la logique de la fonction :
    • Tant que la ligne vaut -1 (c'est à dire est incorrecte) :
      • Demander la colonne au joueur (récupérer le résultat).
      • Trouver la ligne libre pour cette colonne (récupérer le résultat).
      • Si la ligne vaut encore -1 dire au joueur que la colonne qu'il a choisie n'est plus libre.
    • Quand on a trouvé la ligne correspondant à la colonne choisie, placer le jeton du joueur aux coordonnées trouvées.

Nous avons fini de créer le déroulement d'un tour. Dans la prochaine étape, nous nous attaquerons à la fonction qui trouve le gagnant d'une partie.

Étape 7 : Y a-t-il un vainqueur ?

Désormais, on peut faire jouer un tour à un joueur. Il faut maintenant que l'on puisse déterminer à chaque fin de tour si le joueur qui vient de jouer a gagné ou s'il y a match nul.

Pour cela, nous utiliserons deux fonctions différentes : une première qui permet de vérifier si un joueur passé en paramètre a gagné et une seconde qui permet de vérifier si la grille est pleine.

Trouver un alignement

Nous allons commencer par déterminer si un joueur a gagné. Pour cela, nous devons créer 3 fonctions intermédiaires :

  • verifierHorizontalement(joueur) : cette fonction vérifie si le joueur spécifié passé en paramètre a un alignement horizontal de 4 jetons. Pour cela, il faut parcourir toutes les lignes de la liste pour vérifier si le numéro du joueur apparaît 4 fois de suite dans la ligne.
  • verifierVerticalement(joueur) : cette fonction vérifie si le joueur spécifié a un alignement vertical de 4 jetons. Il faudra parcourir chaque colonne de la liste pour vérifier si le numéro du joueur apparaît 4 fois de suite dans la colonne. Conseil : pas besoin de commencer la vérification au-delà de la 3ème ligne, car ce n'est plus possible d'aligner 4 pions sur 3 lignes !
  • verifierDiagonale(joueur) : cette fonction vérifie si le joueur spécifié a un aligement en diagonale de 4 jetons. Il faudra parcourir toute la liste en cherchant si le numéro du joueur apparaît 4 fois de suite dans une diagonale ou dans l'autre. En effet, n'oublie pas les deux sens possibles d'une diagonale ! Cette fonction sera un peu plus difficile que les autres, je te conseille de commencer par essayer de parcourir les diagonales de la liste en faisant des tests d'affichage.

Le joueur a-t-il a gagné ?

Maintenant que nous avons codé nos 3 fonctions intermédiaires, nous pouvons modier la fonction joueurGagne(joueur). La fonction doit maintenant renvoyer True si le joueur a un alignement horizontal, vertical ou en diagonale. Sinon, elle retourne False.

Match nul ?

Enfin, il nous manque la fonction qui vérifie s'il y a match nul. Nous savons qu'il y a match nul si la grille est remplie et que personne n'a gagné. Alors, nous avons simplement besoin d'une fonction qui vérifie si la grille est pleine :

  • Modifie la fonction verifierGrillePleine(). Elle doit renvoyer True si la grille est pleine et False sinon.

Étape 8 : Lancement du jeu !

Désormais, il ne nous reste plus qu'à lancer le jeu : appelle simplement la fonction jeu() dans le programme !

Quand tu vas tester le jeu, il est très fort probable qu'il y ait des "bugs" et que certaines choses ne fonctionnent pas : c'est normal pour un gros programme. Ne t'inquiètes pas et n'hésite pas à faire plein de tests pour chaque fonction pour trouver d'où vient le problème.

Graphismes avec tkinter

Tkinter est un module python qui permet de créer des interfaces graphiques, c'est-à-dire d'afficher à l'écran une interface avec des boutons, des textes, des cases à cocher, etc. Cela permet de créer des programmes plus pratiques et jolis pour les utilisateurs.

Ressources

Voici quelques liens utiles pour en savoir plus sur tkiner.

Peindre sur une toile

Pour introduire quelques concepts clefs de tkinter, nous allons commencer par créer ensemble notre premier petit projet avec interface graphique. Il s'agit de permettre à l'utilisateur de dessiner ce qu'il veut sur un endroit donné avec les couleurs qu'il veut.

Début

Tout d'abord, crée un programme nommé chef_d_oeuvre.py.

Pour commencer, comme tous les modules utilisés jusqu'à préssent (turtle, random, etc), il faut importer tkinter.

import tkinter

La première étape pour créer une interface graphique avec tkinter est de créer une fenêtre et de la stocker dans une variable. Nous utiliserons cette variable tout au long du programme pour savoir dans quelle fenêtre nous travaillons.

fenetre = tkinter.Tk()

Créer et afficher un texte

Maintenant, nous pouvons commencer à configurer l'apparence de notre fenêtre.

Pour afficher du texte dans une fenêtre, nous utilisons la fonction tkinter.Label(). Cette fonction prend une suite de paramètres dont seul le premier est obligatoire : c'est la fenêtre dans laquelle le texte doit se placer. Les autres paramètres sont pour configurer l'apparence du texte (y compris le texte en lui-même).

Comme les autres paramètres sont optionnels, il faut les nommer précisément et on peut les écrire dans l'ordre que l'on veut.

Ensuite, lorsque le texte est configuré, il faut l'insérer dans la fenêtre avec la fonction pack(). Cette étape est toujours nécessaire pour afficher quelque chose dans la fenêtre. Il existe d'autres fonctions pour placer les objets dans la fenêtre mais nous les verrons plus tard.

# Configuration du texte
texte = tkinter.Label(fenetre, text="Pour dessiner, utilise ta souris en appuyant sur le bouton gauche.")
# Placement du texte dans la fenêtre
texte.pack()

Créer et afficher un canvas

Un canvas est un objet de tkinter qui permet de dessiner sur une zone donnée. La fonction utilisée est tkinter.Canvas(). Tout comme le texte, seul le premier paramètre (la fenêtre) est obligatoire.

# Configurationn du canvas: width(=longueur)=750 pixels, height(=hauteur)=500 pixels, background(=arrière-plan) blanc
canvas = tkinter.Canvas(fenetre, width=750, height=500, bg="white")
# Placement du canvas dans la fenêtre
canvas.pack()

Enregistrer la position

Nous allons maintenant nous intéresser à la logique du programme. Avec tkinter, l'utilisateur peut interagir avec l'interface, et chaque interaction déclenche un "évènement" appelé event. Le principe est donc le suivant :

  1. Définir des fonctions à appeler dans le cas d'évènements précis. Par exemple, nous voulons que notre programme appelle la fonction quand_clic() lorsqu'un clic de souris est détecté.
  2. Détecter les évènements qui nous intéressent et les envoyer vers les fonctions associées.

Tout d'abord, nous allons avoir besoin de 3 variables dans notre programme : dernierX, qui stockera la dernière position X, dernierY, qui stockera la dernière position Y et couleur qui correspondra à la couleur de dessin actuelle.

Initialise dernierX et dernierY à 0. Initialise couleur à "black" pour que la couleur de départ soit le noir.

Maintenant, écrivons une fonction enregistrer_position(event) nous permettant de suivre les mouvements du pointeur de souris. Le paramètre event contient plein d'informations relatives à l'évènement qui a déclenché l'appel de la fonction.

Voici le code du corps de la fonction :

global dernierX, dernierY # "global" permet de préciser que dernierX et dernierY sont les variables globales du programme et pas uniquement des variables de la fonction.
dernierX = event.x
dernierY = event.y
# Ces deux lignes enregistrent les position x et y de l'évènement qui a déclenché l'appel de fonction.

Que faire lorsqu'un clic est détecté ?

Nous allons créer la fonction qui sera appelée quand l'utilisateur cliquera sur la souris. Elle enregistrera simplement l'emplacement de la souris au moment du clic.

def quand_clic(event):
    enregistrer_position(event)

Et c'est tout pour le clic !

Que faire lors du déplacement de la souris après le clic ?

C'est ici que l'on va commencer à dessiner des formes sur le canvas. Pour que l'utilisateur puisse dessiner ce qu'il veut, nous utiliserons simplement une ligne qui se dessinera pixel par pixel. Chaque déplacement déclenchera l'appel de la fonction quand_bouge(event). Cette fonction tracera une ligne entre le dernier point enregistré et le point où se trouve la souris actuellement. Ensuite, elle devra enregistrer la nouvelle position pour préparer le prochain mouvement.

Définis la fonction quand_bouge(event). Le code à l'intérieur est le suivant :

# La fonction create_line a 4 parametres obligatoires : les coordonnées du début de la ligne (x, y) et les coordonées de la fin (x, y)
# Nous ajoutons ensuite le parametre de couleur en utilisant la variable gloable couleur puis nous mettons l'épaisseur de la ligne à 3 pixels.
canvas.create_line(dernierX, dernierY, event.x, event.y, fill=couleur, width=3)

La dernière étape de la fonction est d'enregistrer la nouvelle position de event. N'oublie pas d'écrire cette partie (nous l'avons déjà vue précédemment) !

Détecter les évènements

Nous avons préparer les fonctions à appeler lorsque seront détectés les évènements qui nous intéressent. Il faut maintenant que l'on écrive le code qui nous permettra de détecter les évènements en question.

La fonction qui permet d'associer la détection d'évènement à une fonction à déclencer est la fonction bind. Pour détecter un événement dans un objet en particulier, on écrit nom_objet.bind(...). Dans notre cas, nous voulons détecter les évènements dans l'objet canvas. Nous écrivons donc :

canvas.bind("<Button-1>", quand_clic)   # premier paramètre = évènement à détecter
                                        # second paramètre = fonction à appeler

L'évènement qui correspond au mouvement de la souris s'appelle <B1-Motion>. Ajoute la ligne qui permet de détecter cet évènement et d'appler la fonction quand_bouge().

Peindre en couleur

Maintenant, nous allons créer une petite palette de couleurs sur le côté afin de pouvoir choisir la couleur de notre dessin. Pour cela, nous allons créer des petits carrés de couleurs que nous allons placer dans le canvas.

Lorsque l'on crée un objet dans un canvas et de manière générale dans une fenêtre tkinter, l'ordinateur lui attribue un numéro unique appelé id (pour identifiant). Nous le gardons en mémoire afin de pouvoir le réutiliser.

Pour créer une forme, il existe plusieurs fonctions. Pour un rectangle, nous utilisons la fonction create_rectangle de l'objet canvas. Cette fonction prend en paramètres, dans l'odre :

  1. x du point en haut à gauche du rectangle
  2. y du point en haut à gauche du rectangle
  3. x du point en bas à droite du rectangle
  4. y du point en bas à droite du rectangle

A cela nous pouvons ajouter des paramètres nommés, comme fill qui permet de choisir la couleur de remplissage.

Dessinons le premier carré permettant de choisir la couleur rouge :

red_id = canvas.create_rectangle(10, 10, 30, 30, fill="red")

Dessine 3 autres carrés les uns en dessous des autres avec les couleurs de ton choix. Les coordonnées des autres carrés sont :

  • 10,35,30,55
  • 10,60,30,80
  • Trouve les coordonnées du dernier carré !

Il faut maintenant créer les fonctions qui seront associées à l'évènement d'un clic sur un carré. Le plus simple est de faire une fonction par couleur :

def couleur_rouge(event):
    global couleur # le mot-clé global permet de dire à python que nous modifions la variable couleur qui a été créée dans le programme, et non pas uniquement dans la fonction.
    couleur = "red"

Crée les 3 autres fonctions pour les couleurs que tu as choisies.

Il ne nous reste plus qu'à associer le clic sur un carré à la fonction appropriée. Pour détecter un évènement sur un objet précis dans le canvas, on utilise la fonction tag_bind() qui prend en paramètres :

  1. L'id de l'objet
  2. L'évènement à détecter
  3. La fonction à associer à l'évènement

Voici le code pour lier le clic sur le carré rouge à la bonne fonction :

canvas.tag_bind(red_id, "<Button-1>", couleur_rouge)

A toi d'écrire les 3 autres lignes !

Ton programme devrait être prêt désormais, teste-le !