Issue
Recently I have been working on a code and got stuck for days on this error. Basically the program calculates how many calories you have to eat everyday. I have to take input from an entry and I don't know how to convert that input(it's a string by default) into a float to start using the numbers. I am using Python 3 with Tkinter.
Here is the code:
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()
I tried all the methods I found on the internet but nothing worked.
Solution
Probable cause: you forgot to fill out one field
Explanation
a float can be constructed from a str, it just has to have the right format.
You should be able to convert strings that look like floats to floats by just using float(mystr)
.
Pay attention to:
- No spaces (or non-digit characters)
- Period (
.
) as decimal separator, not comma (,
) - some special things are allowed (e.g.
inf
,5e3
, ...)
Most probably (if you didn't cut anything off your error message), you forgot to fill out one field and are thus trying to perform float('')
.
Some examples
>>> 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'
Further thoughts
An alternative for getting the float values is asking for them in a popup window -- this can be done with tkinter.simpledialog.askfloat
. This will return you a float
directly and show an error message if the string entered could not be converted.
But, it may also return None
when the user clicks the "Cancel" button, so you might want to check the result before computing stuff.
Example:
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()
Edit:
If you keep the Entry
widgets, you may want to catch the error and show the user a message. This can easily be done with tkinter.mesagebox
, specifically of this case the showerror
function.
Example:
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()
Answered By - user24343
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.