CS 111 f21 — Objects part 1
1 Objects
- pull back the veil, show what's been going on this whole time
- we've seen functions, and we've seen data
- objects are just the combination of these two things into a single entity
- you've been working with objects this whole time
- We've made extensive use of methods—functions associated with a particular object
line.split()
is an example of a string method we used in Lab 3- PGL graphics involves a lot of applying a particular operation to a particular graphical object
ball.setFilled(True)
,ball.setColor("Black")
gw.add(ball)
- We've also seen an example of using an objects attribute (often called a field)
numpy
arrays have ashape
attribute—a particular piece of data associated with a particular array- We access it using a dot (
.
), but without parentheses, since we're not calling like a function image.shape
- Python let's us define new kinds of objects
- The definition is called a class
- We can have many instances of a class (many specific objects of the same kind)
- For example,
GRect
is a class, and to make a grid of bricks, we created manyGRect
instances
Thought exercise: how could we represent a deck of cards?
- Some useful parts of a class definition:
- define a function for creating a new instance of the class
- called the constructor
- in Python, this method's name is
__init__
- define a function for displaying instances of the class as a string
- the
__repr__
method, short for representation __repr__
is called automatically whenever we print an object
- the
- define a function for creating a new instance of the class
- Inside a class definition,
self
refers to the current object- So in our Breakout! code, we call
setColor
on various objects (e.g.,paddle.setColor("Black")
,ball.setColor("Black")
)def setColor(self, color): """ Sets the color used to display this object. The color parameter is usually one of the CSS color names. The color can also be specified as a string in the form <code>"#rrggbb"</code> where <code>rr</code>, <code>gg</code>, and <code>bb</code> are pairs of hexadecimal digits indicating the red, green, and blue components of the color. """ rgb = convertColorToRGB(color) self.color = convertRGBToColor(rgb) self.updateColor()
- Earlier, I waved my hands and said Python takes care of providing the
self
parameter for us - What's happening is that Python takes the variable before the
.
and puts that in forself
- Meaning,
paddle.setColor("Black")
is essentiallysetColor(paddle, "Black")
- That way,
paddle.setColor("Black")
results insetColor
being called whereself
ispaddle
, andball.setColor("Black")
results insetColor
being called whereself
isball
- Meaning,
- Inside a method definition, we use
self
to access the attributes and methods of whatever specific object the method is being called with
- So in our Breakout! code, we call
- By convention, class names are capitalized
- To create an instance of a class, we call the class name like a function
- This causes
__init__
to be called, and so we provide the non-self parametersc = Card(5, "♥")
- This causes
1.1 Playing Card Class
import random class Card: def __init__(self, value, suit): self.value = value self.suit = suit def __repr__(self): if self.value <= 10: return str(self.value) + " of " + self.suit face = ["Jack", "Queen", "King", "Ace"][self.value - 11] return face + " of " + self.suit deck = [] for value in range(2, 15): for suit in ["♣", "♦", "♠", "♥"]: deck.append(Card(value, suit)) print("deck of", len(deck), "cards") random.shuffle(deck) print(deck[:5]) print(deck[0], ">", deck[1], deck[0] > deck[1])
1.2 Practice
1.2.1 Polls
1.2.2 Define a 2D Point class with fields x and y
class Point: def __init__(self, x, y): self.x = x self.y = y
1.2.3 What is printed by this code?
- "getter" and "setter" methods to access or modify fields
class Student: def __init__(self, name): print("Created new student object.") self.name = name self.major = "CS" def getMajor(self): print("Fetching major from the database.") return self.major def setMajor(self, new_major): print("Changing major to", new_major) self.major = new_major austin = Student("Austin") bao = Student("Bao") print("We made a class!") mA = austin.getMajor() mB = bao.getMajor() print(mA) print(austin.name)
1.3 History Class
# Prisoner's dilemma history objects support CS 111 Lab 1 # Aaron Bauer, Carleton College # 2019, 2020, 2021 class History: """ A representation of the action history for a prisoner's dilemma actioner. The history contains a "c" for cooperation and a "d" for defection. """ def __init__(self): self.history = [] def get_length(self): """Returns the number of actions in the history""" return len(self.history) def get_most_recent(self): """Returns the most recent action (equivalent to `get_past_action(1)`)""" if len(self.history) == 0: raise RuntimeError("cannot get the most recent action from an empty history") return self.history[-1] def get_past_action(self, n): """Returns the action taken `n` rounds ago""" if len(self.history) < n: raise RuntimeError("No past action {} rounds ago for a history of length {}".format(n, len(self.history))) return self.history[-n] def get_num_defects(self): """Returns the number of defections in the history""" return self.history.count('d') def get_num_coops(self): """Returns the number of cooperations in the history""" return self.history.count('c') def has_recent_defect(self, n): """Returns `True` if there was a defection in the last `n` actions, otherwise returns `False`""" return 'd' in self.history[-n:] def has_recent_coop(self, n): """Returns `True` if there was a cooperation in the last `n` actions, otherwise returns `False`""" return 'c' in self.history[-n:] def add_action(self, action): """Adds `action` to the end of the history""" if action != 'c' and action != 'd': raise ValueError("action must be either 'c' or 'd', {} given".format(action)) self.history.append(action) def __iter__(self): return iter(self.history) def __repr__(self): return repr(self.history)
- the
History
objects from lab 1 were just a class I wrote to provide list operations - classes can provide an interface for an internal data representation
- note the documentation strings (doc strings) in triple quotes, format strings, and raised exceptions
- doc strings allow documentation web page to be automatically generated
- raising exceptions allows more informative error messages