1

I am new to python and this is the first project I am working on, it is a Litecoin - Euro conversion program. I had a problem, that if I did not put anything into the Entry() fields of the program and submitted it, the console would output following error message (because int() and float() cannot convert an empty string into an int/ a float):

Exception in Tkinter callback
Traceback (most recent call last):
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk/Tkinter.py", line 1536, in __call__
return self.func(*args)
File "/Users/Samir/Library/Mobile Documents/com~apple~CloudDocs/Coding/Python/hello_world/exch.py", line 13, in exchange
choice = int( exc.get() ) # choice of EUR to LTC or other way around
ValueError: invalid literal for int() with base 10: ''

The whole code I used in that matter:

from Tkinter import *
from json import *
from urllib2 import *

def exchange():
    data = urlopen('https://btc-e.com/api/3/ticker/ltc_eur') # EUR - LTC API

    j_obj = load(data)  #loads json data
    exch = float( j_obj['ltc_eur']['avg'] ) # picks exchange rate out of api

    choice = int( exc.get() ) # choice whether EUR to LTC or other way around
    amount = float ( am.get() ) # amount of the currency the user wants to convert

    if choice == 0:
        print round((1 / exch) * amount, 2), "Litecoins"
    elif choice == 1:
        print round(exch * amount, 2), "Euro"
    else: # if something other than 0 or 1 was typed in
        print "I'm sorry but you have to enter either 0 or 1"

    am.delete(0, END)
    exc.delete(0, END)


master = Tk()   # creates new window in var master
master.wm_title("LTC - EUR converter")   # creates title for the window

Label(master, text = "EUR into LTC (0) or LTC into EUR(1): ").grid(row = 0, sticky = W) # creates choice string in a table (Row 1)
Label(master, text = "Amount: ").grid(row = 1, sticky = E)  # creates text "Amount" in a table (Row 1)

exc = Entry(master) # picks up Entryvalue
exc.grid(row = 0, column = 1)

am = Entry(master)  # picks up Entryvalue
am.grid(row = 1, column = 1)    # places it at row 0 colum 1 in the table

Button(master, text = "Quit", command = master.quit).grid(row = 2, column= 1, sticky = W)   # creates a quit button that closes the window
Button(master, text = "Submit", command = exchange).grid(row = 2, column = 1)   # creates a submit button that executes def "exchange"


mainloop() # starts the program

I managed to fix the problem with changing the if query to comparing the input to strings and converting the input (to int and float) after it confirmed either 0 or 1 has been typed in. The changed code:

choice = exc.get()
amount = am.get()

if choice == '0':
    choice = int(choice)
    amount = float(amount)

    print round((1 / exch) * amount, 2), "Litecoins"
elif choice == '1':
    choice = int(choice)
    amount = float(amount)

    print round(exch * amount, 2), "Euro"
else:
    print "I'm sorry but you have to enter either 0 or 1"

So my question is, is there any solution for that problem that is more efficient? Because I think my approach works but it isn't the best option out there.

1 Answers1

0

"It is better to ask for forgiveness than permission".

You can place your code in a try-except block.

try:
    choice = int(choice)
    amount = float(amount)

except ValueError:
    print "I'm sorry but you have to enter either 0 or 1"
    return

if choice == 1:
    ...
else:
    ...

This way, you check the value of choice once rather than twice.

Edit: If would be prudent to keep separate try-except braces for choice and amount. With the current scenario, entering a valid choice but an invalid amount could yield a misleading error message.

cs95
  • 379,657
  • 97
  • 704
  • 746
  • You might want to generalise this a bit. If you enter zero or one in choice but leave the amount blank you will get a misleading error message. A quick google of tkinter validating input will show you the standard approach to doing this. – Mic Jul 03 '17 at 14:11
  • @Mic Thanks, added a footnote. – cs95 Jul 03 '17 at 14:15