QCM sur python

Fermé
pythonneuse - 19 avril 2015 à 15:50
 Pythonneuse - 29 avril 2015 à 21:28
Bonjour,

Alors dans le cadre de notre projet bac d'ISN, entant que groupe nous vanons décidé de faire un QCM programmé en python et on utilise Tkinter pour cela.
On a réussi à faire un bout de programme qui marche: une fenêtre Tkinter s'ouvre et affiche nos questions qu'on a déjà rédigé dans un fichier bloc-note
Problème: -on voudrais que nos questions s'affichent une par une or elles s'affichent toutes d'un coup dans la fenêtre Tkinter.
- En plus de ça , nos radiobutton (qu'on utilise pour que le joueur choisisse la bonne réponse parmi 3 propositions) sont tous séléctionnés à pars la première. On aimerait que les radiobutton soient désélectionnés pour laisser le choix au joueur. Même en utilisant deselect() ça ne change rien ...

Merci d'avance ...

3 réponses

Zephirr Messages postés 316 Date d'inscription mardi 30 décembre 2014 Statut Membre Dernière intervention 6 novembre 2015 100
19 avril 2015 à 17:45
Votre code serait le bienvenu (sans oublier la coloration syntaxique) ;)
1
from sys import argv
import string
import tkinter as tk
from tkinter import *
from tkinter import ttk

filename = "qcm.txt"

txt = open(filename)

print ("Here's your file %r:" % filename)
#lignes = txt.read()

questions = []


class Question:
question = ""
reponseA = ""
reponseB = ""
reponseC = ""
isAOk = FALSE
isBOk = FALSE
isCOk = FALSE


lignes = [line.strip() for line in open(filename)]

index = 0;
question = ""
reponseA = ""
reponseB = ""
reponseC = ""

def getReponseFromLine(line):
return line.split(":")[0]

def getisReponseOk(line):
return line.split(":")[1] == "OK"

for line in lignes:
if(index % 4 == 0):
question = line;
else:
reponse = line.split(":")[0]
ok = line.split(":")[1]
if(index % 4 == 1):
reponseA = line;
elif(index % 4 == 2):
reponseB = line;
elif(index % 4 == 3):
reponseC = line;
elif(index % 4 == 3):
reponseD = line
index = index+1

if(index%4 == 0):
questionObject = Question()
questionObject.question = question
questionObject.reponseA = getReponseFromLine(reponseA)
questionObject.reponseB = getReponseFromLine(reponseB)
questionObject.reponseC = getReponseFromLine(reponseC)

questionObject.isAOk = getisReponseOk(reponseA)
questionObject.isBOk = getisReponseOk(reponseB)
questionObject.isCOk = getisReponseOk(reponseC)

questions.append(questionObject)

##Interface
root = Tk()
frame = Frame(root)
frame.pack()

for question in questions:
print(question)
labelQuestion = Label(frame, text=question.question)
labelQuestion.pack()
radioReponseA = Radiobutton(frame, text=question.reponseA, variable=labelQuestion, value=question.isAOk).pack(anchor=W)
radioReponseB = Radiobutton(frame, text=question.reponseB, variable=labelQuestion, value=question.isBOk).pack(anchor=W)
radioReponseC = Radiobutton(frame, text=question.reponseC, variable=labelQuestion, value=question.isCOk).pack(anchor=W)


root.mainloop()
0
Zephirr Messages postés 316 Date d'inscription mardi 30 décembre 2014 Statut Membre Dernière intervention 6 novembre 2015 100
26 avril 2015 à 11:20
Pour pouvoir vous aider pleinement, j'aimerais aussi connaitre la structure de votre qcm.txt (ou un exemple) et que vous activiez la coloration syntaxique (en haut à droite) en faisant attention à l'indentation, qui est indispensable en python.
0
Pythonneuse > Zephirr Messages postés 316 Date d'inscription mardi 30 décembre 2014 Statut Membre Dernière intervention 6 novembre 2015
27 avril 2015 à 19:18
from sys import argv 
import string
import tkinter as tk
from tkinter import *
from tkinter import ttk

filename = "qcm.txt"

txt = open(filename)

print ("Here's your file %r:" % filename)
#lignes = txt.read()

questions = []


class Question:
question = ""
reponseA = ""
reponseB = ""
reponseC = ""
isAOk = FALSE
isBOk = FALSE
isCOk = FALSE


lignes = [line.strip() for line in open(filename)]

index = 0;
question = ""
reponseA = ""
reponseB = ""
reponseC = ""

def getReponseFromLine(line):
return line.split(":")[0]

def getisReponseOk(line):
return line.split(":")[1] == "OK"

for line in lignes:
if(index % 4 == 0):
question = line;
else:
reponse = line.split(":")[0]
ok = line.split(":")[1]
if(index % 4 == 1):
reponseA = line;
elif(index % 4 == 2):
reponseB = line;
elif(index % 4 == 3):
reponseC = line;
elif(index % 4 == 3):
reponseD = line
index = index+1

if(index%4 == 0):
questionObject = Question()
questionObject.question = question
questionObject.reponseA = getReponseFromLine(reponseA)
questionObject.reponseB = getReponseFromLine(reponseB)
questionObject.reponseC = getReponseFromLine(reponseC)

questionObject.isAOk = getisReponseOk(reponseA)
questionObject.isBOk = getisReponseOk(reponseB)
questionObject.isCOk = getisReponseOk(reponseC)

questions.append(questionObject)

##Interface
root = Tk()
frame = Frame(root)
frame.pack()

for question in questions:
print(question)
labelQuestion = Label(frame, text=question.question)
labelQuestion.pack()
radioReponseA = Radiobutton(frame, text=question.reponseA, variable=labelQuestion, value=question.isAOk).pack(anchor=W)
radioReponseB = Radiobutton(frame, text=question.reponseB, variable=labelQuestion, value=question.isBOk).pack(anchor=W)
radioReponseC = Radiobutton(frame, text=question.reponseC, variable=labelQuestion, value=question.isCOk).pack(anchor=W)







Voici un exemple sur qcm.txt:

En quelle année le premier Homme a-t-il marché sur la lune
A. en 1969
B. en 1869
C. en 1979

Pour le moment nous avons 5 questions qui suivent le même exemple que celle-ci sur qcm.txt



Pour ce qui est de l'identation je ne vois pas ce que c'est désolé :/
0
Utilisateur anonyme
28 avril 2015 à 09:08
Salut,

Je ne comprends pas vraiment ton code, mais j'ai des pistes pour tes problèmes. Tu peux ajouter la commande time.sleep à la fin des instructions de la dernière boucle de ton programme (for question in questions). Utilise ça : https://www.pythoncentral.io/pythons-time-sleep-pause-wait-sleep-stop-your-code/
1
Utilisateur anonyme
28 avril 2015 à 09:18
Pour tes radiobuttons, il suffirait de leur ajouter une variable v (je crois que ça sert à "rassembler" tous ces radiobuttons dans le même groupe) et une value différente (pour les distinguer). Par défaut, ils sont tous éteint puis tu peux en allumer un de ton choix.

from tkinter import *

root=Tk()

v=IntVar()

r1=Radiobutton(root,text="1. Salut",variable=v,value=1)
r1.pack()
r2=Radiobutton(root,text="2. Salut",variable=v,value=2)
r2.pack()
r3=Radiobutton(root,text="3. Salut",variable=v,value=3)
r3.pack()
r4=Radiobutton(root,text="4. Salut",variable=v,value=4)
r4.pack()


root.mainloop()
0
##Interface
root=Tk()
frame = Frame(root)
frame.pack()

v=IntVar()


for question in questions:
    print(question)
labelQuestion = Label(root,text=question.question)
labelQuestion.pack()

r1=Radiobutton(root,text=questionObject.reponseA,variable=v,value=1)
r1.pack()
r2=Radiobutton(root,text=questionObject.reponseB,variable=v,value=2)
r2.pack()
r3=Radiobutton(root,text=questionObject.reponseC,variable=v,value=3)
r3.pack()



root.mainloop()


Voila pour les questions, votre réponse m'a été d'une grande aide j'ai du modifier légèrement pour l'adapter à mon programme. ça marche !

Maintenant je suis face à un nouveau problème ... Comment faire pour afficher la question suivante quand le joueur choisi la bonne réponse ?
0
Utilisateur anonyme
28 avril 2015 à 15:45
Normalement tu peux récupérer l'état d'un bouton grâce à la méthode .get() (fais des recherches). Si l'état du bouton change, cela signifie que l'utilisateur a répondu. Si c'est faux, il faut lui dire que c'est faux et de recommencer (il serait intéressant de rendre impossible le choix faux). Si c'est vrai, ça affiche la question suivante.

Je pensais à ce que tu créés une fenêtre à chaque fois qu'une question est affichée. Quand l'utilisateur répond vrai, tu détruis la fenêtre actuelle et tu recommences la boucle (qui te créé une nouvelle fenêtre).

Dis-moi si tu rames, je t'ai mâché le boulot en mode réflexion "humaine" à toi de convertir.
0
Pythonneuse > Utilisateur anonyme
28 avril 2015 à 16:07
Merci !

J'ai réussi à créer un bouton pour que le joueur valide sa réponse mais je ne sais pas comment relancer la boucle pour que la question suivante s'affiche quand le joueur valide sa réponse ...

r1=Radiobutton(root,text=questionObject.reponseA,variable=v,value=1)
r1.pack()
r2=Radiobutton(root,text=questionObject.reponseB,variable=v,value=2)
r2.pack()
r3=Radiobutton(root,text=questionObject.reponseC,variable=v,value=3)
r3.pack()
bou1 =Button()
bou1.config(text='question suivante', command=exit)
bou1.pack()
bou1.mainloop()
0
Utilisateur anonyme
28 avril 2015 à 16:37
Tu pourrais créer une fonction où dedans tu mets ton label question et tes Radiobuttons. Du coup, à la place tu appelles directement la fonction (en faisant fonction() ). ça va te créer ton label et tes Radiobuttons. Ensuite, tu crées ton bouton bou1 comme tu l'a fait mais en command, tu mets fonction. Comme ça, à chaque fois qu'il clique sur bou1, cela va exécuter fonction() qui va changer le text de ton label et de tes buttons (la question suivante). Problème : l'utilisateur peut appuyer n'importe quand. Il faut que l'utilisateur puisse appuyer sur bou1 UNIQUEMENT si la réponse est bonne. Soit tu fais cette condition, soit tu passes en paramètre de la fonction fonction() la réponse de l'utilisateur et dans la fonction, tu changes les texts de tes objets seulement si la réponse est juste.

J'espère que tu comprends où je veux en venir.

Si tu as un problème avec la fonction fonction() associée à la commande de bou1, mets à la place :
command=lambda:fonction(paramètre)
0
désolé mais je ne vois pas comment créer une fonction qui comprendrait tout ce bout de programme ... J'ai fait des tentatives en vain , je vous tiens au courant si je réussi à avancer.
0