There's an ugly but useful workaround for this: Use g.getclipstr() to save the original clipboard string at the beginning , and reinstate it using g.setclipstr() at the end. The only problem is when the original clipboard string is extremely long; it wastes a lot of computation, especially if the workaround is done multiple times.dvgrn wrote:Other workable workarounds include creating a new layer, pasting in the pattern, and then
1) selecting and copying the pattern out to the clipboard and using g.getclipstr(). But it's not really a good idea to use the clipboard for a low-level task like this, at least without giving users clear warning. People might like what they have in their clipboard, and not want it to be suddenly clobbered by random junk.
Gustavo Ramos Rehermann's patterns
- praosylen
- Posts: 2449
- Joined: September 13th, 2014, 5:36 pm
- Location: Pembina University, Home of the Gliders
- Contact:
Re: Gustavo Ramos Rehermann's patterns
former username: A for Awesome
praosylen#5847 (Discord)
The only decision I made was made
of flowers, to jump universes to one of springtime in
a land of former winter, where no invisible walls stood,
or could stand for more than a few hours at most...
praosylen#5847 (Discord)
The only decision I made was made
of flowers, to jump universes to one of springtime in
a land of former winter, where no invisible walls stood,
or could stand for more than a few hours at most...
Re: Gustavo Ramos Rehermann's patterns
Another odd case is when something has been copied that isn't a string. Let's say you copy some formatted Rich Text Format text and pictures out of WordPad. After you run your script-with-workaround, you've mysteriously lost all your italics and font sizes and pictures and so forth.A for awesome wrote:There's an ugly but useful workaround for this: Use g.getclipstr() to save the original clipboard string at the beginning , and reinstate it using g.setclipstr() at the end. The only problem is when the original clipboard string is extremely long; it wastes a lot of computation, especially if the workaround is done multiple times.
The clipboard is a strange and uncanny thing, a miracle of rare device. I guess that's why I try to leave it alone, except when I would just be copying something out of some text file as the result of a script anyway.
- Gustavo6046
- Posts: 647
- Joined: December 7th, 2013, 6:26 pm
- Location: Brazil.
Re: Gustavo Ramos Rehermann's patterns
I wonder who uses Wordpad instead of Libreoffice...dvgrn wrote:Another odd case is when something has been copied that isn't a string. Let's say you copy some formatted Rich Text Format text and pictures out of WordPad. After you run your script-with-workaround, you've mysteriously lost all your italics and font sizes and pictures and so forth.A for awesome wrote:There's an ugly but useful workaround for this: Use g.getclipstr() to save the original clipboard string at the beginning , and reinstate it using g.setclipstr() at the end. The only problem is when the original clipboard string is extremely long; it wastes a lot of computation, especially if the workaround is done multiple times.
The clipboard is a strange and uncanny thing, a miracle of rare device. I guess that's why I try to leave it alone, except when I would just be copying something out of some text file as the result of a script anyway.
Anyway the script I done is behaving too weird and unfunctionally in a way that can't be described. (plz-hlp)
*yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times.
Re: Gustavo Ramos Rehermann's patterns
Just to clarify, that was not his point.Gustavo6046 wrote:I wonder who uses Wordpad instead of Libreoffice...
Copying text from WordPad and pasting it directly again doesn't damage anything, but manipulating and restoring the same string damages the format?! Hmm, that's a pretty strange aspect of the clipboard.dvgrn wrote:Let's say you copy some formatted Rich Text Format text and pictures out of WordPad. After you run your script-with-workaround, you've mysteriously lost all your italics and font sizes and pictures and so forth.
I'm not sure if anyone would willingly spend their time to do your work, especially debugging. For a feeble script-writer like me, that is the most annoying step through writing programs.Gustavo6046 wrote:Anyway the script I done is behaving too weird and unfunctionally in a way that can't be described. (plz-hlp)
- Gustavo6046
- Posts: 647
- Joined: December 7th, 2013, 6:26 pm
- Location: Brazil.
Re: Gustavo Ramos Rehermann's patterns
Can there be a console output as well? I didn't tested print but since there is no console I don't think it would work either.
g.show() don't let you scroll, which is a pity.
g.show() don't let you scroll, which is a pity.
*yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times.
Re: Gustavo Ramos Rehermann's patterns
I pointed out a similar thing recently: viewtopic.php?f=9&t=1965#p25957
Summary: launch Golly from the terminal and you'll see the print statements.
(e.g. by launching /your/path/to/Golly/golly in the terminal)
Summary: launch Golly from the terminal and you'll see the print statements.
(e.g. by launching /your/path/to/Golly/golly in the terminal)
- Gustavo6046
- Posts: 647
- Joined: December 7th, 2013, 6:26 pm
- Location: Brazil.
Re: Gustavo Ramos Rehermann's patterns
Golly should have a bShowConsole option... I wonder if they are still working in it.Scorbie wrote:I pointed out a similar thing recently: viewtopic.php?f=9&t=1965#p25957
Summary: launch Golly from the terminal and you'll see the print statements.
(e.g. by launching /your/path/to/Golly/golly in the terminal)
*yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times.
- Gustavo6046
- Posts: 647
- Joined: December 7th, 2013, 6:26 pm
- Location: Brazil.
Re: Gustavo Ramos Rehermann's patterns
This is the VERY FIRST edgy long-boat reaction I've ever found:
Unfortunately no use... to a extent...
Code: Select all
x = 9, y = 13, rule = LifeHistory
6.E$5.E$5.3E7$6.E$5.E.E$2E3.E2.E$2E4.2E!
*yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times.
- Gustavo6046
- Posts: 647
- Joined: December 7th, 2013, 6:26 pm
- Location: Brazil.
Re: Gustavo Ramos Rehermann's patterns
How do I automatically archive the piles of crumbs resultable from that Toaster I? (number of conduits + lots o Snarks) The one I posted earlier, where the snarks are adjustable.
Edit: --
Edit: --
What is a kickback?gmc_nxtman wrote:Incremental synthesis (haven't made one with kickbacks yet):
Code: Select all
<rle>
*yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times.
Re: Gustavo Ramos Rehermann's patterns
Before asking simple questions like this, you should first try looking on the LifeWiki. You would get your answer in only 3 mouse clicks.Gustavo6046 wrote:What is a kickback?
Re: Gustavo Ramos Rehermann's patterns
Rather than just a vague reference to things like "the one I posted earlier", it would be nice if you'd get in the habit of including a link. I'm a lot more likely to click on a link than to go paging back through this thread to find what you're talking about.Gustavo6046 wrote:How do I automatically archive the piles of crumbs resultable from that Toaster I? (number of conduits + lots o Snarks) The one I posted earlier, where the snarks are adjustable.
I can't help remembering Toaster I, though! Please consider simplifying your toaster to make a Toaster II before you start collecting crumbs. Whatever crumbs might spew out of Toaster I won't likely be useful for anything, because of the surplus of Snarks surrounding the output location... as mniemiec has explained.
To make an automatic archive: write a script to run through all possible combinations of reflector adjustments -- nested for loops, let's say. For each combination, the script should
- place Snarks at the correct offsets,
- run the pattern,
- check that the Snarks and other catalysts all survive
- remove the Snarks and other catalysts from the pattern
- dump the remaining crumbs to a text file.
The Life Lexicon (Golly > Help > Life Lexicon) would also be happy to answer this kind of question for you. Kickback reaction. These are used to tighten up continuous syntheses sometimes, at the cost of one more glider per kickback, or to sneak a glider in to a tight recipe where it would otherwise conflict with other incoming gliders.Gustavo6046 wrote:What is a kickback?
Kickbacks don't really seem to be necessary in this case. It's a perfectly nice continuous synthesis already, though it's labeled as "incremental".
- Gustavo6046
- Posts: 647
- Joined: December 7th, 2013, 6:26 pm
- Location: Brazil.
Re: Gustavo Ramos Rehermann's patterns
Oh thanks I forgot about LifeWiki & the Lexicon.
I am fixing HRF and making a Cell list to RLE function:
However it only returns "none" or "!", probably the last FOR isn't working...
I am fixing HRF and making a Cell list to RLE function:
Code: Select all
import golly as g
import time as t
def cell_list_to_rle(debug = False, *cells):
if debug == True:
g.show(str(cells))
t.sleep(1)
top = None
left = None
bottom = None
right = None
tmpn = 0
tmpl = []
clst = []
rle = ""
for x in cells:
tmpn += 1
tmpl.append(x)
if tmpn == 2:
clst.append(tmpl)
tmpl = []
tmpn = 0
if debug == True:
g.show(str(clst))
t.sleep(1)
for x in clst:
if x[0] < left or left == None:
left = x[0]
g.show(str(x[0]))
if x[1] < top or top == None:
top = x[1]
g.show(str(x[1]))
if x[0] > right or right == None:
right = x[0]
g.show(str(x[0]))
if x[1] > bottom or bottom == None:
bottom = x[1]
g.show(str(x[1]))
for x in range(left, right):
for y in range(top, bottom):
bFound = False
for z in clst:
if z == [x, y]:
rle += "o"
bFound = True
if z[0] == right and z[1] == y:
rle += "$"
bFound = True
if z[0] == right and z[1] == bottom:
rle += "!"
return rle
if not bFound:
rle += "b"
*yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times.
Re: Gustavo Ramos Rehermann's patterns
Is there a reason why you're worrying about writing your own function, when there's a perfectly good working one available? If you looked at the link I gave you in this message, what did you think was wrong with that code?Gustavo6046 wrote:I am fixing HRF and making a Cell list to RLE function...
However it only returns "none" or "!", probably the last FOR isn't working.
Here's a slightly altered version of Nathaniel's code. It seems to me that this should solve your problem just fine:
selection-to-clipboard-as-RLE.py:
Code: Select all
# RLE computation script for use with Golly.
# Author: Nathaniel Johnston (nathaniel@nathanieljohnston.com), June 2009.
# DMG: Refactored slightly so that the function input is a simple cell list.
# This script the current selection as a test. No error checking added.
# TBD: check for multistate rule, show appropriate warning.
# Copies the RLE encoding of the current pattern to the clipboard
import golly as g
# --------------------------------------------------------------------
def chunks(l, n):
for i in range(0, len(l), n):
yield l[i:i+n]
# --------------------------------------------------------------------
def giveRLE(clist):
clist_chunks = list (chunks (clist, 2))
mcc = min(clist_chunks)
rl_list = [[x[0]-mcc[0],x[1]-mcc[1]] for x in clist_chunks]
rle_res = ""
rle_len = 1
rl_y = rl_list[0][1] - 1
rl_x = 0
for rl_i in rl_list:
if rl_i[1] == rl_y:
if rl_i[0] == rl_x + 1:
rle_len += 1
else:
if rle_len == 1: rle_strA = ""
else: rle_strA = str (rle_len)
if rl_i[0] - rl_x - 1 == 1: rle_strB = ""
else: rle_strB = str (rl_i[0] - rl_x - 1)
rle_res = rle_res + rle_strA + "o" + rle_strB + "b"
rle_len = 1
else:
if rle_len == 1: rle_strA = ""
else: rle_strA = str (rle_len)
if rl_i[1] - rl_y == 1: rle_strB = ""
else: rle_strB = str (rl_i[1] - rl_y)
if rl_i[0] == 1: rle_strC = "b"
elif rl_i[0] == 0: rle_strC = ""
else: rle_strC = str (rl_i[0]) + "b"
rle_res = rle_res + rle_strA + "o" + rle_strB + "$" + rle_strC
rle_len = 1
rl_x = rl_i[0]
rl_y = rl_i[1]
if rle_len == 1: rle_strA = ""
else: rle_strA = str (rle_len)
rle_res = rle_res[2:] + rle_strA + "o"
return rle_res+"!"
# --------------------------------------------------------------------
test_cell_list = g.getcells (g.getselrect())
RLE = giveRLE(test_cell_list)
g.setclipstr(RLE)
g.show(RLE)
- Gustavo6046
- Posts: 647
- Joined: December 7th, 2013, 6:26 pm
- Location: Brazil.
Re: Gustavo Ramos Rehermann's patterns
It isn't good enough because it don't support multistate rules. I want HRF to work in multistate rules as well.
didn't seem to work. The right hand was just a very long list when I printed it out, even though they should be the very same...
But wait! I found out LifeHistory is the culprit! I can't remove the blue cells...
EDIT: Oooh wait, I also found out this assertion gives a error:
celleq doesn't work!
Code: Select all
# ...
def celleq(self, other):
return g.evolve(self, 0) == g.evolve(other, 0) # Both hand sides are lists, not glife.patterns! No super() needed.
# ...
def testReaction(xpos, ypos, sli):
global found
global debug
orig = g.getcells(g.getrect())
g.putcells(stillLifes[sli], xpos, ypos)
this = g.getcells(g.getrect())
oldgeneration = g.getgen()
for i in range(maxgen):
oldpat = g.getcells(g.getrect())
g.step()
if g.getcells(g.getrect()) == oldpat or g.getcells(g.getrect()) == []:
break
if celleq(g.getcells(g.getrect()), herschels[sli]):
Found = True
break
# ...
But wait! I found out LifeHistory is the culprit! I can't remove the blue cells...
EDIT: Oooh wait, I also found out this assertion gives a error:
Code: Select all
def celleq(self, other):
return g.evolve(self, 0) == g.evolve(other, 0) # Both hand sides are lists, not glife.patterns! No super() needed.
assert celleq([0, 1, 0, 2], [0, 2, 0, 3])
*yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times.
Re: Gustavo Ramos Rehermann's patterns
Sure you can -- you just have to write specific code to ignore them. It's certainly true that they won't just magically go away.Gustavo6046 wrote:The right hand was just a very long list when I printed it out, even though they should be the very same...
But wait! I found out LifeHistory is the culprit! I can't remove the blue cells...
The g.evolve() trick is for making sure that the self and other cell lists don't contain any duplicates, and that the cells are in sorted order. That way you don't get any false negatives from patterns that are really the same but have their cells listed in different orders -- e.g., a block rotated by g.transform(), compared with the original block.Gustavo6046 wrote:EDIT: Oooh wait, I also found out this assertion gives a error:celleq doesn't work!Code: Select all
def celleq(self, other): return g.evolve(self, 0) == g.evolve(other, 0) # Both hand sides are lists, not glife.patterns! No super() needed. assert celleq([0, 1, 0, 2], [0, 2, 0, 3])
The assertion is failing because your two patterns are not normalized -- the top left cell isn't the same, so of course the comparison fails. I'd suggest something like this:
Code: Select all
import golly as g
def celleq(self, other):
ssort, osort = g.evolve(self, 0), g.evolve(other, 0)
return g.transform(ssort,-ssort[0],-ssort[1]) == g.transform(osort,-osort[0],-osort[1])
assert celleq([0, 1, 0, 2], [0, 2, 0, 3])
You could normalize the lists some other way -- make the upper left cell of the bounding box be (0,0) instead, for example. That might be better for some purposes.
This definition is a little simpler to code, though. I've used it in my last several projects, and usually it doesn't cause any trouble at all.
- Gustavo6046
- Posts: 647
- Joined: December 7th, 2013, 6:26 pm
- Location: Brazil.
Re: Gustavo Ramos Rehermann's patterns
IT WOOORKS
Now you can use it for general purpose searches!
EDIT:
I found out something strange. While in real life I have no friends, in virtual life I have these:
Code: Select all
import golly as g
from sys import exit
from time import sleep
found = False
herschels = []
def celleq(self, other):
ssort, osort = g.evolve(self, 0), g.evolve(other, 0)
return g.transform(ssort,-ssort[0],-ssort[1]) == g.transform(osort,-osort[0],-osort[1])
assert celleq([0, 1, 0, 2], [0, 2, 0, 3])
testrect = g.getselrect();
if testrect == []:
g.exit("Select the area where the still life is placeable!")
if g.empty():
g.exit("There is no pattern to add bait!")
stillLifes = []
try:
maxgen = int(g.getstring("Which is the max generation to test for?", "300", "HRF v0.1")) + 1
except ValueError:
g.exit("Invalid number!")
if maxgen < 2:
g.exit("Null number")
def addStillLife():
while True:
stillLife = g.getstring("What still life to test for? (RLE)", "2o$2o!", "HRF v0.1")
stillLifes.append(g.parse(stillLife))
addAnother = g.getstring("Add another still life? (y|n)", "n", "HRF v0.1")
if addAnother.lower() == "n":
break
elif addAnother.lower() != "y":
g.exit("Invalid letter!")
def removeFirstLine(str):
result = str.rsplit('\n')
result.pop(0)
return ''.join(result)
def addResultDesired():
while True:
herschelDesired = g.getstring("What result to find? (RLE)", "3o$obo$obo!", "HRF v0.1")
herschels.append(g.parse(herschelDesired))
addAnother = g.getstring("Add another result desired? (y|n)", "n", "HRF v0.1")
if addAnother.lower() == "n":
break
elif addAnother.lower() != "y":
g.exit("Invalid letter!")
debug = False
addStillLife()
addResultDesired()
dmy = g.getstring("Debug mode? (y|n)", "n", "HRF v0.1")
if dmy.lower() == "y":
debug = True
g.autoupdate(True)
elif dmy.lower() != "n":
g.exit("Invalid letter!")
def testReaction(xpos, ypos, sli):
global found
global debug
global maxgen
orig = g.getcells(g.getrect())
g.putcells(stillLifes[sli], xpos, ypos)
this = g.getcells(g.getrect())
oldgeneration = g.getgen()
for i in range(maxgen):
oldpat = g.getcells(g.getrect())
g.step()
if g.getcells(g.getrect()) == oldpat or g.getcells(g.getrect()) == []:
break
if celleq(g.getcells(g.getrect()), herschels[sli]):
found = True
break
g.clear(0)
g.clear(1)
g.setgen(oldgeneration)
if found:
g.putcells(this)
g.exit("Found reaction!")
else:
g.putcells(orig)
g.show("No result found at x:" + str(xpos) + ", y:" + str(ypos) + ", still life " + str(sli))
def tests():
global found
for n in range(testrect[2]):
for m in range(testrect[3]):
for o in range(len(stillLifes)):
testReaction(n + testrect[0], m + testrect[1], o)
if found:
return
tests()
EDIT:
I found out something strange. While in real life I have no friends, in virtual life I have these:
*yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times.
- Gustavo6046
- Posts: 647
- Joined: December 7th, 2013, 6:26 pm
- Location: Brazil.
Re: Gustavo Ramos Rehermann's patterns
HRF found this:
Code: Select all
x = 16, y = 11, rule = LifeHistory
2.3D$2.DBD$2.DBD2B6.CB$2.6B.B2.BCBC$2.11B2C$.13B$6B3C5B$.14B$2.12B$2.
4B2.2B3C$8.2B.B!
*yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times.
- Gustavo6046
- Posts: 647
- Joined: December 7th, 2013, 6:26 pm
- Location: Brazil.
Re: Gustavo Ramos Rehermann's patterns
This is a experimental HRF version that inputs from a config file (.ini):
I just forgot to test it!!!
ME.AM.DUMB
Anyway here is a sample config file:
Code: Select all
import golly as g
from sys import exit
from time import sleep
from ConfigParser import RawConfigParser
found = False
herschels = []
stillLifes = []
def celleq(self, other):
ssort, osort = g.evolve(self, 0), g.evolve(other, 0)
return g.transform(ssort,-ssort[0],-ssort[1]) == g.transform(osort,-osort[0],-osort[1])
assert celleq([0, 1, 0, 2], [0, 2, 0, 3])
testrect = g.getselrect();
if testrect == []:
g.exit("Select the area where the still life is placeable!")
if g.empty():
g.exit("There is no pattern to add bait!")
inputconfig = g.getstring("Which file to get configuration from?")
input = RawConfigParser()
if input.read(InputConfig) == []:
g.exit("Non-existent config file!")
try:
debug = input.getboolean("General", "DebugMode")
maxgens = input.getint("Input", "Generations")
herschels = input.get("Input", "Results").split(",")
stillLifes = input.get("Input", "Baits").split(",")
logfile = open(input.get("General", "LogFilename"))
except ValueError:
g.exit("Invalid value(s) in config!")
except NoSectionError:
g.exit("Invalid sections in config!")
except NoOptionError:
g.exit("Invalid options in config!")
except IOError:
g.exit("Log can't be made!")
except:
g.exit("Invalid config!")
def logToLogfile(logged = "\n"):
try:
logfile.write(logged + "\n")
except IOError:
g.exit("Log can't be written to!")
else:
print "Written " + raw(logged) + " to the log!"
def testReaction(xpos, ypos, sli):
found = false
global debug
global maxgen
orig = g.getcells(g.getrect())
g.putcells(stillLifes[sli], xpos, ypos)
this = g.getcells(g.getrect())
oldgeneration = g.getgen()
for i in range(maxgen):
oldpat = g.getcells(g.getrect())
g.step()
if g.getcells(g.getrect()) == oldpat or g.getcells(g.getrect()) == []:
break
if celleq(g.getcells(g.getrect()), herschels[sli]):
found = True
break
g.clear(0)
g.clear(1)
g.setgen(oldgeneration)
if found:
g.putcells(this)
logToLogFile("Found reaction!")
else:
g.putcells(orig)
logToLogFile("No result found at x:" + str(xpos) + ", y:" + str(ypos) + ", still life " + str(sli))
def tests():
global found
for n in range(testrect[2]):
for m in range(testrect[3]):
for o in range(len(stillLifes)):
testReaction(n + testrect[0], m + testrect[1], o)
if found:
return
tests()
ME.AM.DUMB
Anyway here is a sample config file:
Code: Select all
[General]
DebugMode=true
LogFilename="hrf.log"
[Input]
Generations=500
Results=3o$2bo$3o!,3o$o$3o!,3o$obo$obo!,obo$obo$3o!,2o$2o!
Baits=2o$2o!,o$3o$3bo$2b2o!,bo$obo$obo$bo!,b2o$o2bo$b2o!,2b2o$bobo$bo$2o!
*yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times.
- Gustavo6046
- Posts: 647
- Joined: December 7th, 2013, 6:26 pm
- Location: Brazil.
Re: Gustavo Ramos Rehermann's patterns
Working HRF v0.2:
Also this is the new INI specification:
Code: Select all
import golly as g
from sys import exit
from time import sleep
import ConfigParser as cp
import os
herschels = []
stillLifes = []
def celleq(self, other):
ssort, osort = g.evolve(self, 0), g.evolve(other, 0)
return g.transform(ssort,-ssort[0],-ssort[1]) == g.transform(osort,-osort[0],-osort[1])
assert celleq([0, 1, 0, 2], [0, 2, 0, 3])
testrect = g.getselrect();
if testrect == []:
g.exit("Select the area where the still life is placeable!")
if g.empty():
g.exit("There is no pattern to add bait!")
def parseRLEs(*args):
tmp = []
for x in args:
tmp.append(g.parse(x))
return tmp
inputconfig = g.getstring("Which file to get configuration from?", "hrf_test1.ini", "HRF v0.2")
input = cp.RawConfigParser()
if input.read(inputconfig) == []:
g.exit("Non-existent config file!")
try:
debug = input.getboolean("General", "DebugMode")
maxgen = input.getint("Input", "Generations")
herschels = parseRLEs(*input.get("Input", "Results").split(","))
stillLifes = parseRLEs(*input.get("Input", "Baits").split(","))
logfile = open(input.get("General", "LogFilename"), "w")
outdir = input.get("General", "OutputDir")
except ValueError:
g.exit("Invalid value(s) in config!")
except cp.NoSectionError:
g.exit("Invalid sections in config!")
except cp.NoOptionError:
g.exit("Invalid options in config!")
def logToLogfile(logged = "\n"):
try:
logfile.write(logged + "\n")
except IOError:
g.exit("Log can't be written to!")
results = 0
this = []
def ensure_dir(f):
if not os.path.exists(f):
os.makedirs(f)
ensure_dir(outdir)
def testReaction(xpos, ypos, sli):
found = False
global debug
global maxgen
global results
global this
orig = g.getcells(g.getrect())
g.putcells(stillLifes[sli], xpos, ypos)
this = g.getcells(g.getrect())
oldgeneration = g.getgen()
for i in range(maxgen):
oldpat = g.getcells(g.getrect())
g.step()
if g.getcells(g.getrect()) == oldpat or g.getcells(g.getrect()) == []:
break
if celleq(g.getcells(g.getrect()), herschels[sli]):
found = True
break
g.clear(0)
g.clear(1)
g.setgen(oldgeneration)
if found:
results += 1
g.putcells(orig)
logToLogfile("Found reaction!")
output = open(outdir + "\\hrf_output" + str(results) + ".cells", "w")
output.write(str(this))
output.close()
else:
g.putcells(orig)
logToLogfile("No result found at x:" + str(xpos) + ", y:" + str(ypos) + ", still life " + str(sli))
def tests():
global found
for n in range(testrect[2]):
for m in range(testrect[3]):
for o in range(len(stillLifes)):
testReaction(n + testrect[0], m + testrect[1], o)
tests()
logfile.close()
g.clear(1)
g.clear(0)
g.putcells(this)
Code: Select all
[General]
DebugMode=<whether debug mode is on>
LogFilename=<filename of log>
OutputDir=<name of directory to save outputs to>
[Input]
Generations=<max number of generations in each test>
Results=<desired result RLEs separated by comma and no space>
Baits=<bait still life RLEs separated by comma and no space>
*yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times.
- Gustavo6046
- Posts: 647
- Joined: December 7th, 2013, 6:26 pm
- Location: Brazil.
Re: Gustavo Ramos Rehermann's patterns
I tried inserting Nathaniel's RLE script but it gives me a "int object has no attribute '__getitem__'" error, which is omfg very freaking weird. Maybe it's for older Python versions?
*yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times.
Re: Gustavo Ramos Rehermann's patterns
No, it works fine with the latest Python. Do you mean you tried using the version of Nathaniel's script that I just re-posted? My version of the function had a few new lines of code at the beginning, which changed the function's expected input so it can handle a regular flat cell list.Gustavo6046 wrote:I tried inserting Nathaniel's RLE script but it gives me a "int object has no attribute '__getitem__'" error, which is omfg very freaking weird. Maybe it's for older Python versions?
Or did you go back and get Nathaniel's original script, and then try to pass it a regular flat cell list? I would imagine you might well get some mysterious error along those lines, in that case. The error is just saying:
Your code wants this data to be a list (or something with multiple pieces, anyway).
But this data that I actually have is not a list, it's just a plain old number.
I haven't tried it, but you might get something similar if you try to pass in a multistate cell list. If you want to handle that case, you need to test for it specifically, set the chunk size to 3 if necessary, throw out any state-2 blue cells, and so forth.
Or keep things simple and just do the conversion to a single-state rule before you start, using some code along the lines of ToLife.py.
- Gustavo6046
- Posts: 647
- Joined: December 7th, 2013, 6:26 pm
- Location: Brazil.
Re: Gustavo Ramos Rehermann's patterns
OK, I'll use your variant them.
But I guess it's later, because I have YET ANOTHER error in my hands: (oh crap)
Yes, that's quite a bit of code. It will most probably be hard to debug.
The error is "list index out of range" at line 126.
Sometimes it will give some "Access Negated" errors but nothing that worries. I wonder how to ignore a exception...
But I guess it's later, because I have YET ANOTHER error in my hands: (oh crap)
Code: Select all
import golly as g
from sys import exit
from time import sleep
import ConfigParser as cp
import os, shutil
herschels = []
stillLifes = []
def celleq(self, other):
ssort, osort = g.evolve(self, 0), g.evolve(other, 0)
return g.transform(ssort,-ssort[0],-ssort[1]) == g.transform(osort,-osort[0],-osort[1])
assert celleq([0, 1, 0, 2], [0, 2, 0, 3])
testrect = g.getselrect();
if testrect == []:
g.exit("Select the area where the still life is placeable!")
if g.empty():
g.exit("There is no pattern to add bait!")
def chunks(l, n):
for i in range(0, len(l), n):
yield l[i:i+n]
def giveRLE(rl_list):
rle_res = ""
rle_len = 1
rl_y = rl_list[0][1] - 1
rl_x = 0
for rl_i in rl_list:
if rl_i[1] == rl_y:
if rl_i[0] == rl_x + 1:
rle_len += 1
else:
if rle_len == 1: rle_strA = ""
else: rle_strA = str (rle_len)
if rl_i[0] - rl_x - 1 == 1: rle_strB = ""
else: rle_strB = str (rl_i[0] - rl_x - 1)
rle_res = rle_res + rle_strA + "o" + rle_strB + "b"
rle_len = 1
else:
if rle_len == 1: rle_strA = ""
else: rle_strA = str (rle_len)
if rl_i[1] - rl_y == 1: rle_strB = ""
else: rle_strB = str (rl_i[1] - rl_y)
if rl_i[0] == 1: rle_strC = "b"
elif rl_i[0] == 0: rle_strC = ""
else: rle_strC = str (rl_i[0]) + "b"
rle_res = rle_res + rle_strA + "o" + rle_strB + "$" + rle_strC
rle_len = 1
rl_x = rl_i[0]
rl_y = rl_i[1]
if rle_len == 1: rle_strA = ""
else: rle_strA = str (rle_len)
rle_res = rle_res[2:] + rle_strA + "o"
return rle_res
def parseRLEs(*args):
tmp = []
for x in args:
tmp.append(g.parse(x))
return tmp
inputconfig = g.getstring("Which file to get configuration from?", "hrf_test1.ini", "HRF v0.2")
input = cp.RawConfigParser()
if input.read(inputconfig) == []:
g.exit("Non-existent config file!")
try:
debug = input.getboolean("General", "DebugMode")
maxgen = input.getint("Input", "Generations")
herschels = parseRLEs(*input.get("Input", "Results").split(","))
stillLifes = parseRLEs(*input.get("Input", "Baits").split(","))
logfile = open(input.get("General", "LogFilename"), "w")
outdir = input.get("General", "OutputDir")
except ValueError:
g.exit("Invalid value(s) in config!")
except cp.NoSectionError:
g.exit("Invalid sections in config!")
except cp.NoOptionError:
g.exit("Invalid options in config!")
def logToLogfile(logged = "\n"):
try:
logfile.write(logged + "\n")
except IOError:
g.exit("Log can't be written to!")
results = 0
this = []
def ensure_dir(f):
if not os.path.exists(f):
os.makedirs(f)
if os.path.isdir(outdir):
shutil.rmtree(outdir)
ensure_dir(outdir)
def testReaction(xpos, ypos, sli):
found = False
global debug
global maxgen
global results
global this
orig = g.getcells(g.getrect())
g.putcells(stillLifes[sli], xpos, ypos)
this = g.getcells(g.getrect())
oldgeneration = g.getgen()
for i in range(maxgen):
oldpat = g.getcells(g.getrect())
g.step()
if g.getcells(g.getrect()) == oldpat or g.getcells(g.getrect()) == []:
break
if celleq(g.getcells(g.getrect()), herschels[sli]):
found = True
break
g.clear(0)
g.clear(1)
g.setgen(oldgeneration)
if found:
results += 1
g.putcells(orig)
logToLogfile("Found reaction!")
output = open(outdir + "\\hrf_output" + str(results) + ".cells", "w")
output.write(giveRLE(g.evolve(this, 0)))
output.close()
else:
g.putcells(orig)
logToLogfile("No result found at x:" + str(xpos) + ", y:" + str(ypos) + ", still life " + str(sli))
def tests():
global found
for n in range(testrect[2]):
for m in range(testrect[3]):
for o in range(len(stillLifes)):
testReaction(n + testrect[0], m + testrect[1], o)
tests()
logfile.close()
g.clear(1)
g.clear(0)
g.putcells(this)
The error is "list index out of range" at line 126.
Sometimes it will give some "Access Negated" errors but nothing that worries. I wonder how to ignore a exception...
*yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times.
Re: Gustavo Ramos Rehermann's patterns
I can see that your python is improving every version. This seems to be good practice for you.
I would recommend posting the whole error message (unless it's too long) so that people would have a better idea of the problem.
Anyway, as there are no more information available, I would have to assume that the error was raised inside the "celleq" function body. For that to raise an IndexError, line 12:should be a problem when osort or ssort has less than 2 items. (Which would be when osort or ssort is an empty cell list.)
@Gustavo You **did** fix that prior bug before you added functionality, right? Extending a not-working program seems to be a little nonsense, and would create a bigger not-working program instead of a small but working one.
@dvgrn By the way, does g.evolve(clist, 0) sort all the coordinates?
EDIT: Thanks for the explanation. (it's in page 38)
Line 126 is a call to the function "celleq", and for that line to raise an error, the function body of celleq may be a problem?Gustavo6046 wrote:The error is "list index out of range" at line 126.
I would recommend posting the whole error message (unless it's too long) so that people would have a better idea of the problem.
Anyway, as there are no more information available, I would have to assume that the error was raised inside the "celleq" function body. For that to raise an IndexError, line 12:
Code: Select all
return g.transform(ssort,-ssort[0],-ssort[1]) == g.transform(osort,-osort[0],-osort[1])
@Gustavo You **did** fix that prior bug before you added functionality, right? Extending a not-working program seems to be a little nonsense, and would create a bigger not-working program instead of a small but working one.
@dvgrn By the way, does g.evolve(clist, 0) sort all the coordinates?
EDIT: Thanks for the explanation. (it's in page 38)
Last edited by Scorbie on January 23rd, 2016, 4:10 am, edited 1 time in total.
- Gustavo6046
- Posts: 647
- Joined: December 7th, 2013, 6:26 pm
- Location: Brazil.
Re: Gustavo Ramos Rehermann's patterns
Thanks! Just fixed it.
It works fine for a few cycles, then crashes because of a line 141 IndexError:
It works fine for a few cycles, then crashes because of a line 141 IndexError:
Code: Select all
import golly as g
from sys import exit
from time import sleep
import ConfigParser as cp
import os, glob
herschels = []
stillLifes = []
def celleq(self, other):
if self != [] or other != []:
ssort, osort = g.evolve(self, 0), g.evolve(other, 0)
return g.transform(ssort,-ssort[0],-ssort[1]) == g.transform(osort,-osort[0],-osort[1])
elif self == other:
return true
else:
return false
assert celleq([0, 1, 0, 2], [0, 2, 0, 3])
testrect = g.getselrect();
if testrect == []:
g.exit("Select the area where the still life is placeable!")
if g.empty():
g.exit("There is no pattern to add bait!")
def chunks(l, n):
for i in range(0, len(l), n):
yield l[i:i+n]
def parseRLEs(*args):
tmp = []
for x in args:
tmp.append(g.parse(x))
return tmp
def chunks(l, n):
for i in range(0, len(l), n):
yield l[i:i+n]
def giveRLE(clist):
clist_chunks = list (chunks (clist, 2))
mcc = min(clist_chunks)
rl_list = [[x[0]-mcc[0],x[1]-mcc[1]] for x in clist_chunks]
rle_res = ""
rle_len = 1
rl_y = rl_list[0][1] - 1
rl_x = 0
for rl_i in rl_list:
if rl_i[1] == rl_y:
if rl_i[0] == rl_x + 1:
rle_len += 1
else:
if rle_len == 1: rle_strA = ""
else: rle_strA = str (rle_len)
if rl_i[0] - rl_x - 1 == 1: rle_strB = ""
else: rle_strB = str (rl_i[0] - rl_x - 1)
rle_res = rle_res + rle_strA + "o" + rle_strB + "b"
rle_len = 1
else:
if rle_len == 1: rle_strA = ""
else: rle_strA = str (rle_len)
if rl_i[1] - rl_y == 1: rle_strB = ""
else: rle_strB = str (rl_i[1] - rl_y)
if rl_i[0] == 1: rle_strC = "b"
elif rl_i[0] == 0: rle_strC = ""
else: rle_strC = str (rl_i[0]) + "b"
rle_res = rle_res + rle_strA + "o" + rle_strB + "$" + rle_strC
rle_len = 1
rl_x = rl_i[0]
rl_y = rl_i[1]
if rle_len == 1: rle_strA = ""
else: rle_strA = str (rle_len)
rle_res = rle_res[2:] + rle_strA + "o"
return rle_res+"!"
inputconfig = g.getstring("Which file to get configuration from?", "hrf_test1.ini", "HRF v0.2")
input = cp.RawConfigParser()
if input.read(inputconfig) == []:
g.exit("Non-existent config file!")
try:
debug = input.getboolean("General", "DebugMode")
maxgen = input.getint("Input", "Generations")
herschels = parseRLEs(*input.get("Input", "Results").split(","))
stillLifes = parseRLEs(*input.get("Input", "Baits").split(","))
logfile = open(input.get("General", "LogFilename"), "w")
outdir = input.get("General", "OutputDir")
except ValueError:
g.exit("Invalid value(s) in config!")
except cp.NoSectionError:
g.exit("Invalid sections in config!")
except cp.NoOptionError:
g.exit("Invalid options in config!")
def logToLogfile(logged = "\n"):
try:
logfile.write(logged + "\n")
except IOError:
g.exit("Log can't be written to!")
results = 0
this = []
def ensure_dir(f):
if not os.path.exists(f):
os.makedirs(f)
os.chmod(f)
def remove_folder_content(f):
filelist = glob.glob(f + "\\*.*")
for x in filelist:
os.remove(x)
remove_folder_content(outdir)
ensure_dir(outdir)
def testReaction(xpos, ypos, sli):
found = False
global debug
global maxgen
global results
global this
orig = g.getcells(g.getrect())
g.putcells(stillLifes[sli], xpos, ypos)
this = g.getcells(g.getrect())
oldgeneration = g.getgen()
for i in range(maxgen):
oldpat = g.getcells(g.getrect())
g.step()
if g.getcells(g.getrect()) == oldpat or g.getcells(g.getrect()) == []:
break
if celleq(g.getcells(g.getrect()), herschels[sli]):
found = True
break
g.clear(0)
g.clear(1)
g.setgen(oldgeneration)
if found:
results += 1
g.putcells(orig)
logToLogfile("Found reaction!")
output = open(outdir + "\\hrf_output" + str(results) + ".cells", "w")
output.write(giveRLE(g.evolve(this, 0)))
output.close()
else:
g.putcells(orig)
logToLogfile("No result found at x:" + str(xpos) + ", y:" + str(ypos) + ", still life " + str(sli))
def tests():
global found
for n in range(testrect[2]):
for m in range(testrect[3]):
for o in range(len(stillLifes)):
testReaction(n + testrect[0], m + testrect[1], o)
tests()
logfile.close()
g.clear(1)
g.clear(0)
g.putcells(this)
*yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times.
Re: Gustavo Ramos Rehermann's patterns
Hmm, it's the same function call again and I'm not sure what's the problem... Good luck. Crashes leave stack traces, so I guess that would be easier to fix than subtle bugs.Gustavo6046 wrote:It works fine for a few cycles, then crashes because of a line 141 IndexError:
Anyway, as I said before,
If a Golly python script crashes, I think it gives the um... call trace(?) with a popup window. Copy that message and paste it here next time.I would recommend posting the whole error message (unless it's too long) so that people would have a better idea of the problem.