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) -> booland 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
len(self.flowers) == len(other.flowers)andlen(self.flowers) < len(other.flowers)len(self.flowers) == len(other.flowers)andlen(self.flowers) > len(other.flowers)len(self.flowers) != len(other.flowers)andlen(self.flowers) < len(other.flowers)len(self.flowers) != len(other.flowers)andlen(self.flowers) > len(other.flowers)
Poll: What does the comparison protocol do in Python?
- It lets us define the "length" of an object (the number returned by
len()) - It lets us iterate over the sub-parts of an object (using a
forloop) - It lets us define what it means for an object to be "bigger" or "smaller" than another object
- It lets us map each object to an int that is used as an index in a hash table