Hi!
I am creating a simple python tkinter calculator. However when I was due to submit my code in my teacher said that my code is inefficient and recommended i change the following:
1.) Create buttons using a for loop
2.) have two classes - one of which is for the functions defintions and one for the GUI components and all
3.) remove all global variables and use parameters and scopes
However i am a novice at programming as i just started recently an have been given a short time. Can anyone help me? Any help is appreciated.
from tkinter import *
from tkinter import messagebox
window = Tk()
window.geometry("314x388") # size of the window
window.resizable(0, 0) # this prevents from resizing the window
window.title("Python Calculator")
def btn_memory_add():
global operation
if(operation != ''): # if the operation isn't empty (nothing on the screen)
Mem_ADD = memory_text.get() # the value of your memory display (top display)
ans = eval(Mem_ADD + '+' + operation) # solve the Mem_ADD plus the value on the main display
memory_text.set(ans) # set the memory display as the answer
input_text.set('') # clear the main display
operation = '' # clear the value of the operation
def btn_memory_sub():
global operation
if(operation != ''): # if the operation isn't empty (nothing on the screen)
Mem_Sub = memory_text.get()# the value of your memory display (top display)
ans = eval(Mem_Sub + '-' + operation)# solve the Mem_Sub minus the value on the main display
memory_text.set(ans)# set the memory display as the answer
input_text.set('') # clear the main display
operation = ''# clear the value of the operation
def memory_call():
global operation
memory = memory_text.get()#gets the value stored in the memory display
input_text.set(memory)# sets it to the main display
memory_text.set("")#clears the memory_text once the memory value is displayed in the main area
def memory_clear():
global operation
memory_text.set("")
def btn_eval(number):
global operation
operation = operation + str(number)
input_text.set(operation)#set the mathematical operation as the answer
if (len(operation)) > 24:
messagebox.showerror("Error Window", "Inputs too Long")
else:
return operation
def btn_del():
global operation
operation = operation[0:len(operation)-1]#this btn_deletes the last number displayed on screen
input_text.set(operation)
operation = operation
def btn_clear():
global operation
operation = "" #clears the value of the operation
input_text.set("")#clears the display
def btn_equal():
global operation
try:
result = str(eval(operation))# eval function evalutes the string operation directly
input_text.set(result)
except ZeroDivisionError:# if zero dividon error arise
result = "Zero Division Error"#inform the user about the zero divison error
input_text.set(result)
operation = result#allow the user to continuously operate once the results are given
if (len(result) > 10 ):
result = "{:e}" .format(float(result))#make a scientific notation once the results length is greater than 10
input_text.set(result)
elif (len(result)) > 24:
messagebox.showerror("Error Window", "Results too Long. Press Clear")#imports message box to show the results is too long
else:
return result#if there is no errors than return the result
operation = ""
# 'StringVar()' is used to get the instance of the display area
input_text = StringVar()
memory_text = StringVar()
# creating a frame for the display area
display_frame = Frame(window, width = 312, height = 50, bd = 0, highlightbackground = "black", highlightcolor = "black", highlightthickness = 1)
display_frame.pack(side = TOP)
# creating a display area inside the display frame
display = Entry(display_frame, font = ('arial', 18, 'bold'), textvariable = memory_text, width = 24, bg = "#eee", bd = 0, justify = RIGHT, state = DISABLED)
display.grid(row = 0, column = 0)
#display.pack(ipady = 10)#internal padding to increase the height of the display area
memory_display = Entry(display_frame, font = ('arial', 18, 'bold'), textvariable = input_text, width = 24, bg = "#eee", bd = 0, justify = RIGHT, state = DISABLED )
memory_display.grid(row = 1, column = 0)
# creating another frame for the button below the display_frame
btns_frame = Frame(window, width = 312, height = 312, bg = "grey")
btns_frame.pack()
#first row that consists of all the memory buttons
memory_add = Button(btns_frame, text = "M+", fg = "black", width = 10, height = 3, bd = 0, bg = "#fff", cursor = "hand2",activebackground = "#1E90FF", command = lambda: btn_memory_add())
memory_add.grid(row = 0, column = 0, padx = 1, pady = 1)
window.bind('a', lambda event: btn_memory_add()) #the letter "a" represents M+ button on the keyboard
memory_subtract = Button(btns_frame, text = "M-", fg = "black", width = 10, height = 3, bd = 0, bg = "#fff", cursor = "hand2",activebackground = "#1E90FF", command = lambda: btn_memory_sub())
memory_subtract.grid(row = 0, column = 1, padx = 1, pady = 1)
window.bind('s', lambda event: btn_memory_sub())#the letter "s" represents M- button on the keyboard
memory_recall = Button(btns_frame, text = "MR", fg = "black", width = 10, height = 3, bd = 0, bg = "#fff", cursor = "hand2",activebackground = "#1E90FF", command = lambda: memory_call())
memory_recall.grid(row = 0, column = 2, padx = 1, pady = 1)
window.bind('r', lambda event: memory_call())#the letter "r" represents MR button on the keyboard
memory_btn_clear = Button(btns_frame, text = "MC", fg = "black", width = 10, height = 3, bd = 0, bg = "#fff", cursor = "hand2", activebackground = "#1E90FF", command = lambda: memory_clear())
memory_btn_clear.grid(row = 0, column = 3, padx = 1, pady = 1)
window.bind('m', lambda event: memory_clear())#the letter "m" represents MC button on the keyboard
#second row that consists of the clear , delete and divide button
clear = Button(btns_frame, text = "C", fg = "black", width = 21, height = 3, bd = 0, bg = "#fff", cursor = "hand2",activebackground = "#1E90FF" ,command = lambda: btn_clear())
clear.grid(row = 1, column = 0,columnspan = 2, padx = 1, pady = 1)
window.bind('c', lambda event: btn_clear())#the letter "a" represents the clear button on the keyboard
btn_delete = Button(btns_frame, text = "Del", fg = "black", width = 10, height = 3, bd = 0, bg = "#fff", cursor = "hand2",activebackground = "#1E90FF", command = lambda: btn_del())
btn_delete.grid(row = 1, column = 2, padx = 1, pady = 1)
window.bind('<BackSpace>', lambda event: btn_del())#the backspace represents the DEL button on the keyboard
btn_divide = Button(btns_frame, text = "/", fg = "black", width = 10, height = 3, bd = 0, bg = "#fff", cursor = "hand2",activebackground = "#1E90FF", command = lambda: btn_eval("/"))
btn_divide.grid(row = 1, column = 3, padx = 1, pady = 1)
window.bind('/', lambda event: btn_eval('/'))#the stroke buttons represent the division button
# third row consists of the number 7 , 8 , 9 and multiplication button
btn_seven = Button(btns_frame, text = "7", fg = "black", width = 10, height = 3, bd = 0, bg = "#fff", cursor = "hand2",activebackground = "#1E90FF", command = lambda: btn_eval(7))
btn_seven.grid(row = 2, column = 0, padx = 1, pady = 1)
window.bind('7', lambda event: btn_eval(7))
btn_eight = Button(btns_frame, text = "8", fg = "black", width = 10, height = 3, bd = 0, bg = "#fff", cursor = "hand2",activebackground = "#1E90FF",command = lambda: btn_eval(8))
btn_eight.grid(row = 2, column = 1, padx = 1, pady = 1)
window.bind('8', lambda event: btn_eval(8))
btn_nine = Button(btns_frame, text = "9", fg = "black", width = 10, height = 3, bd = 0, bg = "#fff", cursor = "hand2",activebackground = "#1E90FF", command = lambda: btn_eval(9))
btn_nine.grid(row = 2, column = 2, padx = 1, pady = 1)
window.bind('9', lambda event: btn_eval(9))
btn_multiply = Button(btns_frame, text = "*", fg = "black", width = 10, height = 3, bd = 0, bg = "#fff", cursor = "hand2",activebackground = "#1E90FF", command = lambda: btn_eval("*"))
btn_multiply.grid(row = 2, column = 3, padx = 1, pady = 1)
window.bind('*', lambda event: btn_eval('*'))
# fourth row consists of the number 4, 5 , 6 and minus buttons
btn_four = Button(btns_frame, text = "4", fg = "black", width = 10, height = 3, bd = 0, bg = "#fff", cursor = "hand2",activebackground = "#1E90FF", command = lambda: btn_eval(4))
btn_four.grid(row = 3, column = 0, padx = 1, pady = 1)
window.bind('4', lambda event: btn_eval(4))
btn_five = Button(btns_frame, text = "5", fg = "black", width = 10, height = 3, bd = 0, bg = "#fff", cursor = "hand2",activebackground = "#1E90FF", command = lambda: btn_eval(5))
btn_five.grid(row = 3, column = 1, padx = 1, pady = 1)
window.bind('5', lambda event: btn_eval(5))
btn_six = Button(btns_frame, text = "6", fg = "black", width = 10, height = 3, bd = 0, bg = "#fff", cursor = "hand2",activebackground = "#1E90FF", command = lambda: btn_eval(6))
btn_six.grid(row = 3, column = 2, padx = 1, pady = 1)
window.bind('6', lambda event: btn_eval(6))
btn_minus = Button(btns_frame, text = "-", fg = "black", width = 10, height = 3, bd = 0, bg = "#fff", cursor = "hand2",activebackground = "#1E90FF", command = lambda: btn_eval("-"))
btn_minus.grid(row = 3, column = 3, padx = 1, pady = 1)
window.bind('-', lambda event: btn_eval('-'))
# fifth row consists of one, two , three and plus button
btn_one = Button(btns_frame, text = "1", fg = "black", width = 10, height = 3, bd = 0, bg = "#fff", cursor = "hand2",activebackground = "#1E90FF", command = lambda: btn_eval(1))
btn_one.grid(row = 4, column = 0, padx = 1, pady = 1)
window.bind('1', lambda event: btn_eval(1))
btn_two= Button(btns_frame, text = "2", fg = "black", width = 10, height = 3, bd = 0, bg = "#fff", cursor = "hand2",activebackground = "#1E90FF", command = lambda: btn_eval(2))
btn_two.grid(row = 4, column = 1, padx = 1, pady = 1)
window.bind('2', lambda event: btn_eval(2))
btn_three = Button(btns_frame, text = "3", fg = "black", width = 10, height = 3, bd = 0, bg = "#fff", cursor = "hand2",activebackground = "#1E90FF", command = lambda: btn_eval(3))
btn_three.grid(row = 4, column = 2, padx = 1, pady = 1)
window.bind('3', lambda event: btn_eval(3))
plus = Button(btns_frame, text = "+", fg = "black", width = 10, height = 3, bd = 0, bg = "#fff", cursor = "hand2",activebackground = "#1E90FF", command = lambda: btn_eval("+"))
plus.grid(row = 4, column = 3, padx = 1, pady = 1)
window.bind('+', lambda event: btn_eval("+"))
#sixth row zero, decimal point and equals button
zero = Button(btns_frame, text = "0", fg = "black", width = 21, height = 3, bd = 0, bg = "#fff", cursor = "hand2",activebackground = "#1E90FF", command = lambda: btn_eval(0))
zero.grid(row = 5, column = 0, columnspan = 2, padx = 1, pady = 1)
window.bind('0', lambda event: btn_eval(0))
point = Button(btns_frame, text = ".", fg = "black", width = 10, height = 3, bd = 0, bg = "#fff", cursor = "hand2",activebackground = "#1E90FF", command = lambda: btn_eval("."))
point.grid(row = 5, column = 2, padx = 1, pady = 1)
window.bind('.', lambda event: btn_eval('.'))
equals = Button(btns_frame, text = "=", fg = "black", width = 10, height = 3, bd = 0, bg = "#fff", cursor = "hand2",activebackground = "#1E90FF", command = lambda: btn_equal())
equals.grid(row = 5, column = 3, padx = 1, pady = 1)
window.bind('=', lambda event: btn_equal())
window.mainloop()