Skip to content

← Pattern Matching, f-Strings and Newer Syntax step 9 of 23

Medium Primitives

Turn Status Codes into Labels with match

A health-check log stores one status per check. Old checks wrote true or false, newer ones write an HTTP status code, and a few write a word such as "retry". Turn each status into a short label for a dashboard.

solve([True, 1, 200, 499, 500, "hello"])
# ["enabled", "one", "ok", "other", "server-error", "text:hello"]

This exercise uses literals, _, int(), str() and guards, and adds three rules.

Compare with a dotted name

A bare name such as OK in a case is a capture pattern. It matches any subject and stores it in OK, so it never compares the subject with your constant. To compare, write a dotted name such as Code.OK. Python looks up its value and checks the subject with ==.

A capture pattern with no guard matches everything, so it must be the last case. If any case comes after it, Python reports a SyntaxError when it compiles the file, and no line of the file runs:

OK = 200


def label(status: int) -> str:
    match status:
        case OK:  # SyntaxError: name capture 'OK' makes remaining patterns unreachable
            return "ok"
        case 404:
            return "missing"
    return "other"

When the capture pattern is the last case, there is no error. The code runs, and case OK: matches every status. Test with a status other than 200 to catch it.

IntEnum members equal plain integers

The log holds plain integers such as 200, not Code.OK. The pattern case Code.OK: still matches 200, because Code is an IntEnum, and an IntEnum member equals its integer value. With a plain Enum, Code.OK == 200 is False, and 200 would fall through to "other".

Put True and False before 1 and 0

bool is a subclass of int, and True == 1. Python compares most literal patterns with ==, so case 1: also matches True. True, False and None are the exception. Python compares them with is, so case True: matches only True. Put the True and False cases first, or True comes back as "one".

What to write

Fill in classify(status) with one match statement. Check the rows in this order. The first row that fits gives the result.

Status Result
True / False "enabled" / "disabled"
1 / 0 "one" / "zero"
Code.OK / Code.NOT_FOUND / Code.TEAPOT "ok" / "missing" / "teapot"
204 "no-content"
Any other integer of 500 or more "server-error"
"retry" "retry"
Any other string s f"text:{s}"
Anything else "other"

Then fill in solve(statuses). It returns the label for each status, in order, and leaves the input list unchanged. An empty list gives [].

Edge cases:

  • 499, 302 and negative numbers give "other".
  • The empty string gives "text:".