from Tkinter import * import math # Define my functions def calculateTraversalInKM(): # This method does the calculations. # First, create a couple 'constants' CLARKE1866EQRADIUS = 6378206.4 # Clarke 1866 equatorial radius in meters METERSPERKM = 1000 # Make sure input text exists, it's numeric, and it's in range try: latDegreesString = e.get() # get the user's data in the text widget # If latDegreesString can't be cast to a float, a ValueError will be # raised by the float() function latDegrees = float(latDegreesString) # Now let's be sure that the latitude value makes sense in terms of # earth geometry. If it's not, we raise a ValueError so it can be # handled cleanly as an exception. if (latDegrees < -90 or latDegrees > 90): raise ValueError latRadians = math.radians(latDegrees) # need radians for cos() below except ValueError: # Bad input--set focus to text field, select all text, and # write error message to the output label e.focus_set() e.selection_range(0, END) # Announce the error in the string associated with outputLabel v.set("Error: input " + latDegreesString + " is illegal") return # A return here just goes back to the message loop. That's # good--we don't want to proceed any further with bad data. # If we got here then the input text is ok--do the calculation circumferenceMeters = 2.0 * math.pi * CLARKE1866EQRADIUS * math.cos(latRadians) circumferenceKm = circumferenceMeters / METERSPERKM # Print the answer in the string associated with outputLabel v.set("At " + latDegreesString + " degrees, your traversal distance would be " + \ str(int(circumferenceKm)) +" km") # don't print float precision for convenience def calculateCallback(): # This is the callback function for goBtn. # When goBtn is clicked, we end up here--just call the calculation function. It's a good # idea to keep your callback functions small and clear--call other functions from here # that do your application's real work calculateTraversalInKM() if __name__ == '__main__': # NOTE: Python does not have block-local scope, meaning that something defined # inside an if statement has the same scope as anything defined just outside of it. # In this particular case, variables defined below have 'global' or the widest possible # scope and are therefore visible to our function definitions above. # Everything below is only run once. Any other action this program takes is a direct # consequence of the user clicking goBtn. master = Tk() # create the main, or root window inputPromptLabel = Label(master, text="Enter a latitude in degrees:") # create a static label inputPromptLabel.pack() # place the label on master e = Entry(master) # create an editable text widget e.pack() # place the text widget on master e.focus_set() # put cursor in text widget automatically as a user convenience goBtn = Button(master, text="Go", command=calculateCallback) # set up the one and only button goBtn.pack() # place it on master v = StringVar() # Set up an interactive label by associating a StringVar object (v) with the Label # attribute textvariable. When we change the contents of v, it will show up # in outputLabel. v.set("Traverse in km will appear here") # put some initial text into v outputLabel = Label(master, textvariable=v) # create and place outputLabel outputLabel.pack() mainloop() # start the message loop (defined somewhere else in Tkinter--don't worry about it)