Exercise: Return From Every Branch
Bartosz Zaczyński RP Team on July 5, 2026
@alexanderwu You’re pointing at a real principle, so let me separate two things that are getting mixed together.
The “Uses no redundant comparison” bonus is about control flow, not input validation. All it checks is whether you test number == 0 explicitly after you’ve already checked number < 0 and number > 0. Once those two branches don’t fire, zero is the only value left, so a plain return "zero" at the end covers it. The redundancy it flags is that third comparison, which can never change the outcome. That is a separate concern from what happens when someone passes a bad type.
And the two ideas don’t actually conflict. If you want to guard against a non-number, you can, and you’ll still pass the bonus, because a type guard is a function call, not a comparison:
def sign(number):
if not isinstance(number, (int, float)):
raise TypeError("number must be numeric")
if number < 0:
return "negative"
if number > 0:
return "positive"
return "zero"
That still has only the two comparisons (< 0 and > 0), so the bonus is satisfied.
Whether you should add that guard is the more interesting question, and Python usually leans the other way. isinstance(number, (int, float)) is actually stricter than the function needs, because it rejects perfectly good numbers:
>>> from decimal import Decimal
>>> isinstance(Decimal("-4"), (int, float))
False
>>> Decimal("-4") < 0
True
Even deciding what to screen for is fiddly. numbers.Number accepts both Decimal and Fraction, but numbers.Real rejects Decimal (it is deliberately not registered as a real number), so a well-meant type guard can quietly turn away valid input. The common Pythonic approach is to skip the pre-screen, let the comparison do its job, and let a TypeError surface naturally if someone passes something that genuinely can’t be ordered. That is the EAFP style (easier to ask forgiveness than permission), and there is a good write-up here: LBYL vs EAFP: Preventing or Handling Errors in Python.
For this exercise, the input is defined as a number in the problem statement, so validation is left out on purpose to keep the focus on the one idea being drilled: every branch returns a value and nothing falls off the end as None. In real code, how much you validate and trust your inputs is a judgment call, and thinking about it the way you are is the right instinct.
Become a Member to join the conversation.

awu on July 4, 2026
The “uses no redundant comparison” reasoning is flawed because it does not use defensive programming. What if
numberwasn’t a number?