0
votes

Pourquoi suis-je incapable d'utiliser try-except pour convertir str en int?

J'ai fait ces deux ensembles de code différents qui font la même fonction sur tkinter. La version simplediaglog fonctionne très bien mais je voulais utiliser l'entrée (car je veux afficher la sortie dans la même fenêtre contextuelle), ce qui ne fonctionne pas.

Le problème réside principalement dans la multiplication d'une liste de valeurs flottantes dans un dictionnaire par la valeur d'entrée d'entrée et de faire en sorte que python reconnaisse même l'entrée d'entrée comme int.

J'ai essayé de restructurer le try-except-else , a essayé d'utiliser différentes méthodes pour convertir l'entrée d'entrée en entier à l'aide de IntVar (). J'ai également essayé d'indexer le dictionnaire, c'est-à-dire x [y] [0]. J'ai essayé de mettre les valeurs flottantes dans une chaîne, par exemple x = {"A": "2,3", "B": "0,3"}. Mais rien ne fonctionne, continuez à avoir des erreurs différentes mais tout se résume à une chose: impossible de multiplier entier / chaîne avec des valeurs flottantes du dictionnaire.

x = {"A": 0.8, "B": 2.5, "C": 1.2}

Ce code fonctionne et a tout montré correctement .

BTW, pour le code ci-dessous, la géométrie de la place est quelque chose que je mets au hasard pour voir si le code global fonctionne, je ne pense pas que l'erreur soit due à la géométrie.

Le code simpledialog ci-dessus fonctionne.

Cependant, ce code de widget d'entrée ne fonctionne pas:

def p(y):
    root = Tk()
    root.title("Average Waiting Time")
    root.geometry("800x500")

    Label(root, text="Enter number of people: ").place(x=20, y=30)
    Q = Entry(root, bd =5)
    Q.place(x=220, y=30)

    def B():
        Q_input = Q.get()
        while True:
            try:
                int(Q_input)
                if Q_input is None:
                    continue
                elif Q_input <=0 or Q_input > 10:
                    raise ValueError
                else:               
                    W = str(round(Q_input * x[y], 1))  # Round off to 1 d.p
                    Label(root, "Ans\n" + W + " minute(s)").place(x=50, y=500)

            except:
                messagebox.showerror("Error", "enter a value from 0 to 10")

            break   

    ok = Button (root, text="OK", command = B)
    ok.place(x=300, y=300)

    cancel = Button (root, text="Cancel", command = root.destroy)
    cancel.place(x=400,y=300)

    root.mainloop()

Ceci est mon dictionnaire pour le liste des valeurs flottantes:

def p(y):
    while True:
        Q = simpledialog.askstring("test", "Enter number:")
        try:
            Q = int(Q)
            if Q is None:
                break
            elif Q <=0 or Q> 10:
                raise ValueError
            else:
                W = str(round(Q * x[y], 1))  # Round off to 1 d.p
                messagebox.showinfo("test", "Ans is\n" + W + " minute(s)")
                break
        except:
            messagebox.showerror("Error", "enter a value from 0 to 10")
        break

Je m'attends à voir une étiquette avec quelque chose comme Ans 2,3 minute (s) apparaître dans la même fenêtre que le widget d'entrée.

Mais même si je saisis un int tel que '5' dans l'entrée d'entrée, le try-except ne le convertit pas en int car je continue à recevoir le message "Error": "enter une valeur de 0 à 10 ".

Pourquoi est-ce ainsi? Est-ce parce qu'il s'agit d'un widget d'entrée et non de simpledialog parce que cela a fonctionné pour simplediaglog?

De plus, même lorsque je suis arrivé à la ligne pour W (parviens à convertir Q_input) en entier, cela montre une erreur: l'objet 'str' n'a pas d'attribut 'items'.

Ma question principale est pourquoi la liste de dictionnaires flottants (et la conversion de type de str en int) est capable de s'enregistrer avec simpledialog mais pas pour le widget d'entrée? Quelle est la différence? Est-il possible de multiplier les valeurs flottantes du dictionnaire avec un entier de l'entrée d'entrée?

De plus, existe-t-il d'autres méthodes pour afficher la sortie dans la même fenêtre contextuelle en plus du widget d'entrée?

Merci d'avance!

Modifier: J'ai donc essayé de convertir Q_input en int avant la boucle while et de l'imprimer. Si je saisis «5», il imprime «5». Je sais qu'il a été converti en int car lorsque j'entre 'hi', il y a une erreur: littéral invalide pour int () avec base 10: 'hi'.

J'ai changé int (Q_input) à Q_input = int (Q_input) également. Par suggestion, j'ai également changé continue en break sous si Q_input est None: .

Mais, le try-except ne fonctionne toujours pas, il n'a même pas essayé de convertir Q_input en int, il est simplement passé directement à sauf.

Désolé pour avoir posé autant de questions, donc je vais juste résumer en une seule question: Mon code try-except ne fonctionne pas en raison des différences entre simpledialog et widget d'entrée, si oui, quelle en est la raison et sinon pourquoi le code ne fonctionne-t-il pas alors?

Solution: J'ai réalisé quelque chose, depuis le début je n'avais pas pu afficher l'étiquette à cause de ceci: Label (racine, "Ans \ n" + W + "minute (s)"). Place (x = 50, y = 500) . Je n'ai pas mis text = , haha ​​j'ai pu montrer l'étiquette avec succès après avoir ajouté text = . Mon mauvais, donc tout le long du problème n'a pas été de convertir l'entrée d'entrée en entier. Il est cependant nécessaire de changer int (Q_input) en Q_input = int (Q_input) . Je passe en quelque sorte à la conclusion que l'erreur était due à la conversion de type parce que le programme continuait à aller directement à sauf.


7 commentaires

J'ai voté contre parce qu'il semble y avoir trop de code et trop d'informations et trop de questions en une. Veuillez recentrer un peu votre message :)


J'ai voté parce que c'est logique si vous lisez réellement le message. Pouvez-vous imprimer la valeur de Q_input et convertir Q_input en un entier avant d'entrer dans la boucle While True? Imprimez-le également et voyez ce que vous obtenez.


@Yepram Yeransian Merci pour la suggestion. J'ai converti et imprimé Q_input avant la boucle while True . Si je saisis «5», il imprime «5». Je sais qu'il a été converti en int parce que lorsque j'entre «hi», il y a une erreur. Cependant, le try-except ne fonctionne toujours pas, tout va simplement à la partie sauf .


@ Corentin Pane Salut, désolé de faire que cela semble compliqué, mais j'ai publié tellement de code parce que la question que je voulais vraiment poser est: "Mon code try-except ne fonctionne-t-il pas à cause des différences entre simpledialog et widget d'entrée, si oui la raison et sinon pourquoi le code ne fonctionne-t-il pas alors? ". Donc, j'ai en quelque sorte besoin de publier les deux codes parce que je compare entre simpledialog et widget d'entrée. J'ai créé un compte juste pour cette question parce que je ne peux vraiment pas le comprendre. Je suis désolé si j'ai fait quelque chose en dehors du protocole - suis-je supposé commenter ou modifier mes questions - pour ce site Web.


Comme Q_input est une chaîne lorsque la clause elif est exécutée Q_input <= 0 ou Q_input> 10 déclenche une TypeError: '<=' non pris en charge entre les instances de 'str' et 'int' < / code> dans le bloc try:. Par conséquent, il exécute le bloc except: et imprime le message d'erreur.


@TlsChris Des suggestions sur la façon de procéder? car Q_input = int (Q_input) ne fonctionnait pas.


Q_input = int (Q_input) a fonctionné à la fin, je ne savais tout simplement pas que je n'avais pas mis text = dans Label (racine, "Ans \ n" + W + "minute (s)"). Place (x = 50, y = 500) .


3 Réponses :


2
votes

Vous n'enregistrez pas réellement la conversion d'entier:

except Exception as e:
 print(e)

également

try:
            Q_input = int(Q_input)

afin que vous sachiez ce qui ne va pas si l'exception est déclenchée


2 commentaires

Merci pour la suggestion. J'ai changé int (Q_input) en Q_input = int (Q_input) mais le try-except ne fonctionne toujours pas. (Je pense que j'ai mis Q_input = int (Q_input) au début, mais après avoir essayé différentes méthodes, il a été raccourci haha.)


Quand je l'ai essayé de mon côté, cela a toujours échoué, oui, mais pour une raison différente maintenant. Je recommande, pour chaque "Sauf" que vous avez dans votre code, faites ceci: sauf Exception comme e: print (e) Ou ajoutez "e" à la sortie de la boîte de message. Ensuite, il vous dira quel est le problème. Auparavant, str et int ne peuvent pas être comparés à> =, maintenant cela devrait être un problème différent.



-1
votes

C'est le problème qu'il semble.

try:
    Q = int(Q)
    if Q is None:
        break

Vous devez affecter int (Q_input) dans une variable comme vous l'avez fait dans votre code de travail. Voir ci-dessous.

try:
    int(Q_input)
    if Q_input is None:
        continue


3 commentaires

Cela pose exactement le même problème. Vous essayez de convertir Q en un entier avant de vérifier qu'il est Aucun . La vérification doit avoir lieu avant d'essayer de convertir, car la conversion échouera si Q est Aucun . De plus, int () ne retournera jamais None .


Merci pour la suggestion. Cependant, le try-except ne fonctionne toujours pas. Le problème est que try-except n'a même pas «essayé», il est simplement passé directement à «except». J'avais essayé différentes méthodes avant de poser finalement cette question et j'ai réussi à arriver à la ligne pour W = str (round (Q_input * x [y], 1)) mais uniquement en utilisant try -except-else par lequel j'ai placé cette ligne particulière dans le bloc else . Cependant, il y a toujours une erreur: l'objet 'str' n'a pas d'attribut 'items'. La chose étrange est que tout cela a fonctionné pour simpledialog mais pas pour le widget d'entrée.


@BryanOakley Donc, je devrais mettre si Q est Aucun sous sauf: alors? Je vois ce qui ne va pas en mettant None sous try mais je suis curieux de savoir pourquoi cela a fonctionné pour le code simpledialog? Quoi qu'il en soit, j'ai supprimé tout cela si si Q est None: , mais le try-except ne fonctionne toujours pas, la sortie passe directement à sauf: .



1
votes

J'utilise souvent une fonction pour convertir en toute sécurité une chaîne en un entier ou un flottant, par exemple to_int ci-dessous.

Le code ci-dessous crée une étiquette de réponse qui est utilisée selon les besoins. Le code d'origine a créé une étiquette pour chaque clic sur le bouton.

from tkinter import *

def to_int(string, fail = 0):
    try: 
        return int(string)
    except ValueError:
        return fail

x = {"A": 0.8, "B": 2.5, "C": 1.2}

def p(y):
    root = Tk()
    root.title("Average Waiting Time")
    root.geometry("800x500")

    Label(root, text="Enter number of people: ").place(x=20, y=30)
    Q = Entry(root, bd =5)
    Q.place(x=220, y=30)

    answer = StringVar()
    answer.set("")
    Label(root, textvariable = answer ).place(x=50, y=500)

    def B():
        Q_input = Q.get()

        v = to_int(Q_input, -1)
        # Returning <0 triggers the error message

        if v <=0 or v > 10:
            answer.set("Enter a value from 0 to 10")
        else:               
            W = str(round(v * x[y], 1))  # Round off to 1 d.p
            answer.set("Ans\n" + W + " minute(s)")
            print(answer.get())

    ok = Button (root, text="OK", command = B)
    ok.place(x=300, y=300)

    cancel = Button (root, text="Cancel", command = root.destroy)
    cancel.place(x=400,y=300)

    root.mainloop()


1 commentaires

Merci! Ça a marché! J'ai cependant réalisé quelque chose, depuis le début je n'avais pas pu afficher l'étiquette à cause de ceci: Label (racine, "Ans \ n" + W + "minute (s)"). Place (x = 50, y = 500) . Je n'ai pas mis text = , haha ​​j'ai pu montrer l'étiquette avec succès après avoir ajouté text = . Mon mauvais, donc tout le long du problème n'a pas été de convertir l'entrée d'entrée en entier. Je viens de sauter à la conclusion que l'erreur était à cause de cela parce que le programme continuait à aller directement à sauf .