Designing Branching Functions

Introduction: Decisions Inside a Function

Welcome to Writing Complex Python Functions, the fourth course in this path and its opening unit. Up to now, our functions have followed a single, straight path: take some inputs, compute one result, and return it. Real functions rarely behave that way. They usually need to choose what to return based on the data they receive.

Our running example for this lesson is classify_score(score), a function that turns a numeric score into a letter grade. By the end, running our program will print exactly this:

A
B
F
invalid

Four calls, four different answers, and one function. Three ideas get us there: one return per branch, correct branch ordering, and guard clauses that reject bad input before anything else runs.

One `return` Per Branch

Let's start with the grading logic itself, without any input checking yet. Inside a function body, an if / elif chain lets each branch end in its own return statement.

def classify_score(score):
    if score >= 90:
        return "A"
    elif score >= 80:
        return "B"
    elif score >= 70:
        return "C"

As we may recall from the previous course, return immediately ends the function; nothing after it in that call ever runs. That behavior is what makes this pattern work. Let's trace classify_score(95):

  • Python evaluates 95 >= 90, which is True.
  • It runs return "A", and the function ends right there.
  • The elif score >= 80 and elif score >= 70 conditions are never evaluated at all.

So each branch is a separate, self-contained answer. Only one of them can ever produce the result for a given call.

The Fallback `return` at the End of the Body

The version above has a hole in it. What does classify_score(41) return? No condition matches, so execution reaches the end of the body without ever hitting a return, and the call quietly produces None: a bug we learned to spot in the previous course. Let's close that hole.

    if score >= 90:
        return "A"
    elif score >= 80:
        return "B"
    elif score >= 70:
        return "C"
    return "F"                  # reached only when no branch above matched

Notice that return "F" sits at the same indentation level as the if, not attached to an else. It is plain code at the end of the function body, so it runs only when every branch above fails to match and therefore does not return. Reading it this way is natural: it is the "everything else" answer. Writing else: return "F" would behave identically here, so the choice is purely about readability. Either way, every path through the function now ends in a return.

Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal