cat in Sawzall (redux)

After playing with Sawsall a little bit more, I have a slightly better version of cat than the last one I posted:

w: string = input;
emit stdout <- w;

This gets rid of the table and makes the program one whole line shorter :)

cat in Sawzall

Google's Sawzall language has been open-sourced (pronouced: saws all). After I heard the news, I came to the conclusion that I needed to write a program in the language named after the reciprocating saw. So here it is, my first program in Sawzal (cat.szl):

out: table text of word: string;
w: string = input;
emit out <- w;

It's pretty much an implementation of cat, which feels like the log analysis/filtering language version of Hello World!.

Show Passwords Bookmarklet

I wrote a bookmarklet that makes password inputs show you their contents. The motivation is threefold:

  1. Pasting $('input[type="password"]').val() the console of a page with saved passwords has always amused me and the bookmarklet makes this easier to do on pages that don't have jQuery.
  2. I sometimes actually want to see the password I'm typing, either because it's fiendishly complicated or for some reason I've messed up a bunch and want to verify my typing.
  3. I wanted to play with SASS and CSS linear gradients. So I put together a tiny website and needed something to put up there on it.

Teh Codez

javascript:(function(){
    var passwords = document.querySelectorAll('input[type="password"]');
    for(var i = 0; i < passwords.length; i++){
        passwords[i].setAttribute('type', 'text');
    }
})();
  1. This is a bookmarklet, hence the javascript: protocol. In order for the browser to not navigate to a new page, bookmarklets need to return undefined, hence the anonymous function.
  2. document.querySelector and friends are very cool and they let you find elements jQuery style without needing to try and pull in jQuery to run your three lines of actual code.
  3. Unfortunately, document.querySelectorAll doesn't return a real Array so you can't use Array.forEach and are stuck using JavaScript's built in for. Sad sauce!

Krypto and 24

Daily WTF inspired me to implement a Krypto and 24 solver:

import functools
import itertools
import operator

class Node:
        def evaluate(self): raise NotImplemted()
        def print(self): raise NotImplemted()

        def __add__(self, other): return Add(self, other)
        def __sub__(self, other): return Sub(self, other)
        def __mul__(self, other): return Mul(self, other)
        def __truediv__(self, other): return Div(self, other)

        def __str__(self):
                return "<Node: {}>".format(self.print())

        def __repr__(self):
                return str(self)

class Binary(Node):
        def __init__(self, left, right):
                self.left = left
                self.right = right

        def evaluate(self):
                try:
                        return self.op(
                                self.left.evaluate(),
                                self.right.evaluate(),
                        )
                except ZeroDivisionError:
                        return float("NaN")

        def print(self):
                return "({} {} {})".format(
                                self.left.print(),
                                self.symbol(),
                                self.right.print()
                )

        def op(self, left, rigth): raise NotImplemted()
        def symbol(self): raise NotImplemted()

class Unary(Node):
        def __init__(self, op, val):
                self.op = op
                self.val = val

        def evaluate(self):
                return self.op(self.val)

        def print(self):
                return str(self.evaluate())

def BinOp(op, symbol, commutative = True):
        class inner(Binary):
                def op(self, left, right):
                        return op(left, right)

                def symbol(self):
                        return symbol

                @classmethod
                def iscommutative(cls):
                        return commutative

        return inner

Add = BinOp(operator.add, "+")
Sub = BinOp(operator.sub, "-", commutative = False)
Mul = BinOp(operator.mul, "*")
Div = BinOp(operator.truediv, "/", commutative = False)
Lit = functools.partial(Unary, lambda x: x)

OPS = [Add, Sub, Mul, Div]

def generate_expressions(nodes):
        if len(nodes) == 1:
                yield first(nodes)

        for x, y, op in itertools.product(nodes, nodes, OPS):
                isnew = not op.iscommutative() or id(x) > id(y)
                if x is not y and isnew:
                        yield generate_expressions((nodes - set([x, y])) | set([op(x, y)]))

def flatten(xs):
        for x in xs:
                try:
                        for y in flatten(x):
                                yield y
                except TypeError:
                        yield x

def first(xs):
        for x in xs:
                return x

def krypto(nums, solution):
        def issolution(expr):
                return expr.evaluate() == solution

        nodes = set(map(Lit, nums))
        expr = first(filter(issolution, flatten(generate_expressions(nodes))))
        print(expr.print(), "=", expr.evaluate())

if __name__ == "__main__":
        import sys
        args = list(map(int, sys.argv[1:]))
        krypto(args[:-1], args[-1])

My favourite part is that the core of the algorithm is 6 lines:

def generate_expressions(nodes):
        if len(nodes) == 1:
                yield first(nodes)

        for x, y, op in itertools.product(nodes, nodes, OPS):
                isnew = not op.iscommutative() or id(x) > id(y)
                if x is not y and isnew:
                        yield generate_expressions((nodes - set([x, y])) | set([op(x, y)]))

The parametric classes are also a reminder of just how badass python is:

def BinOp(op, symbol, commutative = True):
        class inner(Binary):
                def op(self, left, right):
                        return op(left, right)

                def symbol(self):
                        return symbol

                @classmethod
                def iscommutative(cls):
                        return commutative

        return inner

Edit

2010-05-16: Apparently Python comes with an implementation of cross product.

Ford Circles

I picked up a copy of The Math Book after reading the review on John D. Cook's blog.

So far it has been pretty interesting and I've was plesently surprised with how much of the material I am familar with, despite the fact that I haven't studied math beyond the courses that are part of the engineering curriculum at my university.

The best part, though, has been the occasions when I find something that I can play with a little bit on my own. A good example is Ford Circles, which with a little time in NodeBox I had my own renderings:

Ford Circles

Here's the code:

from __future__ import division

scale(1000, 1000)

def circle(x, y, r):
    oval(x * 1000, y * 1000, 2 * r, 2 * r)

def ford(h, k):
    r = 1 / (2 * k**2)
    x, y = h/k, r
    print x, y, r
    circle(x, y, r)


for h in range(0, 200):
    for k in range(1, 200):
        ford(h, k)

... and here's a bigger rendering, if you're interested.