The Five Simple Rules to the Game of Code
- Rule 1: Everything Is a Sequence of Instructions
- Rule 2: Jumps Make the Sequence Non-Linear
- Rule 3: Tests Control Jumps
- Rule 4: Storage Controls Tests
- Rule 5: Input/Output Controls Storage
- Putting It All Together
If you play a game like Go or Chess, you know the rules are fairly simple, yet the games they enable are extremely complex. Really good games have this unique quality of simple rules with complex interactions. Programming is also a game with a few simple rules that create complex interactions, and in this exercise we’re going to learn what those rules are.
Before we do that, I need to stress that you most likely won’t use these rules directly when you code. There are languages that do utilize these rules directly, and your CPU uses them too, but in daily programming you’ll rarely use them. If that’s the case, then why learn the rules?
Because these rules are everywhere, and understanding them will help you understand the code you write. It’ll help you debug the code when it goes wrong. If you ever want to know how the code works, you’ll be able to “disassemble” it down to its basic rules and really see how it works. These rules are a cheat code. Pun totally intended.
I’m also going to warn you that you are not expected to totally understand this right away. Think of this exercise as setting you up for the rest of the exercises in this module. You’re expected to study this exercise deeply, and when you get stuck, move on to the next exercises as a break. You want to bounce between this one and the next ones until the concepts “click” and they start to make sense. You should also study these rules as deeply as you can, but don’t get stuck here. Struggle for a few days, move on, come back, and keep trying. As long as you keep trying, you can’t actually “fail.”
Rule 1: Everything Is a Sequence of Instructions
All programs are a sequence of instructions that tell a computer to do something. You’ve seen Python doing this already when you type code like this:
1 x = 10 2 y = 20 3 z = x + y
This code starts at line 1, goes to line 2, and so on until the end. That’s a sequence of instructions, but inside Python these three lines are converted into another sequence of instructions that look like this:
1 LOAD_CONST 0 (10) # load the number 10 2 STORE_NAME 0 (x) # store that in x 3 4 LOAD_CONST 1 (20) # load the number 20 5 STORE_NAME 1 (y) # store that in y 6 7 LOAD_NAME 0 (x) # loads x (which is 10) 8 LOAD_NAME 1 (y) # loads y (which is 20) 9 BINARY_ADD # adds those 10 STORE_NAME 2 (z) # store the result in z
That looks totally different from the Python version, but I bet you could probably figure out what this sequence of instructions is doing. I’ve added comments to explain each instruction, and you should be able to connect it back to the previous Python code.
I’m not joking. Take some time right now to connect each line of the Python code to the lines of this “byte code.” Using the comments I provided I’m positive you can figure it out, and doing so might turn on a light in your head about the Python code.
It’s not necessary to memorize this or even understand each of these instructions. What you should realize is your Python code is being translated into a sequence of simpler instructions that tell the computer to do something. This sequence of instructions is called “byte code” because it’s usually stored in a file as a sequence of numbers a computer understands. The output you see is usually called an “assembly language” because it’s a human “readable” (barely) version of those bytes.
These simpler instructions are processed starting at the top, do one small thing at a time, and go to the end when the program exits. That’s just like your Python code but with a simpler syntax of INSTRUCTION OPTIONS. Another way to look at this is each part of x = 10 might become its own instructions in this “byte code.”
That’s the first rule of The Game of Code: Everything you write eventually becomes a sequence of bytes fed to a computer as instructions for what the computer should do.
How can I get this output?
To get this output yourself, you use a module called dis, which stands for “disassemble.” This kind of code is traditionally called “byte code” or “assembly language,” so dis means to “disassemble.” To use dis you can import it and use the dis() function like this:
1 # import the dis function 2 from dis import dis 3 4 # pass code to dis() as a string 5 dis(''' 6 x = 10 7 y = 20 8 z = x + y 9 ''')
In this Python code I’m doing the following:
I import the dis() function from the dis module
I run the dis() function, but I give it a multi-line string using '''
I then write the Python code I want to disassemble into this multi-line string
Finally, I end the multi-line string and the dis() function with ''')
When you run this in Jupyter, you’ll see it dump the byte code like I have, but maybe with some extras we’ll cover in a minute.
Where are these bytes stored?
When you run Python (version 3), these bytes are stored in a directory named __pycache__. If you put this code into a ex27.py file and then run it with python ex27.py, you should see this directory.
Looking in this directory you should see a bunch of files ending in .pyc with names similar to the code that generated them. These .pyc files contain your compiled Python code as bytes.
When you run dis(), you’re printing a human-readable version of the numbers in the .pyc file.