Aller au contenu

A : interface

A : Issues d'interface

Les issues de ce groupe visent à améliorer l'affichage.

A.1 : Affichage ligne par ligne

Les questions et chaque réponses sont affichées sur des lignes séparées.

Pour le moment, l'affichage des questions/reponses a une forme comme :

texte (reponse1, reponse2, reponse3, reponse4):reponse_utilisateur
vrai/faux + réponse juste

On veut changer cet affichage pour qu'il soit comme suit :

## texte 

reponse1
reponse2
reponse3
reponse4

choix:reponse_utilisateur
choisissez parmi les réponses ci-dessus:reponse_utilisateur
vrai/faux + réponse juste

Remarquez les deux sauts de ligne avant d'afficher la question. ils servirons à espacer les questions

Modifiez la fonction demander_choix pour arriver à ce résultat.

Aide

Vous n'avez normalement qu'a modifier le texte, ajouter éventuellement des print ou modifier les chaînes de caractères utilisées pour le formattage.

Le caractère "\n" permet de faire un retour à la ligne dans une chaîne :

print("retour\nligne")
affiche
retour
ligne

N'oubliez pas que print ajoute automatiquement un retour à la ligne à la fin du texte.

Un print sans argument print() saute simplement une ligne.

Solution

Faire un print pour chaque saut de ligne permet d'avoir une vue approximative de l'aspect de l'interface.

def demander_choix(question, choix):
    """question une chaine de caractères, la question
    choix un tuple de chaines, les choix possibles.

    Redemande une saisie à l'utilisateur tant que sa réponse n'est pas un des choix
    retourne le choix valide choisi.
    """
    choix_melanges = melange(choix)
    print()
    print()
    print()
    print(f"## {question}\n")
    print()
    print(choix_melanges[0])
    print(choix_melanges[1])
    print(choix_melanges[2])
    print(choix_melanges[3])
    print()
    reponse = input("choix : ")
    while not (reponse in choix_melanges):
        reponse = input(f"Choisissez parmi les choix ci dessus :")
    return reponse

Modifiez maintenant la fonction main pour y ajouter quelques retours à la ligne avant d'afficher le compte des réponses.

Solution
def main():
    nombre_questions = int(input(f"Choisissez le nombre de questions (1-{len(questions)}): "))
    if nombre_questions < 1 :
        nombre_questions = 1
    elif nombre_questions > len(questions):
        nombre_questions = len(questions)

    bonnes_reponses = 0
    questions_choisies = sample(questions, nombre_questions)
    for question in questions_choisies:
        bonnes_reponses += poser_question(question)
    print()
    print()
    print()
    print(f"Nombre de questions : {len(questions_choisies)}")
    print(f"Bonnes réponses : {bonnes_reponses}")
Solution (Code complet)
questions = [
    ("En quelle année a eu lieu la prise de la Bastille ?", ("1789", "1988",  "1987", "1452")),
    ("La SNT est un cours dispensé en classe de ?", ("Seconde", "Première",  "Terminale", "3eme")),
    ("Le terme cortinaire désigne en général un ?", ("champignon", "végétal", "animal",  "minéral")),
    ("Le genre de manga qui consiste à plonger un personnage dans un univers inconnu est ? ", ("isekai", "seinen", "shonen",  "shojo")),
    ("Le MMORPG français qui consiste en une quête de recherche d'oeufs de dragons est ?", ("Dofus", "World Of Warcraft", "Dragon Nest",  "PlanetSide 2")),
    ("Le personnage d'animé qui bat tous ses adversaire d'un coup de poing est ?", ("Saitama", "One Punch Man", "Genos",  "Tatsumaki")),
    ("L'ustensile de cuisine qui utilise la pression pour augmenter la température de la vapeur d'eau et cuire plus rapidement les aliments, est ?", ("Un autocuiseur", "Un cuit-vapeur", "Une cocotte",  "Une Marmite")),
    ("Dans quelle bande dessinée les occupants d'un train s'arrêtent dans une centrale nucléaire défaillante ?", ("Le Transperceneige", "Kabaneri of the Iron Fortress", "Nuclear Train",  "Yoko Tsuno")),
    ("Parmi ces 4 serpents, lequel est aussi un langage de programmation très utilisé ?", ("Python", "Cobra", "Vipère", "Mamba")),
    ("Quel théorème énonce une relation entre les longueurs des côtés et de l'hypothènuse d'un triangle rectangle ?", ("Pythagore", "Thalès", "Godel", "Haskell")),
    ("Une trottinette avec des roues a rayons et des pneus gonflables s'appelle ?", ("kickbike", "trottivelo", "velotinette", "kickcycle"))
    ]

from random import shuffle
from random import sample

def texte(question):
    """question une question,
    retourne le texte de la question

    texte(("a", ("b", "c", "d", "e")))
    retourne "a"
    """
    return question[0]

def reponses(question):
    """question une question,
    retourne le tuple des réponses de la question

    reponses(("a", ("b", "c", "d", "e")))
    retourne ("b", "c", "d", "e")
    """
    return question[1]

def bonne_reponse(question):
    """question une question
    retourne la bonne réponse de la question

    bonne_reponse(("a", ("b", "c", "d", "e")))
    retourne "b"
    """
    return reponses(question)[0]

def melange(tu):
    """tu un tuple à mélanger.
    Retourne une copie de tu mélangée aléatoirement.
    """
    l = list(tu)
    shuffle(l)
    t = tuple(l)
    return t

def demander_choix(question, choix):
    """question une chaine de caractères, la question
    choix un tuple de chaines, les choix possibles.

    Redemande une saisie à l'utilisateur tant que sa réponse n'est pas un des choix
    retourne le choix valide choisi.
    """
    choix_melanges = melange(choix)
    print()
    print()
    print()
    print(f"## {question}\n")
    print()
    print(choix_melanges[0])
    print(choix_melanges[1])
    print(choix_melanges[2])
    print(choix_melanges[3])
    print()
    reponse = input("choix : ")
    while not (reponse in choix_melanges):
        reponse = input(f"Choisissez parmi les choix ci dessus :")
    return reponse

def poser_question(question):
    """question une question

    pose la question à l'utilisateur. Retourne 1 si la réponse est la bonne, 0 sinon.
    """
    bonne_rep = bonne_reponse(question)
    reponse = demander_choix(texte(question), reponses(question))
    if reponse == bonne_rep:
        print("Vrai !")
        return 1
    else:
        print(f"Faux : {bonne_rep}")
        return 0

def main():
    nombre_questions = int(input(f"Choisissez le nombre de questions (1-{len(questions)}): "))
    if nombre_questions < 1 :
        nombre_questions = 1
    elif nombre_questions > len(questions):
        nombre_questions = len(questions)

    bonnes_reponses = 0
    questions_choisies = sample(questions, nombre_questions)
    for question in questions_choisies:
        bonnes_reponses += poser_question(question)
    print()
    print()
    print()
    print(f"Nombre de questions : {len(questions_choisies)}")
    print(f"Bonnes réponses : {bonnes_reponses}")

if __name__=="__main__":
    main()

A.2 : Réponse par lettre

Les réponses ont un numéro attribué (1,2,3,4), et l'utilisateur peut répondre directement la lettre au lieu du texte de la réponse.

Notre affichage va donc devenir :

## texte 

1: reponse1
2: reponse2
3: reponse3
4: reponse4

choix:reponse_utilisateur
choisissez parmi les réponses ci-dessus:reponse_utilisateur
vrai/faux + réponse juste

Modifiez la fonction demander_choix de manière à ce qu'elle propose l'affichage ci-dessus, et qu'elle redemande un choix utilisateur tant que la réponse n'est pas 1, 2, 3, ou 4. Attention, vous ne pourrez plus répondre correctement aux questions avant d'avoir fait les modifications qui suivent dans cette issue.

Aide

vous pouvez spécifier directement un tuple pour l'opérateur in:

"4" in ("1","2","3","4") ## vaut True
Solution
    def demander_choix(question, choix):
    """question une chaine de caractères, la question
    choix un tuple de chaines, les choix possibles.

    Redemande une saisie à l'utilisateur tant que sa réponse n'est pas un des choix
    retourne le choix valide choisi.
    """
    choix_melanges = melange(choix)
    print()
    print()
    print()
    print(f"## {question}\n")
    print()
    print(f"1: {choix_melanges[0]}")
    print(f"2: {choix_melanges[1]}")
    print(f"3: {choix_melanges[2]}")
    print(f"4: {choix_melanges[3]}")
    print()
    reponse = input("choix : ")
    while not (reponse in ("1","2","3","4")):
        reponse = input(f"Choisissez parmi les choix ci dessus :")
    return reponse

Il nous faut maintenant établir une correspondance entre le numéro de réponse \(n\), et l'indice \(i\) d'une réponse dans le tuple des choix mélangés.

Si on regarde les lignes suivantes :

print(f"1: {choix_melanges[0]}")
print(f"2: {choix_melanges[1]}")
print(f"3: {choix_melanges[2]}")
print(f"4: {choix_melanges[3]}")

on s'apercoit que réponse 1 corresponds à l'indice 0, la réponse 2 à l'indice 1, la réponse 3 à l'indice 2 etc... En résumé : \(i = n -1\)

Modifiez la dernière ligne de la fonction demander_choix de manière à retourner non pas le numéro de réponse, mais le texte de la réponse correspondante.

Aide

Pensez à convertir le numéro de réponse en entier si ce n'est pas déjà fait. Vous pouvez utiliser la fonction int pour ça.

Utilisez l'opérateur [] pour accéder à un élément de choix_melanges avec son indice.

Solution

La ligne

return reponse

devient

return choix_melanges[int(reponse)]

fonction complète :

def demander_choix(question, choix):
    """question une chaine de caractères, la question
    choix un tuple de chaines, les choix possibles.

    Redemande une saisie à l'utilisateur tant que sa réponse n'est pas un des choix
    retourne le choix valide choisi.
    """
    choix_melanges = melange(choix)
    print()
    print()
    print()
    print(f"## {question}\n")
    print()
    print(f"1: {choix_melanges[0]}")
    print(f"2: {choix_melanges[1]}")
    print(f"3: {choix_melanges[2]}")
    print(f"4: {choix_melanges[3]}")
    print()
    reponse = input("choix : ")
    while not (reponse in ("1","2","3","4")):
        reponse = input(f"Choisissez parmi les choix ci dessus :")
    return choix_melanges[int(reponse) - 1]
Solution (Code complet)
questions = [
    ("En quelle année a eu lieu la prise de la Bastille ?", ("1789", "1988",  "1987", "1452")),
    ("La SNT est un cours dispensé en classe de ?", ("Seconde", "Première",  "Terminale", "3eme")),
    ("Le terme cortinaire désigne en général un ?", ("champignon", "végétal", "animal",  "minéral")),
    ("Le genre de manga qui consiste à plonger un personnage dans un univers inconnu est ? ", ("isekai", "seinen", "shonen",  "shojo")),
    ("Le MMORPG français qui consiste en une quête de recherche d'oeufs de dragons est ?", ("Dofus", "World Of Warcraft", "Dragon Nest",  "PlanetSide 2")),
    ("Le personnage d'animé qui bat tous ses adversaire d'un coup de poing est ?", ("Saitama", "One Punch Man", "Genos",  "Tatsumaki")),
    ("L'ustensile de cuisine qui utilise la pression pour augmenter la température de la vapeur d'eau et cuire plus rapidement les aliments, est ?", ("Un autocuiseur", "Un cuit-vapeur", "Une cocotte",  "Une Marmite")),
    ("Dans quelle bande dessinée les occupants d'un train s'arrêtent dans une centrale nucléaire défaillante ?", ("Le Transperceneige", "Kabaneri of the Iron Fortress", "Nuclear Train",  "Yoko Tsuno")),
    ("Parmi ces 4 serpents, lequel est aussi un langage de programmation très utilisé ?", ("Python", "Cobra", "Vipère", "Mamba")),
    ("Quel théorème énonce une relation entre les longueurs des côtés et de l'hypothènuse d'un triangle rectangle ?", ("Pythagore", "Thalès", "Godel", "Haskell")),
    ("Une trottinette avec des roues a rayons et des pneus gonflables s'appelle ?", ("kickbike", "trottivelo", "velotinette", "kickcycle"))
    ]

from random import shuffle
from random import sample

def texte(question):
    """question une question,
    retourne le texte de la question

    texte(("a", ("b", "c", "d", "e")))
    retourne "a"
    """
    return question[0]

def reponses(question):
    """question une question,
    retourne le tuple des réponses de la question

    reponses(("a", ("b", "c", "d", "e")))
    retourne ("b", "c", "d", "e")
    """
    return question[1]

def bonne_reponse(question):
    """question une question
    retourne la bonne réponse de la question

    bonne_reponse(("a", ("b", "c", "d", "e")))
    retourne "b"
    """
    return reponses(question)[0]

def melange(tu):
    """tu un tuple à mélanger.
    Retourne une copie de tu mélangée aléatoirement.
    """
    l = list(tu)
    shuffle(l)
    t = tuple(l)
    return t

def demander_choix(question, choix):
    """question une chaine de caractères, la question
    choix un tuple de chaines, les choix possibles.

    Redemande une saisie à l'utilisateur tant que sa réponse n'est pas un des choix
    retourne le choix valide choisi.
    """
    choix_melanges = melange(choix)
    print()
    print()
    print()
    print(f"## {question}\n")
    print()
    print(f"1: {choix_melanges[0]}")
    print(f"2: {choix_melanges[1]}")
    print(f"3: {choix_melanges[2]}")
    print(f"4: {choix_melanges[3]}")
    print()
    reponse = input("choix : ")
    while not (reponse in ("1","2","3","4")):
        reponse = input(f"Choisissez parmi les choix ci dessus :")
    return choix_melanges[int(reponse) - 1]

def poser_question(question):
    """question une question

    pose la question à l'utilisateur. Retourne 1 si la réponse est la bonne, 0 sinon.
    """
    bonne_rep = bonne_reponse(question)
    reponse = demander_choix(texte(question), reponses(question))
    if reponse == bonne_rep:
        print("Vrai !")
        return 1
    else:
        print(f"Faux : {bonne_rep}")
        return 0

def main():
    nombre_questions = int(input(f"Choisissez le nombre de questions (1-{len(questions)}): "))
    if nombre_questions < 1 :
        nombre_questions = 1
    elif nombre_questions > len(questions):
        nombre_questions = len(questions)

    bonnes_reponses = 0
    questions_choisies = sample(questions, nombre_questions)
    for question in questions_choisies:
        bonnes_reponses += poser_question(question)
    print()
    print()
    print()
    print(f"Nombre de questions : {len(questions_choisies)}")
    print(f"Bonnes réponses : {bonnes_reponses}")

if __name__=="__main__":
    main()

A.3 : Affichage "écran"

A chaque question, la question précédente est effacée, et donc la console d'affichage est utilisée comme un écran.

Pour le moment, pour deux question successives, la console ressemble à ça :

Poser question 1 :

## Une trottinette avec des roues a rayons et des pneus gonflables s'appelle ?


1: trottivelo
2: kickbike
3: kickcycle
4: velotinette

choix : 

Poser question 2 :

## Une trottinette avec des roues a rayons et des pneus gonflables s'appelle ?


1: trottivelo
2: kickbike
3: kickcycle
4: velotinette

choix : 4
Faux : kickbike



## Parmi ces 4 serpents, lequel est aussi un langage de programmation très utilisé ?


1: Vipère
2: Cobra
3: Mamba
4: Python

choix : 

On aimerait que le terminal ressemble à :

Poser question 1 :

## Une trottinette avec des roues a rayons et des pneus gonflables s'appelle ?


1: trottivelo
2: kickbike
3: kickcycle
4: velotinette

choix :

Poser question 2 :

## Parmi ces 4 serpents, lequel est aussi un langage de programmation très utilisé ?


1: Vipère
2: Cobra
3: Mamba
4: Python

choix : 

Dans l'idéal, il faudrait que l'on puisse effacer une partie du contenu de la console d'affichage. C'est possible pour certains terminaux, mais le terminal qui est fourni dans les IDE comme Thonny n'est pas toujours compatible avec ces méthodes.

On va donc faire plus simple : avant de poser chaque question, on affichera une centaine de nouvelles lignes, pour "nettoyer" la console.

Creez une fonction nettoyer_console qui affiche environ 100 retours à la ligne. N'utilisez qu'un seul print et pas de boucle, sinon la fonction risque d'être trop lente.

Aide 1

le caractère "\n" permet de faire un retour à la ligne dans une chaîne:

print("a\nb")

affiche :

a
b
Aide 2

L'opérateur * permet de répéter une chaîne de caractères :

"abc" * 3

vaut

"abcabcabc"
Solution
def nettoyer_console():
    """Cette fonction nettoie la console en affichant 
    100 retours à la ligne environ en un seul print
    """
    print("\n" * 100)

Appelez maintenant la fonction nettoyer_console dans la fonction main, de manière à ce que qu'avant chaque question, et que après la dernière question, la console d'affichage soit nettoyée.

Solution
def main():
    nombre_questions = int(input(f"Choisissez le nombre de questions (1-{len(questions)}): "))
    if nombre_questions < 1 :
        nombre_questions = 1
    elif nombre_questions > len(questions):
        nombre_questions = len(questions)

    bonnes_reponses = 0
    questions_choisies = sample(questions, nombre_questions)

    for question in questions_choisies:
        nettoyer_console()
        bonnes_reponses += poser_question(question)
    nettoyer_console()
    print()
    print()
    print()
    print(f"Nombre de questions : {len(questions_choisies)}")
    print(f"Bonnes réponses : {bonnes_reponses}")
Solution (Code complet)
questions = [
    ("En quelle année a eu lieu la prise de la Bastille ?", ("1789", "1988",  "1987", "1452")),
    ("La SNT est un cours dispensé en classe de ?", ("Seconde", "Première",  "Terminale", "3eme")),
    ("Le terme cortinaire désigne en général un ?", ("champignon", "végétal", "animal",  "minéral")),
    ("Le genre de manga qui consiste à plonger un personnage dans un univers inconnu est ? ", ("isekai", "seinen", "shonen",  "shojo")),
    ("Le MMORPG français qui consiste en une quête de recherche d'oeufs de dragons est ?", ("Dofus", "World Of Warcraft", "Dragon Nest",  "PlanetSide 2")),
    ("Le personnage d'animé qui bat tous ses adversaire d'un coup de poing est ?", ("Saitama", "One Punch Man", "Genos",  "Tatsumaki")),
    ("L'ustensile de cuisine qui utilise la pression pour augmenter la température de la vapeur d'eau et cuire plus rapidement les aliments, est ?", ("Un autocuiseur", "Un cuit-vapeur", "Une cocotte",  "Une Marmite")),
    ("Dans quelle bande dessinée les occupants d'un train s'arrêtent dans une centrale nucléaire défaillante ?", ("Le Transperceneige", "Kabaneri of the Iron Fortress", "Nuclear Train",  "Yoko Tsuno")),
    ("Parmi ces 4 serpents, lequel est aussi un langage de programmation très utilisé ?", ("Python", "Cobra", "Vipère", "Mamba")),
    ("Quel théorème énonce une relation entre les longueurs des côtés et de l'hypothènuse d'un triangle rectangle ?", ("Pythagore", "Thalès", "Godel", "Haskell")),
    ("Une trottinette avec des roues a rayons et des pneus gonflables s'appelle ?", ("kickbike", "trottivelo", "velotinette", "kickcycle"))
    ]

from random import shuffle
from random import sample

def texte(question):
    """question une question,
    retourne le texte de la question

    texte(("a", ("b", "c", "d", "e")))
    retourne "a"
    """
    return question[0]

def reponses(question):
    """question une question,
    retourne le tuple des réponses de la question

    reponses(("a", ("b", "c", "d", "e")))
    retourne ("b", "c", "d", "e")
    """
    return question[1]

def bonne_reponse(question):
    """question une question
    retourne la bonne réponse de la question

    bonne_reponse(("a", ("b", "c", "d", "e")))
    retourne "b"
    """
    return reponses(question)[0]

def melange(tu):
    """tu un tuple à mélanger.
    Retourne une copie de tu mélangée aléatoirement.
    """
    l = list(tu)
    shuffle(l)
    t = tuple(l)
    return t

def demander_choix(question, choix):
    """question une chaine de caractères, la question
    choix un tuple de chaines, les choix possibles.

    Redemande une saisie à l'utilisateur tant que sa réponse n'est pas un des choix
    retourne le choix valide choisi.
    """
    choix_melanges = melange(choix)
    print()
    print()
    print()
    print(f"## {question}\n")
    print()
    print(f"1: {choix_melanges[0]}")
    print(f"2: {choix_melanges[1]}")
    print(f"3: {choix_melanges[2]}")
    print(f"4: {choix_melanges[3]}")
    print()
    reponse = input("choix : ")
    while not (reponse in ("1","2","3","4")):
        reponse = input(f"Choisissez parmi les choix ci dessus :")
    return choix_melanges[int(reponse) - 1]

def poser_question(question):
    """question une question

    pose la question à l'utilisateur. Retourne 1 si la réponse est la bonne, 0 sinon.
    """
    bonne_rep = bonne_reponse(question)
    reponse = demander_choix(texte(question), reponses(question))
    if reponse == bonne_rep:
        print("Vrai !")
        return 1
    else:
        print(f"Faux : {bonne_rep}")
        return 0

def nettoyer_console():
    """Cette fonction nettoie la console en affichant 
    100 retours à la ligne environ en un seul print
    """
    print("\n" * 100)

def main():
    nombre_questions = int(input(f"Choisissez le nombre de questions (1-{len(questions)}): "))
    if nombre_questions < 1 :
        nombre_questions = 1
    elif nombre_questions > len(questions):
        nombre_questions = len(questions)

    bonnes_reponses = 0
    questions_choisies = sample(questions, nombre_questions)

    for question in questions_choisies:
        nettoyer_console()
        bonnes_reponses += poser_question(question)
    nettoyer_console()
    print()
    print()
    print()
    print(f"Nombre de questions : {len(questions_choisies)}")
    print(f"Bonnes réponses : {bonnes_reponses}")

if __name__=="__main__":
    main()

Cette solution comporte toutefois un problème : comme la console est nettoyée directement après l'affichage de la réponse correcte, après que le joueur ait répondu, il n'a pas le temps de voir la réponse.

Pour résoudre ce problème, ajoutez dans la fonction main un appel à input pour demander au joueur une confirmation que l'on peut passer à la question suivante, comme dans la sortie ci dessous :

## Le terme cortinaire désigne en général un ?


1: champignon
2: végétal
3: minéral
4: animal

choix : 2
Faux : champignon
Appuyez sur Entrée pour passer à la question suivante : 
Aide

On n'a pas besoin de récupérer la valeur de retour de input dans une variable, puisqu'on ne s'en sert pas.

Solution
def main():
    nombre_questions = int(input(f"Choisissez le nombre de questions (1-{len(questions)}): "))
    if nombre_questions < 1 :
        nombre_questions = 1
    elif nombre_questions > len(questions):
        nombre_questions = len(questions)

    bonnes_reponses = 0
    questions_choisies = sample(questions, nombre_questions)

    for question in questions_choisies:
        nettoyer_console()
        bonnes_reponses += poser_question(question)
        input("Appuyez sur Entrée pour passer à la question suivante :")
    nettoyer_console()
    print()
    print()
    print()
    print(f"Nombre de questions : {len(questions_choisies)}")
    print(f"Bonnes réponses : {bonnes_reponses}")
Solution (Code complet)
questions = [
    ("En quelle année a eu lieu la prise de la Bastille ?", ("1789", "1988",  "1987", "1452")),
    ("La SNT est un cours dispensé en classe de ?", ("Seconde", "Première",  "Terminale", "3eme")),
    ("Le terme cortinaire désigne en général un ?", ("champignon", "végétal", "animal",  "minéral")),
    ("Le genre de manga qui consiste à plonger un personnage dans un univers inconnu est ? ", ("isekai", "seinen", "shonen",  "shojo")),
    ("Le MMORPG français qui consiste en une quête de recherche d'oeufs de dragons est ?", ("Dofus", "World Of Warcraft", "Dragon Nest",  "PlanetSide 2")),
    ("Le personnage d'animé qui bat tous ses adversaire d'un coup de poing est ?", ("Saitama", "One Punch Man", "Genos",  "Tatsumaki")),
    ("L'ustensile de cuisine qui utilise la pression pour augmenter la température de la vapeur d'eau et cuire plus rapidement les aliments, est ?", ("Un autocuiseur", "Un cuit-vapeur", "Une cocotte",  "Une Marmite")),
    ("Dans quelle bande dessinée les occupants d'un train s'arrêtent dans une centrale nucléaire défaillante ?", ("Le Transperceneige", "Kabaneri of the Iron Fortress", "Nuclear Train",  "Yoko Tsuno")),
    ("Parmi ces 4 serpents, lequel est aussi un langage de programmation très utilisé ?", ("Python", "Cobra", "Vipère", "Mamba")),
    ("Quel théorème énonce une relation entre les longueurs des côtés et de l'hypothènuse d'un triangle rectangle ?", ("Pythagore", "Thalès", "Godel", "Haskell")),
    ("Une trottinette avec des roues a rayons et des pneus gonflables s'appelle ?", ("kickbike", "trottivelo", "velotinette", "kickcycle"))
    ]

from random import shuffle
from random import sample

def texte(question):
    """question une question,
    retourne le texte de la question

    texte(("a", ("b", "c", "d", "e")))
    retourne "a"
    """
    return question[0]

def reponses(question):
    """question une question,
    retourne le tuple des réponses de la question

    reponses(("a", ("b", "c", "d", "e")))
    retourne ("b", "c", "d", "e")
    """
    return question[1]

def bonne_reponse(question):
    """question une question
    retourne la bonne réponse de la question

    bonne_reponse(("a", ("b", "c", "d", "e")))
    retourne "b"
    """
    return reponses(question)[0]

def melange(tu):
    """tu un tuple à mélanger.
    Retourne une copie de tu mélangée aléatoirement.
    """
    l = list(tu)
    shuffle(l)
    t = tuple(l)
    return t

def demander_choix(question, choix):
    """question une chaine de caractères, la question
    choix un tuple de chaines, les choix possibles.

    Redemande une saisie à l'utilisateur tant que sa réponse n'est pas un des choix
    retourne le choix valide choisi.
    """
    choix_melanges = melange(choix)
    print()
    print()
    print()
    print(f"## {question}\n")
    print()
    print(f"1: {choix_melanges[0]}")
    print(f"2: {choix_melanges[1]}")
    print(f"3: {choix_melanges[2]}")
    print(f"4: {choix_melanges[3]}")
    print()
    reponse = input("choix : ")
    while not (reponse in ("1","2","3","4")):
        reponse = input(f"Choisissez parmi les choix ci dessus :")
    return choix_melanges[int(reponse) - 1]

def poser_question(question):
    """question une question

    pose la question à l'utilisateur. Retourne 1 si la réponse est la bonne, 0 sinon.
    """
    bonne_rep = bonne_reponse(question)
    reponse = demander_choix(texte(question), reponses(question))
    if reponse == bonne_rep:
        print("Vrai !")
        return 1
    else:
        print(f"Faux : {bonne_rep}")
        return 0

def nettoyer_console():
    """Cette fonction nettoie la console en affichant 
    100 retours à la ligne environ en un seul print
    """
    print("\n" * 100)

def main():
    nombre_questions = int(input(f"Choisissez le nombre de questions (1-{len(questions)}): "))
    if nombre_questions < 1 :
        nombre_questions = 1
    elif nombre_questions > len(questions):
        nombre_questions = len(questions)

    bonnes_reponses = 0
    questions_choisies = sample(questions, nombre_questions)

    for question in questions_choisies:
        nettoyer_console()
        bonnes_reponses += poser_question(question)
    nettoyer_console()
    print()
    print()
    print()
    print(f"Nombre de questions : {len(questions_choisies)}")
    print(f"Bonnes réponses : {bonnes_reponses}")

if __name__=="__main__":
    main()