CS 111 f21 — Objects part 2

1 Practice

1.1 Mystery1

class A:
    def __init__(self, x):
        self.x = x

    def bump(self, i):
        self.x += i

class B:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def bounce(self, i):
        if i % 2 == 0:
            self.y += i
        self.x += i * 2

x = 7
a = A(x)
a.bump(2)
b = B(a.x, x)
b.bounce(1)
b.bounce(2)
print(x, a.x, b.x, b.y)

1.2 Rectangle Class2

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
  • define a Rectangle class with three instance variables: a Point for the upper left corner, a width, and a height
  • add a get_corners method to the class that returns a list of the rectangle's four corners

1.3 Fraction Class

What's missing from the definition?3

class Fraction:
    def value():
        return top / bottom

2 Customizing a class

Are we able to treat these objects as if they were real fractions?

  • Fraction(3, 4) == Fraction(3, 4)
    • Returns False because the it's checking if they are literally the same object in memory
    • Solution: implement an __eq__ method
  • Fraction(1, 2) < Fraction(3, 4)
    • Causes a TypeError
    • Solution: implement a __gt__ method
  • Fraction(1, 2) + Fraction(3, 4)
    • Causes a TypeError
    • Solution: implement an __add__ method
class Fraction:
  def __init__(self, top, bottom):
      self.top = top
      self.bottom = bottom

  def value(self):
      return self.top / self.bottom

  def __eq__(self, other):
    return self.value() == other.value()

  def __gt__(self, other):
    return self.value() > other.value()

  def __add__(self, other):
    return Fraction(self.top * other.bottom + other.top * self.bottom, self.bottom * other.bottom)

See https://docs.python.org/3.9/reference/datamodel.html for details on all the possible special methods like __eq__ that Python supports

3 Cuckoo Class

class Cuckoo:
    def __init__(self, steps):
        self.steps = steps
        self.count = 0

    def tick(self):
        self.count += 1
        if self.count == self.steps:
            print("CUKCOO!!")
            self.count = 0
        else:
            print("tick...")

    # more concise version using %
    def tick(self):
        self.count += 1
        if self.count % self.steps == 0:
            print("CUKCOO!!")
        else:
            print("tick...")

Footnotes:

1

7 9 15 9

2
class Rectangle:
  def __init__(self, position, width, height):
    self.position = position
    self.width = width
    self.height = height

  def get_corners(self):
    corners = [self.position]
    corners.append(Point(self.position.x + width, self.position.y))
    corners.append(Point(self.position.x + width, self.position.y + height))
    corners.append(Point(self.position.x, self.position.y + height))
    return corners
3
# need to include a constructor
# need to use self to access instance variables
class Fraction:
  def __init__(self, top, bottom):
      self.top = top
      self.bottom = bottom

  def value(self):
      return self.top / self.bottom