Constructing a Calculator-Like Application in Python

For one of my research projects focusing on tax cuts in the fuel market (if you are interested, drop me a line), I had to repeatedly calculate the price reductions and the pass-through rate of the tax cut.

So, I took the opportunity to try out the Python library Tkinter. I set up a calculator application that takes a number (an estimated price effect in my case) and a user choice (the choice between different fuel types, diesel and E10 gasoline). Given these inputs, the calculator returns the pass-through rate and the corresponding price reduction in percent.
Let me walk you through it.
First things first, let’s load the Tkinter library.
# --------------------------------------------------
# import modules
import tkinter as tk
from tkinter import ttk
Then, we need to specify the overall layout of our calculator, such as the size of the window and the name.
#--------------------------------------------------
# overall settings
window = tk.Tk()
window.title("Pass-through and Price reduction")
window.resizable(True, True)
window.geometry("500x250")
window.tk.call("tk", "scaling", 2.0)
input_frame = ttk.Frame(master = window, width = 100, height = 50)
input_frame.pack()
I also specify the globals which go into the formulas for calculating the pass-through and the price reduction in means. These numbers could also be user inputs, but I hard-coded them since they are fixed in my setting.
#--------------------------------------------------
# globals
mean_price_diesel = 1.97716
mean_price_e10 = 1.80839
discount_diesel = 16.71
discount_e10 = 35.16
I specify a function that evaluates the user input (the price effect).
#--------------------------------------------------
# function for capturing price effect input
def get_price_input():
try:
# convert entered price into number (if possible)
user_price = float(price_entry.get())
# if it worked, keep warning empty
nonumber["text"] = ""
if fueltype.get() == "nothing":
nonumber["text"] = "Please select a fuel type!"
if fueltype.get() == "diesel":
pass_through["text"] = round((user_price / discount_diesel) * 100, 3)
reduction["text"] = round(user_price / mean_price_diesel, 3)
if fueltype.get() == "e10":
pass_through["text"] = round((user_price / discount_e10) * 100, 3)
reduction["text"] = round(user_price / mean_price_e10, 3)
except ValueError:
nonumber["text"] = "Please enter a valid number!"
The function first checks if the input is a number (provided by the “price_entry” input). If not, the user is prompted to enter a valid number. Then it checks which fuel type has been selected to perform the correct calculation. If no selection is made, the user is prompted to select one of the options.
Since the calculator also has a “Reset” button, let’s define a function for it. It clears all previously output messages and erases all inputs.
#--------------------------------------------------
# function for resetting
def reset():
fueltype.set("0")
price_entry.delete(0, tk.END)
pass_through["text"] = "0"
reduction["text"] = "0"
nonumber["text"] = ""
Now that everything is set up, we can start constructing the inputs. First, I define the input for the price effect. This is an open field where the user can enter any number.
#--------------------------------------------------
# price effect entry
price_label = ttk.Label(
master = input_frame,
text = "Enter price effect (in Cents):"
)
price_entry = ttk.Entry(
master = input_frame,
width = 20
)
price_label.grid(column = 0, row = 0, sticky = tk.W)
price_entry.grid(column = 1, row = 0, sticky = tk.W)
The last two lines are just positioning so that the price input and its label are placed at the top of the calculator. The function above, to get the price effect, also checks if the input is a number. If not, the user gets an error message asking for a number. This output can be obtained by:
#--------------------------------------------------
# make sure that the entry is a number
# otherwise print error
nonumber = tk.Label(
master = input_frame,
text = "",
fg = "red"
)
nonumber.grid(column = 0, row = 6, pady = 20, sticky = tk.W)
After allowing the user to specify the price effect, the user needs to select a fuel type. Thus, I implemented two buttons for this purpose. Their input value is fed into the function at the top, which determines what kind of calculation is performed.
#--------------------------------------------------
# check box for diesel
fueltype = tk.StringVar(value = "nothing")
diesel_check = ttk.Radiobutton(
master = input_frame,
text = "Diesel",
variable = fueltype,
value = "diesel",
command = lambda: fueltype.get()
)
diesel_check.grid(column = 0, row = 2, sticky = tk.W, pady = 5)
#--------------------------------------------------
# check box for e10
# e10 = tk.StringVar()
e10_check = ttk.Radiobutton(
master = input_frame,
text = "E10",
variable = fueltype,
value = "e10",
command = lambda: fueltype.get()
)
e10_check.grid(column = 1, row = 2, sticky= tk.W, pady = 5)
The last action requires the user to hit the “Submit” or “Reset” button.
#--------------------------------------------------
# button for submitting entry
okay_button = ttk.Button(
master = input_frame,
text = "Submit",
command = get_price_input
)
okay_button.grid(column = 0, row = 3, pady = 5)
#--------------------------------------------------
# button for reset
reset_button = ttk.Button(
master = input_frame,
text = "Reset",
command = reset
)
reset_button.grid(column = 1, row = 3, pady = 5)
Once a button is selected, the program executes either a calculation (using the “get_price_input” function) or erases all input (using the “reset” function).
We want to print the results assuming the user is happy with her inputs and has submitted her choices.
#--------------------------------------------------
# output the pass-through rate
pass_through_label = ttk.Label(
master = input_frame,
text = "Pass-through rate (%):"
)
pass_through = ttk.Label(
master = input_frame,
text = "0"
)
pass_through_label.grid(column = 0, row = 4, pady = 5, sticky = tk.W)
pass_through.grid(column = 1, row = 4, pady = 5, sticky = tk.W, padx = 10)
#--------------------------------------------------
# output mean price reduction
reduction_label = ttk.Label(
master = input_frame,
text = "Price reduction in means (%):"
)
reduction = ttk.Label(
master = input_frame,
text = "0"
)
reduction_label.grid(column = 0, row = 5, pady = 5, sticky = tk.W)
reduction.grid(column = 1, row = 5, pady = 5, sticky = tk.W, padx = 10)
Finally, to make everything run, we need to call “mainloop” at the end of our program.
#--------------------------------------------------
# start application
window.mainloop()
There you have it — A calculator that allows the user to set some inputs and receive calculated outputs in return.
The exact application, as described, may be unique to my case, but the general idea of getting some input from the user, processing it with some formula in the back, and returning the result applies to many other scenarios.
Thank you for reading!
The code in one block can be found on my GitHub.
Suggestions or questions? Leave a comment or contact me.