[Tutor] clock programs (and generalization)

Daniel Yoo dyoo@hkn.eecs.berkeley.edu
Sat, 24 Mar 2001 14:47:18 -0800 (PST)


Ok, I've taken a small look at each of your clock classes; you can
definitely shrink this down to just one clock class.  The thing i see is
differnt is the treatment of self.time1.

What makes a class useful is that you tell the general form, or shape of
the thing you're making, but leave some information "floating" or
variable, until you instantiate it.  Let's let the Clock class make
different kinds of clocks which vary by how long the hour is --- when we
make a Clock, let's tell it also how long a day is.  I'll use the variable
"hourlength" to hold this information.

###
class Clock(Frame):
    def __init__(self, master, hourlength):
        Frame.__init__(self,master)
        self.hourlength = hourlength
        timeformat2="Time so far on " + hourlength + \
                    " hr. planet is %d:%d:%d"):

        self.time=(h,m,s)
        self.time1=self.time[0]
        self.time2=self.time[1]
        self.time3=self.time[2]

        if self.time1>self.hourlength:
            self.time1=self.time1 % self.hourlength

        self.timeformat=format2
        self.display=Label(self,fg="green",bg="black",
                           text=format(self.timeformat,self.time))
        self.display.pack(side=TOP,expand=YES,fill=BOTH)
        self.updateDisplay()

    def updateDisplay(self):
        self.time3=self.time3+1

        if self.time3==60:
            self.time3=0
            self.time2=self.time2+1
        if self.time2==60:
            self.time2=0
            self.time1=self.time1+1
        if self.time1==self.hourlength:
            self.time1=0

        self.time=(self.time1,self.time2,self.time3)
        self.display.configure(text=format(self.timeformat,self.time))
        self.after(1000,self.updateDisplay)
###

With this one definition of a Clock, now we can make Clock18's, Clock21's,
or any other kind of clock whenever we instantiate the clock.  For
example, whenever we say;

    Clock21(tkroot).pack(side=TOP)

now we can say:

    Clock(tkroot, 21).pack(side=TOP)

and have it do a similar thing!  Not too exciting yet, but the savings
become significant as soon as we make different clocks, because making a
Clock24 now involves just slightly calling Clock differently:

    Clock(tkroot, 24).pack(side=TOP)

By generalizing things, we don't have a need to write 5 different class
definitions anymore, because it's all covered by Clock.  Generalization is
one of the biggest reasons we have classes --- if you find yourself
writing something over and over, take another look and see if generalizing
it is possible.  There are other idioms specific to Python that can help
make things shorter, but the biggest savings comes from generalization.

It's not an exciting message, but it's an important one.  *grin* Hope this
helps!