<jupyter_start><jupyter_text>Write a sequence of colored blocks to an image in reading order.<jupyter_code>import itertools as it

from PIL import Image
def next_color(seq):
    return next(seq)

def next_byte_color(seq):
    r, g, b = next(seq), next(seq), next(seq)
    return r, g, b

class ColorSequenceImage(object):
    """A sequence of colored blocks printed in reading order."""
    
    def __init__(self, image_width, image_height, block_width, block_height):
        self.img = Image.new('RGB', (image_width, image_height))
        self.pix = self.img.load()
        self.block_width = block_width
        self.block_height = block_height
    
    def write(self, seq, output_filename, next_color='next_color'):
        """Write the sequence of colors out to file."""
        next_color = globals()[next_color]
        i, j = 0, 0
        while j < self.img.height:
            c = next_color(seq)
            self.print_block(i, j, c)
            if i + self.block_width >= self.img.width:
                j += self.block_height
            i += self.block_width
            i %= self.img.width
        self.img.save(output_filename)
    
    def print_block(self, i, j, c):
        """Print a block to the image."""
        for iplus, jplus in it.product(range(self.block_width), range(self.block_height)):
            x = (i + iplus) % self.img.width
            y = j + jplus if (i + iplus) < self.img.width else j + self.block_height + jplus
            if y < self.img.height:
                self.pix[x, y] = c
# Try it out

def off_on():
    """Generate black and white alternating."""
    while True:
        yield (0, 0, 0)
        yield (255, 255, 255)

def white():
    """Generate white."""
    while True:
        yield (255, 255, 255)
ls ..
color_seq = ColorSequenceImage(100, 100, 15, 10)
color_seq.print_block(90, 90, next(white()))
color_seq.img.save('../output/block.png')
color_seq = ColorSequenceImage(100, 100, 15, 10)
color_seq.write(off_on(), '../output/off_on.png')
# OK! Seems to be working now. Stream some different bytes.

def bytes_from_file(filename):
    file_in = open(filename, 'rb')
    bytes_ = file_in.read()
    i = 0
    while True:
        yield bytes_[i]
        i += 1
        i %= len(bytes_)
hello_world = ColorSequenceImage(500, 500, 10, 5)
hello_world.write(
    bytes_from_file('../hello_world/hello_world'),
    '../output/hello_world.png',
    next_color='next_byte_color'
)
# Look at the bytes of the file and see if it's working correctly (should be lots of null bytes)

file_in = open('../hello_world/hello_world', 'rb')
bytes_ = file_in.read()
len(bytes_)
bytes_[-100:]
# OK, so if not entirely null, then very dark.<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12804428044280441, 'fraction_numerical': 0.022509225092250923, 'mean_word_length': 2.7290233837689133, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '655831', 'license': 'MIT', 'n_tokens_mistral': 939, 'n_tokens_neox': 881, 'n_words': 256, 'path': 'notebooks/color_sequence_framework.ipynb', 'repo_name': 'christiemj09/creative_coding', 'size': '2710'}