Tutorials/Your first Python script

From LifeWiki
Jump to navigation Jump to search

Ah! You want to write some Python? Well, look no further. Here you will learn the basics of Python-scripting in Golly™. Note that, while this won't function as a complete tutorial for Python, you should be able to still follow a bit even if you have no Python knowledge.

Things to Install

Wait! You need to prepare some stuff first. You need:

  • Your computer, of course, or you wouldn't be able to run Golly.
  • Golly
  • Python 2.7+ (if using Golly 3.4 or before) or Python 3 (if using Golly 4.0 or later)

If you are on a Mac, Python 2.7 should already be installed, but if you are using Golly 4.0 or later, Python 3 is not automatically installed, so you must download it. On Windows, you will have to install Python no matter what version. Once you have packed your stuff and prepared you can start your Pythoning adventure!

What are we Going to Make?

For this tutorial we are going to make a very simple script that detects the period of the object on screen. Golly already has a built-in script for this exact thing (See oscar.py, which also has additional functionality like detecting spaceship displacement) but we are going to make it anyway because it's a great script to introduce Golly scripts. The script will be able to detect the periods of oscillators and spaceships alike.

The Idea

The idea of this script is to take the pattern and run it until it either repeats or crosses the set border of time. You'll understand later (hopefully) once we get into making the script. Let's draw an outline of our program in a flow chart:
Flow1.png
So there, we have the flow our program is going to go in. Now we just need to translate that to Python. To start, open a new Python IDE window (recommended), or any text editor.

Let's get scripting!

Step 1: Setting things up

Let's set things up.

Believe it or not, Golly has it's own Python module (A python module is basically a set of functions)! It is used to make scripting easier and contains other useful non-Golly-related features such as easy dialog boxes without the need of the bulky tkinter commands. To import the Golly module, simply type

import golly as g

The 'as g' is not needed, but will make typing out the commands (Which are usually used a lot in Golly scripts) less tedious. Commands in that are packed into the Golly module can be found in Golly's help files under Help -> Python Scripting.

You could also do this if you want to omit "g." and make the commands even shorter, but beware of function name collisions:

from golly import *

We'll also need a variable for the period of the pattern, so put this in as well:

period = 0

Step 2: Is there a pattern?

There is a very simple way to test if the pattern is empty in Golly. If you read the Golly help files, you probably have found it already. If you haven't, it's

g.empty()

The g.empty() command returns a simple True or False. It will return True if the pattern is empty and False otherwise. So, we first want to check if there even is a pattern to check the period of. Let's do that by using the Python if statement:

if g.empty():
    g.warn("No pattern!")
    g.exit()

This also shows us two other Golly commands:

  • g.warn() opens a dialog box with the classing yellow triangle warning symbol with the specified message.
  • g.exit() stops the script.

If you'd rather not use a pop-up box and instead show the message on the status bar, the g.exit() command also allows you to show a message:

if g.empty():
    g.exit("No pattern!")

Step 3: Run the pattern

Of course, Golly has a run() command which allows us to run our pattern by a specified amount of generations (in this case 1). We'll also want to increase the period counter by one if we run the pattern by one, which is shown by the following code:

g.run(1)
period += 1

However, this alone in the script will only execute that run command once. That's not what we want - we want to keep running until the pattern repeats. Introduce the magic of the while loop:

while True:
    g.run(1)
    period += 1

The while True loop will not stop until we instruct it to (by the break statement or stopping the program altogether), which makes it a perfect choice for this program. But wait! Without any conditions to stop the while loop, it'll run forever! Which brings us to the next step:

Step 4: Check for equality

There are a lot of ways we can check for pattern equality, like recording every cell in a specified bounding box and then checking if every cell is equal, but the fastest way to do so is by the g.hash() command. First, we'll have to add a line before the while loop (but after the empty check, since it only runs correctly if the pattern is non-empty), which gives us something to compare to:

pattern = g.hash(g.getrect())

The new commands in this line are:

  • g.hash() returns a hash integer for a pattern in a specified bounding box - this is the fastest and easiest way to check for pattern equality as two identical patterns (without reflection or rotation) will return the same hash value no matter what, but beware, as two different patterns might have the same hash value (this probability is low, but hash collisions can happen if you're testing many different patterns).
  • g.getrect() returns the total bounding box of the pattern. Since this can move around over time, using this command can ensure we got the correct bounding rectangle, which is important when finding periods of spaceships.

That provides us with the starting pattern to compare to - now we have to compare the pattern after a certain amount of generations to the starting pattern. This step, due to the g.hash() command, is fortunately easy (add this code inside the while loop in step 3):

if g.hash(g.getrect()) == pattern:
    break

(Note that we are using the equality operator (==) and not the assignment operator (=) when comparing variables. Using a single = to compare is a common mistake for beginning programmers, so don't fall for it!)

The code also breaks us out of the infinite while loop with the break statement, so the program won't be stuck there forever.

Step 5: Also exit if the period is too large

If the pattern we entered doesn't become periodic (possibly because we ran the script on the wrong pattern), the equality statement above won't ever become true and the while loop will again, run forever. Therefore, we should also exit the loop if the period variable becomes too large - let's say above 10,000. Here's the code for that:

if period > 10000:
    g.exit("Period is over 10,000 or pattern is not periodic.")

Step 6: Display the final period

Assuming we got through all the other pieces of code and the program has calculated the period, we need to display it to the program runner! Therefore, we'll show the period using g.show:

g.show("Pattern has period " + str(period))

In this line, we are concatenating strings, or joining them together for Golly to show. For this specific command, the strings we are concatenating are "Pattern has period " (the space at the end is because the second string does not have a space at the beginning, so we have to put the space somewhere), and str(period) (the str() part is very important, because period is an integer by default, while strings can only be concatenated with other strings. The str() command allows us to convert an integer to a string, which allows us to concatenate them.)

Assembling the script

This is what we have after the previous six steps:

import golly as g
period = 0
if g.empty():
    g.warn("No pattern!")
    g.exit()
pattern = g.hash(g.getrect())
while True:
    g.run(1)
    period += 1
    if g.hash(g.getrect()) == pattern:
        break
    if period > 10000:
        g.exit("Period is over 10,000 or pattern is not periodic.")
g.show("Pattern has period " + str(period))

But wait! How do you run this script? Don't worry; we'll guide you through that in the next section.

Running Golly scripts

First of all, we need to save our script by closing the IDE window and confirming the save. Any name is fine, so we'll save it as periodfinder.py.

Next, go to your file browser, and go to the directory where Golly lives on your computer. In the golly-[your version]-[your os] folder, you should see (assuming you didn't add any more files or folders to this folder):

bgolly
Golly
Help
Licence.html
Patterns
ReadMe.html
Rules
Scripts

Now move your periodfinder.py script to the Scripts folder. (Note: If you want to put your Golly scripts somewhere else, use File>Set File Folder to let Golly read a different file directory.)

Enter Golly (this is important; Golly scripts can only be run within Golly), and the file directory (you should see the same files and folders as above unless you changed the file folder Golly reads) should be on the left sidebar. Open the Scripts folder (or wherever you put the script), and you should see your periodfinder.py. Now click on it to run!

Try periodfinder.py with some well-known patterns, like the pentadecathlon or lightweight spaceship. It works!

Next steps

Congratulations, you've made your first Golly Python script! Now move on to: