Table of Contents
SUTOM #
Le but de cette séance est la construction de votre propre sutom.
Dans ce jeu, il faut deviner un mot, dont la première lettre vous est fournie, ainsi que la longueur. Pour avancer dans la résolution, il vous faut proposer d’autres mots, commençant par la même lettre et ayant la même longueur. Le jeu vous indique alors dans le mot que vous proposez si certaines lettres de votre mot font partie du mot à deviner, et si elles sont à la bonne place ou non. Par exemple si le mot à deviner est
RESTAURANT
Le jeu vous donne l’amorce suivante :
R.........
Vous devez alors proposer un mot commençant par R et composé de 10 lettres. Par exemple
RACCOURCIR
Dans ce mot, on commence par regarder les lettre qui sont bien placées. Nous obtenons alors
R....UR...
Ensuite nous regardons pour les lettres restantes s’il y en a qui sont mal placées, nous les écrirons en minuscule
Ra...UR...
Vous pouvez ensuite proposer un nouveau mot, jusqu’à trouver le mot caché. Notre but pour cette séance est de créer un programme pour animer le jeu. Le programme choisira un mot, demandera des propositions, vérifiera que le mot proposé existe, et examinera les lettres en bonne et en mauvaise position.
Info : chaînes de caractères #
Pour commencer, nous allons voir quelques outils pour travailler sur les mots. Tout d’abord, nous allons créer une variable que nous appelerons secret, et qui contiendra le mot RESTAURANT. Cette variable représentera le mot à deviner.
secret = "RESTAURANT"
Nous avons ici utilisé les double guillemets pour créer un mot. En programmation, on utilise généralement le terme chaîne de caractères, car l’objet que nous manipulons est une séquence de caractères mis bout à bout. Chaque caractère est accessible individuellement en utilisant des crochets pour indiquer l’indice du caractère que nous souhaitons extraire.
print(secret[0])
print(secret[1])
print(secret[2])
print(secret[3])
R
E
S
T
Un contrôle est réalisé lors de l’accès aux caractères, et une erreur sera émise si l’indice n’est pas correct.
print(secret[8])
print(secret[9])
print(secret[10])
N
T
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
Cell In[3], line 3
1 print(secret[8])
2 print(secret[9])
----> 3 print(secret[10])
IndexError: string index out of range
L’erreur ici indique string index out of range. Le terme string est le mot anglais pour chaîne de caractères. Cette erreur vous dit donc que l’indice utilisé pour accéder à la chaîne de caractère est en dehors des bornes autorisées, ici car la chaîne ne comporte que 10 caractères, indexés de 0 à 9. Vous pouvez d’ailleurs obtenir le nombre de caractères composant la chaîne de caractères en utilisant la fonction len
len(secret)
10
Les chaînes de caractères en Python ne sont pas modifiables.
copie[0] = 'P'
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[5], line 1
----> 1 copie[0] = 'P'
NameError: name 'copie' is not defined
Il existe par contre de nombreuses manières de forger des chaînes de caractères. Nous allons utiliser le formatage, qui permet d’insérer les valeurs de variables dans une chaîne de caractères. Pour fabriquer une telle chaîne de caractères, il faut faire précéder les guillemets de la chaîne d’un f.
secret = "RESTAURANT"
phrase = f"J'aime bien manger au {secret} parce qu'au {secret} il y a des frites."
print(phrase)
J'aime bien manger au RESTAURANT parce qu'au RESTAURANT il y a des frites.
Vous pouvez également agrandir une chaîne de caractères avec ce principe :
decompte = ""
for i in range(10):
decompte = f"{decompte} !! {i}"
print(decompte)
!! 0 !! 1 !! 2 !! 3 !! 4 !! 5 !! 6 !! 7 !! 8 !! 9
Enfin, pour manipuler une chaîne caractère par caractère, il est possible de l’éclater en une liste de caractères, puis de recomposer cette liste en une seule chaîne.
lettres = list(secret)
print(lettres)
lettres[1] = "A"
print(lettres)
resultat = "-".join(lettres)
print(resultat)
resultat = "/".join(lettres)
print(resultat)
resultat = "".join(lettres)
print(resultat)
['R', 'E', 'S', 'T', 'A', 'U', 'R', 'A', 'N', 'T']
['R', 'A', 'S', 'T', 'A', 'U', 'R', 'A', 'N', 'T']
R-A-S-T-A-U-R-A-N-T
R/A/S/T/A/U/R/A/N/T
RASTAURANT
Exercice : création de l’amorce #
Dans cette partie, à vous de jouer pour créer l’amorce à partir du secret, c’est à dire que si le mot secret est RESTAURANT, votre programme doit proposer R......... pour débuter le jeu. Pour cette exercice, vous aurez besoin des ingrédients suivants :
- fabriquer une variable
amorcepour créer votre amorce, contenant initialement la première lettre du secret - obtenir la longueur du secret en utilisant la fonction
len - augmenter votre amorce avec
+pour ajouter autant de.que de lettres à deviner dans le secret, avec une bouclefor
# Votre code ici
Info : réaliser des tests #
Pour programmer la suite, il va nous falloir pouvoir tester une proposition. Créons une variable proposition pour l’instant.
proposition = "RACCOURCIR"
Python permet de réaliser des tests, et de réaliser certaines actions selon qu’un test est réussi ou échoué. Pour tester si deux choses sont égales, il est possible d’utiliser ==.
print(12 == 12)
print(12 == 15)
print(secret[0] == "R")
print(secret[1] == "E")
print(secret[2] == "T")
True
False
True
True
False
Pour changer le comportement d’un programme, on utilise un bloc if. Comme pour la boucle for, la ligne du if doit se terminer par : et le code à exécuter selon le résultat du test doit être indenté.
if proposition[0] == "R":
print("bravo vous avez trouvé la première lettre")
if proposition[1] == "E":
print("bravo vous avez trouvé la seconde lettre")
bravo vous avez trouvé la première lettre
Pour exécuter un code différent lorsque le test échoue, il est possible de rajouter un bloc else, en terminant la ligne par : comme pour les autres blocs.
if proposition[0] == "R":
print("bravo vous avez trouvé la première lettre")
else:
print("la première lettre est fausse, veuillez retenter")
if proposition[1] == "E":
print("bravo vous avez trouvé la seconde lettre")
else:
print("la seconde lettre est fausse, veuillez retenter")
bravo vous avez trouvé la première lettre
la seconde lettre est fausse, veuillez retenter
Il est possible de mettre des blocs dans des blocs.
if proposition[0] == "R":
if proposition[1] == "E":
print("bravo vous avez trouvé les deux premières lettres")
else:
print("vous avez trouvé la première lettre, mais la seconde est fausse")
else:
print("votre première lettre n'est pas correcte")
vous avez trouvé la première lettre, mais la seconde est fausse
for i in range(10):
if i < 5:
print(f"{i} est plus petit que 5")
0 est plus petit que 5
1 est plus petit que 5
2 est plus petit que 5
3 est plus petit que 5
4 est plus petit que 5
Au delà du ==, il est également possible d’utiliser d’autres opérateurs de comparaison, par exemple < ou >, et leurs variantes autorisant l’égalité <= et >=, ou encore != pour tester la différence.
for i in range(10):
if i < 5:
print(f"{i} est plus petit que 5")
if i >= 7:
print(f"{i} est plus grand ou égal à 7")
0 est plus petit que 5
1 est plus petit que 5
2 est plus petit que 5
3 est plus petit que 5
4 est plus petit que 5
7 est plus grand ou égal à 7
8 est plus grand ou égal à 7
9 est plus grand ou égal à 7
Vous pouvez réaliser des opérations sur les tests pour les combiner via and et or.
for i in range(10):
if i > 3 and i < 7:
print(f"{i} est entre 3 et 7")
if i <= 3 or i >= 7:
print(f"{i} est en dehors des bornes")
0 est en dehors des bornes
1 est en dehors des bornes
2 est en dehors des bornes
3 est en dehors des bornes
4 est entre 3 et 7
5 est entre 3 et 7
6 est entre 3 et 7
7 est en dehors des bornes
8 est en dehors des bornes
9 est en dehors des bornes
Enfin vous pouvez prendre la négation d’un test en utilisant not
for i in range(10):
if not(i > 3 and i < 7):
print(f"{i} est en dehors des bornes")
0 est en dehors des bornes
1 est en dehors des bornes
2 est en dehors des bornes
3 est en dehors des bornes
7 est en dehors des bornes
8 est en dehors des bornes
9 est en dehors des bornes
Exercice : vérifier qu’une proposition est valide #
Pour qu’une proposition soit valide, il faut que sa première lettre soit la même que celle du secret, et qu’elle ait autant de lettres. Écrivez un programme qui vérifie ces deux critères et qui affiche si la proposition est valide ou non.
proposition = "RACCOURCIR"
# Votre code ici
Testez votre code avec plusieurs propositions, et en particulier, vérifiez que votre programme n’a pas d’erreurs si la proposition est la suivante.
proposition = ""
Exercice : identifier les lettres qui sont correctes et à la bonne position #
Le jeu identifie dans la proposition les lettres qui sont correctes et à leur place. À vous de programmer cette étape. Par exemple, pour le secret RESTAURANT et la proposition RACCOURCIR votre programme devra afficher R....UR...
proposition = "RACCOURCIR"
# Votre code ici
Exercice : identifier si une lettre est dans le secret #
Le jeu identifie également les lettres de la proposition qui ne sont pas bien placées mais présentes dans le secret. Pour commencer plus simplement, vous commencerez par écrire un programme qui détermine si une lettre est présente ou non dans le secret. Créez une variable lettre et stockez y une lettre à tester, puis parcourez le secret pour déterminer si une lettre lui correspond. Votre programme affichera s’il trouve la lettre ou non. Vous pouvez vous aider d’une variable supplémentaire que vous initialiserez à la valeur False et dont la valeur changera à True lorsque vous trouverez la lettre.
# Votre code ici
Exercice : ne pas utiliser deux fois la même lettre #
Dans le jeu, une lettre du secret ne peut servir qu’une fois. Si une lettre de la proposition lui correspond, elle ne peut pas également être utilisée pour indiquer qu’une autre lettre identique est mal placée. Dans l’exemple avec le secret RESTAURANT et la proposition RACCOURCIR, les deux R du secret correspondent exactement à deux R de la proposition. Le dernier R de la proposition ne doit donc pas être considéré comme mal placé. De même si une lettre du secret est utilisée pour indiquer qu’une lettre de la proposition est mal placée, elle ne peut pas être utilisée une seconde fois. Par exemple, pour le secret CAROTTE, et la proposition COMPOTE, le premier O de compote sera considéré comme mal placé, mais le second sera considéré comme absent, car il n’y a qu’un O dans CAROTTE.
Pour répondre à ce problème, nous allons ajouter en plus une liste permettant de réserver une lettre. Cette liste aura la même taille que le secret, et contiendra False à l’indice i si la lettre du secret à l’indice i est libre, et True si elle est déjà réservée. Pour créer et manipuler une telle liste de taille 5 par exemple, remplie de False, vous pouvez faire comme suit.
reserve = [False] * 5
print(reserve)
reserve[1] = True
reserve[4] = True
print(reserve)
for i in range(5):
if reserve[i]:
print(f"la lettre {i} est réservée")
else:
print(f"la lettre {i} est libre")
[False, False, False, False, False]
[False, True, False, False, True]
la lettre 0 est libre
la lettre 1 est réservée
la lettre 2 est libre
la lettre 3 est libre
la lettre 4 est réservée
À vous donc d’écrire le programme qui vérifie une proposition par rapport au secret et indique les lettres bien et mal placées. Votre programme donnera son résultat sous la forme d’une chaîne de caractères dans la variable resultat, où une lettre en majuscule correspond à une lettre bien placée de la proposition, une lettre en minuscule à une lettre mal placée, et un point à une lettre inutile. Dans l’exemple du secret RESTAURANT avec la proposition RACCOURCIR, le résultat attendu est Ra...UR.... Pour convertir une lettre en minuscule, vous pouvez utiliser lower() comme suit.
secret = "RESTAURANT"
proposition = "RACCOURCIR"
print(proposition[1])
print(proposition[1].lower())
A
a
# Votre code ici
Info : fonctions #
Jusqu’à présent, vous avez produit votre travail dans des cellules, et utilisé des variables globales pour définir les paramètres et résultats de vos programmes (secret, proposition, resultat). Si vous voulez relancer un programme, il vous faut définir les valeurs des variables globales, et retourner évaluer la cellule souhaitée. Nous allons désormais voir comment envelopper les programmes sous forme de fonctions, pour permettre une utilisation plus pratique.
Il faut comprendre le mot fonction de la même manière que vous l’employez dans la phrase « Nous pouvons obtenir le prix du pain en fonction de celui de la farine ». Cette phrase indique que si on vous donne le prix de la farine, il existe une méthode permettant de calculer le prix du pain. Dans cette phrase, le « prix du pain » est ce que nous appellerons le résultat de la fonction. Le « prix de la farine » est un paramètre. Il faut fournir sa valeur pour lancer le calcul.
Vous utilisez déjà des fonctions fournies par le langage, par exemple len pour obtenir la taille d’une chaîne de caractères, ou print pour afficher du texte.
Pour créer une fonction, nous utiliserons le mot clé def, suivi de nom de la fonction et de ses paramètres, et la ligne doit se terminer par : pour débuter un bloc de code. Le code du bloc sera le programme qu’on pourra lancer à l’évocation du nom de la fonction, et est en charge de produire le résultat. Le résultat est produit en utilisant return.
def saluer(nom):
return f"Bonjour {nom} !"
print(saluer("Charlie"))
print(saluer("Manuela"))
print(saluer("بلقيس"))
Bonjour Charlie !
Bonjour Manuela !
Bonjour بلقيس !
Une fonction n’a pas nécessairement de résultat, elle peut se contenter de faire des effets de bord, par exemple de l’affichage.
def encourager(nom):
print(f"Allez {nom} !")
encourager("Alex")
Allez Alex !
Lorsqu’une fonction retourne un résultat, on peut le récupérer dans une variable, None existe pour indiquer que rien n’est produit.
salutation = saluer("Fatou")
print(f"saluer a produit : {salutation}")
encouragement = encourager("Fatou")
print(f"encourager a produit : {encouragement}")
saluer a produit : Bonjour Fatou !
Allez Fatou !
encourager a produit : None
Une fonction peut prendre plusieurs paramètres, séparés par des virgules
def meteo(jour, temps):
print(f"{jour} le temps sera {temps}")
meteo("jeudi", "soleil")
jeudi le temps sera soleil
Le mot clé return interromp le fonctionnement de la fonction. Les instructions qui suivent ne sont pas exécutées.
def insulter(nom):
return "oups mauvaise idée"
print("ça va chauffer")
insulte = "#!@*%&"
return f"{nom} est {insulte}"
print(insulter("le prof"))
oups mauvaise idée
Exercice : emballer vos programmes #
Jusqu’à présent, vous avez produit plusieurs programmes, je vous propose ici de les emballer sous forme de fonctions pour pouvoir les utiliser et les combiner plus facilement. Créez ainsi les fonctions suivantes :
amorce- paramètre : le secret
- retourne la devinette constituée de sa première lettre et de
.à la place des autres
valider- paramètres : le secret et une proposition
- retourne une chaîne de caractères indiquant le problème s’il y en a un, sinon ne retourne rien
tester- paramètres : le secret et une proposition
- retourne la chaîne de carractère indiquant les lettres bien placées en majuscules et les lettres mal placées en minuscules
Pour tester:
- affichez l’amorce pour les secrets
"RESTAURANT"et"LIBELLULE" - affichez la validation pour le secret
"RESTAURANT"des propositions"RACCOURCIR","LIBELLULES","RAT","LOMBRIC"et"" - afficheé le test pour le secret
"RESTAURANT"des propositions"RESTAURANT","RACCOURCIR"et"RATISSERAS"
# La fonction amorce ici
# La fonction valider ici
# La fonction tester ici
Exercice : première boucle de jeu #
Pour pouvoir faire jouer quelqu’un il est encore nécessaire de pouvoir demander un mot. Vous pouvez le faire avec la fonction input.
proposition = input()
print(f"la proposition est {proposition}")
blabla
la proposition est blabla
Écrivez une fonction jouer qui prend en paramètre le secret, et donne dix chances pour trouver le secret. À chaque essai, la fonction vérifie que l’essai est valide, et lorsque c’est le cas elle affiche le resultat du test. Testez votre fonction pour le secret de votre choix.
# Votre fonction jouer ici
# Testez votre fonction ici
Info : boucler selon un test #
Jusqu’à présent, pour répéter plusieurs fois les mêmes instructions, vous avez employé un bloc introduit par for. Dans l’exercice précédent, nous aimerions pouvoir arrêter le jeu lorsque le bon mot a été deviné, ou par exemple interrompre le jeu en cours de route sans devoir finir le nombre d’essais. Pour cette utilisation, le langage fournit un autre mot clé pour introduire des boucles : while qui signifie tant que. Il permet de réaliser un test avant chaque itération, pour décider s’il faut continuer ou non.
i = 0
while i < 3:
print(f"i vaut {i}")
i = i+1
i vaut 0
i vaut 1
i vaut 2
Exercice : arrêter le jeu #
Refaites votre fonction jouer pour faire en sorte que lorsqu’il n’y ait plus de nombre de tour maximum, mais que le jeu s’arrête lorsque le mot est trouvé. D’autre part, faites en sorte qu’il soit possible d’arrêter le jeu en tapant !.
# Votre nouvelle version de jouer ici
# Testez votre fonction ici
Info : utiliser le dictionnaire #
Pour l’instant vous ne pouvez pas vraiment jouer au jeu, car vous devez fournir vous-même le secret. Un dictionnaire est fourni dans le fichier dico.zip. Nous n’avons pas encore vu comment ouvrir et lire des fichiers, ni comment utiliser le hasard. Quelques outils vous sont fournis dans le fichier sutom_base.py pour charger le dictionnaire, et tirer dedans un mot au hasard.
from sutom_base import *
dico = dictionnaire()
for i in range(5):
print(mot(dico))
RAPPELLENT
ZAPPETTES
ENTUBERENT
MASSORE
REINSCRIS
Vous pouvez également tester si un mot est dans le dictionnaire ou non en utilisant in.
for test in ["RESTAURANT", "RACCOURCIR", "PTDR", "WELSH"]:
if test in dico:
print(f"{test} est dans le dictionnaire")
else:
print(f"{test} n'est pas dans le dictionnaire")
RESTAURANT est dans le dictionnaire
RACCOURCIR est dans le dictionnaire
PTDR n'est pas dans le dictionnaire
WELSH est dans le dictionnaire
Exercice : valider avec le dictionnaire #
Avec le dictionnaire, refaites votre fonction valider pour qu’elle prenne en plus le dictionnaire en paramètre et vérifie que la proposition est bien un mot du dictionnaire.
# Votre nouvelle version de valider ici
Exercice : jouer avec le dictionnaire #
Refaites enfin votre fonction jouer pour qu’elle utilise votre nouvelle fonction valider. Elle devra donc prendre également le dictionnaire en paramètre, mais pourra retirer le secret en paramètre pour le choisir toute seule en utilisant mot(dico).
# Votre nouvell version de jouer ici
# Testez votre fonction ici
Exercice : pour faire joli #
Une fonction est afficher_test également fournie pour joliment afficher les mots.
afficher_test("RESTAURANT")
HBox(children=(Label(value='R', layout=Layout(align_items='center', border_bottom='1px solid black', border_le…
afficher_test("RACCOURCIR", "Ra...UR...")
HBox(children=(Label(value='R', layout=Layout(align_items='center', border_bottom='1px solid black', border_le…
À vous de l’exploiter pour améliorer la lisibilité du jeu.
# Votre nouvelle version de jouer ici
# Testez votre fonction ici