rle2blk Python script outputs rle to unicode block in console

For scripts to aid with computation or simulation in cellular automata.
Post Reply
User avatar
dexter1
Posts: 74
Joined: February 26th, 2020, 8:46 am

rle2blk Python script outputs rle to unicode block in console

Post by dexter1 » March 3rd, 2022, 7:45 am

I've written a python script which reads rle's in log files from qfind and ikpx2 and prints them in block characters on the console.

Code: Select all

frank@bluemoon:~/Documents/GOL/patterns/1c5$ more 76P5H1V0_kermit.rle 
#CXRLE Pos=-11,-7
x = 23, y = 15, rule = B3/S23
bo19bo$2o19b2o$o2bo4b2o3b2o4bo2bo$4bob2obo3bob2obo$3bo15bo$5b4o5b4o$9b
2ob2o2$10bobo$9bo3bo$5b5o3b5o$4b2o2b2o3b2o2b2o$4bo5bobo5bo$2b4o2bobobo
bo2b4o$9bo3bo!
frank@bluemoon:~/Documents/GOL/patterns/1c5$ ./rle2blk.py 76P5H1V0_kermit.rle 
▄█                   █▄
▀  ▀▄ ▄▄▀█   █▀▄▄ ▄▀  ▀
   ▀ ▄▄▄▄     ▄▄▄▄ ▀   
         ▀▀ ▀▀         
         ▄▀ ▀▄         
    ▄█▀▀██   ██▀▀█▄    
  ▄▄█▄  ▄ █ █ ▄  ▄█▄▄  
         ▀   ▀         

5
There is no gap in the console output as opposed to the code formatting in this post.

This way i can quickly eyeball if there are any interesting patterns appearing during calculations without resorting to cut and paste into Golly.
For each rle found and displayed, it will print the line number where the pattern is located in the log file, so the corresponding rle can be located.

Code: Select all

#!/usr/bin/env python3

import copy
import sys
import re

lookup_block = {
        0 : ' ' , 1 : '\u2598', 2 : '\u259d', 3 : '\u2580',
        4 : '\u2596', 5 : '\u258c', 6 : '\u259e', 7 : '\u259b',
        8 : '\u2597', 9 : '\u259a', 10 : '\u2590', 11 : '\u259c',
        12 : '\u2584', 13 : '\u2599', 14 : '\u259f', 15 : '\u2588'
        }

def make_blk(bitmap,maxwidth):
    """Turn bitmap list into a unicode block form"""

    width = len(bitmap[0])
    height = len(bitmap)

    blk_string = ""
    block = []
    for i in range(0,height,2) :
        for j in range(0,width) :
            key = 3 * bitmap[i][j]
            key += 12 * bitmap[i+1][j] if i+1<height else 0
            block.append(lookup_block[key])
        block.append('\n')
    blk_string += "".join(block)
    return blk_string

class RLE2Bitmap:
    def __init__(self):
        self.width = 0
        self.height = 0
        self.x = 0
        self.y = 0
        self.bitmap = []
        self.maxwidth = 100
        self.lineptr = 0

    def dimset(self):
        return ((self.width != 0) & (self.height != 0))

    def setdim(self, ls):
        self.x = 0
        self.y = 0
        values = ls.split(',')
        self.width = int(list(re.findall('\d+', values[0]))[0])
        self.height = int(list(re.findall('\d+', values[1]))[0])
        self.bitmap = [[0 for i in range(self.width)] for j in range(self.height)]
        
    def cleardim(self):
        self.width = 0
        self.height = 0

    def process(self, ls):
        self.lineptr += 1
        if (ls.startswith('x')):
            self.setdim(ls)
        else:
            if self.dimset():
                n = 0
                for c in ls:
                    if (c.isdigit()):
                        n = 10 * n + ord(c) - ord('0')
                    else:
                        if (n == 0):
                            n = 1
                        if (c == 'b'):
                            self.x += n
                            n = 0
                        if (c == '$'):
                            self.x = 0
                            self.y += n
                            n = 0
                        if (c == '!'):
                            print(make_blk(self.bitmap,self.maxwidth))
                            print(self.lineptr)
                            self.cleardim()
                            return
                        if (c == 'o'):
                            for i in range(self.x, self.x + n):
                                self.bitmap[self.y][i] = 1
                            self.x += n
                            n = 0 

if __name__ == "__main__":
    rbm = RLE2Bitmap()
    if len(sys.argv) > 1:
        with open(sys.argv[1],'r') as file_rle:
            for line_str in file_rle:
                rbm.process(line_str.rstrip('\n'))
Frank Everdij

AlbertArmStain
Posts: 1257
Joined: January 28th, 2022, 7:18 pm
Location: Planet Z

Re: rle2blk Python script outputs rle to unicode block in console

Post by AlbertArmStain » March 3rd, 2022, 7:13 pm

dexter1 wrote:
March 3rd, 2022, 7:45 am
I've written a python script which reads rle's in log files from qfind and ikpx2 and prints them in block characters on the console.

Code: Select all

frank@bluemoon:~/Documents/GOL/patterns/1c5$ more 76P5H1V0_kermit.rle 
#CXRLE Pos=-11,-7
x = 23, y = 15, rule = B3/S23
bo19bo$2o19b2o$o2bo4b2o3b2o4bo2bo$4bob2obo3bob2obo$3bo15bo$5b4o5b4o$9b
2ob2o2$10bobo$9bo3bo$5b5o3b5o$4b2o2b2o3b2o2b2o$4bo5bobo5bo$2b4o2bobobo
bo2b4o$9bo3bo!
frank@bluemoon:~/Documents/GOL/patterns/1c5$ ./rle2blk.py 76P5H1V0_kermit.rle 
▄█                   █▄
▀  ▀▄ ▄▄▀█   █▀▄▄ ▄▀  ▀
   ▀ ▄▄▄▄     ▄▄▄▄ ▀   
         ▀▀ ▀▀         
         ▄▀ ▀▄         
    ▄█▀▀██   ██▀▀█▄    
  ▄▄█▄  ▄ █ █ ▄  ▄█▄▄  
         ▀   ▀         

5
There is no gap in the console output as opposed to the code formatting in this post.

This way i can quickly eyeball if there are any interesting patterns appearing during calculations without resorting to cut and paste into Golly.
For each rle found and displayed, it will print the line number where the pattern is located in the log file, so the corresponding rle can be located.

Code: Select all

#!/usr/bin/env python3

import copy
import sys
import re

lookup_block = {
        0 : ' ' , 1 : '\u2598', 2 : '\u259d', 3 : '\u2580',
        4 : '\u2596', 5 : '\u258c', 6 : '\u259e', 7 : '\u259b',
        8 : '\u2597', 9 : '\u259a', 10 : '\u2590', 11 : '\u259c',
        12 : '\u2584', 13 : '\u2599', 14 : '\u259f', 15 : '\u2588'
        }

def make_blk(bitmap,maxwidth):
    """Turn bitmap list into a unicode block form"""

    width = len(bitmap[0])
    height = len(bitmap)

    blk_string = ""
    block = []
    for i in range(0,height,2) :
        for j in range(0,width) :
            key = 3 * bitmap[i][j]
            key += 12 * bitmap[i+1][j] if i+1<height else 0
            block.append(lookup_block[key])
        block.append('\n')
    blk_string += "".join(block)
    return blk_string

class RLE2Bitmap:
    def __init__(self):
        self.width = 0
        self.height = 0
        self.x = 0
        self.y = 0
        self.bitmap = []
        self.maxwidth = 100
        self.lineptr = 0

    def dimset(self):
        return ((self.width != 0) & (self.height != 0))

    def setdim(self, ls):
        self.x = 0
        self.y = 0
        values = ls.split(',')
        self.width = int(list(re.findall('\d+', values[0]))[0])
        self.height = int(list(re.findall('\d+', values[1]))[0])
        self.bitmap = [[0 for i in range(self.width)] for j in range(self.height)]
        
    def cleardim(self):
        self.width = 0
        self.height = 0

    def process(self, ls):
        self.lineptr += 1
        if (ls.startswith('x')):
            self.setdim(ls)
        else:
            if self.dimset():
                n = 0
                for c in ls:
                    if (c.isdigit()):
                        n = 10 * n + ord(c) - ord('0')
                    else:
                        if (n == 0):
                            n = 1
                        if (c == 'b'):
                            self.x += n
                            n = 0
                        if (c == '$'):
                            self.x = 0
                            self.y += n
                            n = 0
                        if (c == '!'):
                            print(make_blk(self.bitmap,self.maxwidth))
                            print(self.lineptr)
                            self.cleardim()
                            return
                        if (c == 'o'):
                            for i in range(self.x, self.x + n):
                                self.bitmap[self.y][i] = 1
                            self.x += n
                            n = 0 

if __name__ == "__main__":
    rbm = RLE2Bitmap()
    if len(sys.argv) > 1:
        with open(sys.argv[1],'r') as file_rle:
            for line_str in file_rle:
                rbm.process(line_str.rstrip('\n'))
Questions:
Can it receive a raw RLE?
Were do you put the RLE?

User avatar
yujh
Posts: 3068
Joined: February 27th, 2020, 11:23 pm
Location: I'm not sure where I am, so please tell me if you know
Contact:

Re: rle2blk Python script outputs rle to unicode block in console

Post by yujh » March 3rd, 2022, 7:21 pm

AlbertArmStain wrote:
March 3rd, 2022, 7:13 pm
dexter1 wrote:
March 3rd, 2022, 7:45 am
snip
Questions:
Can it receive a raw RLE?
Were do you put the RLE?
1. No i think it can't.
2. you don't put the rle anywhere, you give the script its location.
3. you don't need it. It's for those who are searching with ikpx2 or qfind and view their log file and it's not friendly for human to understand. (rle is also not friendly for human to understand)
Edit: or if my 3. is wrong, you won;t need that anyways. you have golly.
Rule modifier

B34kz5e7c8/S23-a4ityz5k
b2n3-q5y6cn7s23-k4c8
B3-kq6cn8/S2-i3-a4ciyz8
B3-kq4z5e7c8/S2-ci3-a4ciq5ek6eik7

Bored of Conway's Game of Life? Try Pedestrian Life -- not pedestrian at all!

User avatar
pzq_alex
Posts: 793
Joined: May 1st, 2021, 9:00 pm
Location: tell me if you know

Re: rle2blk Python script outputs rle to unicode block in console

Post by pzq_alex » March 4th, 2022, 4:06 am

yujh wrote:
March 3rd, 2022, 7:21 pm
3. you don't need it. It's for those who are searching with ikpx2 or qfind and view their log file and it's not friendly for human to understand. (rle is also not friendly for human to understand)
Edit: or if my 3. is wrong, you won;t need that anyways. you have golly.
What we really need (in that case) is a tool that converts a string of concatenated RLEs to a single big RLE, with the results spaced. Then we can paste the big RLE into Golly to see the results.
\sum_{n=1}^\infty H_n/n^2 = \zeta(3)

How much of current CA technology can I redevelop "on a desert island"?

User avatar
wwei47
Posts: 1656
Joined: February 18th, 2021, 11:18 am

Re: rle2blk Python script outputs rle to unicode block in console

Post by wwei47 » March 4th, 2022, 8:45 am

pzq_alex wrote:
March 4th, 2022, 4:06 am
yujh wrote:
March 3rd, 2022, 7:21 pm
3. you don't need it. It's for those who are searching with ikpx2 or qfind and view their log file and it's not friendly for human to understand. (rle is also not friendly for human to understand)
Edit: or if my 3. is wrong, you won;t need that anyways. you have golly.
What we really need (in that case) is a tool that converts a string of concatenated RLEs to a single big RLE, with the results spaced. Then we can paste the big RLE into Golly to see the results.
I agree.

User avatar
pzq_alex
Posts: 793
Joined: May 1st, 2021, 9:00 pm
Location: tell me if you know

Re: rle2blk Python script outputs rle to unicode block in console

Post by pzq_alex » March 4th, 2022, 10:37 am

wwei47 wrote:
March 4th, 2022, 8:45 am
pzq_alex wrote:
March 4th, 2022, 4:06 am
<snip>
What we really need (in that case) is a tool that converts a string of concatenated RLEs to a single big RLE, with the results spaced. Then we can paste the big RLE into Golly to see the results.
I agree.
Thinking about this though, we can just simply discard the '!'s and the headers, and join the (headerless) RLEs with a big number of blank rows (e.g. 20$), and then put the header back. Simple python3 implementation (defaults to B3/S23 rle, does not read rule from input rle):

Code: Select all

# concat.py
# By pzq_alex, March 4, 2022. 
# Reads a string of RLEs from stdin and returns a merged
# version which contains the patterns, verticall spaced
# by 20 blank rows. 

def read_rle():
    """
    Reads an RLE read from stdin.
    The return value is a 2-tuple; the first element is
    the RLE headerless, and the second is a boolean
    indicating whether if EOF is reached. 
    """
    res = ""
    reach_eof = False
    while True:
        try:
            s = input()
            if not s.startswith('x'):
                res += s.strip('!')
            if s.endswith('!'):
                break
        except EOFError:
            reach_eof = True
            break
    return (res, reach_eof)

def main():
    l = []
    while True:
        (res, reach_eof) = read_rle()
        l.append(res)
        if reach_eof:
            break
    print("x = 0, y = 0\n" + "20$".join(l))

if __name__ == "__main__":
    main()
\sum_{n=1}^\infty H_n/n^2 = \zeta(3)

How much of current CA technology can I redevelop "on a desert island"?

AlbertArmStain
Posts: 1257
Joined: January 28th, 2022, 7:18 pm
Location: Planet Z

Re: rle2blk Python script outputs rle to unicode block in console

Post by AlbertArmStain » March 4th, 2022, 5:02 pm

pzq_alex wrote:
March 4th, 2022, 10:37 am
wwei47 wrote:
March 4th, 2022, 8:45 am
pzq_alex wrote:
March 4th, 2022, 4:06 am
<snip>
What we really need (in that case) is a tool that converts a string of concatenated RLEs to a single big RLE, with the results spaced. Then we can paste the big RLE into Golly to see the results.
I agree.
Thinking about this though, we can just simply discard the '!'s and the headers, and join the (headerless) RLEs with a big number of blank rows (e.g. 20$), and then put the header back. Simple python3 implementation (defaults to B3/S23 rle, does not read rule from input rle):

Code: Select all

# concat.py
# By pzq_alex, March 4, 2022. 
# Reads a string of RLEs from stdin and returns a merged
# version which contains the patterns, verticall spaced
# by 20 blank rows. 

def read_rle():
    """
    Reads an RLE read from stdin.
    The return value is a 2-tuple; the first element is
    the RLE headerless, and the second is a boolean
    indicating whether if EOF is reached. 
    """
    res = ""
    reach_eof = False
    while True:
        try:
            s = input()
            if not s.startswith('x'):
                res += s.strip('!')
            if s.endswith('!'):
                break
        except EOFError:
            reach_eof = True
            break
    return (res, reach_eof)

def main():
    l = []
    while True:
        (res, reach_eof) = read_rle()
        l.append(res)
        if reach_eof:
            break
    print("x = 0, y = 0\n" + "20$".join(l))

if __name__ == "__main__":
    main()
We could have the rle as a separate file.

Post Reply