Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
Clean Code Principles  ›  Capstone Project

Avoid Passing Nulls and Booleans

Avoid passing nulls, booleans 14 minFlag arguments hide two functions inside one and null arguments hide a missing case, so both are better replaced by separate functions, named options or real objects.

Avoid Passing Nulls and Booleans

In a Shelfwise pull request you find print_invoice(order, True, None). What does True do? What happens because of None? You cannot tell without opening the function, and neither can the next reader. A call should explain itself, and bare flags and nulls make that impossible.

The rule

A flag argument hides two functions; a null argument hides a missing case.

Boolean flags. A function that takes True or False to switch its behaviour is really two functions sharing one name:

def print_invoice(order, duplicate):
    if duplicate:
        ...  # stamp "COPY", skip the payment QR code
    else:
        ...  # normal invoice

Every caller must remember what the boolean means, and the body carries both behaviours. Better options:

  • Split it: print_invoice(order) and print_duplicate_invoice(order).
  • Name it at the call, when the flag really is a small option: print_invoice(order, duplicate=True). Python's keyword-only parameters (declared after a *) can enforce this.

Nulls. Passing None to mean "use the default" or "not applicable" forces the function to check for it, and returning None for "not found" forces every caller to check too. Forget once, and the program crashes somewhere far from the real cause with a message like 'NoneType' object has no attribute 'email'. Better options:

  • Make the argument required and pass the real value.
  • Give it a sensible default in the signature.
  • For "not found", raise a clear exception, or offer a separate question such as customer_exists(email).

When None really is a normal answer, at least make it visible. A type hint such as def find_customer(email) -> Customer | None tells every reader, and tools like type checkers, that a check is required before use.

The shortcut

Cover the function definition and read only the call. If you cannot say what each argument does, the signature needs fixing.

Fixing print_invoice(order, True, None)Step 1 of 4
  1. Read the call alone

    True and None carry no meaning on their own. The call fails the test.

The trap is adding "just one more" flag. send_email(customer, True, False, True) is what one harmless flag grows into.

Drills

Answer fast — trust the rule.

quick drill

What is the main problem with send_email(customer, True, False)?

quick drill

find_customer(email) returns None when nobody matches. What is the main risk?

quick drill

Which call is the clearest?

quick drill

ship(order, express) runs two unrelated code paths chosen by express. What is the best fix?

Remember

  • A flag hides two functions; a null hides a missing case.
  • Cover the definition and read the call; if an argument means nothing, fix the signature.
  • Trap: "just one more" flag, until calls look like True, False, True.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainAn honest invoice function

Shelfwise has print_invoice(order, True, None), where the boolean means 'print as a duplicate copy' and None means 'use the customer's default address'. Explain what is wrong with this call and redesign the function so every call site reads clearly.