Skip to main content
Version: Next

Comparison and Scraping

Motivating question:

Which string is bigger: "abacus" or "cat"

Which object is bigger: a balloon, or ten nickels?

Comparison

There is a protocol in Python for comparing objects using <, >, ==, !=, <=, and >=. In order to use these comparison operators, we can implement these six methods:

  • __eq__(self, other: object) -> bool: equals ==
  • __ne__(self, other: object) -> bool: not equals !=
  • __lt__(self, other: object) -> bool: less than <
  • __le__(self, other: object) -> bool: less than or equal to <=
  • __gt__(self, other: object) -> bool: greater than >
  • __ge__(self, other: object) -> bool: greater than or equal to >= Not all six methods need to be implemented, since Python can derive some from others. Usually, it suffices to only implement __eq__(self, other: object) -> bool and one ordering method like __lt__(self, other: object) -> bool.

There is not a corresponding interface in the abc module for Comparable, likely because we rarely implement all six methods.

Exercise: Let's write a class for a Plant. Plant are bigger if they get more sunlight.

class Plant:
def __init__(self) -> None:
self.sunlight_hours = 0

def get_sunlight(self) -> None:
self.sunlight_hours += 1

def __eq__(self, other: object) -> bool:
if not isinstance(other, Plant):
return False
return self.sunlight_hours == other.sunlight_hours

def __lt__(self, other: object) -> bool:
if not isinstance(other, Plant):
return NotImplemented
return self.sunlight_hours < other.sunlight_hours

plant1 = Plant()
plant2 = Plant()

plant1.get_sunlight()
True

Poll: What goes in the ??? ?

class Bouquet:
"""Bouquets are compared by the number of flowers in them"""
def __init__(self, flowers: list[Flower]):
self.flowers = flowers

def __eq__(self, other: object) -> bool:
if isinstance(other, Bouquet):
return ???
else:
return False

def __gt__(self, other: object) -> bool:
if isinstance(other, Bouquet):
return ???
else:
return NotImplemented
  1. len(self.flowers) == len(other.flowers) and len(self.flowers) < len(other.flowers)
  2. len(self.flowers) == len(other.flowers) and len(self.flowers) > len(other.flowers)
  3. len(self.flowers) != len(other.flowers) and len(self.flowers) < len(other.flowers)
  4. len(self.flowers) != len(other.flowers) and len(self.flowers) > len(other.flowers)

Poll: What does the comparison protocol do in Python?

  1. It lets us define the "length" of an object (the number returned by len())
  2. It lets us iterate over the sub-parts of an object (using a for loop)
  3. It lets us define what it means for an object to be "bigger" or "smaller" than another object
  4. It lets us map each object to an int that is used as an index in a hash table