-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcalculator.py
152 lines (118 loc) · 4.69 KB
/
calculator.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
"""
wxPython learning program: Integer Calculator
Author: Vitaliy Podoba [email protected]
"""
import wx
# list of math operations and digits to check against
OPERATIONS = ('/', '*', '-', '+')
DIGITS = ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9')
class Calculator(wx.Dialog):
"""Python Integer Calculator"""
def __init__(self):
# initialize our dialog window with: title and size
wx.Dialog.__init__(self, None, id=-1, title='Calculator',
size=wx.Size(182, 190))
# sizers will allows us to put buttons into nice GRID layout
sizer = wx.GridBagSizer(hgap=7, vgap=10)
# add calculator display - text area in read-only mode
# text inside will be right aligned
self.display = wx.TextCtrl(self, id=-1, value='0',
size=wx.Size(182, 40),
style=wx.TE_READONLY|wx.TE_RIGHT)
sizer.Add(self.display, (0, 0), (1, 4), wx.EXPAND)
# put buttons into 4x4 grid
x = 0
y = 1
for row in (('7', '8', '9', '/'),
('4', '5', '6', '*'),
('1', '2', '3', '-'),
('0', 'C', '=', '+')):
for blabel in row:
# create button
button = wx.Button(self, id=-1, label=blabel, size=wx.Size(40, 20))
# bind mouse click on button
self.Bind(wx.EVT_BUTTON, self.HandleButton, button)
# add button to grid sizer
sizer.Add(button, (y, x), (1, 1))
x += 1
x = 0
y += 1
# set a few variables for calculator to work
self.operation = None # remember last operation
self.last = None # remember last number entered
self.resolved = None # flag to clear screen after solve()
# add our grid bag sizer to our dialog
self.SetSizer(sizer)
# set dialog centrally on the screen
self.CenterOnScreen()
def HandleButton(self, event):
"""This Calculator method is called on every button click"""
# define event variables: button, it's label, text field value
button = event.GetEventObject()
label = button.GetLabel()
value = self.getValue()
# below we handle our event differently based on button clicked
# Clear button
if label == 'C':
# simply reset display and forgot any custom calculator variables
self.Clear()
# digit button pressed
elif label in DIGITS:
# it's important to clear display before:
# * new operation
# * after zero digit
# * and after solve() funtion, '=' button
if value == '0' or value in OPERATIONS or self.resolved:
self.update('')
self.resolved = False
self.display.AppendText(label)
# equal sign: try to calculate results
elif label == '=':
# try to solve our equation
self.solve()
# clicked operation button
elif label in OPERATIONS:
# before any new operation try to solve previous operation
self.solve()
# remember previously entered number
# if user is just changing operation - no need to remember any value
if value not in OPERATIONS:
self.last = self.getValue()
# update last operation used and set display to operation label
self.operation = label
self.update(label)
def Clear(self):
"""Calculator Clear button"""
self.display.SetValue('0')
self.operation = None
self.last = None
def update(self, value):
"""Shortcut for display update value"""
self.display.SetValue(value)
def getValue(self):
"""Shortcut for display get value"""
return self.display.GetValue()
def solve(self):
"""Equal operation: let's calculate result"""
# only calculate anything if we got both: operation and last value
if (self.last != None) and (self.operation != None):
# here we use strings and eval to calculate result
result = str(eval(
# e.g. "67 - 24"
self.last + self.operation + self.getValue()
))
# finally reset calculator values and update display with result
self.operation = None
self.last = None
self.update(result)
self.resolved = True
def main():
# run the application
app = wx.App()
# start calcualator dialog
dlg = Calculator()
dlg.ShowModal()
dlg.Destroy()
# initialize our calculator
if __name__ == '__main__':
main()