web-dev-qa-db-ja.com

入力の変換時に「ValueError:文字列を浮動小数点に変換できませんでした」

最近、私はコードに取り組んでいて、このエラーで何日も行き詰まっています。基本的にプログラムはあなたが毎日食べなければならないカロリー数を計算します。エントリから入力を取得する必要があり、その入力(デフォルトでは文字列です)を浮動小数点数に変換して数値の使用を開始する方法がわかりません。私はTkinterでPython 3を使用しています。

これがコードです:

from tkinter import *

root = Tk()
root.geometry("1000x500")
root.resizable(FALSE, FALSE)
root.title("BMI Calculator")

def calc(args):

    def BMI_temp(args):
        print(str(boyage))
        BMI = IntVar()
        BMI = 66.5 + (13.75 * float(boykg)) + (5.003 * float(boycm)) - (6.755 * float(boyage))
        bmi_temp = Label(root, text="This is how many calories you have to eat if you have a non-active life: " + str(float(BMI)))
        bmi_temp.grid(row=3, sticky=W)

    def boy_age_fnct(args):
        boy_age_entry.focus_set()
        boy_cm_entry.delete(0, "end")
        boy_age.grid(row=2, sticky=W)
        boy_age_entry.grid(row=2, column=1)
        boy_age_entry.bind("<Return>", BMI_temp)

    def boy_cm_fnct(args):
        boy_cm_entry.focus_set()
        boy_kg_entry.delete(0, "end")
        boy_cm.grid(row=1, sticky=W)
        boy_cm_entry.grid(row=1, column=1)
        boy_cm_entry.bind("<Return>", boy_age_fnct)

    boy_kg_entry.focus_set()
    temp = boygirle.get()
    gender = temp.title()
    welcome.destroy()
    hello_lbl.destroy()
    boygirle.destroy()
    boygirlq.destroy()

    if gender[0] == 'B':
        boy_kg.grid(row=0, sticky=W)
        boy_kg_entry.grid(row=0, column=1)
        boy_kg_entry.bind("<Return>", boy_cm_fnct)

    boyage = boy_age_entry.get()
    boycm = boy_cm_entry.get()
    boykg = boy_kg_entry.get()

def hello(args):
    name_user = name_entry.get()
    name2 = name_user.title()
    name_entry.delete(0, "end")
    hello = "Hello " + name2 + "!"
    hello_lbl["text"] = hello
    hello_lbl.grid(row=2, sticky=W)
    btn_cont.grid(row=3, sticky=W)
    name.destroy()
    name_entry.destroy()
    btn_cont.focus_set()

def BMI():
    btn_cont.destroy()
    boygirlq.grid(row=3, sticky=W)
    boygirle.grid(row=3, column=0, ipadx=35)
    boygirle.bind("<Return>", calc)
    boygirle.focus_set()

welcome = Label(root, text="Hello! This is a BMR calculator. It tells you how many calories you have to eat!", font="System 14 bold")
name = Label(root, text="Please enter your name:", font="System 12")
hello_lbl = Label(root, font="System 14")
boygirlq = Label(root, text="Are you a boy or a girl?", font="System 12 bold")
boy_kg = Label(root, text="Please enter your weight(in kg):", font="System 12 bold")
boy_cm = Label(root, text="Please enter your height(in cm):", font="System 12")
boy_age = Label(root, text="Please enter your age(in years):", font="System 12")

btn_cont = Button(root, text="Continue", font="Helvetica 12", command=BMI, relief=RAISED)

boy_kg_entry = Entry(root, font="System 12", relief=SUNKEN)
boy_cm_entry = Entry(root, font="System 12", relief=SUNKEN)
boy_age_entry = Entry(root, font="System 12", relief=SUNKEN)
name_entry = Entry(root, font="System 12", relief=SUNKEN)
boygirle = Entry(root, font="System 12", relief=SUNKEN)
name_entry.bind("<Return>", hello)
name_entry.focus_set()

welcome.grid(row=0, columnspan=2, ipadx=200)
name.grid(row=1, sticky=W)
name_entry.grid(row=1, column=0)

root.mainloop()

インターネットで見つけた方法をすべて試しましたが、何もうまくいきませんでした。

3
Vlad Poncea

推定原因:1つのフィールドに入力するのを忘れました

説明

a floatcan strから構築されます。正しい形式でなければなりません。 float(mystr)を使用するだけで、floatのように見える文字列をfloatに変換できるはずです。

注意を払う:

  • スペースなし(または数字以外の文字)
  • コンマ(、)ではなく、小数点記号としてのピリオド(。)
  • some特別なものを使用できます(例: "inf"、 "5e3"、...)

ほとんどの場合(エラーメッセージから何も削除しなかった場合)、1つのフィールドに入力するのを忘れたため、float('')を実行しようとしています。

いくつかの例

>>> float('')  # probably your case
Traceback (most recent call last):
  File "<pyshell#74>", line 1, in <module>
    float('')
ValueError: could not convert string to float:
>>> float('1')
1.0
>>> float('1.0')
1.0
>>> float('no number')
Traceback (most recent call last):
  File "<pyshell#64>", line 1, in <module>
    float('no number')
ValueError: could not convert string to float: 'no number'
>>> float('10e30')
1e+31
>>> float('inf')
inf
>>> float('123.456')
123.456
>>> float('123,456')  # , not allowed
Traceback (most recent call last):
  File "<pyshell#68>", line 1, in <module>
    float('123,456')
ValueError: could not convert string to float: '123,456'
>>> float('123 456')  # no whitespace as separator
Traceback (most recent call last):
  File "<pyshell#69>", line 1, in <module>
    float('123 456')
ValueError: could not convert string to float: '123 456'

さらなる考え

Float値を取得する別の方法は、ポップアップウィンドウでそれらを要求することです。これはtkinter.simpledialog.askfloatで実行できます。入力した文字列を変換できなかった場合は、floatが直接返され、エラーメッセージが表示されます。 しかし、ユーザーが[キャンセル]ボタンをクリックするとNoneが返される場合があるため、計算する前に結果を確認することをお勧めしますもの。

例:

import tkinter as tk
from tkinter.simpledialog import askfloat

def click():
    val = askfloat('Title', 'The Prompt:')  # float or None (cancel)
    if val is not None:
        tk.Label(root, text=f'The value "{val}" is a valid float').pack()  # f-string, replace with `'The value "{}" is ...'.format(val)` if you get an error (Python < 3.6)

root = tk.Tk()
tk.Button(root, text='Click!', command=click).pack()
root.mainloop()

編集:

Entryウィジェットを保持している場合は、エラーをキャッチしてユーザーにメッセージを表示することができます。これは、tkinter.mesagebox、特にこの場合はshowerror関数を使用して簡単に行うことができます。

例:

import tkinter as tk
from tkinter.messagebox import showerror

def click():
    try:
        val = float(entry.get())
    except ValueError as e:
        showerror('Error title', 'The number could not be converted to float:\n'+str(e))
    else:
        entry.delete(0, tk.END)
        Label(root, text=val).pack()

root = tk.Tk()
entry = tk.Entry(root)
tk.Label(root, text='insert a float value below:').pack()
entry.pack()
tk.Button(root, text='and click!', command=click).pack()
root.mainloop()
4
user24343