Re: Golly scripts
Posted: February 5th, 2015, 1:56 pm
Thanks! I finally got Python. But when I try to open python while running some script, Golly just closes itself!
If you just need fast forward many generations use g.setstep() and g.step(). While g.setstep() defines the step size as power of your base (default 8 ).Tezcatlipoca wrote:is there something like a gofast.py that works for arbitrary rules
Thank you for the info! Trying this now. "Hit escape to abort..." I am trying to move forward by about 2,000,000 gen. It's a complex pattern--the population is at 550,000 and the rule set has 14 states. I am assuming this is significantly faster than increasing through the generations with the rendered display. Any idea at all about how much?simsim314 wrote:If you want to get to some very large specific generation see goto.py (comes with golly).
If I'm understanding you correctly -- using a script along the lines of goto.py will be very much faster than running 2M ticks with a step of 0 (i.e., step size 8^0 = 1 tick).Tezcatlipoca wrote:I am trying to move forward by about 2,000,000 gen. It's a complex pattern--the population is at 550,000 and the rule set has 14 states. I am assuming this is significantly faster than increasing through the generations with the rendered display. Any idea at all about how much?
Code: Select all
import golly as g
g.setbase(8)
g.setstep(5)
for i in range(64):
g.step()
g.fit()
g.update()Code: Select all
import golly as g
g.setbase(2)
g.setstep(21)
g.step()It's negligible for moderate step sizes. It would matter a whole lot for really low step sizes. The contrast I tried to draw was something like this:Tezcatlipoca wrote:If I read you right, it doesn't really matter that the states in the middle don't really matter to me, that I just need to get to an arbitrary end point from a complex starting pattern for much of what I'm trying to do.
Do I understand correctly that all the geometry display and rendering is negligible when it comes to resources in Golly?
Regarding the refreshes. It has been confirmed on several machines now, that minimizing golly increase performance (at around x2-x4 rates). I guess golly is smart enough not to draw anything in minimized mode.dvgrn wrote:you'd have to refresh the screen a quarter million times.
Right, I should have mentioned that -- thanks for the reminder.simsim314 wrote:Regarding the refreshes. It has been confirmed on several machines now, that minimizing golly increase performance (at around x2-x4 rates). I guess golly is smart enough not to draw anything in minimized mode.
I know it's kinda strange to improve performance pretty drastically by minimizing the screen - nevertheless this is one of the "cheapest" and best ways to improve golly performance.
Did you get some version of Golly working with a compatible Python? I hope you solved the problem one way or another. You mentioned that you had a version of Python that was intended to be run from a USB drive, so it looked like you must not be able to access python.org downloads from your location. I can't tell from the filename whether your PythonPortable.zip is 32-bit or 64-bit, and I'm not familiar with Portable Python, so can't really troubleshoot much further than that.Gustavo6046 wrote:Anyways I need a goslow.py script, once again.
Code: Select all
# Change all cells from one given state to another given state.
# Works in any rule with more than 2 states.
# Author: Andrew Trevorrow (andrew@trevorrow.com), Oct 2009.
# Modifications by Flipper77, Feb 2015
import golly as g
from glife import rect
from time import time
r = rect( g.getselrect() )
if r.empty: g.exit("There is no selection.")
clist = g.getcells(r)
maxstate = g.numstates() - 1
if maxstate == 1: g.exit("The current rule only has 2 states.")
result = g.getstring(
"Change all the cells in one state (the 1st number)\n" +
"to a different state (the 2nd number) where both\n" +
"numbers must be from 0 to " + str(maxstate) + ":",
"1 2", "Change state")
try:
s1, s2 = result.split()
except:
g.exit("Enter 2 numbers separated by a space.")
try:
fromstate = int(s1)
except:
g.exit("1st state is not a number: " + s1)
try:
tostate = int(s2)
except:
g.exit("2nd state is not a number: " + s2)
if fromstate < 0 or fromstate > maxstate:
g.exit("1st state is out of range: " + s1)
if tostate < 0 or tostate > maxstate:
g.exit("2nd state is out of range: " + s2)
if fromstate == tostate:
g.exit("The given states are the same.")
changed = 0
oldsecs = time()
if fromstate != 0:
total = int(len(clist)/3)
for cell in xrange(2, len(clist), 3):
# might be large pattern so show percentage done each second
x = cell - 2
y = cell - 1
newsecs = time()
if newsecs - oldsecs >= 1.0:
oldsecs = newsecs
g.show("Changing cell states: " +
str(int(100 * x /(3 * total))) + "%")
g.update()
# allow keyboard interaction
g.dokey( g.getkey() )
if clist[cell] == fromstate:
g.setcell(clist[x], clist[y], tostate)
changed += 1
else:
total = float(r.wd) * float(r.ht)
for row in xrange(r.top, r.top + r.height):
newsecs = time()
if newsecs - oldsecs >= 1.0:
oldsecs = newsecs
g.show("Changing cell states: " +
str(int(100 * (row - r.top) * r.wd / total)) + "%")
g.update()
g.dokey( g.getkey() )
for col in xrange(r.left, r.left + r.width):
if g.getcell(col, row) == fromstate:
g.setcell(col, row, tostate)
changed += 1
if changed == 0:
# better to beep in this case
g.exit("There are no cells in state %d." % fromstate)
else:
g.show("%d cells were changed from state %d to state %d."
% (changed, fromstate, tostate))Code: Select all
# Swaps cells between the two given states.
# Works in any rule with more than 2 states.
# Author: Andrew Trevorrow (andrew@trevorrow.com), Oct 2009.
# Modifications by Flipper77, Feb 2015
import golly as g
from glife import rect
from time import time
r = rect( g.getselrect() )
if r.empty: g.exit("There is no selection.")
clist = g.getcells(r)
maxstate = g.numstates() - 1
if maxstate == 1: g.exit("The current rule only has 2 states.")
result = g.getstring(
"Swaps all the cells of one state (the 1st number)\n" +
"with a different state (the 2nd number) where both\n" +
"numbers must be from 0 to " + str(maxstate) + ":",
"1 2", "Swap state")
try:
s1, s2 = result.split()
except:
g.exit("Enter 2 numbers separated by a space.")
try:
state1 = int(s1)
except:
g.exit("1st state is not a number: " + s1)
try:
state2 = int(s2)
except:
g.exit("2nd state is not a number: " + s2)
if state1 < 0 or state1 > maxstate:
g.exit("1st state is out of range: " + s1)
if state2 < 0 or state2 > maxstate:
g.exit("2nd state is out of range: " + s2)
if state1 == state2:
g.exit("The given states are the same.")
changed = 0
oldsecs = time()
if (state1 != 0) and (state2 != 0):
total = int(len(clist)/3)
for cell in xrange(2, len(clist), 3):
# might be large pattern so show percentage done each second
x = cell - 2
y = cell - 1
newsecs = time()
if newsecs - oldsecs >= 1.0:
oldsecs = newsecs
g.show("Changing cell states: " +
str(int(100 * x /(3 * total))) + "%")
g.update()
# allow keyboard interaction
g.dokey( g.getkey() )
if clist[cell] == state1:
g.setcell(clist[x], clist[y], state2)
changed += 1
elif clist[cell] == state2:
g.setcell(clist[x], clist[y], state1)
changed += 1
else:
total = float(r.wd) * float(r.ht)
for row in xrange(r.top, r.top + r.height):
newsecs = time()
if newsecs - oldsecs >= 1.0:
oldsecs = newsecs
g.show("Changing cell states: " +
str(int(100 * (row - r.top) * r.wd / total)) + "%")
g.update()
g.dokey( g.getkey() )
for col in xrange(r.left, r.left + r.width):
if g.getcell(col, row) == state1:
g.setcell(col, row, state2)
changed += 1
elif g.getcell(col, row) == state2:
g.setcell(col, row, state1)
changed += 1
if changed == 0:
# better to beep in this case
g.exit("There are no cells in state %d." % state1)
else:
g.show("%d cells were swapped between state %d and state %d."
% (changed, state1, state2))Ah, there's the actual problem. Try to mention specific details along these lines as early as possible in the future.Gustavo6046 wrote:Anyway my Python is a heck cause it won't work! Also my system don't accept setups for some reason... either an very incomodating one...
"Sorry but you need admin permissions to run it."
Code: Select all
import golly as g
import os
def check(string):
symmetries = {"C1": [],
"C2": ["1", "2", "4"],
"C4": ["1", "4"],
"D2": ["+1", "+2", "x"],
"D4": ["+1", "+2", "+4", "x1", "x4"],
"D8": ["1", "4"]}
if len(string.split("_")) != 2:
if string == "C1":
return "C1"
g.exit("Please enter a valid symmetry.")
pr, z = string.split("_")
if symmetries.has_key(pr):
if z in symmetries[pr]:
return string
g.exit("Please enter a valid symmetry.")
def shift_list(rect, clist):
for x in xrange(0, len(clist), 2):
clist[x] -= rect[0]
clist[x+1] -= rect[1]
return clist
def diagonal(rect, clist):
d = 0
d1 = 0
d2 = 0
l = len(clist)
for i in xrange(0, l, 2):
for j in xrange(0, l, 2):
if ( (clist[i+1]) == (clist[j]) ) and ( (clist[i]) == (clist[j+1]) ):
d1 += 1
break
if d1 == l/2:
d += 1
for i in xrange(0, l, 2):
for j in xrange(0, l, 2):
if ( (rect[2]-1-clist[i+1]) == (clist[j]) ) and ( (rect[2]-1-clist[i]) == (clist[j+1]) ):
d2 += 1
break
if d2 == l/2:
d += 1
return d
def orthogonal(rect, clist):
xline = rect[3]-1
yline = rect[2]-1
l = len(clist)
x = 0
y = 0
o = 0
for i in xrange(0, l, 2):
for j in xrange(0, l, 2):
if ( (yline-clist[i]) == (clist[j]) ) and ( (clist[i+1]) == (clist[j+1]) ):
x += 1
break
if x == l/2:
o += 1
for i in xrange(0, l, 2):
for j in xrange(0, l, 2):
if ( (clist[i]) == (clist[j]) ) and ( (xline-clist[i+1]) == (clist[j+1]) ):
y += 1
break
if y == l/2:
o += 1
if o == 1:
return (o + 2 + (y > x))
return o
def rotation(rect, clist):
l = len(clist)
r2 = 0
r4 = 0
for i in xrange(0, l, 2):
for j in xrange(0, l, 2):
if ( (clist[i+1]) == (clist[j]) ) and ( (rect[2]-1-clist[i]) == (clist[j+1]) ):
r4 += 1
break
if r4 == l/2:
return 2
for i in xrange(0, l, 2):
for j in xrange(0, l, 2):
if ( (rect[2]-1-clist[i]) == (clist[j]) ) and ( (rect[3]-1-clist[i+1]) == (clist[j+1]) ):
r2 += 1
break
if r2 == l/2:
return 1
return 0
def get_symmetry():
rect = g.getrect()
patt = shift_list(rect, g.getcells(rect))
if rect[2] == rect[3]:
d = diagonal(rect, patt)
else:
d = 0
o = orthogonal(rect, patt)
r = rotation(rect, patt)
a = 2-(rect[2]%2)
b = 2-(rect[3]%2)
if d and o:
return "D8_%d" % (a**2)
if d == 1:
return "D2_x"
if d == 2:
return "D4_x%d" % (a**2)
if o == 2:
return "D4_+%d" % (a*b)
if o > 2:
return "D2_+%d" % (2-(rect[o-1]%2))
if r == 1:
return "C2_%d" % (a*b)
if r == 2:
return "C4_%d" % (a**2)
return "C1"
# ------------------------------------------------------------------------
count = 0
rule = g.getstring("Enter rule.", "B3/S23").replace("/", "")
all = {}
dir = g.getdir("data")
s = dir[-1]
place = dir + "Symmetrical_objects" + s
path = dir + "apgsearch" + s + "objects" + s + rule + s
if not os.path.exists(path):
g.exit("The specified directory doesn't exist: %s" % path)
if not os.path.exists(place):
os.mkdir(place)
for obj in os.listdir(path):
g.open(path + obj)
objname = obj.partition(".")[0]
symm = get_symmetry()
if all.has_key(symm):
all[symm] += "\n"
all[symm] += objname
else:
all[symm] = objname
if (count % 100) == 0:
g.show("Objects processed: %d" % count)
g.update()
count += 1
for key in all:
out = open(place + rule + "-" + key + ".txt", 'w')
out.write(all[key])
out.close()
g.show("Objects processed: %d" % count)The two existing (C/C++) search utilities are Paul Callahan's 'ptbsearch' and Gabriel Nivasch's 'catalyst'. Both are command-line utilities and there's a steep learning curve, but definitely worth learning if you're interested in this kind of thing... simsim314 has written a Python-based front end for 'catalyst', so if you get Python installed that might be helpful.Gustavo6046 wrote:Now I want to see if someone has a program that places some eaters in a selected unstable pattern so to supress the junk into something useful... like some eaters around a R-pentomino could eat the R-pentomino and only remain the eaters.
Code: Select all
# Runs the current selection for a given number of steps and
# creates a black and white animated GIF file.
# Based on giffer.pl, which is based on code by Tony Smith.
import golly as g
import os
import struct
rect=g.getselrect()
if len(rect)==0:
g.exit("Nothing in selection.")
[x,y,width,height]=rect
if(width>=65536 or height>=65536):
g.exit("The width or height of the GIF file must be less than 65536 pixels.")
s = g.getstring( "Enter:\nthe number of frames,\n"
+"the pause time of each frame(in centicecs),\n"
+"the size of each cell(in pixels), and\n"
+"the file name.\n"
+"ex) 100 1 10 out.gif"
,"","Create Animated GIF");
frames, pause, cellsize, filename = s.split()
if(frames==""): frames = 100
if(pause==""): pause = 1
if(cellsize==""): cellsize = 1
try:
frames = int(frames)
except:
g.exit("Number of frames is not an integer: " + frames)
try:
pause = int(pause)
except:
g.exit("Pause time is not an integer: " + pause)
try:
cellsize = int(cellsize)
except:
g.exit("Cell size is not an integer: " + cellsize)
if(cellsize*height>=65536 or cellsize*width>=65536):
g.exit("The width or height of the GIF file must be less than 65536 pixels.")
# ------------------------------------------------------------------------------
def getdata():
lines = []
#each array element is a line of 0 and 1 characters
for row in xrange(y, y+height):
line = ""
for col in xrange(x, x+width):
line += str(g.getcell(col,row))*cellsize
lines += [line]*cellsize
return lines
# ------------------------------------------------------------------------------
def compress(lines):
table = {'0': 0, '1': 1}
curr = cc = 4
used = eoi = 5
bits = size = 3
mask = 7
output = code = ""
for line in lines:
for i in xrange(len(line)):
next = line[i]
if (code + next) in table:
code += next
else:
used += 1
table[(code + next)] = used
curr += table[code] << bits
bits += size
while(bits >= 8):
output += chr(curr & 255)
curr >>= 8
bits -= 8
if(used > mask):
if(size < 12):
size += 1
mask = mask*2 + 1
else:
curr += cc << bits # output cc in current width
bits += size
while(bits >= 8):
output += chr(curr & 255)
curr >>= 8
bits -= 8
table = {'0': 0, '1': 1} #reset table
used = 5
bits = 3
mask = 7
code = next
curr += table[code] << bits
bits += size
while(bits >= 8):
output += chr(curr & 255)
curr >>= 8
bits -= 8
output += chr(curr)
subbed = ""
while(len(output) > 255):
subbed += chr(255) + output[:255]
output = output[255:]
return subbed + chr(len(output)) + output + chr(0)
# ----------------------------------------------------------------------
# GIF formatting
# Useful information of GIF formats in:
# http://www.matthewflickinger.com/lab/whatsinagif/bits_and_bytes.asp
# I'm a novice both at python and perl.
# Anybody is welcome in modifying the "part that I wrote",
# especially the pack implementations.
# (Added the original perl code in comments)
# ----------------------------------------------------------------------
header = "GIF89a"
screendesc = struct.pack("<2HB2b", cellsize*width, cellsize*height, 0x80, 0, 0)
#global is a keyword in python.
#my $global = pack('v2B8c2', $width, $height, '10000000', 0, 0);
colortable = "\xFF\xFF\xFF\x00\x00\x00"
#Sadly, I don't know an elegant way in python.
#my $colortable = pack('H*', 'FFFFFF000000');
applic = chr(11) + "NETSCAPE2.0" + struct.pack("<2bHb", 3, 1, 0, 0)
#my $applic = chr(11) . 'NETSCAPE2.0' . pack('c2vc', 3, 1, 0, 0);
imagedesc = struct.pack("<4HB", 0, 0, cellsize*width, cellsize*height, 0x00)
#my $descriptor = pack('v4B8', 0, 0, $width, $height, '00000000');
try:
gif = open(os.getcwd() + "\\" + filename,"wb")
except:
g.exit("Unable to open file.")
gif.write(header + screendesc + colortable)
gif.write("!" + chr(0xFF) + applic)
for f in xrange(frames):
gif.write("!" + chr(0xF9) + struct.pack("<bBH2b", 4, 0x00, pause, 0, 0))
#print GIF '!', chr(0xF9), pack('cB8vc2', 4, '00000000', $pause, 0, 0);
#get data for this frame
gif.write("," + imagedesc + chr(2) + compress(getdata()))
g.show(str(f+1)+"/"+str(frames))
if(f+1 < frames):
g.run(1)
g.update()
gif.close()
g.show("GIF animation saved in " + filename)
Python 2.7.Scorbie wrote:Uh, oh. I saw a similar msg when I was trying to use pillow. I could not fix that. Do you have an older version of python?
Code: Select all
# find-object.py
# This script goes to http://catagolue.appspot.com
# and tells you if there are sample soups for the
# object in the universe under the
# current rule and specified symmetry.
#
# If there are any soups, it fetches them
# from the site, and places them down in a
# seperate layer.
#
# There are special variables before the function
# definitions for modifying if necessary.
import golly as g
from glife import rect
import hashlib
import urllib2
import math
spacing = 250
maxsoups = 16
max_finite_period = 500
def canonise(duration):
representation = "#"
# We need to compare each phase to find the one with the smallest
# description:
for t in xrange(duration):
r = rect(g.getrect())
if r.empty:
return "0"
if ((r.wd <= 40) & (r.ht <= 40)):
# Fits within a 40-by-40 bounding box, so eligible to be canonised.
# Choose the orientation which results in the smallest description:
representation = compare_representations(representation, canonise_orientation(r.wd, r.ht, r.x, r.y, 1, 0, 0, 1))
representation = compare_representations(representation, canonise_orientation(r.wd, r.ht, r.x+r.wd-1, r.y, -1, 0, 0, 1))
representation = compare_representations(representation, canonise_orientation(r.wd, r.ht, r.x, r.y+r.ht-1, 1, 0, 0, -1))
representation = compare_representations(representation, canonise_orientation(r.wd, r.ht, r.x+r.wd-1, r.y+r.ht-1, -1, 0, 0, -1))
representation = compare_representations(representation, canonise_orientation(r.ht, r.wd, r.x, r.y, 0, 1, 1, 0))
representation = compare_representations(representation, canonise_orientation(r.ht, r.wd, r.x+r.wd-1, r.y, 0, -1, 1, 0))
representation = compare_representations(representation, canonise_orientation(r.ht, r.wd, r.x, r.y+r.ht-1, 0, 1, -1, 0))
representation = compare_representations(representation, canonise_orientation(r.ht, r.wd, r.x+r.wd-1, r.y+r.ht-1, 0, -1, -1, 0))
g.run(1)
g.setgen('0')
return representation
# A subroutine used by canonise:
def canonise_orientation(length, breadth, ox, oy, a, b, c, d):
representation = ""
chars = "0123456789abcdefghijklmnopqrstuvwxyz"
for v in xrange(int((breadth-1)/5)+1):
zeroes = 0
if (v != 0):
representation += "z"
for u in xrange(length):
baudot = 0
for w in xrange(5):
x = ox + a*u + b*(5*v + w)
y = oy + c*u + d*(5*v + w)
baudot = (baudot >> 1) + 16*g.getcell(x, y)
if (baudot == 0):
zeroes += 1
else:
if (zeroes > 0):
if (zeroes == 1):
representation += "0"
elif (zeroes == 2):
representation += "w"
elif (zeroes == 3):
representation += "x"
else:
representation += "y"
representation += chars[zeroes - 4]
zeroes = 0
representation += chars[baudot]
return representation
# Compares strings first by length, then by lexicographical ordering.
# A hash character is worse than anything else.
def compare_representations(a, b):
if (a == "#"):
return b
elif (b == "#"):
return a
elif (len(a) < len(b)):
return a
elif (len(b) < len(a)):
return b
elif (a < b):
return a
else:
return b
# Gets the period of an interleaving of degree-d polynomials:
def deepperiod(sequence, maxperiod, degree):
for p in xrange(1, maxperiod, 1):
good = True
for i in xrange(maxperiod):
diffs = [0] * (degree + 2)
for j in xrange(degree + 2):
diffs[j] = sequence[i + j*p]
# Produce successive differences:
for j in xrange(degree + 1):
for k in xrange(degree + 1):
diffs[k] = diffs[k] - diffs[k + 1]
if (diffs[0] != 0):
good = False
break
if (good):
return p
return -1
# Analyses a linear-growth pattern, returning a hash:
def linearlyse(maxperiod):
poplist = [0]*(3*maxperiod)
for i in xrange(3*maxperiod):
g.run(1)
poplist[i] = int(g.getpop())
p = deepperiod(poplist, maxperiod, 1)
if (p == -1):
return "unidentified"
difflist = [0]*(2*maxperiod)
for i in xrange(2*maxperiod):
difflist[i] = poplist[i + p] - poplist[i]
q = deepperiod(difflist, maxperiod, 0)
moments = [0, 0, 0]
for i in xrange(p):
moments[0] += (poplist[i + q] - poplist[i])
moments[1] += (poplist[i + q] - poplist[i]) ** 2
moments[2] += (poplist[i + q] - poplist[i]) ** 3
prehash = str(moments[1]) + "#" + str(moments[2])
# Linear-growth patterns with growth rate zero are clearly errors!
if (moments[0] == 0):
return "unidentified"
return "yl" + str(p) + "_" + str(q) + "_" + str(moments[0]) + "_" + hashlib.md5(prehash).hexdigest()
def simple_osc(r, h, p):
rect = g.getrect()
hash = g.hash(rect)
pop = g.getpop()
if ((r[2] != rect[2]) | (r[3] != rect[3])):
return False
if (h != hash):
return False
if (p != pop):
return False
return True
def encode(maxperiod):
period = 0
irect = g.getrect()
ihash = g.hash(irect)
ipop = g.getpop()
ipatt = g.getcells(irect)
oscillating = False
while not oscillating:
if (period == maxperiod):
g.setgen('0')
repr = linearlyse(1500)
if repr == "unidentified":
g.exit("Object encoding failed.")
return repr
g.run(1)
period += 1
if (simple_osc(irect, ihash, ipop)):
oscillating = True
crect = g.getrect()
cpatt = g.getcells(crect)
for i in xrange(0, int(ipop), 2):
if ((ipatt[i] - irect[0] == cpatt[i] - crect[0]) \
& (ipatt[i+1] - irect[1] == cpatt[i+1] - crect[1])):
continue
oscillating = False
break
if ((irect[0] == crect[0]) & (irect[1] == crect[1])):
if (period == 1):
return "xs" + str(ipop) + '_' + canonise(period)
else:
return "xp" + str(period) + '_' + canonise(period)
else:
return "xq" + str(period) + '_' + canonise(period)
def grule():
return g.getrule().split(":")[0].replace('/', '').replace('B', 'b').replace('S', 's')
def get_soups(symm):
apgcode = "/" + encode(max_finite_period)
rule = "/" + grule()
req = urllib2.Request('http://catagolue.appspot.com/object' + apgcode + rule)
response = urllib2.urlopen(req)
page = response.read().splitlines()
for line in page:
if line[:13] == "<p>There are ":
sentence = line.split()
if "no" in sentence:
return (0, 0)
else:
soups = []
start = page.index(line) + 1
numsoups = int(sentence[2])
if symm == "All":
for sample in page[start:start+numsoups]:
soups.append(sample.split('"')[1])
return (numsoups, soups)
for sample in page[start:start+numsoups]:
parts = sample.split("/")
if parts[2] != symm:
numsoups -= 1
elif len(soups) < maxsoups:
soups.append(sample.split('"')[1])
return (numsoups, soups)
def generate_soups(souplist):
main = "http://catagolue.appspot.com"
width = int(math.ceil(math.sqrt(len(souplist))))
total = len(souplist)
g.addlayer()
g.setname("Soups")
for i in xrange(len(souplist)):
g.show("Placing down soups: "+str(100*i/total)+"%" + " complete...")
req = urllib2.Request(main + souplist[i])
response = urllib2.urlopen(req)
page = response.read()
g.putcells(g.parse(page, (i%width)*spacing, int(i/width)*spacing))
g.update()
g.fit()
def display(symm):
numsoups, soups = get_soups(symm)
if symm != "All":
symm += " "
else:
symm = ""
if numsoups == 1:
verb = "is"
mult = ""
else:
verb = "are"
mult = "s"
if numsoups == 0:
g.exit("There are no %ssample soups available for this object yet." % symm)
else:
generate_soups(soups)
g.show("There %s %d %ssample soup%s available." % (verb, numsoups, symm, mult))
def fetch():
if g.empty():
g.exit("The universe is empty.")
algo = g.getalgo()
if ((algo != "QuickLife") & (algo != "HashLife")):
g.exit("Please use a Life-like rule.")
if g.getrule()[1] == '0':
g.exit("Please use a rule without B0.")
if g.numlayers() == g.maxlayers():
g.exit("Please have an extra layer available.")
symm = g.getstring('What symmetry do you want to check?\n(Enter "All" for all sample occurences)', "C1")
if symm not in ["All", "C1", "C2_1", "C2_2", \
"C2_4", "C4_1", "C4_4", "D2_+1", \
"D2_+2", "D2_x", "D4_+1", "D4_+2", \
"D4_+4", "D4_x1", "D4_x4", "D8_1", "D8_4"]:
g.exit("Please enter a valid symmetry.")
display(symm)
fetch()