← Home

042. Else Statement

Handle the default case explicitly

042. Else Statement

RAM Manager: Process Status

Aryan’s RAM manager needs to respond to process status checks. When a process is alive and consuming RAM, report it. When it’s gone, report that too.

The silent None return bug is one of the most common Python mistakes:

def check_process(pid, processes):
    if pid in processes:
        return f"PID {pid}: {processes[pid]}MB"
    # ← if pid is NOT in processes, returns None silently
    # caller does: status = check_process(999, procs)
    # then: print(status)  →  "None"  (confusing!)

Aryan’s dispense function has this exact bug — it returns None when the item is out of stock instead of the error message. The tests catch the missing else.


💡 Fun fact: Implicit None returns are one of the most common sources of AttributeError: 'NoneType' object has no attribute '...' errors in Python. This error is so frequent that a popular saying in the Python community is: “Explicit is better than implicit” — the very first line of The Zen of Python (import this), written by Tim Peters in 1999.

⚠️ Watch out: A function missing an else branch doesn’t raise an error — it silently returns None. Your code will appear to work until something tries to use the return value, at which point you get a confusing TypeError or AttributeError far from the actual bug. Always ask: “What does this function return when the if condition is False?”

🤔 Think about it: Every if without an else has an implicit “do nothing and return None” branch. Is there ever a situation where returning None from a function is the correct, intentional design — and how would you communicate to callers that None is a valid return value rather than a bug?

Learning objectives

  • Add else to handle the default/fallback case
  • Avoid implicit None returns from missing else branches
  • Use else to make all code paths explicit

Key concepts

  • else
  • default case
  • explicit branching

Try it

Concept detail

Python functions that don’t explicitly return a value return None. This is legal but dangerous — callers may not check for None.

Without else: def dispense(item, stock): if item in stock: return “Dispensing “ + item # falls off the end → returns None implicitly

With else: def dispense(item, stock): if item in stock: return “Dispensing “ + item else: return “Out of stock” # explicit, can’t be accidentally None

Every if/elif chain should ask: “what happens when NONE of my conditions are True?”

  • If None is acceptable, document it with a comment
  • If it’s a bug, add an else with an explicit return or raise an exception

else on loops (unusual but valid): for item in items: if found_it(item): break else: # runs only if loop completed WITHOUT hitting break print(“not found”)

This for/else pattern is rare but useful for search loops.

Solution

def dispense(item, stock):
    if item in stock and stock[item] > 0:
        stock[item] -= 1
        return "Dispensing " + item
    else:
        return "Sorry, " + item + " is out of stock"

def max_of_two(a, b):
    if a >= b:
        return a
    else:
        return b

Tests

def test_dispense_available():
    stock = {"cola": 3, "water": 1}
    assert dispense("cola", stock) == "Dispensing cola"

def test_dispense_reduces_stock():
    stock = {"cola": 3}
    dispense("cola", stock)
    assert stock["cola"] == 2

def test_dispense_out_of_stock():
    stock = {"cola": 0}
    result = dispense("cola", stock)
    assert result == "Sorry, cola is out of stock", f"Got {repr(result)} — missing else branch returns None"

def test_dispense_not_in_stock():
    stock = {"cola": 3}
    result = dispense("juice", stock)
    assert result == "Sorry, juice is out of stock", f"Got {repr(result)} — missing else branch returns None"

def test_dispense_none_check():
    stock = {"cola": 0}
    result = dispense("cola", stock)
    assert result is not None, "Function returned None — add an else branch"

def test_max_of_two():
    assert max_of_two(5, 3) == 5
    assert max_of_two(3, 5) == 5
    assert max_of_two(5, 5) == 5

Resources