Manage Patterns
00:00
In the previous lesson, I took a first stab at the code adding the Grid
class with the evolve
method to create the next frame. In this lesson, I’ll dive into a better way to store initial patterns instead of hard coding patterns in our Python, it’d be good to store them in a file.
00:17 That way a user could pass in their own file and see any pattern they wish. I’ve chosen to use the TOML file format as it’s relatively easy for a human to read and the data types in it map nicely to our pattern.
00:30
TOML was added to Python 3.11. If you or your users are on something earlier, the tomli
library is fully compatible with the use of a try
except
block.
00:43 Your code can correctly use whichever library is there. TOML files get represented in Python as dictionaries, so a TOML section denoted by square brackets will be a key to a dictionary and used as our pattern ID.
00:58
Then inside of it, there’s another dictionary with the key alive_cells
that stores a list of lists. This will get converted into a set of tuples in our code.
01:08 Let’s go write our pattern loading code.
01:12
I’m back inside the patterns.py
file where the Pattern
data class is defined. This time though, I’ve added some stuff starting out as promised, with a try
except
block that attempts to import the standard library’s tomllib
module.
01:28
If the user is in Python 3.11 or greater, the module gets loaded. If not, the exception fires and tomli
is loaded. Instead, notice that I’m aliasing the tomli
library so that I can always use tomllib
everywhere in the code.
01:44
Later I’ll show you how to make sure tomli
is included as a dependency for your script.
01:50
Here I’m creating a constant that points to the patterns.toml
file that is inside the module. I’ve used pathlib
to figure out what the current file is.
01:59
Then I get the parent directory. From that, then append the name of patterns.toml
. I’ve added a factory class method to the Pattern
class.
02:09 A factory method is what you call a method that returns an instance of the class it is associated with. Note, this is a class method. It gets called on the class itself and returns an instance object.
02:22 This factory takes an argument containing part of the data loaded from the TOML file, which the highlighted line converts from a list of lists into a set of tuples.
02:32 Let me scroll down. In addition to the class, I’ve added two helper functions. This first one fetches a single pattern from a file with the default file being the one contained in the module.
02:45
I use the tomllib
to read the file into a variable, then call the factory class method, passing the name of the pattern and the subsection of the TOML file with that same name.
02:57 This code could be a bit friendlier. Calling it with a name that doesn’t exist will cause a key error. A better programmer would wrap this with some error handling code and print out a helpful message.
03:07
One more thing for my to-do list: become a better programmer. The second helper function is similar to the first, but it loads multiple patterns, returning a list of Pattern
objects instead.
03:20 Let’s take a look at the TOML file.
03:26 This is the TOML file I plan to ship with the module. It has a bunch of different named sections, one for each pattern, and inside each section, the list of alive cell coordinates. Time to test our pattern loading code. Off to the REPL.
03:49
and this time, instead of loading the Pattern
class, I’ll import the helper method.
03:58 Then use the helper to load the blinker pattern from the TOML file.
04:06
Remember, the file name argument to this function defaults to the name of the file that’s in the module. Okay? Then like in the last lesson, create a Grid
04:25
and like before, the pattern works and the call to evolve
our next frame.
04:33
Now you’ve got patterns as data. It’s time to terminal
. Our game game.
Become a Member to join the conversation.