1 #Simple Calculator
2 import tkinter
3 from tkinter import RIGHT, END, DISABLED, NORMAL
4
5 #Define window
6 root = tkinter.Tk()
7 root.title('Calculator')
8 root.iconbitmap('calc.ico')
9 root.geometry('300x400')
10 root.resizable(0,0)
11
12 #Define colors and fonts
13 dark_green = '#93af22'
14 light_green = '#acc253'
15 white_green = '#edefe0'
16 button_font = ('Arial', 18)
17 display_font = ('Arial', 30)
18
19 #Define functions
20 def submit_number(number):
21 """Add a number or decimal to the display"""
22 #Insert the number or decimal pressed to the end of the display
23 display.insert(END, number)
24
25 #If decimal was pressed, disable the decimal button so it cannot be pressed twice
26 if "." in display.get():
27 decimal_button.config(state=DISABLED)
28
29
30 def operate(operator):
31 """Store the first number of the expression and the operation to be used"""
32 global first_number
33 global operation
34
35 #Get the operator pressed and the current value of the display. This is the first
number in the calculation
36 operation = operator
37 first_number = display.get()
38
39 #Delete the value (first number) from entry display
40 display.delete(0, END)
41
42 #Dispable all operator buttons until equal or clear is pressed
43 add_button.config(state=DISABLED)
44 subtract_button.config(state=DISABLED)
45 multiply_button.config(state=DISABLED)
46 divide_button.config(state=DISABLED)
47 exponent_button.config(state=DISABLED)
48 inverse_button.config(state=DISABLED)
49 square_button.config(state=DISABLED)
50
51 #Return decimal button to normal state
52 decimal_button.config(state=NORMAL)
53
54
55 def equal():
56 """Run the stored operation for two number."""
57 #Perform the desired mathematics
58 if operation == 'add':
59 value = float(first_number) + float(display.get())
60 elif operation == 'subtract':
61 value = float(first_number) - float(display.get())
62 elif operation == 'multiply':
63 value = float(first_number) * float(display.get())
64 elif operation == 'divide':
65 if display.get() == "0":
66 value = "ERROR"
67 else:
68 value = float(first_number) / float(display.get())
69 elif operation == 'exponent':
70 value = float(first_number) ** float(display.get())
71
72 #Remove the curent value of the display and update it with the answer
73 display.delete(0, END)
74 display.insert(0, value)
75
76 #Return buttons to normal states
77 enable_buttons()
78
79
80 def enable_buttons():
81 """Enabel all butonns on the calculator"""
82 decimal_button.config(state=NORMAL)
83 add_button.config(state=NORMAL)
84 subtract_button.config(state=NORMAL)
85 multiply_button.config(state=NORMAL)
86 divide_button.config(state=NORMAL)
87 exponent_button.config(state=NORMAL)
88 inverse_button.config(state=NORMAL)
89 square_button.config(state=NORMAL)
90
91
92 def clear():
93 """Clear the display"""
94 display.delete(0, END)
95
96 #Return buttons to normal state
97 enable_buttons()
98
99
100 def inverse():
101 """Calculate the inverse of a given number."""
102 #Do not allow for 1/0
103 if display.get() == '0':
104 value = 'ERROR'
105 else:
106 value = 1/float(display.get())
107
108 #Remove the current value in the display and update it with the answer
109 display.delete(0, END)
110 display.insert(0, value)
111
112
113 def square():
114 """Calculate the square of a given number."""
115 value = float(display.get())**2
116
117 #Remove the current value in the display and update it with the answer
118 display.delete(0, END)
119 display.insert(0, value)
120
121
122 def negate():
123 """Negate a given number."""
124 value = -1*float(display.get())
125
126 #Remove the current value in the display and update it with the answer
127 display.delete(0, END)
128 display.insert(0, value)
129
130
131 #GUI Layout
132 #Define frames
133 display_frame = tkinter.LabelFrame(root)
134 button_frame = tkinter.LabelFrame(root)
135 display_frame.pack(padx=2, pady=(5,20))
136 button_frame.pack(padx=2, pady=5)
137
138 #Layout for the display frame
139 display = tkinter.Entry(display_frame, width=50, font=display_font, bg=white_green,
borderwidth=5, justify=RIGHT)
140 display.pack(padx=5, pady=5)
141
142 #Layout for the button frame
143 clear_button = tkinter.Button(button_frame, text="Clear", font=button_font,
bg=dark_green, command=clear)
144 quit_button = tkinter.Button(button_frame, text="Quit", font=button_font,
bg=dark_green, command=root.destroy)
145
146 inverse_button = tkinter.Button(button_frame, text='1/x', font=button_font,
bg=light_green, command=inverse)
147 square_button = tkinter.Button(button_frame, text='x^2', font=button_font,
bg=light_green, command=square)
148 exponent_button = tkinter.Button(button_frame, text='x^n', font=button_font,
bg=light_green, command=lambda:operate('exponent'))
149 divide_button = tkinter.Button(button_frame, text=' / ', font=button_font,
bg=light_green, command=lambda:operate('divide'))
150 multiply_button = tkinter.Button(button_frame, text='*', font=button_font,
bg=light_green, command=lambda:operate('multiply'))
151 subtract_button = tkinter.Button(button_frame, text='-', font=button_font,
bg=light_green, command=lambda:operate('subtract'))
152 add_button = tkinter.Button(button_frame, text='+', font=button_font, bg=light_green,
command=lambda:operate('add'))
153 equal_button = tkinter.Button(button_frame, text='=', font=button_font, bg=dark_green,
command=equal)
154 decimal_button = tkinter.Button(button_frame, text='.', font=button_font, bg='black',
fg='white', command=lambda:submit_number("."))
155 negate_button = tkinter.Button(button_frame, text='+/-', font=button_font, bg='black',
fg='white', command=negate)
156
157 nine_button = tkinter.Button(button_frame, text='9', font=button_font, bg='black',
fg='white', command=lambda:submit_number(9))
158 eight_button = tkinter.Button(button_frame, text='8', font=button_font, bg='black',
fg='white', command=lambda:submit_number(8))
159 seven_button = tkinter.Button(button_frame, text='7', font=button_font, bg='black',
fg='white', command=lambda:submit_number(7))
160 six_button = tkinter.Button(button_frame, text='6', font=button_font, bg='black',
fg='white', command=lambda:submit_number(6))
161 five_button = tkinter.Button(button_frame, text='5', font=button_font, bg='black',
fg='white', command=lambda:submit_number(5))
162 four_button = tkinter.Button(button_frame, text='4', font=button_font, bg='black',
fg='white', command=lambda:submit_number(4))
163 three_button = tkinter.Button(button_frame, text='3', font=button_font, bg='black',
fg='white', command=lambda:submit_number(3))
164 two_button = tkinter.Button(button_frame, text='2', font=button_font, bg='black',
fg='white', command=lambda:submit_number(2))
165 one_button = tkinter.Button(button_frame, text='1', font=button_font, bg='black',
fg='white', command=lambda:submit_number(1))
166 zero_button = tkinter.Button(button_frame, text='0', font=button_font, bg='black',
fg='white', command=lambda:submit_number(0))
167
168 #First row
169 clear_button.grid(row=0, column=0, columnspan=2, pady=1, sticky="WE")
170 quit_button.grid(row=0, column=2, columnspan=2, pady=1, sticky="WE")
171 #Second row
172 inverse_button.grid(row=1, column=0, pady=1, sticky="WE")
173 square_button.grid(row=1, column=1, pady=1, sticky="WE")
174 exponent_button.grid(row=1, column=2, pady=1, sticky="WE")
175 divide_button.grid(row=1, column=3, pady=1, sticky="WE")
176 #Third row (Add padding to create the size of the columns)
177 seven_button.grid(row=2, column=0, pady=1, sticky="WE", ipadx=20)
178 eight_button.grid(row=2, column=1, pady=1, sticky="WE", ipadx=20)
179 nine_button.grid(row=2, column=2, pady=1, sticky="WE", ipadx=20)
180 multiply_button.grid(row=2, column=3, pady=1, sticky="WE", ipadx=20)
181 #Fourth row
182 four_button.grid(row=3, column=0, pady=1, sticky="WE")
183 five_button.grid(row=3, column=1, pady=1, sticky="WE")
184 six_button.grid(row=3, column=2, pady=1, sticky="WE")
185 subtract_button.grid(row=3, column=3, pady=1, sticky="WE")
186 #Fifth row
187 one_button.grid(row=4, column=0, pady=1, sticky="WE")
188 two_button.grid(row=4, column=1, pady=1, sticky="WE")
189 three_button.grid(row=4, column=2, pady=1, sticky="WE")
190 add_button.grid(row=4, column=3, pady=1, sticky="WE")
191 #Sixth row
192 negate_button.grid(row=5, column=0, pady=1, sticky="WE")
193 zero_button.grid(row=5, column=1, pady=1, sticky="WE")
194 decimal_button.grid(row=5, column=2, pady=1, sticky="WE")
195 equal_button.grid(row=5, column=3, pady=1, sticky="WE")
196
197 #Run the root window's main loop
198 root.mainloop()