Почему я не могу использовать try-кроме того, чтобы преобразовать str в int? - PullRequest
0 голосов
/ 07 ноября 2019

Я сделал эти два разных набора кода, которые выполняют ту же функцию на tkinter. Версия simplediaglog работает просто отлично, но я хотел использовать запись (потому что я хочу отобразить вывод в том же всплывающем окне), которая не работает.

Проблема заключается, главным образом, в умножении списка значений с плавающей запятой в словаре на входное значение записи и получении Python даже для распознавания входного ввода как int.

Я попытался реструктурировать try-кроме-почем, пробовал использовать разные способы преобразования входных данных в целочисленные, используя IntVar (). Я также пытался индексировать словарь, т. Е. X [y] [0]. Я попытался поместить значения с плавающей точкой в ​​строку, например, x = {"A": "2.3", "B": "0.3"}. Но ничего не работает, продолжайте получать разные ошибки, но все сводится к одному: невозможно умножить целое число / str на значения с плавающей запятой из словаря.

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

Этот код работает и показывает все правильно.

Кстати, для приведенного ниже кода геометрия места - это то, что я помещаю случайным образом, чтобы увидеть, работает ли общий код, я не думаю, что ошибка связана с геометрией

Вышеприведенный код Simpledialog работает.

Однако этот код виджета ввода не:

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()

Это мой словарь для списка значений с плавающей запятой:

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

Я ожидаю увидеть ярлык с примерно 2,3 минуты, который появится в том же окне, что и виджет ввода.

Но даже если я введу int, например '5', во входную запись, try-кроме не преобразует его в int, потому что я продолжаю получать сообщение «Ошибка»: «введите значение от 0до 10 ".

Почему это так? Это потому, что это виджет ввода, а не simpledialog, потому что он работал для simplediaglog?

Кроме того, даже когда я попал в строку для W (удалось преобразовать Q_input) в целое число, он показывает ошибку: объект 'str' не имеет атрибута 'items'.

Мой главный вопрос - почему список словаря с плавающей запятой (и преобразование типов из str в int) может регистрироваться в simpledialog, но не для виджета ввода? В чем разница? Можно ли умножить значения с плавающей запятой из словаря на целое число из входных данных?

Кроме того, есть ли другие способы отображения вывода в том же всплывающем окне, кроме виджета ввода?

Заранее спасибо!

Редактировать: Итак, я попытался преобразовать Q_input в int до цикла while и распечатать его. Если я введу «5», будет напечатано «5». Я знаю, что он конвертировался в int, потому что когда я вводил 'hi', возникает ошибка: недопустимый литерал для int () с основанием 10: 'hi'.

Я также изменил int(Q_input) на Q_input=int(Q_input),Согласно предложению, я также изменил continue на break в if Q_input is None:.

Но попытка-исключение все еще не работает, она даже не пыталась преобразовать Q_input в int, она просто пропускалась прямо кexcept.

Извините, что задал так много вопросов, поэтому я просто суммирую его в один вопрос: мой код try-except не работает из-за различий между simpledialog и виджетом ввода, если да, то чтопричина, а если нет, то почему код не работает тогда?

Решение: Я что-то понял, все время не мог отобразить ярлык из-за этого: Label(root, "Ans\n" + W + " minute(s)").place(x=50, y=500). Я не поставил text=, хаха, я смог успешно показать ярлык после добавления text=. Мой плохой, поэтому все время проблема не заключалась в преобразовании входных данных в целое число. Однако необходимо изменить int(Q_input) на Q_input=int(Q_input). Я просто делаю поспешный вывод, что ошибка произошла из-за преобразования типов, потому что программа продолжала идти прямо к except.

Ответы [ 3 ]

2 голосов
/ 07 ноября 2019

Вы на самом деле не сохраняете целочисленное преобразование:

try:
            Q_input = int(Q_input)

также

except Exception as e:
 print(e)

, чтобы вы знали, что происходит, если сработало исключение

1 голос
/ 08 ноября 2019

Я часто использую функцию для безопасного преобразования строки в целое или число с плавающей точкой, например, to_int ниже.

Приведенный ниже код создает метку ответа, которая используется по мере необходимости. Исходный код создавал метку для каждого нажатия кнопки.

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()
0 голосов
/ 07 ноября 2019

Это проблема, кажется.

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

Вам необходимо присвоить int (Q_input) переменной, как вы это делали в своем рабочем коде. Смотри ниже.

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