Your app has a menu: 1=New, 2=Open, 3=Save, 4=Quit. Python 3.10's match statement lets you handle each option cleanly. But it goes beyond simple values - you can match and destructure tuples, lists, even objects.

Day number to name

Convert a number (1-7) to the day name.

day
day_name.py
Replay: real traced execution (multi-file project)
day = 3

match day:
    case 1:
        name = "Monday"
    case 2:
        name = "Tuesday"
    case 3:
        name = "Wednesday"
    case 4:
        name = "Thursday"
    case 5:
        name = "Friday"
    case 6:
        name = "Saturday"
    case 7:
        name = "Sunday"
    case _:
        name = "Invalid day"

print(f"Day {day} is {name}")

day = 1

match day:
    case 1:
        name = "Monday"
    case 2:
        name = "Tuesday"
    case 3:
        name = "Wednesday"
    case 4:
        name = "Thursday"
    case 5:
        name = "Friday"
    case 6:
        name = "Saturday"
    case 7:
        name = "Sunday"
    case _:
        name = "Invalid day"

print(f"Day {day} is {name}")

day = 5

match day:
    case 1:
        name = "Monday"
    case 2:
        name = "Tuesday"
    case 3:
        name = "Wednesday"
    case 4:
        name = "Thursday"
    case 5:
        name = "Friday"
    case 6:
        name = "Saturday"
    case 7:
        name = "Sunday"
    case _:
        name = "Invalid day"

print(f"Day {day} is {name}")

day = 7

match day:
    case 1:
        name = "Monday"
    case 2:
        name = "Tuesday"
    case 3:
        name = "Wednesday"
    case 4:
        name = "Thursday"
    case 5:
        name = "Friday"
    case 6:
        name = "Saturday"
    case 7:
        name = "Sunday"
    case _:
        name = "Invalid day"

print(f"Day {day} is {name}")

  1. day ← 3

    1day→ 3 = 3  #@day=1, 5, 7
  2. match day:

    3match day3:4    case 1:5        name = "Monday"
  3. name ← Wednesday

    7    name = "Tuesday"8case 3:9    name→ Wednesday = "Wednesday"10case 4:
  4. print(f"Day {day} is {name}")

    21print(f"Day {day3} is {nameWednesday}")
    outputDay 3 is Wednesday
  1. day ← 1

    1day→ 1 = 1
  2. match day:

    3match day1:4    case 1:5        name = "Monday"
  3. name ← Monday

    3match day:4    case 1:5        name→ Monday = "Monday"6    case 2:
  4. print(f"Day {day} is {name}")

    21print(f"Day {day1} is {nameMonday}")
    outputDay 1 is Monday
  1. day ← 5

    1day→ 5 = 5
  2. match day:

    3match day5:4    case 1:5        name = "Monday"
  3. name ← Friday

    11    name = "Thursday"12case 5:13    name→ Friday = "Friday"14case 6:
  4. print(f"Day {day} is {name}")

    21print(f"Day {day5} is {nameFriday}")
    outputDay 5 is Friday
  1. day ← 7

    1day→ 7 = 7
  2. match day:

    3match day7:4    case 1:5        name = "Monday"
  3. name ← Sunday

    15    name = "Saturday"16case 7:17    name→ Sunday = "Sunday"18case _:
  4. print(f"Day {day} is {name}")

    21print(f"Day {day7} is {nameSunday}")
    outputDay 7 is Sunday

Each case pattern is checked in order. _ is the wildcard (matches anything).

match Structural pattern matching (Python 3.10+). More powerful than switch.
case A pattern to match: `case 1:`, `case "yes":`, `case (x, y):`
_ Wildcard pattern - matches anything. Like `default` in switch.

Menu option handler

Handle user menu selections with match.

choice
menu.py
Replay: real traced execution (multi-file project)
choice = 2

print("=== Main Menu ===")
print("1. New Game")
print("2. Load Game")
print("3. Settings")
print("4. Exit")
print(f"Choice: {choice}")
print()

match choice:
    case 1:
        print("Starting new game...")
    case 2:
        print("Loading saved game...")
    case 3:
        print("Opening settings...")
    case 4:
        print("Goodbye!")
    case _:
        print("Invalid option. Please try again.")
choice = 1

print("=== Main Menu ===")
print("1. New Game")
print("2. Load Game")
print("3. Settings")
print("4. Exit")
print(f"Choice: {choice}")
print()

match choice:
    case 1:
        print("Starting new game...")
    case 2:
        print("Loading saved game...")
    case 3:
        print("Opening settings...")
    case 4:
        print("Goodbye!")
    case _:
        print("Invalid option. Please try again.")
choice = 3

print("=== Main Menu ===")
print("1. New Game")
print("2. Load Game")
print("3. Settings")
print("4. Exit")
print(f"Choice: {choice}")
print()

match choice:
    case 1:
        print("Starting new game...")
    case 2:
        print("Loading saved game...")
    case 3:
        print("Opening settings...")
    case 4:
        print("Goodbye!")
    case _:
        print("Invalid option. Please try again.")
choice = 4

print("=== Main Menu ===")
print("1. New Game")
print("2. Load Game")
print("3. Settings")
print("4. Exit")
print(f"Choice: {choice}")
print()

match choice:
    case 1:
        print("Starting new game...")
    case 2:
        print("Loading saved game...")
    case 3:
        print("Opening settings...")
    case 4:
        print("Goodbye!")
    case _:
        print("Invalid option. Please try again.")
choice = 9

print("=== Main Menu ===")
print("1. New Game")
print("2. Load Game")
print("3. Settings")
print("4. Exit")
print(f"Choice: {choice}")
print()

match choice:
    case 1:
        print("Starting new game...")
    case 2:
        print("Loading saved game...")
    case 3:
        print("Opening settings...")
    case 4:
        print("Goodbye!")
    case _:
        print("Invalid option. Please try again.")
  1. choice ← 2

    1choice→ 2 = 2  #@choice=1, 3, 4, 923print("=== Main Menu ===")4print("1. New Game")5print("2. Load Game")6print("3. Settings")7print("4. Exit")8print(f"Choice: {choice2}")9print()
    output=== Main Menu ===
    1. New Game
    2. Load Game
    3. Settings
    4. Exit
    Choice: 2
  2. match choice:

    11match choice2:12    case 1:13        print("Starting new game...")
  3. case 2:

    13    print("Starting new game...")14case 2:15    print("Loading saved game...")16case 3:
    outputLoading saved game...
  1. choice ← 1

    1choice→ 1 = 123print("=== Main Menu ===")4print("1. New Game")5print("2. Load Game")6print("3. Settings")7print("4. Exit")8print(f"Choice: {choice1}")9print()
    output=== Main Menu ===
    1. New Game
    2. Load Game
    3. Settings
    4. Exit
    Choice: 1
  2. match choice:

    11match choice1:12    case 1:13        print("Starting new game...")
  3. case 1:

    11match choice:12    case 1:13        print("Starting new game...")14    case 2:
    outputStarting new game...
  1. choice ← 3

    1choice→ 3 = 323print("=== Main Menu ===")4print("1. New Game")5print("2. Load Game")6print("3. Settings")7print("4. Exit")8print(f"Choice: {choice3}")9print()
    output=== Main Menu ===
    1. New Game
    2. Load Game
    3. Settings
    4. Exit
    Choice: 3
  2. match choice:

    11match choice3:12    case 1:13        print("Starting new game...")
  3. case 3:

    15    print("Loading saved game...")16case 3:17    print("Opening settings...")18case 4:
    outputOpening settings...
  1. choice ← 4

    1choice→ 4 = 423print("=== Main Menu ===")4print("1. New Game")5print("2. Load Game")6print("3. Settings")7print("4. Exit")8print(f"Choice: {choice4}")9print()
    output=== Main Menu ===
    1. New Game
    2. Load Game
    3. Settings
    4. Exit
    Choice: 4
  2. match choice:

    11match choice4:12    case 1:13        print("Starting new game...")
  3. case 4:

    17    print("Opening settings...")18case 4:19    print("Goodbye!")20case _:
    outputGoodbye!
  1. choice ← 9

    1choice→ 9 = 923print("=== Main Menu ===")4print("1. New Game")5print("2. Load Game")6print("3. Settings")7print("4. Exit")8print(f"Choice: {choice9}")9print()
    output=== Main Menu ===
    1. New Game
    2. Load Game
    3. Settings
    4. Exit
    Choice: 9
  2. match choice:

    11match choice9:12    case 1:13        print("Starting new game...")
  3. case _:

    19    print("Goodbye!")20case _:21    print("Invalid option. Please try again.")
    outputInvalid option. Please try again.

Match is perfect for menu systems - cleaner than if-elif chains.

Grade to description

Convert letter grades to descriptions.

example
grade.py
Replay: real traced execution (multi-file project)
grade = 'B'

match grade:
    case 'A':
        description = "Excellent work!"
    case 'B':
        description = "Good job!"
    case 'C':
        description = "Satisfactory"
    case 'D':
        description = "Needs improvement"
    case 'F':
        description = "Please see instructor"
    case _:
        description = "Invalid grade"

print(f"Grade: {grade}")
print(f"Feedback: {description}")

# Using or-pattern for grouped cases
month = 4

match month:
    case 12 | 1 | 2:
        season = "Winter"
    case 3 | 4 | 5:
        season = "Spring"
    case 6 | 7 | 8:
        season = "Summer"
    case 9 | 10 | 11:
        season = "Autumn"
    case _:
        season = "Invalid month"

print(f"Month {month} is in {season}")

grade = 'A'

match grade:
    case 'A':
        description = "Excellent work!"
    case 'B':
        description = "Good job!"
    case 'C':
        description = "Satisfactory"
    case 'D':
        description = "Needs improvement"
    case 'F':
        description = "Please see instructor"
    case _:
        description = "Invalid grade"

print(f"Grade: {grade}")
print(f"Feedback: {description}")

# Using or-pattern for grouped cases
month = 4

match month:
    case 12 | 1 | 2:
        season = "Winter"
    case 3 | 4 | 5:
        season = "Spring"
    case 6 | 7 | 8:
        season = "Summer"
    case 9 | 10 | 11:
        season = "Autumn"
    case _:
        season = "Invalid month"

print(f"Month {month} is in {season}")

grade = 'C'

match grade:
    case 'A':
        description = "Excellent work!"
    case 'B':
        description = "Good job!"
    case 'C':
        description = "Satisfactory"
    case 'D':
        description = "Needs improvement"
    case 'F':
        description = "Please see instructor"
    case _:
        description = "Invalid grade"

print(f"Grade: {grade}")
print(f"Feedback: {description}")

# Using or-pattern for grouped cases
month = 4

match month:
    case 12 | 1 | 2:
        season = "Winter"
    case 3 | 4 | 5:
        season = "Spring"
    case 6 | 7 | 8:
        season = "Summer"
    case 9 | 10 | 11:
        season = "Autumn"
    case _:
        season = "Invalid month"

print(f"Month {month} is in {season}")

grade = 'F'

match grade:
    case 'A':
        description = "Excellent work!"
    case 'B':
        description = "Good job!"
    case 'C':
        description = "Satisfactory"
    case 'D':
        description = "Needs improvement"
    case 'F':
        description = "Please see instructor"
    case _:
        description = "Invalid grade"

print(f"Grade: {grade}")
print(f"Feedback: {description}")

# Using or-pattern for grouped cases
month = 4

match month:
    case 12 | 1 | 2:
        season = "Winter"
    case 3 | 4 | 5:
        season = "Spring"
    case 6 | 7 | 8:
        season = "Summer"
    case 9 | 10 | 11:
        season = "Autumn"
    case _:
        season = "Invalid month"

print(f"Month {month} is in {season}")

grade = 'X'

match grade:
    case 'A':
        description = "Excellent work!"
    case 'B':
        description = "Good job!"
    case 'C':
        description = "Satisfactory"
    case 'D':
        description = "Needs improvement"
    case 'F':
        description = "Please see instructor"
    case _:
        description = "Invalid grade"

print(f"Grade: {grade}")
print(f"Feedback: {description}")

# Using or-pattern for grouped cases
month = 4

match month:
    case 12 | 1 | 2:
        season = "Winter"
    case 3 | 4 | 5:
        season = "Spring"
    case 6 | 7 | 8:
        season = "Summer"
    case 9 | 10 | 11:
        season = "Autumn"
    case _:
        season = "Invalid month"

print(f"Month {month} is in {season}")

grade = 'B'

match grade:
    case 'A':
        description = "Excellent work!"
    case 'B':
        description = "Good job!"
    case 'C':
        description = "Satisfactory"
    case 'D':
        description = "Needs improvement"
    case 'F':
        description = "Please see instructor"
    case _:
        description = "Invalid grade"

print(f"Grade: {grade}")
print(f"Feedback: {description}")

# Using or-pattern for grouped cases
month = 1

match month:
    case 12 | 1 | 2:
        season = "Winter"
    case 3 | 4 | 5:
        season = "Spring"
    case 6 | 7 | 8:
        season = "Summer"
    case 9 | 10 | 11:
        season = "Autumn"
    case _:
        season = "Invalid month"

print(f"Month {month} is in {season}")

grade = 'B'

match grade:
    case 'A':
        description = "Excellent work!"
    case 'B':
        description = "Good job!"
    case 'C':
        description = "Satisfactory"
    case 'D':
        description = "Needs improvement"
    case 'F':
        description = "Please see instructor"
    case _:
        description = "Invalid grade"

print(f"Grade: {grade}")
print(f"Feedback: {description}")

# Using or-pattern for grouped cases
month = 7

match month:
    case 12 | 1 | 2:
        season = "Winter"
    case 3 | 4 | 5:
        season = "Spring"
    case 6 | 7 | 8:
        season = "Summer"
    case 9 | 10 | 11:
        season = "Autumn"
    case _:
        season = "Invalid month"

print(f"Month {month} is in {season}")

grade = 'B'

match grade:
    case 'A':
        description = "Excellent work!"
    case 'B':
        description = "Good job!"
    case 'C':
        description = "Satisfactory"
    case 'D':
        description = "Needs improvement"
    case 'F':
        description = "Please see instructor"
    case _:
        description = "Invalid grade"

print(f"Grade: {grade}")
print(f"Feedback: {description}")

# Using or-pattern for grouped cases
month = 11

match month:
    case 12 | 1 | 2:
        season = "Winter"
    case 3 | 4 | 5:
        season = "Spring"
    case 6 | 7 | 8:
        season = "Summer"
    case 9 | 10 | 11:
        season = "Autumn"
    case _:
        season = "Invalid month"

print(f"Month {month} is in {season}")

  1. grade ← B

    1grade→ B = 'B'  #@grade='A', 'C', 'F', 'X'
  2. match grade:

    3match gradeB:4    case 'A':5        description = "Excellent work!"
  3. description ← Good job!

    5    description = "Excellent work!"6case 'B':7    description→ Good job! = "Good job!"8case 'C':
  4. month ← 4

    17print(f"Grade: {gradeB}")18print(f"Feedback: {descriptionGood job!}")1920# Using or-pattern for grouped cases21month→ 4 = 4  #@month=1, 7, 11
    outputGrade: B
    Feedback: Good job!
  5. match month:

    23match month4:24    case 12 | 1 | 2:  #?or_pattern25        season = "Winter"
  6. season ← Spring

    25    season = "Winter"26case 3 | 4 | 5:27    season→ Spring = "Spring"28case 6 | 7 | 8:
  7. print(f"Month {month} is in {season}")

    35print(f"Month {month4} is in {seasonSpring}")
    outputMonth 4 is in Spring
  1. grade ← A

    1grade→ A = 'A'
  2. match grade:

    3match gradeA:4    case 'A':5        description = "Excellent work!"
  3. description ← Excellent work!

    3match grade:4    case 'A':5        description→ Excellent work! = "Excellent work!"6    case 'B':
  4. month ← 4

    17print(f"Grade: {gradeA}")18print(f"Feedback: {descriptionExcellent work!}")1920# Using or-pattern for grouped cases21month→ 4 = 4
    outputGrade: A
    Feedback: Excellent work!
  5. match month:

    23match month4:24    case 12 | 1 | 2:25        season = "Winter"
  6. season ← Spring

    25    season = "Winter"26case 3 | 4 | 5:27    season→ Spring = "Spring"28case 6 | 7 | 8:
  7. print(f"Month {month} is in {season}")

    35print(f"Month {month4} is in {seasonSpring}")
    outputMonth 4 is in Spring
  1. grade ← C

    1grade→ C = 'C'
  2. match grade:

    3match gradeC:4    case 'A':5        description = "Excellent work!"
  3. description ← Satisfactory

    7    description = "Good job!"8case 'C':9    description→ Satisfactory = "Satisfactory"10case 'D':
  4. month ← 4

    17print(f"Grade: {gradeC}")18print(f"Feedback: {descriptionSatisfactory}")1920# Using or-pattern for grouped cases21month→ 4 = 4
    outputGrade: C
    Feedback: Satisfactory
  5. match month:

    23match month4:24    case 12 | 1 | 2:25        season = "Winter"
  6. season ← Spring

    25    season = "Winter"26case 3 | 4 | 5:27    season→ Spring = "Spring"28case 6 | 7 | 8:
  7. print(f"Month {month} is in {season}")

    35print(f"Month {month4} is in {seasonSpring}")
    outputMonth 4 is in Spring
  1. grade ← F

    1grade→ F = 'F'
  2. match grade:

    3match gradeF:4    case 'A':5        description = "Excellent work!"
  3. description ← Please see instructor

    11    description = "Needs improvement"12case 'F':13    description→ Please see instructor = "Please see instructor"14case _:
  4. month ← 4

    17print(f"Grade: {gradeF}")18print(f"Feedback: {descriptionPlease see instructor}")1920# Using or-pattern for grouped cases21month→ 4 = 4
    outputGrade: F
    Feedback: Please see instructor
  5. match month:

    23match month4:24    case 12 | 1 | 2:25        season = "Winter"
  6. season ← Spring

    25    season = "Winter"26case 3 | 4 | 5:27    season→ Spring = "Spring"28case 6 | 7 | 8:
  7. print(f"Month {month} is in {season}")

    35print(f"Month {month4} is in {seasonSpring}")
    outputMonth 4 is in Spring
  1. grade ← X

    1grade→ X = 'X'
  2. match grade:

    3match gradeX:4    case 'A':5        description = "Excellent work!"
  3. description ← Invalid grade

    13    description = "Please see instructor"14case _:15    description→ Invalid grade = "Invalid grade"
  4. month ← 4

    17print(f"Grade: {gradeX}")18print(f"Feedback: {descriptionInvalid grade}")1920# Using or-pattern for grouped cases21month→ 4 = 4
    outputGrade: X
    Feedback: Invalid grade
  5. match month:

    23match month4:24    case 12 | 1 | 2:25        season = "Winter"
  6. season ← Spring

    25    season = "Winter"26case 3 | 4 | 5:27    season→ Spring = "Spring"28case 6 | 7 | 8:
  7. print(f"Month {month} is in {season}")

    35print(f"Month {month4} is in {seasonSpring}")
    outputMonth 4 is in Spring
  1. grade ← B

    1grade→ B = 'B'
  2. match grade:

    3match gradeB:4    case 'A':5        description = "Excellent work!"
  3. description ← Good job!

    5    description = "Excellent work!"6case 'B':7    description→ Good job! = "Good job!"8case 'C':
  4. month ← 1

    17print(f"Grade: {gradeB}")18print(f"Feedback: {descriptionGood job!}")1920# Using or-pattern for grouped cases21month→ 1 = 1
    outputGrade: B
    Feedback: Good job!
  5. match month:

    23match month1:24    case 12 | 1 | 2:25        season = "Winter"
  6. season ← Winter

    23match month:24    case 12 | 1 | 2:25        season→ Winter = "Winter"26    case 3 | 4 | 5:
  7. print(f"Month {month} is in {season}")

    35print(f"Month {month1} is in {seasonWinter}")
    outputMonth 1 is in Winter
  1. grade ← B

    1grade→ B = 'B'
  2. match grade:

    3match gradeB:4    case 'A':5        description = "Excellent work!"
  3. description ← Good job!

    5    description = "Excellent work!"6case 'B':7    description→ Good job! = "Good job!"8case 'C':
  4. month ← 7

    17print(f"Grade: {gradeB}")18print(f"Feedback: {descriptionGood job!}")1920# Using or-pattern for grouped cases21month→ 7 = 7
    outputGrade: B
    Feedback: Good job!
  5. match month:

    23match month7:24    case 12 | 1 | 2:25        season = "Winter"
  6. season ← Summer

    27    season = "Spring"28case 6 | 7 | 8:29    season→ Summer = "Summer"30case 9 | 10 | 11:
  7. print(f"Month {month} is in {season}")

    35print(f"Month {month7} is in {seasonSummer}")
    outputMonth 7 is in Summer
  1. grade ← B

    1grade→ B = 'B'
  2. match grade:

    3match gradeB:4    case 'A':5        description = "Excellent work!"
  3. description ← Good job!

    5    description = "Excellent work!"6case 'B':7    description→ Good job! = "Good job!"8case 'C':
  4. month ← 11

    17print(f"Grade: {gradeB}")18print(f"Feedback: {descriptionGood job!}")1920# Using or-pattern for grouped cases21month→ 11 = 11
    outputGrade: B
    Feedback: Good job!
  5. match month:

    23match month11:24    case 12 | 1 | 2:25        season = "Winter"
  6. season ← Autumn

    29    season = "Summer"30case 9 | 10 | 11:31    season→ Autumn = "Autumn"32case _:
  7. print(f"Month {month} is in {season}")

    35print(f"Month {month11} is in {seasonAutumn}")
    outputMonth 11 is in Autumn

Use | (or-pattern) to combine multiple cases.

| Or-pattern: `case 1 | 2 | 3:` matches 1, 2, or 3.

Calculator operator

Implement a basic calculator using match.

example
calculator.py
Replay: real traced execution (multi-file project)
a = 10
b = 3
op = '/'

match op:
    case '+':
        result = a + b
        valid = True
    case '-':
        result = a - b
        valid = True
    case '*':
        result = a * b
        valid = True
    case '/':
        if b != 0:
            result = a / b
            valid = True
        else:
            print("Error: Division by zero")
            result = 0
            valid = False
    case '%':
        result = a % b
        valid = True
    case _:
        print(f"Unknown operator: {op}")
        result = 0
        valid = False

if valid:
    print(f"{a} {op} {b} = {result}")
a = 20
b = 3
op = '/'

match op:
    case '+':
        result = a + b
        valid = True
    case '-':
        result = a - b
        valid = True
    case '*':
        result = a * b
        valid = True
    case '/':
        if b != 0:
            result = a / b
            valid = True
        else:
            print("Error: Division by zero")
            result = 0
            valid = False
    case '%':
        result = a % b
        valid = True
    case _:
        print(f"Unknown operator: {op}")
        result = 0
        valid = False

if valid:
    print(f"{a} {op} {b} = {result}")
a = 15.5
b = 3
op = '/'

match op:
    case '+':
        result = a + b
        valid = True
    case '-':
        result = a - b
        valid = True
    case '*':
        result = a * b
        valid = True
    case '/':
        if b != 0:
            result = a / b
            valid = True
        else:
            print("Error: Division by zero")
            result = 0
            valid = False
    case '%':
        result = a % b
        valid = True
    case _:
        print(f"Unknown operator: {op}")
        result = 0
        valid = False

if valid:
    print(f"{a} {op} {b} = {result}")
a = 10
b = 2
op = '/'

match op:
    case '+':
        result = a + b
        valid = True
    case '-':
        result = a - b
        valid = True
    case '*':
        result = a * b
        valid = True
    case '/':
        if b != 0:
            result = a / b
            valid = True
        else:
            print("Error: Division by zero")
            result = 0
            valid = False
    case '%':
        result = a % b
        valid = True
    case _:
        print(f"Unknown operator: {op}")
        result = 0
        valid = False

if valid:
    print(f"{a} {op} {b} = {result}")
a = 10
b = 4
op = '/'

match op:
    case '+':
        result = a + b
        valid = True
    case '-':
        result = a - b
        valid = True
    case '*':
        result = a * b
        valid = True
    case '/':
        if b != 0:
            result = a / b
            valid = True
        else:
            print("Error: Division by zero")
            result = 0
            valid = False
    case '%':
        result = a % b
        valid = True
    case _:
        print(f"Unknown operator: {op}")
        result = 0
        valid = False

if valid:
    print(f"{a} {op} {b} = {result}")
a = 10
b = 3
op = '+'

match op:
    case '+':
        result = a + b
        valid = True
    case '-':
        result = a - b
        valid = True
    case '*':
        result = a * b
        valid = True
    case '/':
        if b != 0:
            result = a / b
            valid = True
        else:
            print("Error: Division by zero")
            result = 0
            valid = False
    case '%':
        result = a % b
        valid = True
    case _:
        print(f"Unknown operator: {op}")
        result = 0
        valid = False

if valid:
    print(f"{a} {op} {b} = {result}")
a = 10
b = 3
op = '-'

match op:
    case '+':
        result = a + b
        valid = True
    case '-':
        result = a - b
        valid = True
    case '*':
        result = a * b
        valid = True
    case '/':
        if b != 0:
            result = a / b
            valid = True
        else:
            print("Error: Division by zero")
            result = 0
            valid = False
    case '%':
        result = a % b
        valid = True
    case _:
        print(f"Unknown operator: {op}")
        result = 0
        valid = False

if valid:
    print(f"{a} {op} {b} = {result}")
a = 10
b = 3
op = '*'

match op:
    case '+':
        result = a + b
        valid = True
    case '-':
        result = a - b
        valid = True
    case '*':
        result = a * b
        valid = True
    case '/':
        if b != 0:
            result = a / b
            valid = True
        else:
            print("Error: Division by zero")
            result = 0
            valid = False
    case '%':
        result = a % b
        valid = True
    case _:
        print(f"Unknown operator: {op}")
        result = 0
        valid = False

if valid:
    print(f"{a} {op} {b} = {result}")
a = 10
b = 3
op = '%'

match op:
    case '+':
        result = a + b
        valid = True
    case '-':
        result = a - b
        valid = True
    case '*':
        result = a * b
        valid = True
    case '/':
        if b != 0:
            result = a / b
            valid = True
        else:
            print("Error: Division by zero")
            result = 0
            valid = False
    case '%':
        result = a % b
        valid = True
    case _:
        print(f"Unknown operator: {op}")
        result = 0
        valid = False

if valid:
    print(f"{a} {op} {b} = {result}")
  1. a ← 10, b ← 3, op ← /

    1a→ 10 = 10   #@a=20, 15.52b→ 3 = 3    #@b=4, 23op→ / = '/'   #@op='+', '-', '*', '%'
  2. match op:

    5match op/:6    case '+':7        result = a + b
  3. result ← 3.3333333333333335, valid ← True

    15case '/':16    if b3 != 0:17        result→ 3.3333333333333335 = a10 / b318        valid→ True = True19    else:
  4. if valid:

    31if validTrue:32    print(f"{a10} {op/} {b3} = {result3.3333333333333335}")
    output10 / 3 = 3.3333333333333335
  1. a ← 20, b ← 3, op ← /

    1a→ 20 = 202b→ 3 = 33op→ / = '/'
  2. match op:

    5match op/:6    case '+':7        result = a + b
  3. result ← 6.666666666666667, valid ← True

    15case '/':16    if b3 != 0:17        result→ 6.666666666666667 = a20 / b318        valid→ True = True19    else:
  4. if valid:

    31if validTrue:32    print(f"{a20} {op/} {b3} = {result6.666666666666667}")
    output20 / 3 = 6.666666666666667
  1. a ← 15.5, b ← 3, op ← /

    1a→ 15.5 = 15.52b→ 3 = 33op→ / = '/'
  2. match op:

    5match op/:6    case '+':7        result = a + b
  3. result ← 5.166666666666667, valid ← True

    15case '/':16    if b3 != 0:17        result→ 5.166666666666667 = a15.5 / b318        valid→ True = True19    else:
  4. if valid:

    31if validTrue:32    print(f"{a15.5} {op/} {b3} = {result5.166666666666667}")
    output15.5 / 3 = 5.166666666666667
  1. a ← 10, b ← 2, op ← /

    1a→ 10 = 102b→ 2 = 23op→ / = '/'
  2. match op:

    5match op/:6    case '+':7        result = a + b
  3. result ← 5.0, valid ← True

    15case '/':16    if b2 != 0:17        result→ 5.0 = a10 / b218        valid→ True = True19    else:
  4. if valid:

    31if validTrue:32    print(f"{a10} {op/} {b2} = {result5.0}")
    output10 / 2 = 5.0
  1. a ← 10, b ← 4, op ← /

    1a→ 10 = 102b→ 4 = 43op→ / = '/'
  2. match op:

    5match op/:6    case '+':7        result = a + b
  3. result ← 2.5, valid ← True

    15case '/':16    if b4 != 0:17        result→ 2.5 = a10 / b418        valid→ True = True19    else:
  4. if valid:

    31if validTrue:32    print(f"{a10} {op/} {b4} = {result2.5}")
    output10 / 4 = 2.5
  1. a ← 10, b ← 3, op ← +

    1a→ 10 = 102b→ 3 = 33op→ + = '+'
  2. match op:

    5match op+:6    case '+':7        result = a + b
  3. result ← 13, valid ← True

    5match op:6    case '+':7        result→ 13 = a10 + b38        valid→ True = True9    case '-':
  4. if valid:

    31if validTrue:32    print(f"{a10} {op+} {b3} = {result13}")
    output10 + 3 = 13
  1. a ← 10, b ← 3, op ← -

    1a→ 10 = 102b→ 3 = 33op→ - = '-'
  2. match op:

    5match op-:6    case '+':7        result = a + b
  3. result ← 7, valid ← True

    8    valid = True9case '-':10    result→ 7 = a10 - b311    valid→ True = True12case '*':
  4. if valid:

    31if validTrue:32    print(f"{a10} {op-} {b3} = {result7}")
    output10 - 3 = 7
  1. a ← 10, b ← 3, op ← *

    1a→ 10 = 102b→ 3 = 33op→ * = '*'
  2. match op:

    5match op*:6    case '+':7        result = a + b
  3. result ← 30, valid ← True

    11    valid = True12case '*':13    result→ 30 = a10 * b314    valid→ True = True15case '/':
  4. if valid:

    31if validTrue:32    print(f"{a10} {op*} {b3} = {result30}")
    output10 * 3 = 30
  1. a ← 10, b ← 3, op ← %

    1a→ 10 = 102b→ 3 = 33op→ % = '%'
  2. match op:

    5match op%:6    case '+':7        result = a + b
  3. result ← 1, valid ← True

    22        valid = False23case '%':24    result→ 1 = a10 % b325    valid→ True = True26case _:
  4. if valid:

    31if validTrue:32    print(f"{a10} {op%} {b3} = {result1}")
    output10 % 3 = 1

Match on strings works great for command parsing.

Pattern matching on structure

Match can destructure tuples, lists, and objects.

example
destructure.py
Replay: real traced execution (multi-file project)
# Match can destructure tuples
point = (3, 4)

match point:
    case (0, 0):
        description = "Origin"
    case (x, 0):
        description = f"On X-axis at x={x}"
    case (0, y):
        description = f"On Y-axis at y={y}"
    case (x, y):
        description = f"Point at ({x}, {y})"

print(f"Point {point}: {description}")

# Match on list structure
command = ["move", "north", 5]

match command:
    case ["quit"]:
        action = "Exiting game"
    case ["look"]:
        action = "Looking around..."
    case ["move", direction]:
        action = f"Moving {direction}"
    case ["move", direction, distance]:
        action = f"Moving {direction} for {distance} units"
    case ["attack", target]:
        action = f"Attacking {target}!"
    case _:
        action = "Unknown command"

print(f"Command: {command}")
print(f"Action: {action}")

# Match can destructure tuples
point = (0, 0)

match point:
    case (0, 0):
        description = "Origin"
    case (x, 0):
        description = f"On X-axis at x={x}"
    case (0, y):
        description = f"On Y-axis at y={y}"
    case (x, y):
        description = f"Point at ({x}, {y})"

print(f"Point {point}: {description}")

# Match on list structure
command = ["move", "north", 5]

match command:
    case ["quit"]:
        action = "Exiting game"
    case ["look"]:
        action = "Looking around..."
    case ["move", direction]:
        action = f"Moving {direction}"
    case ["move", direction, distance]:
        action = f"Moving {direction} for {distance} units"
    case ["attack", target]:
        action = f"Attacking {target}!"
    case _:
        action = "Unknown command"

print(f"Command: {command}")
print(f"Action: {action}")

# Match can destructure tuples
point = (5, 0)

match point:
    case (0, 0):
        description = "Origin"
    case (x, 0):
        description = f"On X-axis at x={x}"
    case (0, y):
        description = f"On Y-axis at y={y}"
    case (x, y):
        description = f"Point at ({x}, {y})"

print(f"Point {point}: {description}")

# Match on list structure
command = ["move", "north", 5]

match command:
    case ["quit"]:
        action = "Exiting game"
    case ["look"]:
        action = "Looking around..."
    case ["move", direction]:
        action = f"Moving {direction}"
    case ["move", direction, distance]:
        action = f"Moving {direction} for {distance} units"
    case ["attack", target]:
        action = f"Attacking {target}!"
    case _:
        action = "Unknown command"

print(f"Command: {command}")
print(f"Action: {action}")

# Match can destructure tuples
point = (0, 5)

match point:
    case (0, 0):
        description = "Origin"
    case (x, 0):
        description = f"On X-axis at x={x}"
    case (0, y):
        description = f"On Y-axis at y={y}"
    case (x, y):
        description = f"Point at ({x}, {y})"

print(f"Point {point}: {description}")

# Match on list structure
command = ["move", "north", 5]

match command:
    case ["quit"]:
        action = "Exiting game"
    case ["look"]:
        action = "Looking around..."
    case ["move", direction]:
        action = f"Moving {direction}"
    case ["move", direction, distance]:
        action = f"Moving {direction} for {distance} units"
    case ["attack", target]:
        action = f"Attacking {target}!"
    case _:
        action = "Unknown command"

print(f"Command: {command}")
print(f"Action: {action}")

# Match can destructure tuples
point = (3, 4)

match point:
    case (0, 0):
        description = "Origin"
    case (x, 0):
        description = f"On X-axis at x={x}"
    case (0, y):
        description = f"On Y-axis at y={y}"
    case (x, y):
        description = f"Point at ({x}, {y})"

print(f"Point {point}: {description}")

# Match on list structure
command = ["quit"]

match command:
    case ["quit"]:
        action = "Exiting game"
    case ["look"]:
        action = "Looking around..."
    case ["move", direction]:
        action = f"Moving {direction}"
    case ["move", direction, distance]:
        action = f"Moving {direction} for {distance} units"
    case ["attack", target]:
        action = f"Attacking {target}!"
    case _:
        action = "Unknown command"

print(f"Command: {command}")
print(f"Action: {action}")

# Match can destructure tuples
point = (3, 4)

match point:
    case (0, 0):
        description = "Origin"
    case (x, 0):
        description = f"On X-axis at x={x}"
    case (0, y):
        description = f"On Y-axis at y={y}"
    case (x, y):
        description = f"Point at ({x}, {y})"

print(f"Point {point}: {description}")

# Match on list structure
command = ["look"]

match command:
    case ["quit"]:
        action = "Exiting game"
    case ["look"]:
        action = "Looking around..."
    case ["move", direction]:
        action = f"Moving {direction}"
    case ["move", direction, distance]:
        action = f"Moving {direction} for {distance} units"
    case ["attack", target]:
        action = f"Attacking {target}!"
    case _:
        action = "Unknown command"

print(f"Command: {command}")
print(f"Action: {action}")

# Match can destructure tuples
point = (3, 4)

match point:
    case (0, 0):
        description = "Origin"
    case (x, 0):
        description = f"On X-axis at x={x}"
    case (0, y):
        description = f"On Y-axis at y={y}"
    case (x, y):
        description = f"Point at ({x}, {y})"

print(f"Point {point}: {description}")

# Match on list structure
command = ["attack", "dragon"]

match command:
    case ["quit"]:
        action = "Exiting game"
    case ["look"]:
        action = "Looking around..."
    case ["move", direction]:
        action = f"Moving {direction}"
    case ["move", direction, distance]:
        action = f"Moving {direction} for {distance} units"
    case ["attack", target]:
        action = f"Attacking {target}!"
    case _:
        action = "Unknown command"

print(f"Command: {command}")
print(f"Action: {action}")

  1. point ← (3, 4)

    1# Match can destructure tuples2point→ (3, 4) = (3, 4)  #@point=(0, 0), (5, 0), (0, 5)
  2. match point:

    4match point(3, 4):5    case (0, 0):6        description = "Origin"
  3. description ← Point at (3, 4)

    10    description = f"On Y-axis at y={y}"11case (x, y):12    description→ Point at (3, 4) = f"Point at ({x3}, {y4})"
  4. command ← ['move', 'north', 5]

    14print(f"Point {point(3, 4)}: {descriptionPoint at (3, 4)}")1516# Match on list structure17command→ ['move', 'north', 5] = ["move", "north", 5]  #@command=["quit"], ["look"], ["attack", "dragon"]
    outputPoint (3, 4): Point at (3, 4)
  5. match command:

    19match command['move', 'north', 5]:20    case ["quit"]:21        action = "Exiting game"
  6. action ← Moving north for 5 units

    25    action = f"Moving {direction}"26case ["move", direction, distance]:27    action→ Moving north for 5 units = f"Moving {directionnorth} for {distance5} units"28case ["attack", target]:
  7. print(f"Command: {command}")

    33print(f"Command: {command['move', 'north', 5]}")34print(f"Action: {actionMoving north for 5 units}")
    outputCommand: ['move', 'north', 5]
    Action: Moving north for 5 units
  1. point ← (0, 0)

    1# Match can destructure tuples2point→ (0, 0) = (0, 0)
  2. match point:

    4match point(0, 0):5    case (0, 0):6        description = "Origin"
  3. description ← Origin

    4match point:5    case (0, 0):6        description→ Origin = "Origin"7    case (x, 0):
  4. command ← ['move', 'north', 5]

    14print(f"Point {point(0, 0)}: {descriptionOrigin}")1516# Match on list structure17command→ ['move', 'north', 5] = ["move", "north", 5]
    outputPoint (0, 0): Origin
  5. match command:

    19match command['move', 'north', 5]:20    case ["quit"]:21        action = "Exiting game"
  6. action ← Moving north for 5 units

    25    action = f"Moving {direction}"26case ["move", direction, distance]:27    action→ Moving north for 5 units = f"Moving {directionnorth} for {distance5} units"28case ["attack", target]:
  7. print(f"Command: {command}")

    33print(f"Command: {command['move', 'north', 5]}")34print(f"Action: {actionMoving north for 5 units}")
    outputCommand: ['move', 'north', 5]
    Action: Moving north for 5 units
  1. point ← (5, 0)

    1# Match can destructure tuples2point→ (5, 0) = (5, 0)
  2. match point:

    4match point(5, 0):5    case (0, 0):6        description = "Origin"
  3. description ← On X-axis at x=5

    6    description = "Origin"7case (x, 0):8    description→ On X-axis at x=5 = f"On X-axis at x={x5}"9case (0, y):
  4. command ← ['move', 'north', 5]

    14print(f"Point {point(5, 0)}: {descriptionOn X-axis at x=5}")1516# Match on list structure17command→ ['move', 'north', 5] = ["move", "north", 5]
    outputPoint (5, 0): On X-axis at x=5
  5. match command:

    19match command['move', 'north', 5]:20    case ["quit"]:21        action = "Exiting game"
  6. action ← Moving north for 5 units

    25    action = f"Moving {direction}"26case ["move", direction, distance]:27    action→ Moving north for 5 units = f"Moving {directionnorth} for {distance5} units"28case ["attack", target]:
  7. print(f"Command: {command}")

    33print(f"Command: {command['move', 'north', 5]}")34print(f"Action: {actionMoving north for 5 units}")
    outputCommand: ['move', 'north', 5]
    Action: Moving north for 5 units
  1. point ← (0, 5)

    1# Match can destructure tuples2point→ (0, 5) = (0, 5)
  2. match point:

    4match point(0, 5):5    case (0, 0):6        description = "Origin"
  3. description ← On Y-axis at y=5

    8    description = f"On X-axis at x={x}"9case (0, y):10    description→ On Y-axis at y=5 = f"On Y-axis at y={y5}"11case (x, y):
  4. command ← ['move', 'north', 5]

    14print(f"Point {point(0, 5)}: {descriptionOn Y-axis at y=5}")1516# Match on list structure17command→ ['move', 'north', 5] = ["move", "north", 5]
    outputPoint (0, 5): On Y-axis at y=5
  5. match command:

    19match command['move', 'north', 5]:20    case ["quit"]:21        action = "Exiting game"
  6. action ← Moving north for 5 units

    25    action = f"Moving {direction}"26case ["move", direction, distance]:27    action→ Moving north for 5 units = f"Moving {directionnorth} for {distance5} units"28case ["attack", target]:
  7. print(f"Command: {command}")

    33print(f"Command: {command['move', 'north', 5]}")34print(f"Action: {actionMoving north for 5 units}")
    outputCommand: ['move', 'north', 5]
    Action: Moving north for 5 units
  1. point ← (3, 4)

    1# Match can destructure tuples2point→ (3, 4) = (3, 4)
  2. match point:

    4match point(3, 4):5    case (0, 0):6        description = "Origin"
  3. description ← Point at (3, 4)

    10    description = f"On Y-axis at y={y}"11case (x, y):12    description→ Point at (3, 4) = f"Point at ({x3}, {y4})"
  4. command ← ['quit']

    14print(f"Point {point(3, 4)}: {descriptionPoint at (3, 4)}")1516# Match on list structure17command→ ['quit'] = ["quit"]
    outputPoint (3, 4): Point at (3, 4)
  5. match command:

    19match command['quit']:20    case ["quit"]:21        action = "Exiting game"
  6. action ← Exiting game

    19match command:20    case ["quit"]:21        action→ Exiting game = "Exiting game"22    case ["look"]:
  7. print(f"Command: {command}")

    33print(f"Command: {command['quit']}")34print(f"Action: {actionExiting game}")
    outputCommand: ['quit']
    Action: Exiting game
  1. point ← (3, 4)

    1# Match can destructure tuples2point→ (3, 4) = (3, 4)
  2. match point:

    4match point(3, 4):5    case (0, 0):6        description = "Origin"
  3. description ← Point at (3, 4)

    10    description = f"On Y-axis at y={y}"11case (x, y):12    description→ Point at (3, 4) = f"Point at ({x3}, {y4})"
  4. command ← ['look']

    14print(f"Point {point(3, 4)}: {descriptionPoint at (3, 4)}")1516# Match on list structure17command→ ['look'] = ["look"]
    outputPoint (3, 4): Point at (3, 4)
  5. match command:

    19match command['look']:20    case ["quit"]:21        action = "Exiting game"
  6. action ← Looking around...

    21    action = "Exiting game"22case ["look"]:23    action→ Looking around... = "Looking around..."24case ["move", direction]:
  7. print(f"Command: {command}")

    33print(f"Command: {command['look']}")34print(f"Action: {actionLooking around...}")
    outputCommand: ['look']
    Action: Looking around...
  1. point ← (3, 4)

    1# Match can destructure tuples2point→ (3, 4) = (3, 4)
  2. match point:

    4match point(3, 4):5    case (0, 0):6        description = "Origin"
  3. description ← Point at (3, 4)

    10    description = f"On Y-axis at y={y}"11case (x, y):12    description→ Point at (3, 4) = f"Point at ({x3}, {y4})"
  4. command ← ['attack', 'dragon']

    14print(f"Point {point(3, 4)}: {descriptionPoint at (3, 4)}")1516# Match on list structure17command→ ['attack', 'dragon'] = ["attack", "dragon"]
    outputPoint (3, 4): Point at (3, 4)
  5. match command:

    19match command['attack', 'dragon']:20    case ["quit"]:21        action = "Exiting game"
  6. action ← Attacking dragon!

    27    action = f"Moving {direction} for {distance} units"28case ["attack", target]:29    action→ Attacking dragon! = f"Attacking {targetdragon}!"30case _:
  7. print(f"Command: {command}")

    33print(f"Command: {command['attack', 'dragon']}")34print(f"Action: {actionAttacking dragon!}")
    outputCommand: ['attack', 'dragon']
    Action: Attacking dragon!

This is where match shines - extracting values while matching patterns.

Exercise: advanced_patterns.py

Explore advanced patterns: guards, as-pattern, class patterns