knerr cs21 notes...

back to schedule

WEEK11: defining our own classes/object-oriented programming
---------------------------------------------------------------
 M: classes

OBJECTS REVIEW:

 - we've used objects already:

       cenpt = Point(200,200)
       c1 = Circle(cenpt, 100)
       c1.setFill("blue")
       c1.draw(win)

   in the above code, cenpt is a Point object, and c1 is a Circle
   object. We also used the Circle class' methods setFill and draw

 - an object is just data *and* functions all together in one "thing"

 - for the above Circle object, the data are the center point, the
   radius (100), and the color. The functions are just the methods
   that do something to the circle (fill it, draw it, move it)

 - in Python, almost everything is an object. Look at the help info
   for str and list and you can see all of their methods:

>>> help(str)

>>> help(list)


FIRST EXAMPLE of WRITING A NEW CLASS:

 - if we were going to write a game program that uses a deck of cards,
   we would probably write classes for the cards, the deck, and maybe
   a hand of cards, and the players

 - see /home/jk/inclass/card.py for an example card class

 - terms/syntax/definitions...

       __init__     the constructor method -- called when we create
                    a new variable of this type (ex: c = Card(8, "hearts"))
       __str__      the print method -- called when we print a
                    variable of this type (ex: print c). This method must
                    return a string!
       self         the first parameter to any method. This is just a reference
                    to the object on which the method is acting (if I say
                    c.getRank(), self = c)
       accessors    methods that get or access the object data (like getRank)
       mutator      methods that change object data (no mutators in the Card class)

if __name__ == '__main__':         this line is for testing your new class. if your
  # add your test code here        new class is imported, this code will not be run.
                                   if your class is run directly (like "python card.py"),
                                   then this test code *will* be executed.

"""triple-quote comments"""        also note the use of the triple-quoted comments in card.py!
                                   if you say "import card" and then "help(card)" the documentation
                                   you see *is* the triple-quoted comments!!


SECOND EXAMPLE: deck of cards class

 - here's a second example of creating a new class. See how the card class
   is imported and used? the data for this class is a list of 52 card objects
   (self.cards)


from card import *
from random import shuffle

class Deck(object):
  """Deck of Cards class. Allows shuffling and dealing of cards"""

  def __init__(self):
    """Constructor for Deck class. Initializes 52-card deck of cards"""
    self.cards = []
    for suit in ["clubs","hearts","diamonds","spades"]:
      for rank in range(2,15):
        self.cards.append(Card(rank, suit))

  def __str__(self):
    """return string for the entire deck"""
    s = ""
    for c in self.cards:
      s += c.sname() + " "
    s = s + "\n"
    return s

  def shuffle(self):
    """randomly shuffle all the cards"""
    shuffle(self.cards)

  def dealOneCard(self):
    """remove and return one card from the top of the deck"""
    card = self.cards.pop(0)
    return card

  def cardsLeft(self):
    """return number of cards left in the deck"""
    return len(self.cards)

if __name__ == '__main__': 
  # test code...
  d = Deck()
  print d
  d.shuffle()
  print d


WHY ARE WE DOING THIS???

 - object-oriented programming (OOP) is a different way to program. Some
   think it is better (easier to maintain, cleaner) for large, complicated programs.

 - if you write a good general class, it's easy to use it over and over
   in many programs (code reuse == good)

 - some think OOP is more intuitive, since the objects you create usually
   represent real-life objects (cards, planets, students, etc)