Qcm en python

dylois92 Messages postés 5 Date d'inscription lundi 13 novembre 2023 Statut Membre Dernière intervention 27 novembre 2023 - Modifié le 28 nov. 2023 à 15:36
mamiemando Messages postés 33333 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 31 octobre 2024 - 28 nov. 2023 à 16:15

Bonjour,

J'ai un code python et un fichier texte. Je voudrais lire les questions du fichier une par une, mais mon programme ne lit juste le premier caractère des questions et le premier caractère de la premiere réponse.

S'il vous plaît, j'ai besoin d'aide.

# LES FONCTIONS : PROJET QUESTIONNAIRE
#
# Question : Quelle est la capitale de la France ?
# (a) Marseille
# (b) Nice
# (c) Paris
# (d) Nantes
#
# Votre réponse :
# Bonne réponse / Mauvaise réponse

# ...
# Question : Quelle est la capitale de l'Italie ?
# ...
#
# 4 questions
from random import randint


def demander_reponse_numerique_utlisateur(min, max):
    reponse_str = input("Votre réponse (entre " + str(min) + " et " + str(max) + ") :")
    try:
        reponse_int = int(reponse_str)
        if min <= reponse_int <= max:
            return reponse_int

        print("ERREUR : Vous devez rentrer un nombre entre", min, "et", max)
    except:
        print("ERREUR : Veuillez rentrer uniquement des chiffres")
    return demander_reponse_numerique_utlisateur(min, max)
    

'''
titre = question[0]
choix = question[1]
bonne_reponse = question[2]
'''
def poser_question(question):
    # titre_question, r1, r2, r3, r4, choix_bonne_reponse
    
    choix = question[1]
    bonne_reponse = question[2]
    print("QUESTION")
    print("  " + question[0])
    for i in range(len(choix)):
        print("  ", i+1, "-", choix[i])

    print()
    resultat_response_correcte = False
    reponse_int = demander_reponse_numerique_utlisateur(1, len(choix))
    if choix[reponse_int-1].lower() == bonne_reponse.lower():
        print("Bonne réponse")
        resultat_response_correcte = True
    else:
        print("Mauvaise réponse")
        
    print()
    return resultat_response_correcte


'''
    questionnaire[]
        question
            titre = "Quelle est la capitale de la France ?"
            reponses = ("Marseille", "Nice", "Paris", "Nantes")
            bonne_reponse = "Paris"

'''

def lancer_questionnaire(ligne):
    score = 0
    
    for question in ligne:
        if poser_question(question):
            score += 1
    print("Score final :", score, "sur", len())


with open("informatique1.txt") as fp:
    
    questionnaire = fp.readlines()
    exam=[]
    
    
'''questionnaire = (
    ("Quelle est la capitale de la France ?", ("Marseille", "Nice", "Paris", "Nantes", "Lille"), "Paris"), 
    ("Quelle est la capitale de l'Italie ?", ("Rome", "Venise", "Pise", "Florence"), "Rome"),
    ("Quelle est la capitale de la Belgique ?", ("Anvers", "Bruxelles", "Bruges", "Liège"), "Bruxelles"),
    ("Quels sont les périphériques d’entrée?", ("la souris", "la batterie", "Le moniteur", "Le baffle"), " la souris"),
    ("Quels sont les périphériques d’entrée?", ("le clavier", "l'imprimante", " Le moniteur", "Le baffle"), "le clavier"),
    ("Quels sont les  périphériques de sortie :",("L’écran", "Le clavier", "L’imprimante", "Le scanner"), "l'imprimante"),
    ("Relever l’intrus dans la Iiste suivante :", ("LAN, WAN, MAN, FDII"), "FDII"),
    ("Lequel des périphériques suivant permet de gérer la confidentialité en réseau:", ("Câble réseau", "Le concentrateur", "Le répéteur", "Le commutateur"), "Le commutateur"),
    ("Internet est née d’un projet de l’armée américaine dénommée:", ("WAN", "ARPANET", "DARPA", "WEB"), "WEB"),
    ("Pour s’affranchir des limites du matériel et couvrir de grandes distances par le signal, on utilise :", ("Le répéteur", "Le pont", "Le câble réseau", "Les câbles réseau"), "Le répéteur"),
    ("Relever l’intrus dans la Iiste suivante :", ("Un logiciel de communication", "Un appareil connecté à l’UC", "Responsable des traitements"), "Un appareil connecté à l’UC"),
    ("un pilot permet:", ("Le décollage des documents", " Le fonctionnement d’un périphérique", "Impression des documents"), "Le fonctionnement d’un périphérique"),
    ("la RAM est :", ("Responsable des traitements", "Le chef d’orchestre de la machine", "Une mémoire volatile"),"Une mémoire volatile"),
    ("Repérer l’intrus dans chaque cas:", ("Excel", "Word", "Access", "Photoshop"), "Photoshop"),
    ("Repérer l’intrus dans chaque cas:", ("Encarta", "Ubuntu", "Windows", "Mac OS"), "Encarta"),
    ("Repérer l’intrus dans chaque cas:", ("PowerDVD", "Paint", "VLC", "Nero Vision"), "Paint"),
    ("Relever l’action de maintenance préventive :", ("Remplacer le disque dur, Brancher sous onduleur, Ajouter la mémoire vive, Installer un logiciel"), "Brancher sous onduleur"),
    ("la maintenance évolutive consiste à :", ("Réparer  une panne sur l’ équipement, Protéger  l’ équipement contre tout problème, Adapter  la machine à une nouvelle utilisation, Installer des logiciels dans la machine    "), "Installer des logiciels dans la machine"),
    ("Lorsqu'on installe de nouveaux logiciels, on fait de :", ("La maintenance préventive, La maintenance matérielle, La maintenance corrective, La maintenance évolutive"), "FDII"),
    ("L’utilisation d’un onduleur protège la machine contre :", ("Les débris de poussière, Les microcoupures d’énergie, Les éventuelles chocs préjudiciables, Les variations de tension électrique"), "Les microcoupures d’énergie"),
    ("laquelle des actions suivantes, relève de la maintenance logicielle? :", ("Installer un antivirus, Brancher sous onduleur, Recouvrir d’une nappe propre, Nettoyer régulièrement"), "Installer un antivirus"),
    (" Pour solliciter le tableur dans un calcul, il faut saisir la formule  :", ("Précéder du nom de la cellule, En utilisant une référence relative, Précédé d’un symbole << = >>, Suivi du symbole  << = >> "), "Précédé d’un symbole << = >>"),
    ("Pour relire la formule saisie dans une cellule :", ("Il faut la rendre active, Il faut la rendre active et lire la barre des formules, Il faut la rendre active et lire la zone du nom, Il faut y effectuer un clic-droit"), "Il faut la rendre active et lire la barre des formules"),
    ("Les cellules B3 et F4 forment :", ("Des cellules côte-à-côte, Une liste de cellule, Une plage de cellule, Des cellules contigües"),"Une liste de cellule"),
    ("La formule =SOMME(B5:G5) réalise :", ("L’addition des cellules B5, C5, D5, E5, F5 et G5", "La multiplication des cellules B5, C5, DS, ES, F5 et G5", "L’addition des cellules C5, C5, DS, E5 et F5", "La soustraction des cellules B5, CS, DS, ES, F5 et G5"), "L’addition des cellules B5, C5, D5, E5, F5 et G5"),
    ("La recopie incrémentée d’ une cellule :", ("Additionne la formule de la cellule de départ, Reporte la valeur de cellules dans les autres cellules, Adapte logiquement le contenu de cette cellule a la cellule de départ"), "Adapte logiquement le contenu de cette cellule a la cellule de départ?"),
    ("Relever l’intrus dans la Iiste suivante :", ("lLAN, WAN, MAN, FDII"), "FDII"),

)'''

lancer_questionnaire(questionnaire)


voici mon fichier texte

Quels sont les périphériques d’entrée?, ("la souris","la batterie","Le moniteur","Le baffle"), la souris"
("Quels sont les périphériques d’entrée?", ("le clavier", "l'imprimante", " Le moniteur", "Le baffle"), "le clavier")
("Quels sont les  périphériques de sortie :", ("L’écran, "Le clavier", "L’imprimante", "Le scanner"), "l'imprimante"),
("Relever l’intrus dans la Iiste suivante :", ("LAN, WAN, MAN, FDII"), "FDII"),
("Lequel des périphériques suivant permet de gérer la confidentialité en réseau:", ("Câble réseau", "Le concentrateur", "Le répéteur", "Le commutateur"), "Le commutateur"),
("Internet est née d’un projet de l’armée américaine dénommée:", ("WAN", "ARPANET", "DARPA", "WEB"), "WEB"),
("Pour s’affranchir des limites du matériel et couvrir de grandes distances par le signal, on utilise :", ("Le répéteur", "Le pont", "Le câble réseau", "Les câbles réseau"), "Le répéteur"),
("Relever l’intrus dans la Iiste suivante :", ("Un logiciel de communication", "Un appareil connecté à l’UC", "Responsable des traitements"), "Un appareil connecté à l’UC"),
("un pilot permet:", ("Le décollage des documents", " Le fonctionnement d’un périphérique", "Impression des documents"), "Le fonctionnement d’un périphérique"),
("un tableur est :", ("Un logiciel de calcul, Un logiciel de traitement de texte, Un périphérique d’entrée / sortie"), "Un logiciel de calcul")
("la RAM est :", ("Responsable des traitements", "Le chef d’orchestre de la machine", "Une mémoire volatile"),"Une mémoire volatile"),
("Repérer l’intrus dans chaque cas:", ("Excel", "Word", "Access", "Photoshop"), "Photoshop"),
("Repérer l’intrus dans chaque cas:", ("Encarta", "Ubuntu", "Windows", "Mac OS"), "Encarta"),
("Repérer l’intrus dans chaque cas:", ("PowerDVD", "Paint", "VLC", "Nero Vision"), "Paint"),
("Relever l’action de maintenance préventive :", ("Remplacer le disque dur, Brancher sous onduleur, Ajouter la mémoire vive, Installer un logiciel"), "Brancher sous onduleur"),
("la maintenance évolutive consiste à :", ("Réparer  une panne sur l’ équipement, Protéger  l’ équipement contre tout problème, Adapter  la machine à une nouvelle utilisation, Installer des logiciels dans la machine    "), "Installer des logiciels dans la machine"),
("Lorsqu'on installe de nouveaux logiciels, on fait de :", ("La maintenance préventive, La maintenance matérielle, La maintenance corrective, La maintenance évolutive"), "FDII"),
("L’utilisation d’un onduleur protège la machine contre :", ("Les débris de poussière, Les microcoupures d’énergie, Les éventuelles chocs préjudiciables, Les variations de tension électrique"), "Les microcoupures d’énergie"),
("laquelle des actions suivantes, relève de la maintenance logicielle? :", ("Installer un antivirus, Brancher sous onduleur, Recouvrir d’une nappe propre, Nettoyer régulièrement"), "Installer un antivirus"),
(" Pour solliciter le tableur dans un calcul, il faut saisir la formule  :", ("Précéder du nom de la cellule, En utilisant une référence relative, Précédé d’un symbole << = >>, Suivi du symbole  << = >> "), "Précédé d’un symbole << = >>"),
("Pour relire la formule saisie dans une cellule :", ("Il faut la rendre active, Il faut la rendre active et lire la barre des formules, Il faut la rendre active et lire la zone du nom, Il faut y effectuer un clic-droit"), "Il faut la rendre active et lire la barre des formules"),
("Les cellules B3 et F4 forment :", ("Des cellules côte-à-côte, Une liste de cellule, Une plage de cellule, Des cellules contigües), "Une liste de cellule"),
("La formule =SOMME(B5:G5) réalise :", ("L’addition des cellules B5, C5, D5, E5, F5 et G5", "La multiplication des cellules B5, C5, DS, ES, F5 et G5", "L’addition des cellules C5, C5, DS, E5 et F5", "La soustraction des cellules B5, CS, DS, ES, F5 et G5"), "L’addition des cellules B5, C5, D5, E5, F5 et G5"),
("La recopie incrémentée d’ une cellule :", ("Additionne la formule de la cellule de départ, Reporte la valeur de cellules dans les autres cellules, Adapte logiquement le contenu de cette cellule a la cellule de départ"), "Adapte logiquement le contenu de cette cellule a la cellule de départ?"),
("Relever l’intrus dans la Iiste suivante :", ("lLAN, WAN, MAN, FDII"), "FDII")

J'aimerais qu'on puisse faire passer chaque question avec les choix des réponses.

2 réponses

jee pee Messages postés 40413 Date d'inscription mercredi 2 mai 2007 Statut Modérateur Dernière intervention 3 novembre 2024 9 411
Modifié le 28 nov. 2023 à 15:36

Bonjour,

La structure de ton fichier en entrée est imparfaite, il manque des doubles-quotes, il y a plusieurs types d'apostrophe,...

J'en ai retravaillé un, pas complet :

("Quels sont les périphériques d’entrée?", ("le clavier", "l'imprimante", " Le moniteur", "Le baffle"), "le clavier")
("Relever l’intrus dans la Iiste suivante :", ("LAN", "WAN", "MAN", "FDII"), "FDII")
("Lequel des périphériques suivant permet de gérer la confidentialité en réseau:", ("Câble réseau", "Le concentrateur", "Le répéteur", "Le commutateur"), "Le commutateur")
("Internet est née d’un projet de l’armée américaine dénommée:", ("WAN", "ARPANET", "DARPA", "WEB"), "WEB")
("Pour s’affranchir des limites du matériel et couvrir de grandes distances par le signal, on utilise :", ("Le répéteur", "Le pont", "Le câble réseau", "Les câbles réseau"), "Le répéteur")
("Relever l’intrus dans la Iiste suivante :", ("Un logiciel de communication", "Un appareil connecté à l’UC", "Responsable des traitements"), "Un appareil connecté à l’UC")
("un pilot permet:", ("Le décollage des documents", " Le fonctionnement d’un périphérique", "Impression des documents"), "Le fonctionnement d’un périphérique")
("un tableur est :", ("Un logiciel de calcul", "Un logiciel de traitement de texte", "Un périphérique d’entrée / sortie"), "Un logiciel de calcul")
("la RAM est :", ("Responsable des traitements", "Le chef d’orchestre de la machine", "Une mémoire volatile"),"Une mémoire volatile")
("Repérer l’intrus dans chaque cas:", ("Excel", "Word", "Access", "Photoshop"), "Photoshop")
("Repérer l’intrus dans chaque cas:", ("Encarta", "Ubuntu", "Windows", "Mac OS"), "Encarta")
("Repérer l’intrus dans chaque cas:", ("PowerDVD", "Paint", "VLC", "Nero Vision"), "Paint")
("Relever l’action de maintenance préventive :", ("Remplacer le disque dur", "Brancher sous onduleur", "Ajouter la mémoire vive", "Installer un logiciel"), "Brancher sous onduleur")
("la maintenance évolutive consiste à :", ("Réparer  une panne sur l’ équipement", "Protéger  l’ équipement contre tout problème", "Adapter  la machine à une nouvelle utilisation", "Installer des logiciels dans la machine"), "Installer des logiciels dans la machine")
("Lorsqu'on installe de nouveaux logiciels, on fait de :", ("La maintenance préventive", "La maintenance matérielle", "La maintenance corrective", "La maintenance évolutive"), "FDII")
("L’utilisation d’un onduleur protège la machine contre :", ("Les débris de poussière", "Les microcoupures d’énergie", "Les éventuelles chocs préjudiciables", "Les variations de tension électrique"), "Les microcoupures d’énergie")
("laquelle des actions suivantes, relève de la maintenance logicielle? :", ("Installer un antivirus", "Brancher sous onduleur", "Recouvrir d’une nappe propre", "Nettoyer régulièrement"), "Installer un antivirus")
("Pour solliciter le tableur dans un calcul, il faut saisir la formule  :", ("Précéder du nom de la cellule", "En utilisant une référence relative", "Précédé d’un symbole << = >>", "Suivi du symbole  << = >> "), "Précédé d’un symbole << = >>")
("La formule =SOMME(B5:G5) réalise :", ("L’addition des cellules B5, C5, D5, E5, F5 et G5", "La multiplication des cellules B5, C5, DS, ES, F5 et G5", "L’addition des cellules C5, C5, DS, E5 et F5", "La soustraction des cellules B5, CS, DS, ES, F5 et G5"), "L’addition des cellules B5, C5, D5, E5, F5 et G5")
("La recopie incrémentée d’ une cellule :", ("Additionne la formule de la cellule de départ", "Reporte la valeur de cellules dans les autres cellules", "Adapte logiquement le contenu de cette cellule a la cellule de départ"), "Adapte logiquement le contenu de cette cellule a la cellule de départ?")
("Relever l’intrus dans la Iiste suivante :", ("lLAN", "WAN", "MAN", "FDII"), "FDII")

Et pour lire ce fichier, il peut y avoir de nombreuses méthodes, mais je te propose

questionnaire=[]
with open("informatique1.txt", "r", encoding="utf-8") as fp:
    for ligne in fp:
        questionnaire.append(eval(ligne.rstrip('\r\n')))

Tu pourras avancer pour corriger les autres soucis


1
mamiemando Messages postés 33333 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 31 octobre 2024 7 801
28 nov. 2023 à 16:15

Bonjour,

Une fois les corrections mentionnées par jee pee faite à ton fichier d'entrée, comme chaque ligne correspond exactement à la définition de tuples python, tu peux  aussi directement évaluer ces lignes. Je ne le ferais pas sur un code "sérieux" car c'est la porte ouvertes aux injections, mais dans le cadre d'un exercice je pense que c'est suffisant.

import ast
import sys

def load_qcm(filename: str):
    with open(filename, "r") as f:
        return [
            eval(line)
            for line in f.readlines()
        ]

load_qcm("questions.txt")

Concernant ton fichier de questions, il serait plus stratégique que le 3e élément de chaque tuple soit l'index de la bonne réponse plutôt qu'une recopie (parfois approximative) de la bonne réponse.

Quoi qu'il en soit, voici comment tu pourrais améliorer ton code :

import ast
import sys

def load_qcm(filename: str):
    with open(filename, "r") as f:
        return [
            eval(line)
            for line in f.readlines()
        ]

def question(qcm: list, i: int) -> str:
    return qcm[i][0]

def proposals(qcm: list, i: int) -> tuple:
    return qcm[i][1]

def answer(qcm: list, i: int) -> str:
    return qcm[i][2]

def print_question(qcm: list, i: int) -> int:
    print(question(qcm, i))
    choices = proposals(qcm, i)
    for (j, choice) in enumerate(choices):
        # On réindexe à partir de 1
        print(j + 1, choice.strip().title())
    return len(choices)

def prompt_answer(n: int) -> int:
    ok = False
    j = None
    while not ok:
        try:
            j = int(input(f"Réponse [1-{n}]: "))
            if (1 <= j <= n):
                break
        except ValueError:
            pass
        print("Réponse invalide !", file=sys.stderr)
    # On réindexe à partir de 0
    return j - 1

def check_answer(qcm: list, i: int, j: int) -> bool:
    choices = proposals(qcm, i)
    choice = choices[j]
    expected = answer(qcm, i)
    return choice.strip().lower() == expected.strip().lower()

def main():
    qcm = load_qcm("toto.txt")
    for i in range(len(qcm)):
        print(f"Question {i}:")
        n = print_question(qcm, i)
        j = prompt_answer(n)
        if check_answer(qcm, i, j):
            print("Bravo!")
        else:
            print(f"Désolé, la réponse était {answer(qcm, i)}")

main()

Dans le programme ci-dessus,

  • i désigne l'index de la question courante
  • j désigne de la réponse choisie
  • Comme python indexe à partir de 0 et que les humains indexent en général à partir de 1, il faut veiller à bien ré-indexer.
  • Afin de mettre en forme les réponses, la méthode str.title() est indiquée. Par ailleurs, str.strip() permet de supprimer les espaces en trop en début et fin de chaîne.
  • Afin de comparer une proposition avec la réponse attendue, vue que la casse peut différer, il peut être avisé d'appliquer par exemple str.lower(). Attention aussi aux espaces, donc là aussi str.strip(). Note que ces soucis disparaissent si comme je le suggérais plus haut, tu stockes l'index de la bonne réponse au lieu du texte de la bonne réponse.

Bonne chance

0