The new Python match

Just in Case

Lines 24-33 define make3Dpoint, where the match statement resides, in this case to pt. The first case statement on line 26 is looking for two variables in a tuple. If a tuple with two elements is received, this case matches, and x and y are assigned to the variables of the tuple. The function closes by returning a Point3D instance, passing x and y, along with  , because a z value was not received.

The second case statement on line 28 works the same way, except it matches a three-member tuple. The third case statement on line 30 begins to get even more interesting. Here, the case matches if pt is an instance of Point2D and x and y are defined. In this case, x and y will be assigned to their values from the instance of Point2D that is currently being evaluated; then, a Point3D is created with the existing x and y, with z as  . This x and y mapping derives from __match_args__.

The final case statement checks for an instance of Point3D and has three positional arguments. An underscore (_) is a match wildcard. In that case, it has already been handed a Point3D, so it just returns it unmodified.

Line 35 defines pointList as a list, and then lines 36-39 append different sized tuples and class instances to the list of things to be processed. Line 41 loops over pointList; line 42 calls make3Dpoint which has the match statement; and line 43 calls the print method on the resulting 3D point (Figure 1).

Figure 1: The output of example1.py. Note how all of the points are of the same type and align nicely without any missing parameters.

Nine lines of code have normalized four different styles of input and received uniform objects. With this new syntax, you can take all sorts of input and pass them through a single function that returns consistent objects for further work.

Guards

The match statement also includes an additional check called a guard, which is a conditional statement that can further evaluate the input being checked in a case. Consider the "guess a number" game (Listing 3). Here, the program chooses a number between 0 and 100, and you must figure it out in as few guesses as possible.

Listing 3

numberGuess.py

01 import random
02
03 target = random.randint ( 0 , 100 )
04 guessCount = 0
05 gameOver = False
06
07 def checkGuess ( guess ):
08    global target
09    global guessCount
10    global gameOver
11
12    match guess:
13       case ( i ) if i < 0 or i > 100:
14          print ( "Guess out of range, game is from 0 to 100" )
15       case ( i ) if i < target:
16          print ( "Higher!" )
17          guessCount += 1
18       case ( i ) if i > target:
19          print ( "Lower!" )
20          guessCount += 1
21       case ( i ) if i == target:
22          print ( "Got it!" )
23          gameOver = True
24
25 while gameOver == False:
26    print ( "You've guessed {0} times".format ( guessCount ) )
27    guess = int ( input ( "Your guess:" ) )
28    checkGuess ( guess )

The code begins with an import of the random library and then creates the random integer target between 0 and 100 and initializes a couple of other variables: guessCount, the number of guesses that have been made, and gameOver, which indicates whether the game is finished.

Guesses

The checkGuess function (lines 7-23) contains the match statement, but first, lines 8-10 use the global keyword to bring in the variables defined earlier so they are accessible inside the function without passing them in each time.

Line 12 starts the match on guess, which is the player's guess. Notice that all of the case statements use i instead of guess, and because match includes variable assignment, guess becomes i.

You'll also notice that each case checks i but then is followed by if. These if statements are called guards, and they create extra conditions for the item to match. The first case (line 13) checks whether i is less than 0 or greater than 100. If so, a Guess out of range message is displayed.

The second (line 15) and third (line 18) case statements determine whether the guess is too high or too low, display an appropriate message, increment guessCount, and exit the match.

The last case (line 21) checks to see whether the correct number has been guessed. If so, it prints the Got it! message and sets gameOver to True to exit the main loop.

Line 25 sets up the main loop (Figure 2), watching for gameOver to become True. Until then, it prints the number of guesses (line 26), asks for a guess (line 27), and checks it with the checkGuess function (line 28).

Figure 2: A game of guess the number.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • CardStock

    CardStock provides a simple development environment for building a Python graphical application.

  • Hidden Meaning: Working with Microformats

    Programs aren’t as smart as humans when it comes to interpreting the meaning of web information. If you want to maximize your search rank, you might want to dress up your HTML documents with microformats and microdata.

  • Practical Python in Linux

    We’ll introduce you to Python, an easy-to-learn scripting language, and also help you get started creating your own practical Python scripts.

  • Treasure Hunt

    A geolocation guessing game based on the popular Wordle evaluates a player's guesses based on the distance from and direction to the target location. Mike Schilli turns this concept into a desktop game in Go using the photos from his private collection.

  • Calculating Probability

    To tackle mathematical problems with conditional probabilities, math buffs rely on Bayes' formula or discrete distributions, generated by short Perl scripts.

comments powered by Disqus
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters

Support Our Work

Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.

Learn More

News