IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Premier programme sous Python


Sujet :

Python

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 38
    Points : 26
    Points
    26
    Par défaut Premier programme sous Python
    Bonjour,

    Afin de me familiariser avec Python, j'ai essayé de développer un programme de révision des tables de multiplications. Le principe est simple, dix questions sont posées avec correction immédiate et à la fin, le résultat final est affiché avec un mot d'encouragement. J'ai essayé d'ajouter un bloc Try...except au cas où l'utilisateur tape autre chose qu'un nombre. Le programme a l'air de fonctionner sauf sur un point :

    Lorsque je saisi autre chose qu'un entier, il me repose la même question. Jusque-là logique. Ensuite, que je donne une bonne ou une mauvaise réponse, peu importe, le programme réagit correctement. Le problème est qu'à la question suivante, plutôt que de générer aléatoirement une nouvelle question, la même est à nouveau posée et je ne sais pas d'où sa peut venir.

    Je ne sais pas si j'ai été assez clair, le code parlera peut-être mieux pour moi. Si vous avez d'autres remarques ou conseils, n'hésitez surtout pas à m'en faire part. Merci !

    Voici le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    # -*- coding:Latin-1 -*-
     
    import random
     
    note = 0
    questionsPosees = 0
     
    while questionsPosees < 10:
     
    	a = random.randint(1, 10)
    	b = random.randint(1, 10)
     
    	def question():
     
    		global note, questionsPosees
     
    		try:
    			reponse = int(raw_input("Combien font %d x %d ? " % (a, b)))
    			if reponse == a * b:
    				print "Exact ! %d x %d = %d" % (a, b, a * b)
    				note += 1
    				questionsPosees += 1
    			else:
    				print "Faux ! %d x %d = %d et pas %d." % (a, b, a * b, reponse)
    				questionsPosees += 1
    			return 1
     
    		except ValueError:
    			print "Réponse non valide. Tu dois saisir un nombre."
    			return 0
     
    	while question() != 1:
    		question()
     
    #Affichage du résultat final
     
    if note <= 4:
    	print "Ta note est de %d/10. Tu ferais bien de réviser." % (note)
    elif note > 4 and note <= 6:
    	print "Ta note est de %d/10. Courage ! Tu tiens le bon bout." % (note)
    elif note > 6 and note <= 9:
    	print "Ta note est de %d/10. Tu y es presque ! Encore un petit effort." % (note)
    elif note == 10:
    	print "Parfait ! Ta note est de 10/10. N'oublie cependant pas de réviser régulièrement. Ce serait dommage d'oublier ce que tu as appris après tous ces efforts."
    Et son résultat :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    $ python tables.py
    Combien font 4 x 3 ? 12
    Exact ! 4 x 3 = 12
    Combien font 3 x 10 ? 3
    Faux ! 3 x 10 = 30 et pas 3.
    Combien font 3 x 6 ? cas1
    Réponse non valide. Tu dois saisir un nombre.
    Combien font 3 x 6 ? 18
    Exact ! 3 x 6 = 18
    Combien font 3 x 6 ? 18
    Exact ! 3 x 6 = 18
    Combien font 9 x 6 ? cas2
    Réponse non valide. Tu dois saisir un nombre.
    Combien font 9 x 6 ? 6
    Faux ! 9 x 6 = 54 et pas 6.
    Combien font 9 x 6 ? 54
    Exact ! 9 x 6 = 54

  2. #2
    Membre habitué
    Inscrit en
    Novembre 2007
    Messages
    129
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 129
    Points : 160
    Points
    160
    Par défaut
    Je ne pense pas avoir corrigé l'erreure que tu as décrit parce que je ne trouve pas la cause.

    En tout cas j'ai effectué une toute petite modification de ton code.
    Bon : Ta fonction question() tu l'appel plus de 10 fois lorsque ton programme tourne. Le mieu c'est de déclarer cette fonction au début puis de l'appeler autant de fois que tu le souhaite.

    Ce que tu faisait c'est de déclarer la fonction dans une boucle while :
    Immagine donc que ta fonction est redéclaré à chaque exécution de la boucle ... enfin je pense que l'interpréteur python se débrouille pour ne pas redéclarer la fonction. En tout cas pour etre sur il faut faire attention et déclarer/definir tes fonctions et autres procédures les unes apres les autres et non pas les unes dans les autres ....

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
     
    # -*- coding:Latin-1 -*-
     
    import random
     
    note = 0
    questionsPosees = 0
     
    def question(a,b):
     
    		global note, questionsPosees
     
    		try:
    			reponse = int(raw_input("Combien font %d x %d ? " % (a, b)))
    			if reponse == a * b:
    				print "Exact ! %d x %d = %d" % (a, b, a * b)
    				note += 1
    				questionsPosees += 1
    			else:
    				print "Faux ! %d x %d = %d et pas %d." % (a, b, a * b, reponse)
    				questionsPosees += 1
    			return 1
     
    		except ValueError:
    			print "Réponse non valide. Tu dois saisir un nombre."
    			return 0
     
    while questionsPosees < 10:
     
    	a = random.randint(1, 10)
    	b = random.randint(1, 10)
     
     
     
    	while question(a,b) != 1:
    		question(a,b)
     
    #Affichage du résultat final
     
    if note <= 4:
    	print "Ta note est de %d/10. Tu ferais bien de réviser." % (note)
    elif note > 4 and note <= 6:
    	print "Ta note est de %d/10. Courage ! Tu tiens le bon bout." % (note)
    elif note > 6 and note <= 9:
    	print "Ta note est de %d/10. Tu y es presque ! Encore un petit effort." % (note)
    elif note == 10:
    	print "Parfait ! Ta note est de 10/10. N'oublie cependant pas de réviser régulièrement. Ce serait dommage d'oublier ce que tu as appris après tous ces efforts."

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 38
    Points : 26
    Points
    26
    Par défaut
    Effectivement, je te remercie pour ta remarque, c'est tout à fait préférable de déclarer cette fonction en dehors de la boucle pour ne pas demander à Python de la déclarer dix fois.

    En revanche, ça n'a malheureusement pas changé mon problème de génération aléatoire d'une nouvelle question suite à une saisie valide après voir tapé autre chose qu'un entier.

    Si quelqu'un a une idée ?

  4. #4
    Membre habitué
    Inscrit en
    Novembre 2007
    Messages
    129
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 129
    Points : 160
    Points
    160
    Par défaut
    ah oui je n'avait pas compris :
    en effet si tu saisie autre chose qu'un nombre ca te remet la meme question

    pourquoi :

    exemple

    dans le code suivant int("blabla") va declencher une exception donc l'exécution est suspendu (il ne traite pas return 1) et faire ce qui est ecrit aprs try donc retourner 0
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    try :
    	valeur = int("blabla")
    	return 1
    except ValueError:
    	return 0
    par copntre dans le cas suivant tout se passe bien pas d'exception donc la valeur retourné sera 1
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    try :
    	valeur = int("125.36")
    	return 1
    except ValueError:
    	return 0
    c'est ce qui se passe dans ton code

    il suffit pour contourner le probleme d'enlever la ligne while (question .....)

    Nouveau code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
     
     
    # -*- coding:Latin-1 -*-
     
    import random
     
    note = 0
    questionsPosees = 0
     
    def question(a,b):
     
    		global note, questionsPosees
     
    		try:
    			reponse = int(raw_input("Combien font %d x %d ? " % (a, b)))
    			if reponse == a * b:
    				print "Exact ! %d x %d = %d" % (a, b, a * b)
    				note += 1
    				questionsPosees += 1
    			else:
    				print "Faux ! %d x %d = %d et pas %d." % (a, b, a * b, reponse)
    				questionsPosees += 1
    			return 1
     
    		except ValueError:
    			print "Réponse non valide. Tu dois saisir un nombre."
    			return 0
     
    while questionsPosees < 10:
     
    	a = random.randint(1, 10)
    	b = random.randint(1, 10)
     
     
     
     
    	question(a,b)
     
    #Affichage du résultat final
     
    if note <= 4:
    	print "Ta note est de %d/10. Tu ferais bien de réviser." % (note)
    elif note > 4 and note <= 6:
    	print "Ta note est de %d/10. Courage ! Tu tiens le bon bout." % (note)
    elif note > 6 and note <= 9:
    	print "Ta note est de %d/10. Tu y es presque ! Encore un petit effort." % (note)
    elif note == 10:
    	print "Parfait ! Ta note est de 10/10. N'oublie cependant pas de réviser régulièrement. Ce serait dommage d'oublier ce que tu as appris après tous ces efforts."

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 38
    Points : 26
    Points
    26
    Par défaut
    Ce n'est pas tout à fait ça

    Je vais essayer d'être le plus clair possible sur le point qui coince...

    Voilà ce que je veux :

    1) Le programme m'interroge sur une table de multiplication. Ex: 4 x 3 ?
    2) Mettons que je ne saisisse pas un entier. Ex: 1é
    3) Le programme m'affiche le message "Réponse invalide. Seuls les nombres sont autorisés."
    4) Il me repose la même question. Ici donc à nouveau 4 x 3 ?
    5) Cette fois-ci, je donne un entier. Ex: 12
    6) Le programme me dit si c'est bon ou non avec la correction.
    7) Si la réponse est bonne, la variable note augmente de 1. Et que la réponse soit bonne ou non, la variable gérant le nombre de questions posées augmente de 1.
    8) Le programme me pose une nouvelle question. Ex: 7 x 7

    Et ainsi de suite jusqu'à avoir posé 10 questions.


    Voilà ce qui se passe avec mon code :

    Les 7 premières étapes fonctionne mais pour la 8), j'ai :

    8) Le programme ne me pose pas une nouvelle question et me sort encore le 4 x 3 ?

    Note bien ici que lorsque je saisi autre chose qu'un entier, je veux que le programme me repose la même question encore et encore jusqu'à ce que la réponse soit valide (un entier) d'où le while question () != 1. Sinon, à chaque fois que je n'ai pas la réponse, il me suffirait de taper autre chose qu'un entier pour avoir une nouvelle question à laquelle je pourrais répondre et donc ne pas pénaliser la note.

    Note également, que lorsque je ne me trompe pas dans la saisie d'un entier, le programme génère bien une nouvelle question après :

    1) Le programme m'interroge sur une table de multiplication. Ex: 4 x 3 ?
    2) Je saisi un nombre. Ex: 28
    3) Le programme me dit si c'est bon ou non avec la correction.
    7) Si la réponse est bonne, la variable note augmente de 1. Et que la réponse soit bonne ou non, la variable gérant le nombre de questions posées augmente de 1.
    8) Le programme me pose une nouvelle question. Ex: 7 x 7

    Alors pourquoi ça se passe comme ça ? D'où ça vient ? Pourquoi est-ce que même après avoir répondu à la question 3/10 après une levée d'exception, la question 4/10 sera identique ?

    Merci ;-)

  6. #6
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut R
    je veux que le programme me repose la même question encore et encore jusqu'à ce que la réponse soit valide (un entier)
    C'est pour cela que la définition de a et b est située en dehors de la boucle
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    while question() != 1:
        question()
    et c'est correct.

    Mais la conception de la boucle ne l'est pas.
    En effet, quand le programme rencontre le nom d'une fonction, il l'appelle. C'est ce qu'il fait même quand il rencontre question() dans l'instruction while question()!=1: , pas seulement à l'instruction suivante.

    Par conséquent, quand on n'entre que des nombres comme réponses, le programme n'appelle, à chaque tour de la boucle commandée par while questionsPosees < 10: , qu'une seule fois la fonction question(), conformément à ce qui a été voulu.
    Mais c'est par l'exécution de l'instruction while question()!=1: que la fonction question() est appelée et uniquement par elle, sans que le programme puisse rentrer DANS la boucle, puisque la valeur 1 que renvoie la fonction question() dans l'instruction while ne respecte pas la condition d'entrée DANS la boucle.

    Par contre, quand une réponse non valide est donnée, la fonction question() de l'instruction while renvoie 0, valeur qui pour le coup permet au programme d'entrer DANS la boucle.
    Le programme appelle donc une deuxième fois la fonction question() , celle située dans la boucle.
    Ensuite, et ce quelle que soit la validité de la réponse que l'on a donnée (nombre ou pas nombre) et donc de la valeur (1 ou 0) que renvoie cette fonction, le programme exécute l'instruction qui va lui permettre de déterminer s'il doit sortir de la boucle ou non, c'est à dire qu'il exécute à nouveau l'instruction while question()!=1: . Nécessairement, cela appelle la fonction question() , avec des valeurs de a et b qui n'ont pas changé puisque le programme n'est toujours pas sorti de la boucle et n'a pas encore fait un tour par les instructions du haut de la boucle commandée par while questionsPosees < 10:


    Ouf .... J'ai mis quelques instructions print pour détecter par où passait le programme, mais j'ai eu du mal à comprendre.

    Pour corriger le code, il y a deux possibilités:

    1)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    while question() != 1:
        pass
    C'est surprenant, mais ça marche et cela permet d'ailleurs de vérifier mon explication.


    2)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        crit = 0
        while crit != 1:
                crit = question()

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 38
    Points : 26
    Points
    26
    Par défaut
    Je suis bluffé

    Il m'a fallu relire ta réponse plusieurs fois pour bien comprendre les concepts évoqués mais j'y suis arrivé. Le code tourne à merveille maintenant !

    Lorsque j'avais écrit dans mon programme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    while question() != 1:
        question()
    Je ne te cache que ça me paraissait pas forcément très orthodoxe... mais comme en apparence, ça avait l'air de fonctionner, je m'étais dit "pourquoi pas".

    Un grand MERCI à toi de m'avoir clarifier le fonctionnement d'une boucle while, d'avoir trouvé d'où venait le problème (assez vicieux ^^) et du temps que tu as bien voulu me consacrer

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Premier programme en python
    Par zerros dans le forum Général Python
    Réponses: 15
    Dernier message: 12/07/2011, 16h52
  2. Premiers pas sous Python
    Par .Nawak dans le forum Général Python
    Réponses: 32
    Dernier message: 27/09/2010, 21h55
  3. Premier programme en Python
    Par VinsS dans le forum Contribuez
    Réponses: 2
    Dernier message: 17/11/2008, 14h36
  4. Mon premier programme sous éclipse
    Par dot-_-net dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 09/07/2008, 14h26
  5. mon premier programme sous eclipse
    Par ninours23 dans le forum Eclipse C & C++
    Réponses: 3
    Dernier message: 28/02/2008, 13h29

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo