Challenge 3: Value-Based Equality — Possible Solution ==================================================================== class Fraction: def __init__(self, numerator, denominator): self.numerator = numerator self.denominator = denominator def __str__(self): return f"{self.numerator}/{self.denominator}" def __eq__(self, other): return (self.numerator == other.numerator and self.denominator == other.denominator) a = Fraction(3, 4) b = Fraction(3, 4) print(a == b) Output: True WHY THIS WORKS AS AN ANSWER ------------------------------ Without __eq__, this chapter's warn-box explains that a == b would evaluate to False even though a and b hold identical numerator and denominator values — the default == compares object IDENTITY (are these literally the same object in memory?), and a and b are two separate Fraction objects that just happen to share the same data. __eq__(self, other) reuses the exact same dunder-method mechanism as __str__ from Challenge 2, but hooks into the == operator instead of print(). Defining it directly mirrors this chapter's own Point class example: self.numerator == other.numerator and self.denominator == other.denominator compares the actual VALUES stored in both objects, field by field, using the plain == and and operators already covered back in Course 1. Because __eq__ now explicitly defines "equal" as "same numerator AND same denominator," a == b correctly returns True — this is value-based equality, overriding Python's default identity-based behavior, exactly the distinction the chapter's warn-box called out.