un QCM

Programmation d'applications complexes
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

un QCM

Message par Backup »

bon vu que cette question est récurente

(comment faire un QCM )
voici un prg de base , qui fait ce genre de chose .... un QCM

le prg ne prends que 3 réponses par question ... mais c'est facilement modifiable ......

les Questions sont entrées dans un Data
chaque data représente une question

le format de chaque question est :

" La Question " / "la reponse A" / "la reponse B" / "la reponse C" / "le chiffre représentant la bonne réponse attendu"

exemple :

Code : Tout sélectionner

Data.s "Quel etait la couleur du cheval blanc d'Henry 4 ? /Bleu/Jaune/blanc/3"
ici le 3 en fin de Data , représente la bonne réponse ......

il faut s'entendre sur un format , comme ça la suite est plus simple a gérer ......

le caractere "/" est utiles pour séparer les Champs de la question et des réponses affichées , ainsi que de la bonne réponse attendue
avec la fonction Stringfied() c'est un jeu d'enfant a trier ....
cela permet d'afficher proprement chaque partie extraite du Data dans l’éditeur ...

pour ajouter des questions , il faut modifier la variable

Code : Tout sélectionner

Global nombre_de_fiche=4 ; pour 4 questions ...... attention a bien mettre le bon nombre de questions au total
c'est tres important de mettre le bon chiffre (ou nombre ) le meme que le nombre de ligne de data (et donc de questions)



dans ce prg je note dans un tableau Structuré les Réponses données par l'utilisateur
ça permet de pouvoir compter le Score .....

le code est commenté il est programmé limite "Old School" (utilisation d'un Tableau au lieu d'une liste Chainée )
mais est assez clair a mon avis ...pour modifications éventuelles

utilisation :
on répond en cliquant sur les Options Gadget
ça passe a la question suivante ...
a la fin les options Gadget sont désactivés , le résultat du Score est affiché




il y a mille façon d'arriver au même résultat ... c'est est une parmi d'autres :)

le code :

Code : Tout sélectionner

; ***************************************************
; Codé par Dobro
; En PureBasic 5.11
; Exemple de QCM 
; ***************************************************



;{- Enumerations / DataSections
;{ Windows
Enumeration
	#Win
EndEnumeration
;}
;{ Gadgets
Enumeration
	#Text_titre
	#Button_backward
	#Button_Forward
	#Editor_question
	#Container_4
	#Reponse_A
	#Reponse_B
	#Reponse_C
EndEnumeration
;}
;{ Fonts
Enumeration
	#Font_Text_titre
EndEnumeration

Structure Fiche
	Question.s
	Reponse.s
EndStructure

Global nombre_de_fiche=4 ; pour 4 questions ...... attention a bien mettre le bon nombre de questions au total
Global N_Fiche=1  ; commence a la fiche numero 1
global Dim Fiche.Fiche(nombre_de_fiche)
Global Question$

Declare  OpenWindow_Win()
Declare  Affiche_question(N_Fiche)
Declare  Compte()


;}
;}


OpenWindow_Win()

Affiche_question(N_Fiche)



;{- Event loop
Repeat
	Select WaitWindowEvent(2)
		; ///////////////////
		Case #PB_Event_Gadget
		Select EventGadget()
			Case #Text_titre
			Case #Button_backward
			N_Fiche=N_Fiche-1
			if N_Fiche<1 ; bloc la limite minimum
				N_Fiche=1
			Endif
			Affiche_question(N_Fiche)
			; remet la reponse qui avait été donné
			Select val(Fiche(N_Fiche)\Reponse.s)
				Case 1
				SetGadgetState(#Reponse_A, 1) ; on change l'etat des options en fonction des reponses qui ont été enregistrées dans le Tableau Structuré
				SetGadgetState(#Reponse_B, 0)
				SetGadgetState(#Reponse_C, 0)
				Case 2
				SetGadgetState(#Reponse_A, 0)
				SetGadgetState(#Reponse_B, 1)
				SetGadgetState(#Reponse_C, 0)
				Case 3
				SetGadgetState(#Reponse_A, 0)
				SetGadgetState(#Reponse_B, 0)
				SetGadgetState(#Reponse_C, 1)
			Endselect
			
			Case #Button_Forward
			N_Fiche=N_Fiche+1
			if N_Fiche>nombre_de_fiche ; Bloc la limite maximum
				N_Fiche=nombre_de_fiche
			Endif
			Affiche_question(N_Fiche)
			; remet la reponse qui avait été donné
			Select val(Fiche(N_Fiche)\Reponse.s)
				Case 1
				SetGadgetState(#Reponse_A, 1) ; on change l'etat des options en fonction des reponses qui ont été enregistrées dans le Tableau Structuré
				SetGadgetState(#Reponse_B, 0)
				SetGadgetState(#Reponse_C, 0)
				Case 2
				SetGadgetState(#Reponse_A, 0)
				SetGadgetState(#Reponse_B, 1)
				SetGadgetState(#Reponse_C, 0)
				Case 3
				SetGadgetState(#Reponse_A, 0)
				SetGadgetState(#Reponse_B, 0)
				SetGadgetState(#Reponse_C, 1)
			Endselect
			Case #Editor_question
			Case #Container_4
			Case #Reponse_A
			Fiche(N_Fiche)\Reponse.s="1" ; on stock la reponse 
			N_Fiche=N_Fiche+1
			if N_Fiche>nombre_de_fiche ; Bloc la limite maximum
				N_Fiche=nombre_de_fiche
				; on a repondu a la derniere Question ...  on desative les Options gadget , et on efface l'editeur le questionnaire est fini
				DisableGadget(#Reponse_A, 1)
				DisableGadget(#Reponse_B, 1)
				DisableGadget(#Reponse_C, 1)
				ClearGadgetItems(#Editor_question) ; on efface l'editeur
				AddGadgetItem(#Editor_question, -1, "Merci d'avoir Participé a ce QCM :o ) ") ; on ecrit que c'est fini .... on passe au compte
				Compte()
				Else
				Affiche_question(N_Fiche)
			Endif
			
			Case #Reponse_B
			Fiche(N_Fiche)\Reponse.s="2" ; on stock la reponse 
			N_Fiche=N_Fiche+1
			if N_Fiche>nombre_de_fiche ; Bloc la limite maximum
				N_Fiche=nombre_de_fiche
				; on a repondu a la derniere Question ...  on desative les Options gadget , et on efface l'editeur le questionnaire est fini
				DisableGadget(#Reponse_A, 1)
				DisableGadget(#Reponse_B, 1)
				DisableGadget(#Reponse_C, 1)
				ClearGadgetItems(#Editor_question) ; on efface l'editeur
				AddGadgetItem(#Editor_question, -1, "Merci d'avoir Participé a ce QCM :o ) ") ; on ecrit que c'est fini .... on passe au compte
				Compte()
				Else
				Affiche_question(N_Fiche)
			Endif
			Case #Reponse_C
			Fiche(N_Fiche)\Reponse.s="3" ; on stock la reponse 
			N_Fiche=N_Fiche+1
			if N_Fiche>nombre_de_fiche ; Bloc la limite maximum
				N_Fiche=nombre_de_fiche
				; on a repondu a la derniere Question ...  on desative les Options gadget , et on efface l'editeur le questionnaire est fini
				DisableGadget(#Reponse_A, 1)
				DisableGadget(#Reponse_B, 1)
				DisableGadget(#Reponse_C, 1)
				ClearGadgetItems(#Editor_question) ; on efface l'editeur
				AddGadgetItem(#Editor_question, -1, "Merci d'avoir Participé a ce QCM :o ) ") ; on ecrit que c'est fini .... on passe au compte
				Compte()
				Else
				Affiche_question(N_Fiche)
			Endif
		EndSelect
		; ////////////////////////
		Case #PB_Event_CloseWindow
		Select EventWindow()
			Case #Win
			CloseWindow(#Win)
			Break
		EndSelect
	EndSelect
Forever
;
;}

;- ****** Zone Procedures ************

Procedure OpenWindow_Win()
	If OpenWindow(#Win, 450, 200, 657, 336, "Sample By Dobro", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_TitleBar)
		
		TextGadget(#Text_titre, 230, 10, 86, 37, "QCM")
		ButtonGadget(#Button_backward, 71, 262, 140, 36, "<------")
		ButtonGadget(#Button_Forward, 335, 262, 140, 36, "------>")
		EditorGadget(#Editor_question, 68, 72, 409, 169)
		ContainerGadget(#Container_4, 490, 70, 110, 160, #PB_Container_Raised)
		OptionGadget(#Reponse_A, 10, 10, 90, 30, "Reponse A")
		OptionGadget(#Reponse_B, 10, 60, 90, 30, "Reponse B")
		OptionGadget(#Reponse_C, 10, 110, 80, 30, "Reponse C")
		CloseGadgetList()
		; Gadget Fonts
		SetGadgetFont(#Text_titre, LoadFont(#Font_Text_titre, "Arial", 24, #PB_Font_HighQuality))
		
	EndIf
EndProcedure


Procedure Affiche_question(N_Fiche)
	;By Dobro
	; ************* voila comment lire une question precise dans des Data ***************
	Restore Question:
	For i=1 to N_Fiche
		Read.s Question$
	Next i
	; ****************************************************************************
	Extrait_1$=StringField(Question$,1,"/") ; la question
	Extrait_2$=StringField(Question$,2,"/") ; reponse A
	Extrait_3$=StringField(Question$,3,"/") ; reponse B
	Extrait_4$=StringField(Question$,4,"/") ; reponse C
	; on affiche tout ça dans l'editeur 
	ClearGadgetItems(#Editor_question) ; on commence par faire le menage
	AddGadgetItem(#Editor_question, -1, Extrait_1$) ; on ecrit la Question
	AddGadgetItem(#Editor_question, -1, "") ; on ecrit une ligne Vide
	AddGadgetItem(#Editor_question, -1, " A --- "+Extrait_2$) ; on ecrit la reponse A
	AddGadgetItem(#Editor_question, -1, " B --- "+Extrait_3$) ; on ecrit la reponse B
	AddGadgetItem(#Editor_question, -1, " C --- "+Extrait_4$) ; on ecrit la reponse C
	; ajoute la question dans le tableau 
	Fiche(N_Fiche)\Question.s=Extrait_1$
EndProcedure


Procedure Compte()
	;By Dobro
	Restore Question:
	For Y=1 to nombre_de_fiche ; pour chaque Fiche
		; ************* voila comment lire une question precise dans des Data ***************
		Read.s Question$ ; on relit la question, et on extrait les reponse proposé +++ l'indice de la bonne reponse
		; ****************************************************************************
		Extrait_1$=StringField(Question$,1,"/") ; la question
		Extrait_2$=StringField(Question$,2,"/") ; reponse A
		Extrait_3$=StringField(Question$,3,"/") ; reponse B
		Extrait_4$=StringField(Question$,4,"/") ; reponse C
		Extrait_5$=StringField(Question$,5,"/") ; la bonne reponse ..... qu'on va comparer avec celle qu'on a stocké dans le tableau Structuré
		if Val(Fiche(y)\Reponse.s) = val(Extrait_5$)
			Compteur_de_bonne_reponse=Compteur_de_bonne_reponse+1
		Endif
	Next y
	AddGadgetItem(#Editor_question, -1, "") ; on ecrit une ligne Vide
	AddGadgetItem(#Editor_question, -1, "Vous avez :"+str(Compteur_de_bonne_reponse)+" bonne(s) reponse(s) sur "+str(nombre_de_fiche)+" Questions") ; on ecrit une ligne Vide
Endprocedure



; ***********************************















; les Questions ont cette forme .......  Question,Reponse a/ Reponse b /Reponse c / reponse_correcte (1,2,3)
DataSection
	Question:
	Data.s "Quel etait la couleur du cheval blanc d'Henry 4 ? /Bleu/Jaune/blanc/3" ; Question 1 ......  on se sert des "/" pour la recuperation et la mise a la ligne pour la mise en forme
	Data.s "Combien de Bit y a t'il dans un Octet ?/4/6/8/3" ; Question 2 ......
	Data.s "Depuis Combien de Temp Dobro Joue de la Guitare ? /1 an/35 ans/15 ans/2" ; Question 3 ......
	Data.s "En quel Année est né  le Basic ? / 1964/1974/1984/1" ; Question 4......
EndDataSection











; EPB
Avatar de l’utilisateur
Micoute
Messages : 2522
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: un QCM

Message par Micoute »

Bonjour Dobro et merci beaucoup, ton exemple est excellentissime, mais ce que je souhaiterais, c'est avoir un tirage au sort des questions, c'est pour ça que j'aurais voulu que la même question ne soit pas posée plus d'une fois, c'est pourquoi je désirerais utiliser un marqueur pour vérifier si la question n'a pas déjà été posée !

Merci encore.
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 5.73 PB 6.00 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: un QCM

Message par Backup »

on peut aussi ajouter un indice de plus a la question (dans les data une info suplementaire qui identifie la question ... un numero quoi )


tirer au sort une question , et mettre l'indice en question dans une liste chainée

lorsq'on tire une question , on lis sont indice (sont numero ) et on regarde si il est present dans la fameuse liste

si c'est le cas , on retire une autre question ... etc ... :)
Avatar de l’utilisateur
Micoute
Messages : 2522
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: un QCM

Message par Micoute »

Merci Dobro, comme d'habitude tu as toujours la bonne réponse, je t'en remercie d'autant plus, je pensais déjà à un truc dans ce genre, mais je n'avais pas eu le déclic, je pense que c'est surement une séquelle de mon AVC, ça m'empêche vraiment de réfléchir, mais je ne souhaite pas arrêter de programmer.
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 5.73 PB 6.00 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: un QCM

Message par Backup »

tu sais lorsque je code , je pense comme dans le reel :)

je me dit :
comment je ferai si j'avais une serie de questions dans un pot a piocher au hasard
et que je ne veuille pas retirer la meme question ??

voyons, plusieurs solutions s'offre a moi
je prends les questions dans un pot, et je depose cette question dans un autre pot
de sorte que le pots aux questions diminue, et l'autre augmente ... :)

ou bien avec un seul pot, il me faut un carnet pour noter la question pioché
comme ça, si elle reviens, je regarde mon carnet, et je sais qu'elle a été posée ...
du coup je la repose pour en choisir une autre ... :)

pour le coup , la 2em solution le carnet c'est une liste chainée
(pour moi une liste chainée c'est comme une liste des courses a faire :lol: )

je pratique ce genre de pensée pour chaque probleme que je rencontre en informatique !
le fait de transposer dans le Reel , permet de solutionner bien des choses :)

cette façon de faire me viens des premiers magazine informatique , ou l'on apprenais
la programmation par la bande dessinée ( dans le style de Lanturlu de Jean-Pierre Petit, )
http://www.jp-petit.org/TELECHARGEABLES ... eables.htm

:)
Répondre