talideon.com

Blackout Ireland

Entries for January 2009

January 3, 2009 at 10:19AM Minesweeper Kata

I did the minesweeper kata a few days back. It was a bit too easy, though it’s quite possible that this is more an artifact of how I approached it. Given that it’s a simple one, it might be an idea to see if I can take it in smaller steps, much smaller steps.

There’s not really much to say, so here’s the code:

#!/usr/bin/env python

import doctest
import sys

def unpack_line(s):
    """
    >>> unpack_line('.....')
    [0, 0, 0, 0, 0]
    >>> unpack_line('')
    []
    >>> unpack_line('.*.')
    [0, '*', 0]
    """
    line = []
    for c in s:
        if c == '*':
            line.append('*')
        else:
            line.append(0)
    return line

def mark_adjacents(lines):
    """
    >>> mark_adjacents([[0, 0], [0, 0]])
    [[0, 0], [0, 0]]
    >>> mark_adjacents([['*', 0], [0, 0]])
    [['*', 1], [1, 1]]
    >>> mark_adjacents([['*', 0], [0, '*']])
    [['*', 2], [2, '*']]
    >>> mark_adjacents([[0, 0, 0], [0, '*', 0], [0, 0, 0]])
    [[1, 1, 1], [1, '*', 1], [1, 1, 1]]
    >>> mark_adjacents([['*', 0, 0], [0, 0, 0], [0, 0, '*']])
    [['*', 1, 0], [1, 2, 1], [0, 1, '*']]
    """
    for y in range(len(lines)):
        for x in range(len(lines[y])):
            if lines[y][x] == '*':
                for oy in [y - 1, y, y + 1]:
                    if oy < 0 or oy == len(lines):
                        continue
                    for ox in [x - 1, x, x + 1]:
                        if ox < 0 or ox == len(lines[y]):
                            continue
                        if lines[oy][ox] != '*':
                            lines[oy][ox] += 1
    return lines

def process_fields(iterable):
    start = True
    for line in iterable:
        line = line.rstrip()
        if start:
            start = False
            lines = []
            height, width = [int(x) for x in line.split(' ')]
            if width == 0 and height == 0:
                break
        else:
            lines.append(unpack_line(line))
            height -= 1
            if height == 0:
                start = True
                yield mark_adjacents(lines)

def main():
    field = 0
    for f in process_fields(sys.stdin):
        field += 1
        if field > 1:
            print
        print "Field #%d:" % field
        for l in f:
            print ''.join([str(x) for x in l])

def _test():
    doctest.testmod()

if __name__ == '__main__':
    main()

I should really buckle down and finish the code that’s meant to replace the crappy one-evening hack the this blog runs on.

January 19, 2009 at 2:13PM I feel myself wanting to type ‘return new self($args)’ from as static method

I know this is a little silly, but I feel myself wanting to do something like this in a piece of code I’m writing:

abstract class Base {

    protected $arg;

    public function __construct($arg) {
        $this->arg = $arg;
    }

    public abstract function stuff();

    public static function wrap($arg) {
        // Here be the magic.
        return new Wrapper(new self($arg));
    }
}

class Wrapper {

    private $wrapped;

    public function __construct(Base $wrapped) {
        $this->wrapped = $wrapped;
    }

    public function nonsense() {
        return sprintf("[%s]\n", $this->wrapped->stuff());
    }
}

class A extends Base {

    public function stuff() {
        return strtoupper($this->arg);
    }
}

class B extends Base {

    public function stuff() {
        return strtolower($this->arg);
    }
}

echo A::wrap('Foo')->nonsense();
echo B::wrap('Bar')->nonsense();

Which would give:

[FOO]
[bar]

Of course, PHP doesn’t allow self to be (ab)used like that, and I’m sure there’s a much better way of achieving something similar to this, but I thought I’d record this particular brainfart for posterity anyway.

January 19, 2009 at 3:52PM QOTD: hubris experience

Every company thinks its special. So special, customers should be grateful for the mere privilege of doing business with the company. Call it egocentric design, hubris experience, entitlement architecture. The truth is, your customers don’t care as much as you wish they would. They just want to get the product or use the service and get on with other, more important things.

Ironically, if you design software by putting the emphasis on others, you end up increasing your value to other people. Funny how that works.

- Assaf Arkin