Menu

Répéter ma fonction un certain nombre de fois

Messages postés
7
Date d'inscription
dimanche 30 décembre 2018
Dernière intervention
2 janvier 2019
-
Bonjour,
J'ai un projet à faire en isn ou je dois proposer une série de 10 calculs.
J'ai réussi à programmer ma fonction mais je n'arrive pas à ce qu'elle se stop au bout du 10ème cacul.
Pouvez vous m'aider svp?
Voici la partie de mon programme avec ma fonction pour les additions :

def addition (): 

def question() : 

global resultat 
signe = ("+") 
chiffre1 = randint(0,99) 
chiffre2 = randint(0,99) 
calcul = (chiffre1, signe, chiffre2, ("=")) 
resultat = chiffre1 + chiffre2 #résultat de l'addition 
resultat = str(resultat) #converti resultat en chaine 
affichageoperation = Label(fenetre, text= calcul) 
affichageoperation.pack() 
global entree 
value = StringVar() 
value.set("" ) 
entree = Entry(fenetre, textvariable=value, width=30) 
entree.pack() 
entree.bind("<Return>", reponse) 

def reponse(chiffre): 

reponse = str(entree.get()) 
if reponse == resultat : 
print = Label(fenetre, text = "BRAVO", bg = "green" ) 
print.pack() 

else : 
print = Label(fenetre, text = "MAUVAIS", bg = "red" ) 
print.pack() 
question() 

fenetre = Tk() 
fenetre.geometry("400x700") 
fenetre.title("ADDITIONS") 
text1= Label(fenetre,text="Quelques additions...") 
text1.pack() 
question ()


EDIT : Ajout des balises de code (la coloration syntaxique).
Explications disponibles ici : ICI

Merci d'y penser dans tes prochains messages.
Afficher la suite 

Votre réponse

5 réponses

0
Merci
Bonjour.

Où est censé être dans ton code cette série de 10 calculs ?

Tu utilises une interface graphique, donc cela implique de faire agir l'utilisateur.
Les grandes lignes de ton interface devraient-être :

1 - Affichage d'une opération.
2 - Attente de la saisie du résultat par l'utilisateur.
3 - Si nombre d'opérations effectuées est de 10 => afficher un bouton "voir résultats"
.... Sinon, afficher un bouton "suivant' pour l'opération suivante.
arizona22
Messages postés
7
Date d'inscription
dimanche 30 décembre 2018
Dernière intervention
2 janvier 2019
-
Merci pour votre réponse je vais essayer de faire ça.
Car avec ma fonction les calculs s'enchaînent en disant si le résultat est correct ou non mais cela ne s'arrête jamais.
Commenter la réponse de potyrond
Messages postés
7
Date d'inscription
dimanche 30 décembre 2018
Dernière intervention
2 janvier 2019
0
Merci
Boujour,
Je n'ai pas réussi à faire apparaître les boutons j'ai donc essayé de mettre un compteur dans ma fonction mais elle ne s'arrête toujours pas.
Pouvez-vous me dire le problème dans mon code svp ?

def addition ():

    def question() :
            nb=0
            global resultat
            signe = ("+") 
            chiffre1 = randint(0,99)     
            chiffre2 = randint(0,99)    
            calcul = (chiffre1, signe, chiffre2, ("=")) 
            resultat = chiffre1 + chiffre2
            resultat = str(resultat) 
            affichageoperation = Label(fenetre, text= calcul) 
            affichageoperation.pack()
            global entree
            value = StringVar()
            value.set("" )
            entree = Entry(fenetre, textvariable=value, width=30)
            entree.pack()
            if nb<=10:
                entree.bind("<Return>", reponse) 
                nb=nb+1
            else :
                entree.bind("<Return>", fin)

    def fin ():
            print = Label(fenetre, text = "FIN", bg = "green" )

    def reponse(chiffre):

            reponse = str(entree.get()) 
            if reponse == resultat :  
                print = Label(fenetre, text = "BRAVO", bg = "green" ) 
                print.pack()

            else : 
                print = Label(fenetre, text = "MAUVAIS", bg = "red" ) 
                print.pack()
            question()

    fenetre = Tk()
    fenetre.geometry("400x700")
    fenetre.title("ADDITIONS")
    text1= Label(fenetre,text="Quelques additions...")
    text1.pack()
    question ()
Commenter la réponse de arizona22
Messages postés
3300
Date d'inscription
jeudi 16 juin 2005
Dernière intervention
14 janvier 2019
1163
0
Merci
Bonjour,

Cela ne s'arrête jamais car à chaque fois que la fonction question() est appelée, nb est remis à 0.
Tu peux par exemple t'en sortir en faisant en sorte que ce ne soit pas question() qui définisse la valeur de nb, mais qu'elle soit une variable globale, comme "resultat".

Xavier
arizona22
Messages postés
7
Date d'inscription
dimanche 30 décembre 2018
Dernière intervention
2 janvier 2019
-
Bonsoir,
Je ne vois pas exactement ce que vous voulez dire, pourriez vous me faire un exemple ?
Merci d'avance
Commenter la réponse de Reivax962
Messages postés
7
Date d'inscription
dimanche 30 décembre 2018
Dernière intervention
2 janvier 2019
0
Merci
Bonsoir,
j'ai essayé d'insérer une variable globale à ma fonction pour que nb ne reparte pas tout le temps à 0 mais cela ne marche toujours pas. Pourriez vous m'expliquer pourquoi ?


nb=0

def addition ():

    def question() :
            global resultat
            signe = ("+") 
            chiffre1 = randint(0,99)    
            chiffre2 = randint(0,99)     
            calcul = (chiffre1, signe, chiffre2, ("="))
            resultat = chiffre1 + chiffre2 
            resultat = str(resultat) 
            affichageoperation = Label(fenetre, text= calcul) 
            affichageoperation.pack()
            global entree
            value = StringVar()
            value.set("" )
            entree = Entry(fenetre, textvariable=value, width=30)
            entree.pack()

            if nb==0:
                entree.bind("<Return>", reponse) 
                global nb
                nb=nb+1
            else :
                entree.bind("<Return>", fin)

    def fin (chiffre):
            print = Label(fenetre, text = "FIN", bg = "green" )

    def reponse(chiffre):

            reponse = str(entree.get()) 
            if reponse == resultat :  
                print = Label(fenetre, text = "BRAVO", bg = "green" ) 
                print.pack()

            else : 
                print = Label(fenetre, text = "MAUVAIS", bg = "red" ) 
                print.pack()
            question()

    fenetre = Tk()
    fenetre.geometry("400x700")
    fenetre.title("ADDITIONS")
    text1= Label(fenetre,text="Quelques additions...")
    text1.pack()
    question ()
Reivax962
Messages postés
3300
Date d'inscription
jeudi 16 juin 2005
Dernière intervention
14 janvier 2019
1163 -
Bonjour,

Je ne sais pas vraiment coder en Python, mais il ne faudrait pas déclarer ta variable comme pour « resultat », avec « global nb » ?

Xavier
Reivax962
Messages postés
3300
Date d'inscription
jeudi 16 juin 2005
Dernière intervention
14 janvier 2019
1163 -
Au temps pour moi, je n'avais pas vu que tu l'avais mis...
Tu peux faire un "print nb" quelque part dans question() pour voir quelle valeur y est stockée ?
Bonjour.

Les global à l'intérieur d'une fonction doivent se situer de préférences en début de fonctions.
Il vaut mieux éviter de déclarer des fonctions à l'intérieur d'autres fonctions, il y a rarement de cas où l'on a besoin de faire cela.

Voici un exemple de comment ton programme devrait être structuré, ce n'est sans doute pas ce que tu souhaites obtenir, mais ça peut te montrer un peu un exemple simple et fonctionnel.

import random
import tkinter as tk

def additionner(nombre1, nombre2):
    return nombre1 + nombre2
    
def soustraire(nombre1, nombre2):
    return nombre1 - nombre2
    
def multiplier(nombre1, nombre2):
    return nombre1 * nombre2

# Dictionnaire reliant signes et fonctions
operateurs = {
    '+':additionner,
    '-':soustraire,
    '×':multiplier,
}

# Fonction choisissant et retournant un tuple de deux nombres et un opérateur
def choisir_operation():
    nombres = (random.randint(0, 99), random.randint(0, 99))
    signe = random.choice(list(operateurs))
    return nombres, signe
    
    
# Fonction calculant le résultat d'une opération
def calculer_operation(nombres, signe):
    operateur = operateurs[signe]
    return operateur(nombres[0], nombres[1])
    # Plus simplement
    # return operateurs[signe](*nombres)


# Fonction formatant l'opération en chaîne de caractères 
def formater_operation(nombres, signe):
    return '{1} {0} {2}'.format(signe, *nombres)
    

# Fonction affichant une opération à effectuer
def questionner():
    # Reset de la valeur de l'entrée à une chaîne vide
    entree.delete(0, 'end')
    # Récupération d'une nouvelle opération
    nombres, signe = choisir_operation()
    # Formatage en chaîne de l'opération
    operation = formater_operation(nombres, signe)
    # Calcul du résultat correct
    resultat_correct = calculer_operation(nombres, signe)
    # Enregistrement de l'opération, et du résultat correct
    resultats.append([operation, resultat_correct])
    # Affichage de l'opération à résoudre
    label_operation['text'] = 'Combien font %s ?' % operation


# Fonction enregistrant le résultat saisi par l'utilisateur
def valider_resultat(event=None):
    # Ajout au dernier élément de résultats, la valeur saisie 
    resultats[-1].append(entree.get())
    # Si nombre de résultats pas encore atteint
    if len(resultats) < NOMBRE_QUESTIONS:
        # Rappel de la fonction questionner
        questionner()
    else:
        # Le nombre d'opération total a été atteint, affichage des résultats
        afficher_resultats()


# Affiche les résultats des opérations enregistrées
def afficher_resultats():
    # Destruction du label et de l'entry
    label_operation.destroy()
    entree.destroy()
    
    frame_resultats = tk.Frame(fenetre)
    frame_resultats.grid()
    # Titre
    label_titre = tk.Label(frame_resultats, text='Résultats')
    label_titre.grid(columnspan=3)
    
    # Parcours et affichage de la liste des résultats
    for i, resultat in enumerate(resultats, 1):
        label_question = tk.Label(frame_resultats, text=resultat[0])
        label_question.grid(row=i, column=0, padx=10)
        label_reponse = tk.Label(frame_resultats, text=resultat[2], fg='green')
        label_reponse.grid(row=i, column=1, padx=10)
        # Si résultat incorrect, affichage du bon résultat
        if str(resultat[1]) != resultat[2]:
            label_reponse['fg'] = 'red'
            label_reponse_correcte = tk.Label(frame_resultats, text=resultat[1], fg='yellow')
            label_reponse_correcte.grid(row=i, column=2, padx=10)


# Constante déterminant combien d'opérations sont à résoudre
NOMBRE_QUESTIONS = 10

# Liste qui contiendra des listes avec pour valeurs :
# - opération à résoudre
# - résultat correct
# - valeur saisie par l'utilisateur 
resultats = []

fenetre = tk.Tk()
fenetre.geometry("300x400")
fenetre.title("OPÉRATIONS")

label_operation = tk.Label(fenetre)
label_operation.pack()

entree = tk.Entry(fenetre)
entree.pack()
entree.focus()
entree.bind("<Return>", valider_resultat) 

# Appel de la première question
questionner()

fenetre.mainloop()


On pourrait grandement améliorer et condenser ce simple programme, mais en l'état, cela te permettra de comprendre comment organiser ton script un peu plus correctement avec de simples fonctions.
arizona22
Messages postés
7
Date d'inscription
dimanche 30 décembre 2018
Dernière intervention
2 janvier 2019
-
Merci beaucoup pour votre réponse je vais essayer de modifier un peu ce programme afin qu'il réponde à mes critères.

# Fonction enregistrant le résultat saisi par l'utilisateur
def valider_resultat(event=None):
# Ajout au dernier élément de résultats, la valeur saisie
resultats[-1].append(entree.get())
# Si nombre de résultats pas encore atteint
if len(resultats) < NOMBRE_QUESTIONS:
# Rappel de la fonction questionner
questionner()
else:
# Le nombre d'opération total a été atteint, affichage des résultats
afficher_resultats()


Pouvez-vous m'expliquer à quoi sert le "event=None" et le "len" devanr résultat dans cette partie du programme svp ?
Bonjour.

len
est une fonction de base en python retournant le nombre d'éléments d'un objet itérable.
En ce qui concerne le
event=None
, c'est une façon de donner à un argument de fonction une valeur par défaut, en fait ici ce n'est point utile.
Commenter la réponse de arizona22
Messages postés
7
Date d'inscription
dimanche 30 décembre 2018
Dernière intervention
2 janvier 2019
0
Merci
Boujour,
voici mon nouveau code :

global nb
if nb<=10:
nb=nb+1
entree.bind("<Return>", reponse)
else :
entree.bind("<Return>", fin)

Cependant ma fonction ne s'arrête toujours pas alors que quand j'affiche nb cela marche bien j'ai 1,2,3...
Commenter la réponse de arizona22