Sep 25

At my job, I’m the youngest programmer there

Youngest at 23 here. Then again, we’re four programmers and the oldest one is 25.

appliedcoffeetechnology:

Is it just my imagination or is that cat writing in lisp?

zombiechan:

They’re all in their 30’s while I’m 21. I’m pretty sure this is how they view me.


Jun 12
“Programs must be written for people to read, and only incidentally for machines to execute.” — Abelson & Sussman, SICP, preface to the first edition

Jun 9

Multiple JSONP Requests and a Single Callback

…does not work. A workaround is to do

window['callback'+idx] = callback;

and then ?jsonp=callback0, ?jsonp=callback1, …


Aug 16

Applying patches using SCons

A project has third-party dependencies that need to be patched before being used. I’m new to SCons, but here is my go at applying patches using the build tool.

site_scons/site_init.py

import os

def TOOL_VENDOR(env):
    def patch_generator(source, target, env, for_signature):
        """Generate a patched version of source in target (both being
        directories). If a patch is missing, do nothing.
        """
        target = target[0]
        source = source[0]
        patch_path = '%s.patch' % source.path
        cmds = []
        if len(Glob(patch_path)):
            cmds += [
                Delete(target),
                Copy(target, source),
                "cd %s && patch -p1 < %s" % (target.path, os.path.abspath(patch_path)),
                ]
        return cmds
    env.Append(BUILDERS = {'VendorPatch': Builder(generator=patch_generator)})

SConstruct

env = Environment(tools=['default', TOOL_VENDOR])
SConscript([
        'vendor/SConscript',
        ], exports='env')

vendor/ is a directory with third-party libraries. The vendor/SConscript file will

  1. find directories such as vendor/acme-parser/repo and create a patched version of it in vendor/acme-parser/patched, if vendor/acme-parser/repo.patch exists, and
  2. run any existing library SConscript files.

vendor/SConscript

Import('env')
import os

for repo in Glob('*/repo'):
    env.VendorPatch(Dir(os.path.join(repo.dir.name, 'patched')), repo)

SConscript(Glob('*/SConscript'), exports='env')

Aug 11

Mar 10

Color Palette in Python

I though this might be of use to somebody. It got some rough edges but is good enough™ for my needs.

# -*- coding: utf-8 -*-
from colorsys import rgb_to_hls, hls_to_rgb
from PIL import Image
import struct
from cStringIO import StringIO

__author__ = 'Simon Pantzare'

class Color(object):
    def __init__(self, r, g, b):
        self.r = r
        self.g = g
        self.b = b
        self.h, self.l, self.s = rgb_to_hls(r/255.0, g/255.0, b/255.0)
        self.h *= 360
        self.l *= 100
        self.s *= 100


class RangeImage(object):
    def __init__(
            self, 
            start_rgb, 
            lightness_pc, 
            hue_dg,
            dim=(200,50)
            ):
        """
        lightness_pc 
            Range 0-50%.

        hue_dg
            Range 0-180 degrees.
        """
        self.start_color = Color(*start_rgb)
        self.lightness_pc = lightness_pc
        self.hue_dg = hue_dg
        self.width_px = dim[0]
        self.height_px = dim[1]

    def h_vector(self):
        assert 0 <= self.hue_dg and self.hue_dg <= 180
        start_h = self.start_color.h - self.hue_dg
        if start_h < 0:
            start_h = 360 + start_h
        incr = float(self.hue_dg*2) / self.height_px
        return [(start_h+i*incr)%(360+1) for i in range(0, self.height_px)]

    def l_vector(self):
        assert 0 <= self.lightness_pc and self.lightness_pc <= 50
        minv = max(self.start_color.l - self.lightness_pc, 0)
        incr = float(self.lightness_pc*2) / self.width_px
        return [min(minv+i*incr,100) for i in range(0, self.width_px)]

    def image(self):
        arr = [[0] * self.width_px for _ in range(self.height_px)] # the outer list comprehension IS needed
        hues = self.h_vector()
        ls = self.l_vector()
        sat = self.start_color.s / 100

        for row_idx, row in enumerate(arr):
            h = hues[row_idx] / 360.0
            for col_idx, px in enumerate(row):
                l = ls[col_idx] / 100.0
                r,g,b = hls_to_rgb(h, l, sat)
                arr[row_idx][col_idx] = struct.pack(
                        "BBBB", 
                        int(r*255),
                        int(g*255),
                        int(b*255),
                        255
                        )

        buf = StringIO()
        [[buf.write(px) for px in row] for row in arr]
        buf.seek(0)

        im = Image.frombuffer(
                "RGBA", 
                (self.width_px, self.height_px), 
                buf.read(),
                "raw",
                "RGBA",
                0,
                1
                )
        return im

Output for RangeImage((0, 255, 0), 50, 180, (200, 100)).image():

RangeImage((0, 255, 0), 50, 180, (200, 100))



Simon Pantzare
Simon Pantzare, also available on
Facebook,
Twitter,
Google+,
Reddit,
Github (dev blog).
Ask me anything.