0

I'm in the process of creating a budget app and I'm running into a ValueError: invalid literal for int() with base 10: ''. I know a lot of you guys are probably going to comment that this thread has been answered already but not in my case. I know that I can not convert empty string data to an integer but when it comes to entry boxes on Tkinter. In this case, the value will be imputed by the user but in the meantime, the boxes are empty until the user inputs a response. At one point in time, the code worked when month_amount was a local variable.

I then tried to make it a global variable then I got this error. Then when I switched it back to being a local variable inside the calculate() function it gave me the same error. My biggest question is what is the workaround I can do to convert the entry box responses into int() data? I've added a snippet of the code below.

Month_entry = tk.Entry(root, font=('Arial', 12, "bold"))
Month_entry.grid(row=5, column=1, columnspan=1)
Month_entry.configure(width=68)
Month_entry.place(x=0, y=120)

def calculate():
    month_amount = int(Month_entry.get())

ValueError: invalid literal for int() with base 10: ''
  • Save the result of `Month_entry.get()` in a variable. Then use an `if` statement to check if it's an empty string. If it isn't you can try using `int()` on it. – TheLizzard Aug 06 '21 at 22:30
  • 2
    You shouldn't be calling `calculate()` until the user has entered something into all Entries. Do you perhaps have a Button with `command=calculate()` (which calls the function *immediately*, rather than waiting for the button to be clicked) instead of `command=calculate`? – jasonharper Aug 06 '21 at 22:31
  • Can you elaborate a little more on this please and thank you? Do you mean make month_amount = Month_entry.get()? What would I be doing with the if statement exactly that's where I'm mainly confused on. – Don_de.coder Aug 06 '21 at 22:34
  • 1
    I don't see what you're asking. You seem to know that you can't convert an empty string to an integer, so why not just check for the entry string or catch the error? Your code is responsible for sanitizing user input. – Bryan Oakley Aug 06 '21 at 22:34
  • I do have a calculate button that calls the function immediately. I'll adjust that and see if I get the same error. – Don_de.coder Aug 06 '21 at 22:35
  • @jasonharper thanks for your help I just edited the command function of the calculate button. It works if the variables are local to calculate function. Is there a workaround that I can do if I want the variables to be global so I can use other functions to use those global variables? – Don_de.coder Aug 06 '21 at 22:42
  • @Don_de.coder Just add `global month_amount` at the start of the `calculate` function. Also changing `command=calculate()` to `command=calculate` isn't a *workaround*. It's a solution. Look at [this](https://stackoverflow.com/questions/5767228/why-is-the-command-bound-to-a-button-or-event-executed-when-declared) for more info. – TheLizzard Aug 06 '21 at 22:45
  • @jasonharper Nice catch with the button `command=calculate()`. – TheLizzard Aug 06 '21 at 22:46
  • Thanks, guys I'm going to try it out and get back to you. – Don_de.coder Aug 06 '21 at 23:00
  • You've mentioned "workaround" a couple of times. There are no workarounds for what you're doing. The solution is just sticking to the fundamentals - verifying data before acting upon it, catching exceptions, not processing data before it's ready, etc. – Bryan Oakley Aug 06 '21 at 23:04
  • @jasonharper Thank you the "solution" to adjust the calculate command worked like a charm. Thanks for your help I adjusted all the variables globally and it worked. Thank you. I think in my own haste I was getting flustered. – Don_de.coder Aug 06 '21 at 23:14

1 Answers1

2

There is no workaround necessary, you just need to use standard best practices. In your case, you either need to detect an empty string, or catch the error when trying to convert the empty string, or both.

For example, if you want to report the error to the user, define a function for doing that and then catch the error:

Month_entry = tk.Entry(root, font=('Arial', 12, "bold"))
...

def calculate():
    month = Month_entry.get()
    try:
        month_amount = int(month)
    except ValueError:
       report_error(f"month ('{month}') is not a valid number")

Another solution might be to set the month to a default value if the user hasn't entered anything:

def calculate():
    month = Month_entry.get()
    if month == "":
        month = 0
    else:
        month = int(month)

Or, you might want to combine the two, so that you can gracefully handle an empty string while still catching errors.

Arguably, the best solution is for you to be validating the data as the user types, and only enable a button that calls the calculate function if all of the inputs have valid data.

For an example of how to do entry validation, see Interactively validating Entry widget content in tkinter

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685