Control Flow

Guard Clauses

Guard clauses handle boundary cases early so the main path stays flat.

The nested version is correct, but the useful work is buried inside both tests.

Source

def nested_discount(price, percent):
    if price >= 0:
        if 0 <= percent <= 100:
            return round(price - price * percent / 100, 2)
        return "invalid discount"
    return "invalid price"

print(nested_discount(100, 15))

Output

85.0
if not valid: returnif missing: return Noneif special_case: return Xmain work …exit
Early returns handle the exceptional cases first so the main work is the body of the function, not its tail.

The guard-clause version handles impossible inputs first, then lets the ordinary calculation sit at the top level of the function body.

Source

def guarded_discount(price, percent):
    if price < 0:
        return "invalid price"
    if not 0 <= percent <= 100:
        return "invalid discount"

    return round(price - price * percent / 100, 2)

print(guarded_discount(-5, 10))
print(guarded_discount(100, 120))

Output

invalid price
invalid discount

Notes

See also

Run the complete example

Example code

Expected output

85.0
invalid price
invalid discount

Execution time appears here after you run the example.