How do `a * b`, `a.__mul__(b)` and `Fraction.__mul__(a, b)` all run the same code, and why is only the last handed `self` by hand?
Short drills on what this video just taught. Write the code, run the checks, and reveal the answer only if you are stuck.
The Fraction class below can build itself and print itself, but a * b currently fails — nothing in the class says what a star between two fractions should mean.
Add __mul__, the method Python runs behind the * shorthand, so that multiplying two fractions multiplies the numerators, multiplies the denominators, and hands back a new Fraction object rather than a float. Then multiply a, which is 2/5, by b, which is 3/7, and assign the result to product.
__mul__ in place of the old times
Write the body returning Fraction(top, bottom), record that the value before the * maps to self and the value after it to other, and trace Fraction(1, 4) * Fraction(3, 4) printing 3/16.
Three equivalent ways to write one call
Put a * b, a.__mul__(b) and Fraction.__mul__(a, b) side by side, record that the third form passes the full parameter list including the object for self, and mark the shorthand as the Pythonic one.
Casting with __float__, and unreduced results
Write return self.num/self.denom, trace float(c) giving 0.1875 for the fraction 3/16, then trace Fraction(1, 4) * Fraction(2, 3) printing 2/12.