Python Arena
Step 4 of 4

Comparing two objects of the same class

Often you want to compare two objects of the same kind: is this parcel heavier than that one? Is this runner faster? You could write a function that takes both objects:

def heavier(first, second):
    return first.weight > second.weight

In object-oriented programming, though, the code that works on parcels belongs in the Parcel class, as a method. A method can take another object of its own class as a parameter. Then one parcel is self, the one the method is called on, and the other is the parameter, often called other:

class Parcel:
    def __init__(self, label, weight):
        self.label = label
        self.weight = weight

    def heavier_than(self, other):
        return self.weight > other.weight


books = Parcel("books", 12)
pillow = Parcel("pillow", 2)

if books.heavier_than(pillow):
    print(f"The {books.label} parcel is heavier than the {pillow.label} parcel")
print(pillow.heavier_than(books))
Output
The books parcel is heavier than the pillow parcel
False

In books.heavier_than(pillow), the object to the left of the dot (books) is self inside the method, and the object in the parentheses (pillow) is other. Swap them and you ask the opposite question.

The method returns the comparison itself. self.weight > other.weight is already True or False, so there's no need for an if that returns True in one branch and False in the other.

If you write type hints, the hint for other is the class's own name: def heavier_than(self, other: "Parcel"):. Many programs put it in quotes, because older versions of Python read the hint before the class was finished and didn't know the name yet. Python 3.14, which runs your code on this site, accepts it with or without the quotes.

Helper variables: self or no self?

Sometimes a method needs a few values only while it works. As you have seen with helper methods, those are local variables, written without self.:

class Order:
    def __init__(self, item, unit_price, quantity):
        self.item = item
        self.unit_price = unit_price
        self.quantity = quantity

    def costs_more_than(self, other):
        my_total = self.unit_price * self.quantity
        other_total = other.unit_price * other.quantity
        return my_total > other_total


pens = Order("pens", 2, 30)
paper = Order("paper", 7, 5)
print(pens.costs_more_than(paper))
print(paper.costs_more_than(pens))
Output
True
False

my_total and other_total disappear when the method ends, which is what you want. Writing self.my_total = ... would work too, but it would quietly add a new attribute to the object that stays there after the method is done. Other methods could then use it by accident, and some objects would have the attribute while others wouldn't, depending on which methods happened to run. Keep the rule simple: an attribute (self.) is something the object has to remember; a helper variable is scratch paper for one method.

Your task

Challenge 1 of 3

A runner is faster than another runner when their time in seconds is smaller. Fill in the blanks in faster_than so the program prints:

False
True

Challenge 2

Write the method larger(self, other) in the class Rectangle. It compares the areas (width times height) of the two rectangles and returns the one with the larger area: the object itself. When the areas are equal, it returns self.

For example, this code:

tile = Rectangle(3, 4)
door = Rectangle(2, 7)
print(tile.larger(door))
print(door.larger(tile))

prints:

2 x 7
2 x 7

Challenge 3

A program's version number has three parts, such as 2.10.3: major, minor and patch. One version is newer than another when its major number is bigger. If the major numbers are the same, the minor numbers decide, and if those are the same too, the patch numbers decide.

Write the method newer_than(self, other) in the class Version. It returns True when self is newer than other, and False otherwise (also when they are the same version).

For example, this code:

old = Version(2, 9, 7)
new = Version(2, 10, 0)
print(new.newer_than(old))
print(old.newer_than(new))

prints:

True
False