Uses Tkinter for platform-independent (Tk-based) GUI and re module for regular expressions.
Tried to be reasonably Pythony about it, using tuples and lists and dictionaries etc. as (I think) is typical.
The worst parts were trying to remember regex syntax and formatting syntax; nothing really to do with Python itself. Just rusty on those bits because I don't use them much these days.
The code:
from Tkinter import *
import re
class Calculator(Frame):
# dict of buttons
buttons = {}
# track if need to clear display before updating display
to_clear = True
def createWidgets(self):
options = {'width':10, 'textvariable':'self.display', 'bd':1, 'relief':GROOVE, 'anchor':E}
self.label = Label(self, options)
self.label.grid(row=0, column=0, columnspan=4, sticky=W+E)
# labels for calculator buttons
b_text = ["/"] + range(9, 6, -1)
b_text += ["*"] + range(6, 3, -1)
b_text += ["-"] + range(3, 0, -1) + ["+", "=", ".", 0]
# lay the buttons out, making the key layout coords, value a button widget
for row in range(4, 0, -1):
for column in range(4):
self.buttons[(column, row)] = Button(self, text = b_text.pop())
self.buttons[(column, row)].grid(row = row, column = column)
self.buttons[(column, row)].bind('', self.button_click)
def __init__(self, master):
Frame.__init__(self, master)
self.pack()
# to keep the display dynamically updated
self.display = StringVar()
# initialize to something purty
self.display.set("0.0")
# set me up!
self.createWidgets()
# callback when button is click'd
def button_click(self, event):
wut = event.widget['text']
if wut == '=': # calc it!
eval_me = self.display.get()
# if there are no decimals, convert the first number to a float
# this forces floating-point maths
if not '.' in self.display.get():
# find the first group of digits, stick a '.0' on the end of it!
eval_me = re.sub(r'(\d+)', r'\1.0', self.display.get(), count=1)
result = '{: f}'.format(eval(eval_me))
self.display.set(str(result).rstrip('0').rstrip('.'))
self.to_clear = True
else: # track the input
# keep using result if you want to
if wut in ["+", "-", ".", "/", "*"]:
self.to_clear = False
if self.to_clear:
self.display.set(wut)
self.to_clear = False
else: #keep using the result value displayed
show_me = self.display.get() + str(wut)
self.display.set(show_me)
# begin!
root = Tk()
calculator = Calculator(root)
calculator.mainloop()
root.destroy()
No comments:
Post a Comment