Why does one `elif` branch handing back an int instead of a Fraction quietly break multiplication for the whole class?
Short drills on what this video just taught. Write the code, run the checks, and reveal the answer only if you are stuck.
The helper from the lecture is about to run on n = 84 and d = 36:
while d != 0: (d, n) = (n%d, d) return n
Work the loop through on paper. Assign to gcd_trace a list holding the pair (n, d) as it stands after each tuple assignment, in order — one tuple per pass of the loop, and nothing else in the list.
The nested gcd helper
Write gcd(n, d) with its while d != 0 tuple-swap loop inside reduce, note the absence of self from its parameter list, and record the guideline of keeping a helper in the scope that needs it.
The three branches and their return types
Write all three, None for a denominator of 0, self.num for 1, and a new Fraction from top and bottom divided by the divisor and cast to int, tracing 2/12 to 1/6.
The int-versus-Fraction inconsistency and its fix
Trace Fraction(4, 1).reduce() giving the int 4 and Fraction(3, 9).reduce() giving a Fraction, record the failure of ar * br, and rewrite the elif to return Fraction(self.num, 1).
Bundling data with behaviors
Close by writing down that a class packages the data making up an object together with the behaviors acting on it, carrying the decomposition and abstraction of functions into modular, reusable types.