C'est un problème de logique. J'ai écrit un programme méga-simple en Python :
Le programme lit la première ligne d'un fichier "questions.txt", grâce à la fonction readline().
Le programme lit la première ligne d'un fichier "réponses_attendues.txt", grâce à la fonction readline().
Le programme affiche la question 1
L'utilisateur entre la réponse 1.
Le programme compare la réponse entrée et la réponse attendue
SI la réponse entrée et la réponse attendue correspondent > on affiche une question 2
Ainsi de suite.
Le problème c'est que, comme je me sers de la fonction readline() pour déterminer la variable "reponse_attendue", quand l'utilisateur appuie sur le bouton Valider, la réponse attendue change, que l'utilisateur ait bien répondu ou pas à la question précédente.
Et moi, je voudrais qu'elle ne change pas tant que l'utilisateur n'a pas entré la bonne réponse
Il faudrait que je puisse séparer ma variable "réponse_attendue" de la fonction readline(). Ou "figer" la fonction readline(). Je ne sais pas comment je pourrais faire ça... J'ai passé l'aprèm a me craquer la tête avec des boucles de condition, sans succès.
Merci d'avoir lu, en tout cas ! Voilà mon code :
from __future__ import unicode_literals
from tkinter import *
import codecs
f = codecs.open('questions.txt', encoding='utf-8') # On ouvre (avec le bon encodage) le fichier qui contient les questions.
g = codecs.open('reponses_attendues.txt', encoding='utf-8') # On ouvre (avec le bon encodage) le fichier qui contient les reponses.
def repondre(): # Fonction déclenchée par un bouton Valider, plus bas
reponse_utilisateur_str=str(reponse_utilisateur.get()) # On transforme la reponse de l'utilisateur en str
reponse_attendue = g.readline() # On lit le fichier des réponses ligne par ligne
reponse_attendue = reponse_attendue.replace('\n','')
reponse_attendue = reponse_attendue.replace('\r','')
affichage2['text'] = 'Réponse attendue :' + reponse_attendue
affichage3['text'] = 'Ce que tu viens de répondre : ' + reponse_utilisateur_str
if reponse_utilisateur_str == reponse_attendue: # Le problème est là ! Je dois vérifier si la réponse de l'utilisateur correspond a la reponse attendue. Pour ça il faut que je déclare au préalable la variable "reponse" ... or a chaque fois que je la declare elle change, puisque je la crée a partir de la fonction readline(). Brain = Fucked.
reponse_attendue = g.readline()
affichage['text'] = 'Question : ' + f.readline()
Fenetre = Tk()
Fenetre.title('Coca Sans Bulles')
Fenetre.geometry("900x200+300+300")
affichage = Label(Fenetre)
reponse_utilisateur = Entry(Fenetre, width=200) # Champ de réponse
valeur = Button(Fenetre, text =' Valider', command=repondre) # Bouton Valider
affichage['text'] = 'Question : ' + f.readline() # On affiche la première question
affichage2 = Label(Fenetre)
affichage3 = Label(Fenetre)
affichage.pack()
affichage2.pack()
affichage3.pack()
reponse_utilisateur.pack()
valeur.pack()
Fenetre.mainloop()
Il faut au préalable que je déclare ma variable "reponse_attendue" ... Et je dois la déclarer à l'intérieur de la fonction correspondant au bouton "Valider", qui se déclenche toutes les fois où l'utilisateur appuie sur le bouton Or ma variable reponse_attendue change dès qu'on la déclare, puisqu'elle est liée à la fonction readline()
Y'a sûrement un while() à placer, mais je te promets que j'ai essayé partout ...
Mon code corrigé avec ton aide :
def repondre():
reponse_utilisateur_str=str(reponse_utilisateur.get()) # Je transforme la reponse de l'utilisateur en str
reponse = g.readline() # On lit le fichier des réponses ligne par ligne
reponse = reponse.replace('\n','')
reponse = reponse.replace('\r','')
question = f.readline()
affichage2['text'] = 'Réponse attendue :' + reponse
affichage3['text'] = 'Ce que tu viens de répondre : ' + reponse_utilisateur_str
while reponse_utilisateur_str != reponse:
affichage['text'] = question
PS : Il plante, en fait ... Tkinter part aux fraises, je crois qu'il n'apprécie pas que je mette un Label() dans une boucle while(). J'y travaille.
data = list()
with open("questions.txt") as question_fd:
with open("reponses.txt") as answer_fd:
data.append((question_fd.readline(), answer_fd.readline()))
# Le code du dessus ouvre les deux fichiers et génère la variable data qui sera de la forme suivante :
# [(question, reponse), (question, reponse), ...]
for question, expected in data:
print(question)
answer = input()
while answer != expected:
print("Mauvaise réponse.")
print(question)
answer = input()
def repondre():
global f
global g
global reponse_utilisateur
global affichage2
global affichage3
reponse_utilisateur_str = str(reponse_utilisateur.get())
reponse_attendue = g.readline().replace #...
affichage2['text'] = "Réponse Attendue: " + reponse_attendue
affichage3.['text'] = "Ta réponse: " + reponse_utilisateur_str
while reponse_utilisateur_str != reponse attendue:
reponse_utilisateur_str = str(reponse_utilisateur.get())
#Poser une autre question
Tu mélanges beaucoup de choses pas logiques ... Dans une fonction tu poses la question suivante mais la première question n'est pas appelée par la fonction ... Ton code est très bizarre et je te conseille de refaire différentes fonctions, en pensant bien à la durée de vie de tes variables.
- Edité par IQbrod 21 mai 2015 à 12:51:30
OpenClassrooms retire tellement d'aiguilles de nos pieds qu'on pourrait ne plus trouver le foin de notre botte :)
Il faut juste décomposer ta fonction repondre() en 2 fonctions. Une que tu associera à ton bouton valeur, et qui permettra de passer à la question suivante, et une autre que tu associera à reponse_utilisateur et qui servira à vérifier que le résultat est bon. Dans la première fonction, tu fera en sorte de "cacher" le bouton pour qu'il ne soit pas possible de passer à la question suivante sans avoir la bonne réponse. Et dans la fonction associé à ton Entry, si le résultat est validé, tu affiche de nouveau le bouton:
import tkinter as tk
def verif(event):
if rep_attendue = rep_utilisateur: #La convertion en str() est inutile
#tu peux afficher un message de félicitation
valeur["state"] = "normal" #On réactive le bouton
else: #facultatif
#Tu peux afficher un message pour la mauvaise réponse
def repondre():
#Fonction qui va afficher la question et sauvegarder la réponse
#Désactivation du bouton pour ne pas passer la question
valeur["state"] = "disabled"
Après il faudra sûrement utiliser une variable muable pour enregistrer la réponse (par exemple une liste, dont le premier élément est la réponse).
Et j'ai oublié de préciser que pour associer ta fonction à l'entrée utilisateur, tu utilisera la méthode bind (juste après l'instanciation par exemple):
À l'instar du paramètre command, la méthode bind permet également la gestion des événements à ceci près que command est un raccourci pour le clic gauche, alors que bind prend n'importe quel événement. Ici le <Return> correspond à la touche Entrée de ton clavier.
Merci beaucoup pour vos réponses, en les combinant (et en utilisant des variables globales, nom d'un petit bonhomme) j'ai réussi à avoir le résultat voulu.
IQBrod > Oui, j'ai beaucoup de progrès à faire pour structurer mes codes ... merci de ta proposition, je vais m'en inspirer
- Edité par Bemsha Swing 21 mai 2015 à 20:32:28
J'aimerais "figer" la fonction readline()
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Si ça peut t'aider.
Tu mélanges beaucoup de choses pas logiques ... Dans une fonction tu poses la question suivante mais la première question n'est pas appelée par la fonction ... Ton code est très bizarre et je te conseille de refaire différentes fonctions, en pensant bien à la durée de vie de tes variables.