Week 11, Wednesday: Classes

the Pizza class

Here is the pizza class we talked about last time:

class Pizza(object):

  def __init__(self, topping):
    """constructor for pizza class...requires topping string"""
    self.topping = topping
    self.slices = 8           # defaults to 8 slices

  def __str__(self):
    """should create and return a string from instance vars"""
    s = "%s pizza :: slices left = %d" % (self.topping, self.slices)
    return s

  def eatSlice(self):
    """removes one slice from the pizza"""
    if self.slices > 0:
      self.slices -= 1
    else:
      print("No slices left... :(")

  def getSlices(self):
    """getter for number of slices"""
    return self.slices
  def getTopping(self):
    """getter for topping"""
    return self.topping

terminology

another example

Let's write a Counter class, for an object that keeps track of some value, where the value starts at zero, counts up to some maximum value, and then resets back to zero. Think of the seconds on a clock or a watch (starts at 0, increments by 1 up to 59, then back to 0 again), or the minutes (0 to 59) or hours (0 to 12 or 24). You could also have a counter for the individual numbers in an odometer (0 to 9).

Here's how we want this object to be used (note: we will build a clock application later that uses these counter objects):

c = Counter(60)    # create 0 -> 59 counter object
print(c)
for i in range(10):
  c.increment()    # test increment() method
  print(c)

print("-"*20)
print("set counter value to 55")

c.setValue(55)
print(c)
for i in range(10):
  c.increment()    # test roll-over of counter
  print(c)

And here is the output from the above code:

Value:  0    (MaxValue = 60)
Value:  1    (MaxValue = 60)
Value:  2    (MaxValue = 60)
Value:  3    (MaxValue = 60)
Value:  4    (MaxValue = 60)
Value:  5    (MaxValue = 60)
Value:  6    (MaxValue = 60)
Value:  7    (MaxValue = 60)
Value:  8    (MaxValue = 60)
Value:  9    (MaxValue = 60)
Value: 10    (MaxValue = 60)
--------------------
set counter value to 55
Value: 55    (MaxValue = 60)
Value: 56    (MaxValue = 60)
Value: 57    (MaxValue = 60)
Value: 58    (MaxValue = 60)
Value: 59    (MaxValue = 60)
Value:  0    (MaxValue = 60)
Value:  1    (MaxValue = 60)
Value:  2    (MaxValue = 60)
Value:  3    (MaxValue = 60)
Value:  4    (MaxValue = 60)
Value:  5    (MaxValue = 60)

testing your class

Once you have written your class definition, you should test it to make sure all methods work. We want to include the test code in the counter.py file, but if this counter object is used in other programs, we do not want the test code to run each time the object is imported. The if __name__ == "__main__": line below is one way to include test code in your class definition file. Anything below that line will be run when the file is run (python counter.py) but not when it is imported (from counter import *). This way we can test our objects to make sure everything works, then let other programs import them.

class Counter(object):

  def __init__(self, maxval):
    """construct counter obj, given max value"""

    self.maxval = maxval
    self.value = 0

  def __str__(self):
    """create and return a string"""
    s = "Value: %2d    (MaxValue = %2d)" % (self.value, self.maxval)
    return s

  def getValue(self):
    return self.value
  def setValue(self, v):
    self.value = v

  def increment(self):
    """add 1 to current value, rollover if needed"""
    self.value += 1
    if self.value == self.maxval:
      self.value = 0


if __name__ == "__main__":
  # test code here

  c = Counter(60)
  print(c)
  for i in range(10):
    c.increment()
    print(c)

  print("-"*20)
  print("set counter value to 55")

  c.setValue(55)
  print(c)
  for i in range(10):
    c.increment()
    print(c)

the Clock class

Now create a 24-hour clock object, made of three counter objects: one for the seconds (0->59), one for the minutes (0->59), and one for the hour (0->23). Your clock class should work with the following test code:

c1 = Clock(12,55,21)
print(c1)
print("Setting time to 23:59:55...")
c1.setHour(23)
c1.setMinutes(59)
c1.setSeconds(55)
print("Hour for c1: %d" % (c1.getHour()))
print(c1)
for i in range(15):
  c1.tick()
  print(c1)

producing the following output:

Clock: 12:55:21
Setting time to 23:59:55...
Hour for c1: 23
Clock: 23:59:55
Clock: 23:59:56
Clock: 23:59:57
Clock: 23:59:58
Clock: 23:59:59
Clock: 00:00:00
Clock: 00:00:01
Clock: 00:00:02
Clock: 00:00:03
Clock: 00:00:04
Clock: 00:00:05
Clock: 00:00:06
Clock: 00:00:07
Clock: 00:00:08
Clock: 00:00:09
Clock: 00:00:10

digital clock

I have included a program that uses the clock class. Look at digital-clock.py and see what other methods you need to add to clock.py to get the digital clock to work.