[Tutor] My best GUI app so far.

Kent Johnson kent37 at tds.net
Tue Jan 11 04:09:02 CET 2005


My suggestions:

- How about some white space! Yikes, you trying to make me go blind?
- You don't actually need to save all the buttons to attributes.
- Much of the button creation is common - I made a button creating function and call that.
   Copy / paste is not your friend, it is a danger! Refactor instead of copying!
- Now you can get rid of all the adddigit functions by making a single generic adddigit
   and calling it with a lambda.
- The four operation functions are identical except the operator; factor out handleOperation()
   (Copy / paste is not your friend!)

- I didn't put the button generation in a loop, once you strip out the repeated arguments what is 
left is pretty readable as is.

Kent


from __future__ import division
from Tkinter import *

class Application(Frame):
     def ctb(self):
         if self.shouldblank:
             self.distext.set('')
             self.shouldblank = False

     def adddigit(self, digit):
         self.ctb()
         self.distext.set(self.distext.get()+digit)

     def adddigitdot(self):
         if not self.distext.get().count('.'):
             self.ctb()
             self.distext.set(self.distext.get()+'.')

     def equal(self):
         if self.action:
             self.newnum = self.distext.get()
             self.newnum = str(eval(self.oldnum+self.action+self.newnum))
             self.distext.set(self.newnum)
             self.oldnum = '0'
             self.action = ''
             self.shouldblank = True

     def add(self):
         self.handleOperator('+')

     def subtract(self):
         self.handleOperator('-')

     def multiply(self):
         self.handleOperator('*')

     def divide(self):
         self.handleOperator('/')


     def handleOperator(self, oper):
         if self.action:
             self.equal()
             self.oldnum = self.distext.get()
             self.action = oper
         else:
             self.oldnum = self.distext.get()
             self.action = oper
             self.shouldblank = True


     def clear(self):
         self.action = ''
         self.oldnum = '0'
         self.distext.set('0')
         self.shouldblank = True

     def memrecall(self):
         self.distext.set(self.memory)
         self.shouldblank = True

     def memminus(self):
         self.memory = str(eval(self.memory+"-"+self.distext.get()))
         self.shouldblank = True

     def memplus(self):
         self.memory = str(eval(self.memory+"+"+self.distext.get()))
         self.shouldblank = True


     def makeButton(self, text, command, row, column):
         button = Button(self,text=text,command=command,width=4,height=3)
         button.grid(row=row,column=column)


     def createWidgets(self):
         self.distext = StringVar()
         self.display =Entry(self,textvariable=self.distext,width=22,justify='right')
         self.display.grid(row=0,column=1,columnspan=4)

         self.makeButton(text='0',command=lambda: self.adddigit('0'),row=5,column=1)
         self.makeButton(text='1',command=lambda: self.adddigit('1'),row=4,column=1)
         self.makeButton(text='2',command=lambda: self.adddigit('2'),row=4,column=2)
         self.makeButton(text='3',command=lambda: self.adddigit('3'),row=4,column=3)
         self.makeButton(text='4',command=lambda: self.adddigit('4'),row=3,column=1)
         self.makeButton(text='5',command=lambda: self.adddigit('5'),row=3,column=2)
         self.makeButton(text='6',command=lambda: self.adddigit('6'),row=3,column=3)
         self.makeButton(text='7',command=lambda: self.adddigit('7'),row=2,column=1)
         self.makeButton(text='8',command=lambda: self.adddigit('8'),row=2,column=2)
         self.makeButton(text='9',command=lambda: self.adddigit('9'),row=2,column=3)
         self.makeButton(text='.',command=self.adddigitdot,row=5,column=2)
         self.makeButton(text="=",command=self.equal,row=5,column=3)
         self.makeButton(text='+',command=self.add,row=5,column=4)
         self.makeButton(text="-",command=self.subtract,row=4,column=4)
         self.makeButton(text='x',command=self.multiply,row=3,column=4)
         self.makeButton(text='/',command=self.divide,row=2,column=4)
         self.makeButton(text='ON/C',command=self.clear,row=1,column=4)
         self.makeButton(text='MRC',command=self.memrecall,row=1,column=1)
         self.makeButton(text="M-",command=self.memminus,row=1,column=2)
         self.makeButton(text="M+",command=self.memplus,row=1,column=3)


     def __init__(self, master=None):
         Frame.__init__(self,master)
         self.master.title("Calculator by Jacob, Inc.")
         self.pack(fill='both')
         self.oldnum = '0'
         self.memory = '0'
         self.action = ''
         self.shouldblank = True
         self.createWidgets()

app = Application()
app.mainloop()
### End of Calculator.py ###



Jacob S. wrote:
> Here's the code. If you have time, look it over and give me suggestions for
> improvement!
> (big toothy grin)
> 
> ### Start of Calculator.py ###
> from __future__ import division
> from Tkinter import *
> 
> class Application(Frame):
>     def ctb(self):
>         if self.shouldblank:
>             self.distext.set('')
>             self.shouldblank = False
>     def adddigit0(self):
>         self.ctb()
>         self.distext.set(self.distext.get()+'0')
>     def adddigit1(self):
>         self.ctb()
>         self.distext.set(self.distext.get()+'1')
>     def adddigit2(self):
>         self.ctb()
>         self.distext.set(self.distext.get()+'2')
>     def adddigit3(self):
>         self.ctb()
>         self.distext.set(self.distext.get()+'3')
>     def adddigit4(self):
>         self.ctb()
>         self.distext.set(self.distext.get()+'4')
>     def adddigit5(self):
>         self.ctb()
>         self.distext.set(self.distext.get()+'5')
>     def adddigit6(self):
>         self.ctb()
>         self.distext.set(self.distext.get()+'6')
>     def adddigit7(self):
>         self.ctb()
>         self.distext.set(self.distext.get()+'7')
>     def adddigit8(self):
>         self.ctb()
>         self.distext.set(self.distext.get()+'8')
>     def adddigit9(self):
>         self.ctb()
>         self.distext.set(self.distext.get()+'9')
>     def adddigitdot(self):
>         if not self.distext.get().count('.'):
>             self.ctb()
>             self.distext.set(self.distext.get()+'.')
>     def equal(self):
>         if self.action:
>             self.newnum = self.distext.get()
>             self.newnum = str(eval(self.oldnum+self.action+self.newnum))
>             self.distext.set(self.newnum)
>             self.oldnum = '0'
>             self.action = ''
>             self.shouldblank = True
>     def add(self):
>         if self.action:
>             self.equal()
>             self.oldnum = self.distext.get()
>             self.action = '+'
>         else:
>             self.oldnum = self.distext.get()
>             self.action = '+'
>             self.shouldblank = True
>     def subtract(self):
>         if self.action:
>             self.equal()
>             self.oldnum = self.distext.get()
>             self.action = '-'
>         else:
>             self.oldnum = self.distext.get()
>             self.action = '-'
>             self.shouldblank = True
>     def multiply(self):
>         if self.action:
>             self.equal()
>             self.oldnum = self.distext.get()
>             self.action = '*'
>         else:
>             self.oldnum = self.distext.get()
>             self.action = '*'
>             self.shouldblank = True
>     def divide(self):
>         if self.action:
>             self.equal()
>             self.oldnum = self.distext.get()
>             self.action = '/'
>         else:
>             self.oldnum = self.distext.get()
>             self.action = '/'
>             self.shouldblank = True
>     def clear(self):
>         self.action = ''
>         self.oldnum = '0'
>         self.distext.set('0')
>         self.shouldblank = True
>     def memrecall(self):
>         self.distext.set(self.memory)
>         self.shouldblank = True
>     def memminus(self):
>         self.memory = str(eval(self.memory+"-"+self.distext.get()))
>         self.shouldblank = True
>     def memplus(self):
>         self.memory = str(eval(self.memory+"+"+self.distext.get()))
>         self.shouldblank = True
> 
> 
> 
>     def createWidgets(self):
>         self.distext = StringVar()
>         self.display =
> Entry(self,textvariable=self.distext,width=22,justify='right')
>         self.display.grid(row=0,column=1,columnspan=4)
> 
>         self.b0 =
> Button(self,text='0',command=self.adddigit0,width=4,height=3)
>         self.b0.grid(row=5,column=1)
>         self.b1 =
> Button(self,text='1',command=self.adddigit1,width=4,height=3)
>         self.b1.grid(row=4,column=1)
>         self.b2 =
> Button(self,text='2',command=self.adddigit2,width=4,height=3)
>         self.b2.grid(row=4,column=2)
>         self.b3 =
> Button(self,text='3',command=self.adddigit3,width=4,height=3)
>         self.b3.grid(row=4,column=3)
>         self.b4 =
> Button(self,text='4',command=self.adddigit4,width=4,height=3)
>         self.b4.grid(row=3,column=1)
>         self.b5 =
> Button(self,text='5',command=self.adddigit5,width=4,height=3)
>         self.b5.grid(row=3,column=2)
>         self.b6 =
> Button(self,text='6',command=self.adddigit6,width=4,height=3)
>         self.b6.grid(row=3,column=3)
>         self.b7 =
> Button(self,text='7',command=self.adddigit7,width=4,height=3)
>         self.b7.grid(row=2,column=1)
>         self.b8 =
> Button(self,text='8',command=self.adddigit8,width=4,height=3)
>         self.b8.grid(row=2,column=2)
>         self.b9 =
> Button(self,text='9',command=self.adddigit9,width=4,height=3)
>         self.b9.grid(row=2,column=3)
>         self.bdot =
> Button(self,text='.',command=self.adddigitdot,width=4,height=3)
>         self.bdot.grid(row=5,column=2)
>         self.equalsign =
> Button(self,text="=",command=self.equal,width=4,height=3)
>         self.equalsign.grid(row=5,column=3)
>         self.plussign =
> Button(self,text='+',command=self.add,width=4,height=3)
>         self.plussign.grid(row=5,column=4)
>         self.minussign =
> Button(self,text="-",command=self.subtract,width=4,height=3)
>         self.minussign.grid(row=4,column=4)
>         self.timessign =
> Button(self,text='x',command=self.multiply,width=4,height=3)
>         self.timessign.grid(row=3,column=4)
>         self.divsign =
> Button(self,text='/',command=self.divide,width=4,height=3)
>         self.divsign.grid(row=2,column=4)
>         self.clearb =
> Button(self,text='ON/C',command=self.clear,width=4,height=3)
>         self.clearb.grid(row=1,column=4)
>         self.mrc =
> Button(self,text='MRC',command=self.memrecall,width=4,height=3)
>         self.mrc.grid(row=1,column=1)
>         self.mm =
> Button(self,text="M-",command=self.memminus,width=4,height=3)
>         self.mm.grid(row=1,column=2)
>         self.mp =
> Button(self,text="M+",command=self.memplus,width=4,height=3)
>         self.mp.grid(row=1,column=3)
> 
> 
>     def __init__(self, master=None):
>         Frame.__init__(self,master)
>         self.master.title("Calculator by Jacob, Inc.")
>         self.pack(fill='both')
>         self.oldnum = '0'
>         self.memory = '0'
>         self.action = ''
>         self.shouldblank = True
>         self.createWidgets()
> 
> app = Application()
> app.mainloop()
> ### End of Calculator.py ###
> 
> Is there some way that I could loop over those button definitions?
> 
> proposal - code
> 
> a = """
> def adddigit%s(self):
>     self.ctb()
>     self.distext.set(self.distext.get()+'%s')
> """
> for i in range(10):
>     exec a % (i,i)
> 
> Pretty cool, huh? I've got my thinking cap on today!
> 
> Thanks in advance for suggestions,
> Jacob
> 
> 
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> http://mail.python.org/mailman/listinfo/tutor
> 


More information about the Tutor mailing list