Script request thread for Python 3.x updates

For scripts to aid with computation or simulation in cellular automata.
Post Reply
User avatar
dvgrn
Moderator
Posts: 9016
Joined: May 17th, 2009, 11:00 pm
Location: Madison, WI
Contact:

Script request thread for Python 3.x updates

Post by dvgrn » October 31st, 2020, 8:06 am

In the last few weeks, whenever I've needed an old Golly Python 2.x script that was posted on the forums to work in Golly 4.0 and Python 3.x, I've been running the 2to3 update utility on it to change xrange to range and so forth. Usually the script runs fine after 2to3 has done its work on it.

Then I've been cavalierly using my ModeratorSuperPowers (TM) to edit the original post, using patent-pending green text, to either add a Python 3.x version of the script directly to the post, or in some cases to point to where the 3.x version lives in a GitHub repository. An example is biggiemac's script for looking up objects on Catagolue. I'll probably take this opportunity to build a big collection of works-in-3.x utility scripts, over time, in this GitHub folder,

Please post here any links you find to posted Python scripts that need the same treatment... and preferably include the text of a corrected, working version of the script! I'll be happy to make edits as needed to the original posts, but I'd very much appreciate a "many hands make light work" approach to doing the actual conversions. Anyone else seeing a request here before I get to it is welcome to post a converted script, if the original requester doesn't do that.

Comments and discussion about possible improvements to this approach to the 2.x -> 3.x upgrade problem are also welcome here.

User avatar
GUYTU6J
Posts: 1881
Joined: August 5th, 2016, 10:27 am
Location: 拆哪!I repeat, CHINA! (a.k.a. 种花家)
Contact:

Re: Script request thread for Python 3.x updates

Post by GUYTU6J » October 31st, 2020, 11:50 am

The repeat.py comes from here, and works well after removing the x before range. But nobody is going to care about it besides me so I may just edit my user page Another problematic script I have is the giffer.py from Scorbie.
---
Apart from xrange, the phrase "from string import replace" malfunctions too with python 3.9. It happens when I try running the following version of isorule.py, which unfortunately I can't find the source:

Code: Select all

# isorule.py
# A modification of partialrule.py which returns the isotropic rulespace for a pattern in a format suitable for infoboxes on the wiki.
# This simply checks the number of generations you input to see if the pattern's evolution is the same, so it can be used for non-periodic patterns as well.
# Shamelessly stolen from Rhombic (Feb 2018) by Ian07 (Jan 2019).
 
import golly as g
from glife import validint
from string import replace
 
Hensel = [
    ['0'],
    ['1c', '1e'],
    ['2a', '2c', '2e', '2i', '2k', '2n'],
    ['3a', '3c', '3e', '3i', '3j', '3k', '3n', '3q', '3r', '3y'],
    ['4a', '4c', '4e', '4i', '4j', '4k', '4n', '4q', '4r', '4t', '4w', '4y', '4z'],
    ['5a', '5c', '5e', '5i', '5j', '5k', '5n', '5q', '5r', '5y'],
    ['6a', '6c', '6e', '6i', '6k', '6n'],
    ['7c', '7e'],
    ['8']
]
 
# Python versions < 2.4 don't have "sorted" built-in
try:
    sorted
except NameError:
    def sorted(inlist):
        outlist = list(inlist)
        outlist.sort()
        return outlist
 
# --------------------------------------------------------------------
 
def chunks(l, n):
    for i in range(0, len(l), n):
        yield l[i:i+n]
 
# --------------------------------------------------------------------
 
def rulestringopt(a):
    result = ''
    context = ''
    lastnum = ''
    lastcontext = ''
    for i in a:
        if i in 'BS':
            context = i
            result += i
        elif i in '012345678':
            if (i == lastnum) and (lastcontext == context):
                pass
            else:
                lastcontext = context
                lastnum = i
                result += i
        else:
            result += i
    result = replace(result, '4aceijknqrtwyz', '4')
    result = replace(result, '3aceijknqry', '3')
    result = replace(result, '5aceijknqry', '5')
    result = replace(result, '2aceikn', '2')
    result = replace(result, '6aceikn', '6')
    result = replace(result, '1ce', '1')
    result = replace(result, '7ce', '7')
    return result
 
clist = []
rule = g.getrule().split(':')[0]
 
fuzzer = rule + '9'
oldrule = rule
rule = ''
context = ''
deletefrom = []
for i in fuzzer:
    if i == '-':
        deletefrom = [x[1] for x in Hensel[int(context)]]
    elif i in '0123456789/S':
        if deletefrom:
            rule += ''.join(deletefrom)
            deletefrom = []
        context = i
    if len(deletefrom) == 0:
        rule += i
    elif i in deletefrom:
        deletefrom.remove(i)
rule = rule.strip('9')
 
if not (rule[0] == 'B' and '/S' in rule):
    g.exit('Please set Golly to a Life-like rule.')
 
if g.empty():
    g.exit('The pattern is empty.')
 
s = g.getstring('Enter the period:', '', 'Rules calculator')
if not validint(s):
    g.exit('Bad number: %s' % s)
 
numsteps = int(s)
if numsteps < 1:
    g.exit('Period must be at least 1.')
 
g.select(g.getrect())
g.copy()
s = int(s)
 
for i in range(0,s):
    g.run(1)
    clist.append(list(chunks(g.getcells(g.getrect()), 2)))
    mcc = min(clist[i])
    clist[i] = [[x[0] - mcc[0], x[1] - mcc[1]] for x in clist[i]]
 
g.show('Processing...')
 
ruleArr = rule.split('/')
ruleArr[0] = ruleArr[0].lstrip('B')
ruleArr[1] = ruleArr[1].lstrip('S')
 
b_need = []
b_OK = []
s_need = []
s_OK = []
 
context = ''
fuzzed = ruleArr[0] + '9'
for i in fuzzed:
    if i in '0123456789':
        if len(context) == 1:
            b_need += Hensel[int(context)]
            b_OK += Hensel[int(context)]
        context = i
    elif context != '':
        b_need.append(context[0] + i)
        b_OK.append(context[0] + i)
        context += context[0]
context = ''
fuzzed = ruleArr[1] + '9'
for i in fuzzed:
    if i in '0123456789':
        if len(context) == 1:
            s_need += Hensel[int(context)]
            s_OK += Hensel[int(context)]
        context = i
    elif context != '':
        s_need.append(context[0] + i)
        s_OK.append(context[0] + i)
        context += context[0]
 
for i in [iter2 for iter1 in Hensel for iter2 in iter1]:
    if not i in b_OK:
        b_OK.append(i)
        execfor = 1
        # B0 and nontotalistic rulestrings are mutually exclusive
        try:
            g.setrule(rulestringopt('B' + ''.join(b_OK) + '/S' + ruleArr[1]))
        except:
            b_OK.remove(i)
            execfor = 0
        for j in range(0, s * execfor):
            g.run(1)
            try:
                dlist = list(chunks(g.getcells(g.getrect()), 2))
                mcc = min(dlist)
                dlist = [[x[0] - mcc[0], x[1] - mcc[1]] for x in dlist]
                if not(clist[j] == dlist):
                    b_OK.remove(i)
                    break
            except:
                b_OK.remove(i)
                break
        g.new('')
        g.paste(0, 0, 'or')
        g.select(g.getrect())
        b_OK.sort()
 
    if not i in s_OK:
        s_OK.append(i)
        execfor = 1
        # B0 and nontotalistic rulestrings are mutually exclusive
        try:
            g.setrule(rulestringopt('B' + ruleArr[0] + '/S' + ''.join(s_OK)))
        except:
            s_OK.remove(i)
            execfor = 0
        for j in range(0, s * execfor):
            g.run(1)
            try:
                dlist = list(chunks(g.getcells(g.getrect()), 2))
                mcc = min(dlist)
                dlist = [[x[0] - mcc[0], x[1] - mcc[1]] for x in dlist]
                if not(clist[j] == dlist):
                    s_OK.remove(i)
                    break
            except:
                s_OK.remove(i)
                break
        g.new('')
        g.paste(0, 0, 'or')
        g.select(g.getrect())
        s_OK.sort()
 
    if i in b_need:
        b_need.remove(i)
        g.setrule(rulestringopt('B' + ''.join(b_need) + '/S' + ruleArr[1]))
        for j in range(0, s):
            g.run(1)
            try:
                dlist = list(chunks(g.getcells(g.getrect()), 2))
                mcc = min(dlist)
                dlist = [[x[0] - mcc[0], x[1] - mcc[1]] for x in dlist]
                if not(clist[j] == dlist):
                    b_need.append(i)
                    break
            except:
                b_need.append(i)
                break
        g.new('')
        g.paste(0, 0, 'or')
        g.select(g.getrect())
        b_need.sort()
 
    if i in s_need:
        s_need.remove(i)
        g.setrule(rulestringopt('B' + ruleArr[0] + '/S' + ''.join(s_need)))
        for j in range(0, s):
            g.run(1)
            try:
                dlist = list(chunks(g.getcells(g.getrect()), 2))
                mcc = min(dlist)
                dlist = [[x[0] - mcc[0], x[1] - mcc[1]] for x in dlist]
                if not(clist[j] == dlist):
                    s_need.append(i)
                    break
            except:
                s_need.append(i)
                break
        g.new('')
        g.paste(0, 0, 'or')
        g.select(g.getrect())
        s_need.sort()
 
g.setrule('B' + ''.join(sorted(b_need)) + '/S' + ''.join(sorted(s_need)))
rulemin = g.getrule()
 
g.setrule('B' + ''.join(sorted(b_OK)) + '/S' + ''.join(sorted(s_OK)))
rulemax = g.getrule()
 
ruleres = '|isorulemin       = ' + rulemin + '|isorulemax       = ' + rulemax
g.show(ruleres)
g.setclipstr(ruleres)
g.setrule(oldrule)
Why do most 2-state OCA rules tend to get a diminishing span of interest and go into oblivion, like lost civilizations leaving little records for their beauty and power?

Here multiflorate splendour blooms forlorn
Midst broken fountains, mouldering walls.

User avatar
Ian07
Posts: 837
Joined: September 22nd, 2018, 8:48 am

Re: Script request thread for Python 3.x updates

Post by Ian07 » October 31st, 2020, 9:51 pm

GUYTU6J wrote:
October 31st, 2020, 11:50 am
---
Apart from xrange, the phrase "from string import replace" malfunctions too with python 3.9. It happens when I try running the following version of isorule.py, which unfortunately I can't find the source:
That's from Pastebin, which has now been updated accordingly. It was an easy fix - all I had to do was remove that line and replace replace() with str.replace():

Code: Select all

# isorule.py
# A modification of partialrule.py which returns the isotropic rulespace for a pattern in a format suitable for infoboxes on the wiki.
# This simply checks the number of generations you input to see if the pattern's evolution is the same, so it can be used for non-periodic patterns as well.
# Shamelessly stolen from Rhombic (Feb 2018) by Ian07 (Jan 2019).
# Now fixed for Python 3.x! (Oct 2020)

import golly as g
from glife import validint

Hensel = [
    ['0'],
    ['1c', '1e'],
    ['2a', '2c', '2e', '2i', '2k', '2n'],
    ['3a', '3c', '3e', '3i', '3j', '3k', '3n', '3q', '3r', '3y'],
    ['4a', '4c', '4e', '4i', '4j', '4k', '4n', '4q', '4r', '4t', '4w', '4y', '4z'],
    ['5a', '5c', '5e', '5i', '5j', '5k', '5n', '5q', '5r', '5y'],
    ['6a', '6c', '6e', '6i', '6k', '6n'],
    ['7c', '7e'],
    ['8']
]

# Python versions < 2.4 don't have "sorted" built-in
try:
    sorted
except NameError:
    def sorted(inlist):
        outlist = list(inlist)
        outlist.sort()
        return outlist

# --------------------------------------------------------------------

def chunks(l, n):
    for i in range(0, len(l), n):
        yield l[i:i+n]

# --------------------------------------------------------------------

def rulestringopt(a):
    result = ''
    context = ''
    lastnum = ''
    lastcontext = ''
    for i in a:
        if i in 'BS':
            context = i
            result += i
        elif i in '012345678':
            if (i == lastnum) and (lastcontext == context):
                pass
            else:
                lastcontext = context
                lastnum = i
                result += i
        else:
            result += i
    result = str.replace(result, '4aceijknqrtwyz', '4')
    result = str.replace(result, '3aceijknqry', '3')
    result = str.replace(result, '5aceijknqry', '5')
    result = str.replace(result, '2aceikn', '2')
    result = str.replace(result, '6aceikn', '6')
    result = str.replace(result, '1ce', '1')
    result = str.replace(result, '7ce', '7')
    return result

clist = []
rule = g.getrule().split(':')[0]

fuzzer = rule + '9'
oldrule = rule
rule = ''
context = ''
deletefrom = []
for i in fuzzer:
    if i == '-':
        deletefrom = [x[1] for x in Hensel[int(context)]]
    elif i in '0123456789/S':
        if deletefrom:
            rule += ''.join(deletefrom)
            deletefrom = []
        context = i
    if len(deletefrom) == 0:
        rule += i
    elif i in deletefrom:
        deletefrom.remove(i)
rule = rule.strip('9')

if not (rule[0] == 'B' and '/S' in rule):
    g.exit('Please set Golly to a Life-like rule.')

if g.empty():
    g.exit('The pattern is empty.')

s = g.getstring('Enter the period:', '', 'Rules calculator')
if not validint(s):
    g.exit('Bad number: %s' % s)

numsteps = int(s)
if numsteps < 1:
    g.exit('Period must be at least 1.')

g.select(g.getrect())
g.copy()
s = int(s)

for i in range(0,s):
    g.run(1)
    clist.append(list(chunks(g.getcells(g.getrect()), 2)))
    mcc = min(clist[i])
    clist[i] = [[x[0] - mcc[0], x[1] - mcc[1]] for x in clist[i]]

g.show('Processing...')

ruleArr = rule.split('/')
ruleArr[0] = ruleArr[0].lstrip('B')
ruleArr[1] = ruleArr[1].lstrip('S')

b_need = []
b_OK = []
s_need = []
s_OK = []

context = ''
fuzzed = ruleArr[0] + '9'
for i in fuzzed:
    if i in '0123456789':
        if len(context) == 1:
            b_need += Hensel[int(context)]
            b_OK += Hensel[int(context)]
        context = i
    elif context != '':
        b_need.append(context[0] + i)
        b_OK.append(context[0] + i)
        context += context[0]
context = ''
fuzzed = ruleArr[1] + '9'
for i in fuzzed:
    if i in '0123456789':
        if len(context) == 1:
            s_need += Hensel[int(context)]
            s_OK += Hensel[int(context)]
        context = i
    elif context != '':
        s_need.append(context[0] + i)
        s_OK.append(context[0] + i)
        context += context[0]

for i in [iter2 for iter1 in Hensel for iter2 in iter1]:
    if not i in b_OK:
        b_OK.append(i)
        execfor = 1
        # B0 and nontotalistic rulestrings are mutually exclusive
        try:
            g.setrule(rulestringopt('B' + ''.join(b_OK) + '/S' + ruleArr[1]))
        except:
            b_OK.remove(i)
            execfor = 0
        for j in range(0, s * execfor):
            g.run(1)
            try:
                dlist = list(chunks(g.getcells(g.getrect()), 2))
                mcc = min(dlist)
                dlist = [[x[0] - mcc[0], x[1] - mcc[1]] for x in dlist]
                if not(clist[j] == dlist):
                    b_OK.remove(i)
                    break
            except:
                b_OK.remove(i)
                break
        g.new('')
        g.paste(0, 0, 'or')
        g.select(g.getrect())
        b_OK.sort()

    if not i in s_OK:
        s_OK.append(i)
        execfor = 1
        # B0 and nontotalistic rulestrings are mutually exclusive
        try:
            g.setrule(rulestringopt('B' + ruleArr[0] + '/S' + ''.join(s_OK)))
        except:
            s_OK.remove(i)
            execfor = 0
        for j in range(0, s * execfor):
            g.run(1)
            try:
                dlist = list(chunks(g.getcells(g.getrect()), 2))
                mcc = min(dlist)
                dlist = [[x[0] - mcc[0], x[1] - mcc[1]] for x in dlist]
                if not(clist[j] == dlist):
                    s_OK.remove(i)
                    break
            except:
                s_OK.remove(i)
                break
        g.new('')
        g.paste(0, 0, 'or')
        g.select(g.getrect())
        s_OK.sort()

    if i in b_need:
        b_need.remove(i)
        g.setrule(rulestringopt('B' + ''.join(b_need) + '/S' + ruleArr[1]))
        for j in range(0, s):
            g.run(1)
            try:
                dlist = list(chunks(g.getcells(g.getrect()), 2))
                mcc = min(dlist)
                dlist = [[x[0] - mcc[0], x[1] - mcc[1]] for x in dlist]
                if not(clist[j] == dlist):
                    b_need.append(i)
                    break
            except:
                b_need.append(i)
                break
        g.new('')
        g.paste(0, 0, 'or')
        g.select(g.getrect())
        b_need.sort()

    if i in s_need:
        s_need.remove(i)
        g.setrule(rulestringopt('B' + ruleArr[0] + '/S' + ''.join(s_need)))
        for j in range(0, s):
            g.run(1)
            try:
                dlist = list(chunks(g.getcells(g.getrect()), 2))
                mcc = min(dlist)
                dlist = [[x[0] - mcc[0], x[1] - mcc[1]] for x in dlist]
                if not(clist[j] == dlist):
                    s_need.append(i)
                    break
            except:
                s_need.append(i)
                break
        g.new('')
        g.paste(0, 0, 'or')
        g.select(g.getrect())
        s_need.sort()

g.setrule('B' + ''.join(sorted(b_need)) + '/S' + ''.join(sorted(s_need)))
rulemin = g.getrule()

g.setrule('B' + ''.join(sorted(b_OK)) + '/S' + ''.join(sorted(s_OK)))
rulemax = g.getrule()

ruleres = '|isorulemin       = ' + rulemin + '|isorulemax       = ' + rulemax
g.show(ruleres)
g.setclipstr(ruleres)
g.setrule(oldrule)
P.S. general tip: Notepad++'s "Find in files" feature has been extremely helpful for me in finding instances of the most common errors, since I'm too lazy to use 2to3. :P

User avatar
GUYTU6J
Posts: 1881
Joined: August 5th, 2016, 10:27 am
Location: 拆哪!I repeat, CHINA! (a.k.a. 种花家)
Contact:

Re: Script request thread for Python 3.x updates

Post by GUYTU6J » November 7th, 2020, 6:03 am

Bump again:
GUYTU6J wrote:
October 31st, 2020, 11:50 am
...Another problematic script I have is the giffer.py from Scorbie.
If there is limited time for such fixes, then please start from considering the scripts employed in LifeWiki tutorials, especially:Tutorials/Contributing to 5S
Tutorials/Glider syntheses

(There is wildmyron's MuPopByPeriod.py somewhat related to the first tutorial as well)
Why do most 2-state OCA rules tend to get a diminishing span of interest and go into oblivion, like lost civilizations leaving little records for their beauty and power?

Here multiflorate splendour blooms forlorn
Midst broken fountains, mouldering walls.

User avatar
Scorbie
Posts: 1645
Joined: December 7th, 2013, 1:05 am

Re: Script request thread for Python 3.x updates

Post by Scorbie » December 5th, 2020, 10:52 pm

GUYTU6J wrote:
November 7th, 2020, 6:03 am
Bump again:
GUYTU6J wrote:
October 31st, 2020, 11:50 am
...Another problematic script I have is the giffer.py from Scorbie.
Cough cough, fixed and updated. I'm planning to freeze that repo without new features, only bugfixes.
(Cause I'm thinking of rewriting a new version in Lua)

User avatar
Ian07
Posts: 837
Joined: September 22nd, 2018, 8:48 am

Re: Script request thread for Python 3.x updates

Post by Ian07 » December 6th, 2020, 12:12 pm

Scorbie wrote:
December 5th, 2020, 10:52 pm
(Cause I'm thinking of rewriting a new version in Lua)
Awesome. Will it have the ability to make .png files as well for static images? Would be nice to have that feature for wiki work.

User avatar
LaundryPizza03
Posts: 1891
Joined: December 15th, 2017, 12:05 am
Location: Unidentified location "https://en.wikipedia.org/wiki/Texas"

Re: Script request thread for Python 3.x updates

Post by LaundryPizza03 » December 6th, 2020, 9:29 pm

All the 5s scripts stopped working in 3.9.

Code: Select all

x = 4, y = 3, rule = B3-q4z5y/S234k5j
2b2o$b2o$2o!
LaundryPizza03 at Wikipedia

The latest edition of new-gliders.db.txt and oscillators.db.txt have 35296 spaceships and 1451 oscillators from outer-totalistic rules. You are invited to help!

User avatar
Extrementhusiast
Posts: 1944
Joined: June 16th, 2009, 11:24 pm
Location: USA

Re: Script request thread for Python 3.x updates

Post by Extrementhusiast » January 29th, 2021, 4:22 pm

While spark_search.py runs without crashing, it returns way too many results (as in 1124 results for a southbound 2G block-to-beehive), all of which don't even include the pattern being changed.

EDIT: I think I figured it out:

Code: Select all

import golly as g
from collections import deque

direction = g.getstring("Enter direction (S or SE):", "S").upper()

if direction not in ["S", "SE"]:
    g.exit("Invalid direction")

delay = int(g.getstring("Enter delay:", "0"))
increase = int(g.getstring("Enter cell increase at penultimate step:", "1"))
offset = int(g.getstring("Enter horizontal offset between before/after:", "40"))
finalpop = int(g.getstring("Enter final population (-1 == don't care):", "-1"))
filename = g.getstring("Enter gencols filename:", "3g")
symm = g.getstring("Enter symmetries (x, d or xd):", "default")

if symm == "default":
    symm = ""
    if filename == "3g":
        symm += "x"
    if direction == "SE" and filename in ["2g", "3g", "s2g"]:
        symm += "d"

status = "dir: %s; delay %d; inc %d; symm %s; " % (direction, delay, increase, symm)
if finalpop >= 0: status += "finalpop %d; " % finalpop
status += "cols %s; " % filename

g.getevent()

[a, b] = [1, 1000] if direction == "S" else [1000, 1001]
    
cells = g.getcells(g.getrect())
cells = list(zip(cells[::3], cells[1::3], cells[2::3]))

mx = -9999999
ox = oy = 0

for x, y, z in cells:
    if z != 3:
        continue
    idx = a * x + b * y
    if idx > mx:
        mx = idx
        ox = x
        oy = y

on_cells = []
off_cells = []
example_cells = []
start_cells = []

for x, y, z in cells:
    if x <= ox + offset // 2:
        if z == 3:
            example_cells.append(x - ox)
            example_cells.append(y - oy)
        elif z == 1:
            start_cells.append(x - ox)
            start_cells.append(y - oy)
    else:
        if z == 1:
            on_cells.append((x - ox - offset, y - oy))
        elif z == 2:
            off_cells.append((x - ox - offset, y - oy))


results_layer = g.addlayer()
g.setname("Results")
g.setrule("Life")
g.setalgo("QuickLife")
work_layer = g.addlayer()
g.setname("Work area")

g.putcells(start_cells)
g.putcells(example_cells)
g.run(delay)

if not all(g.getcell(x, y) for x, y in on_cells) or any(g.getcell(x, y) for x, y in off_cells):
    g.warn("Warning: the example pattern is not a solution")

results = 0
spacing = 100

def apply_sym(pat, symm):
    yield pat
    if "x" in symm: yield g.transform(pat, 0, 0, -1, 0, 0, 1)
    if "d" in symm: yield g.transform(pat, 0, 0,  0, 1, 1, 0)
    if "x" in symm and "d" in symm:
        yield g.transform(pat, 0, 0, 1, -1, 0)

def testkey():
    if results and g.getevent().startswith("key x"):
        g.setlayer(results_layer)
        g.select(g.getrect())
        g.copy()
        g.select([])
        g.setlayer(work_layer)
        
def test(pat, gen, loc, x, y):

    global results, spacing
    
    if not all(g.getcell(x+loc, y) for x, y in on_cells):
        return
    
    if any(g.getcell(x+loc, y) for x, y in off_cells):
        return

    begin = start_cells + g.evolve(g.transform(pat, -x, -y), gen)

    if finalpop >= 0 and len(g.evolve(begin, 100)) != 2 * finalpop:
        return

    results += 1
    g.setlayer(results_layer)
    g.putcells(g.evolve(pat, gen % 8), spacing * results-x, -y)
    g.putcells(begin, spacing * results, spacing)
    g.putcells(g.evolve(begin, delay), spacing * results, 2*spacing)
    g.setlayer(work_layer)

    
count = 0
for s in open("gencols/" + filename + ".col"):
    count += 1
    pat = g.parse(s.split(" ")[0].replace('!','$').replace('.','b').replace('*','o')+'!')
    if count % 100 == 0:
        g.show(status + "results %d; <x> to copy to clipboard. count %d" % (results, count))
        testkey()

    for pat in apply_sym(pat, symm):
        g.new('')
        g.putcells(pat)
        q = deque()
        orect = [-128, -128, 256, 256]
        all_max = -9999999
        locs = set()
        for gen in range(80 + delay):

            cells = g.getcells(orect)
            current_max = -9999999
            for i in range(0, len(cells), 2):
                idx = a * cells[i] + b * cells[i+1]
                if idx > current_max:
                    current_max = idx
                    ox = cells[i]
                    oy = cells[i+1]

            if gen > 0 and current_max >= all_max + increase:
                loc = 256
                while loc in locs:
                    loc += 256
                locs.add(loc)
                q.append((gen, loc, ox, oy))
                g.putcells(cells, loc - ox, -oy)
                g.putcells(start_cells, loc)

            if q and q[0][0] + delay == gen:
                test(pat, *q[0])
                g.select([-128 + q[0][1], -128, 256, 256])
                g.clear(0)
                locs.remove(q[0][1])
                q.popleft()
            
            all_max = max(all_max, current_max)
            g.run(1)

testkey()
g.dellayer()
g.setlayer(results_layer)
g.fit()
The only change is in line 32, enclosing list() around zip(...).
I Like My Heisenburps! (and others)

User avatar
GUYTU6J
Posts: 1881
Joined: August 5th, 2016, 10:27 am
Location: 拆哪!I repeat, CHINA! (a.k.a. 种花家)
Contact:

Re: Script request thread for Python 3.x updates

Post by GUYTU6J » June 25th, 2021, 11:35 pm

Another bump, but the link is not available now. Where can I find new versions of this giffer?
Scorbie wrote:
December 5th, 2020, 10:52 pm
GUYTU6J wrote:
October 31st, 2020, 11:50 am
...Another problematic script I have is the giffer.py from Scorbie.
Cough cough, fixed and updated. I'm planning to freeze that repo without new features, only bugfixes.
(Cause I'm thinking of rewriting a new version in Lua)
(Stressed "this" because I remember there is another one floating around which is less adjustable and makes colorful 1-pixel-per cell gif only, and I have been confused by their relationship)
Why do most 2-state OCA rules tend to get a diminishing span of interest and go into oblivion, like lost civilizations leaving little records for their beauty and power?

Here multiflorate splendour blooms forlorn
Midst broken fountains, mouldering walls.

User avatar
Scorbie
Posts: 1645
Joined: December 7th, 2013, 1:05 am

Re: Script request thread for Python 3.x updates

Post by Scorbie » June 26th, 2021, 7:21 pm

GUYTU6J wrote:
June 25th, 2021, 11:35 pm
Another bump, but the link is not available now. Where can I find new versions of this giffer?
Scorbie wrote:
December 5th, 2020, 10:52 pm
GUYTU6J wrote:
October 31st, 2020, 11:50 am
...Another problematic script I have is the giffer.py from Scorbie.
Cough cough, fixed and updated. I'm planning to freeze that repo without new features, only bugfixes.
(Cause I'm thinking of rewriting a new version in Lua)
(Stressed "this" because I remember there is another one floating around which is less adjustable and makes colorful 1-pixel-per cell gif only, and I have been confused by their relationship)
Apologies, here you go.
I've removed my Github account and this is the code I've been using personally, so not 100% sure if there are no personal clobberings.
Should work without problems tho
Attachments
giffer.zip
Edited 2022-05-11 (bugfix)
(5.78 KiB) Downloaded 8 times

Post Reply