xKnify
xKnify

Reputation: 21

ValueError: invalid literal for int() with base 10: '' happened and i have tried everything to fix it

I've been trying to do this all day I'm making a gui with tkinter but I can't convert the Entry() into a int, Ive tried pretty much everything and still cant fix it.

This is the code:

from tkinter import *

root = Tk()

root.title("Calculator")
root.configure(bg="#E1E1E1")

# left side labels
l1 = Label(root, text="PD>", bg="#E1E1E1")
l1.grid(row=0, column=0)

l2 = Label(root, text="P1>", bg="#E1E1E1")
l2.grid(row=2, column=0)

l3 = Label(root, text="P2>", bg="#E1E1E1")
l3.grid(row=3, column=0)

l4 = Label(root, text="RD>", bg="#E1E1E1")
l4.grid(row=1, column=0)

# inputs
e = Entry(root, width=25, borderwidth=2, bg="#F0F0F0")
e.grid(row=0, column=1, columnspan=2, padx=10, pady=10)

c = Entry(root, width=25, borderwidth=2, bg="#F0F0F0")
c.grid(row=1, column=1, columnspan=2, padx=10, pady=10)

p1 = Entry(root, width=25, borderwidth=2, bg="#F0F0F0")
p1.grid(row=2, column=1, columnspan=2, padx=10, pady=10)

p2 = Entry(root, width=25, borderwidth=2, bg="#F0F0F0")
p2.grid(row=3, column=1, columnspan=2, padx=10, pady=10)

l5 = Label(root, text=" ", bg="#E1E1E1", pady=20)
l5.grid(row=4, column=1)

# Descriptions
l6 = Label(root, text="PD = Piston Diameter, Bore;", bg="#E1E1E1")
l6.grid(row=6, column=1, rowspan=1)

l7 = Label(root, text="RD = Rod Diameter, Rod;", bg="#E1E1E1")
l7.grid(row=7, column=1, rowspan=1)

l8 = Label(root, text="P1 = Pressure, Push;", bg="#E1E1E1")
l8.grid(row=8, column=1, rowspan=1)

l9 = Label(root, text="P2 = Pressure, Traction;", bg="#E1E1E1")
l9.grid(row=9, column=1, rowspan=1)

l10 = Label(root, text="mm", bg="#E1E1E1")
l10.grid(row=0, column=2)

l11 = Label(root, text="mm", bg="#E1E1E1")
l11.grid(row=1, column=2)

l12 = Label(root, text="Mpa", bg="#E1E1E1")
l12.grid(row=2, column=2)

l13 = Label(root, text="Mpa", bg="#E1E1E1")
l13.grid(row=3, column=2)

#getting the input 
mp1 = p1.get()
mp2 = p2.get()
me = e.get()
mc = c.get()

mmp1 = int(float(mp1))
mmp2 = int(float(mp2))
mme = int(float(me))
mmc = int(float(mc))

P = ((mmp1 * (mme * mme) * 3.14) / 4) / 1000
R = (mmp2 * ((mme ** 2) - ((mmc ** 2)) * (3.14 / 4)) / 1000

#buttons
def ClickP():
    LP = Label(root, text=(P), bg="#E1E1E1")
    LP.grid(row=5, column=1)


def ClickR():
    LR = Label(root, text=(R), bg="#E1E1E1")
    LR.grid(row=5, column=2)


BP = Button(root, text="P Force", padx=40, pady=20, command=ClickP)
BR = Button(root, text="R Force", padx=40, pady=20, command=ClickR)

BP.grid(row=4, column=1, columnspan=2)
BR.grid(row=4, column=2, columnspan=2)

root.mainloop()

Haven't finished it yet, I was about to work on the buttons tested it and got this error:

ValueError: invalid literal for int() with base 10

Hope I can find the solution soon. I've had similar errors when I change things like:

ValueError: could not convert string to float: ''

or cannot multiply strings. Don't know what else to try.

Upvotes: 0

Views: 972

Answers (2)

oskros
oskros

Reputation: 3305

You are getting this error because the entries you have made are empty at the point where you call the get() function on them.

Think of an Entry as a textbox where the user can fill in something. By default this textbox will spawn empty, and you can then at a later point in time fill something in it, after the application has started.

This means that when you run

#getting the input 
mp1 = p1.get()
mp2 = p2.get()
me = e.get()
mc = c.get()

Python will just fetch the empty fields '' of each of your entries, which of course cannot be converted to a number, since it is empty.

So how do you solve this? Well that depends mostly on what you are trying to achieve.

Option 1

You could define a default value for the entries to hold at creation. That can be done using the insert() function. An example (for your first entry) would be something like this

e = Entry(root, width=25, borderwidth=2, bg="#F0F0F0")
e.insert(END, '0')  # Here, I set zero as the default value for your entry
e.grid(row=0, column=1, columnspan=2, padx=10, pady=10)

Option 2

You define a fallback behaviour when converting to int. That could be something like

def fallback_value(entry_val):
    if entry_val == '':
        return 0  # Replace with your default value
    else:
        return int(entry_val)

mp1 = fallback_value(p1.get())
mp2 = fallback_value(p2.get())
me = fallback_value(e.get())
mc = fallback_value(c.get())

Option 3

Make your get() calls only triggered after the user filled the entries you've created and pressed a button or something similar. That can be done in a lot of ways, use your imagination.

Upvotes: 1

Red
Red

Reputation: 27577

You can use this for loop too see where the problem(s) is/are happening:

mp1 = p1.get()
mp2 = p2.get()
me = e.get()
mc = c.get()

lst = [mp1, mp2, me, mc]
for m in lst:
    try:
        m = int(float(m))
    except:
        print(f"Can't convert {m} into a float.")

The above loop will tell you which of the four strings cannot be converted to a float.

Note: The except statement used above will blindly take any error and proceed to print. If you only want it to print when the ValueError happens, do this instead:

for m in lst:
    try:
        m = int(float(m))
    except ValueError:
        print(f"Can't convert {m} into a float.")

Upvotes: 2

Related Questions