talideon.com

Blackout Ireland

February 27, 2009 at 1:37PM Discouraging clientelism in Irish politics

Ireland is a country of just over four million people, with a parliament consisting of 226 members in total, with 166 members in the the lower house and 60 in the upper, so for a nation of our size, we’ve a disproportionally high number of public representatives for a country our size.

The constitution places upper and lower limits on the number of representatives in the lower house in article 16.2.2, specifically one representative for every 20,000 to 30,000 of the population. The use of electoral constituencies is implicit in the language of the article, but does not specify the shape of those constituencies, nor whether they can overlap--these are all matters of statute rather than basic law.

As things stand, Irish politics is riddled with clientelism, with our politicians overly focused on getting elected again the next time an election comes around, so they spend far too much time acting as delegates from their constituency rather than as trustees of the best interests of the nation as a whole, which is what they ought to be. We need some way of breaking this cycle, and I think I’ve a way.

My idea is that fully one third of the representation should be elected nationally from a single national constituency. Doing this alone would be technically feasible due to so through an act to amend our electoral law, but the one sticking point is the use of the single transferrable vote (STV)--three-, four- and five-seater constituencies are enough of a pain to do the count on, never mind a massive national constituency that can elect over fifty TDs!

The use of STV is codified into the constitution. This has been a good thing because it’s avoided the situation where Fianna Fail could change the electoral law to use first past the post (FPTP) to get a permanent majority of the seats in the Dail. For a national constituency to be practical, a constitutional amendment would be required to specify the method used for electing from that constituency. In my mind, a party list system appear be the feasible method.

Do I think this would solve our problems? No, but I do think it would be a step in the right direction towards governments that worked in the best interests of the nation rather than themselves.

[I’ve reposted this article on Irish Election, so head over there if you want to discuss it.]

February 23, 2009 at 2:13PM If programmers had to make planes

Painfully true to life:

February 8, 2009 at 9:55PM Quick notes: Changes afoot

There are a few changes that’ll be happening around these parts mighty soon. Let’s start with some site news:

Other bits and pieces:

Update (Feb 21st): I missed a few bits of the comments code for dealing with spam, which is why some may have seen an error page on the weblog’s frontpage. My bad. It’s fixed now, and I stripped out yet more junk.

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

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 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.

December 31, 2008 at 12:44AM Harry Potter Kata

I did the Harry Potter Kata earlier because I was feeling a little bored. Here’s the result. I use cents rather than euros as my unit of currency here.

I’d a start when I was thinking about how I’d solve the problem. I thought that being greedy and trying to make the biggest sets would do the trick, but the first example test case given soon managed to disabuse me of that notion.

Then I got the idea of turning things around 90 degrees by creating a set of buckets within the basket and distributing the sets between them. However, given the sample test case, I realised that the maximum discount could come from an obscure distribution of books, so I took the brute force route and decided to enumerate all the possible ways to distribute all the books of a certain volume, tracking which combination gave the greatest discount, and did this iteratively for each volume.

I already had the intuition to eliminate the larger groups of volumes sooner than the smaller ones, and I knew that the important thing was the number of books of each volume there were rather than what the particular volumes were, so sorting basket by volume made sense and avoided the need to do any backtracking later.

I looked at other implementations after I’d finished, and mine seems to be sorter and more general--though not purposely so--than most, but I’m still pretty sure there’s a much more elegant way to find an ideal distribution of volumes than the brute force method I used, though I’ve yet to think of one. Here’s the code:

#!/usr/bin/env python

import doctest
import itertools

def sum_basket(basket, unit_price, discount_pcs):
    """
    Gets the sum price of the books in the basket.

    basket - list of number of each book
    unit_price - price of a book
    discount_pcs - percentage discount to apply for each additional book in a set

    >>> price = 800
    >>> discount_pcs = [0, 0, 5, 10, 20, 25]
    >>> sum_basket([0, 0, 0, 0, 0], price, discount_pcs)
    0
    >>> sum_basket([0, 1, 0, 0, 0], price, discount_pcs)
    800
    >>> sum_basket([0, 3, 0, 0, 0], price, discount_pcs)
    2400
    >>> sum_basket([1, 1, 0, 0, 0], price, discount_pcs)
    1520
    >>> sum_basket([2, 1, 2, 1, 0], price, discount_pcs)
    4080
    >>> sum_basket([2, 1, 1, 1, 1], price, discount_pcs)
    3800
    >>> sum_basket([2, 2, 2, 1, 1], price, discount_pcs)
    5120
    >>> sum_basket([1, 1, 2, 2, 2], price, discount_pcs)
    5120
    >>> sum_basket([5, 5, 4, 5, 4], price, discount_pcs)
    14120
    """
    buckets = get_basket_buckets(basket)
    result = 0

    for books in sorted(basket, reverse=True):
        best = None
        for patterns in bitmap_combinations(books, len(buckets)):
            attempt = [x + y for x, y in itertools.izip(buckets, patterns)]
            attempt_sum = 0
            for bucket in attempt:
                attempt_sum += sum_bucket(bucket, unit_price, discount_pcs)
            if best is None or attempt_sum < result:
                best = attempt
                result = attempt_sum
        buckets = best

    return result

def sum_bucket(bucket, unit_price, discount_pcs):
    """
    Gets the sum cost of a set of books.

    bucket - number of unique books in a set.
    unit_price - price of a book
    discount_pcs - percentage discount to apply for each additional book in a set

    >>> price = 800
    >>> discount_pcs = [0, 0, 5, 10, 20, 25]
    >>> sum_bucket(0, price, discount_pcs)
    0
    >>> sum_bucket(1, price, discount_pcs)
    800
    >>> sum_bucket(2, price, discount_pcs)
    1520
    >>> sum_bucket(3, price, discount_pcs)
    2160
    >>> sum_bucket(4, price, discount_pcs)
    2560
    >>> sum_bucket(5, price, discount_pcs)
    3000
    """
    return bucket * unit_price * (100 - discount_pcs[bucket]) / 100

def bitmap_combinations(ones, length):
    if length == 0:
        yield []
    else:
        if ones < length:
            for tail in bitmap_combinations(ones, length - 1):
                yield itertools.chain([0], tail)
        if ones > 0:
            for tail in bitmap_combinations(ones - 1, length - 1):
                yield itertools.chain([1], tail)

def get_basket_buckets(basket):
    """
    Creates enough basket buckets to hold the maximum number of unique book sets in
    the basket.

    >>> get_basket_buckets([0])
    []
    >>> get_basket_buckets([0, 0])
    []
    >>> get_basket_buckets([1, 0])
    [0]
    >>> get_basket_buckets([0, 1])
    [0]
    >>> get_basket_buckets([0, 2])
    [0, 0]
    >>> get_basket_buckets([1, 2])
    [0, 0]
    >>> get_basket_buckets([1, 2, 3, 5, 2])
    [0, 0, 0, 0, 0]
    """
    return [0 for i in range(max(basket))]

def _test():
    doctest.testmod()

if __name__ == '__main__':
    _test()