When should a function raise its own ValueError, and when should an assert refuse to let the program continue at all?
Short drills on what this video just taught. Write the code, run the checks, and reveal the answer only if you are stuck.
Define pairwise_division(Lnum, Ldenom). Both arguments are non-empty lists of numbers of equal length. Return a new list holding each element of Lnum divided by the element sitting at the matching position of Ldenom. With [4, 5, 6] and [1, 2, 3] the result is [4.0, 2.5, 2.0].
A loop or a one-line comprehension are equally fine. (Hint: len() reports a list's length, range() counts up to it, and L.append(v) adds v to the end of a list.)
pairwise_division written two ways
Write the list comprehension [Lnum[i]/Ldenom[i] for i in range(len(Lnum))] and the equivalent loop that builds an empty list L with append, checking both on [4, 5, 6] over [1, 2, 3].
Indexing to walk two lists in step
State that range(len(Lnum)) supplies the index i, that Lnum[i] pairs with Ldenom[i] at the same position, and that i is an index rather than an element.
Two placements of the zero-denominator guard
Write the try/except version whose handler raises a ValueError naming the zero denominator, and the alternative if 0 in Ldenom: guard raising the same error before the loop.
assert condition, message as a contract
Write assert len(s) != 0 for sum_digits plus the two asserts requiring Lnum and Ldenom to be equal in length and non-empty, recording the AssertionError each run produces.