How about this for a four line singleton? Taken from Matt Kangas’ comment on the Python Cookbook

class ThereCanBeOnlyOne():
    def __call__(self):
        return self
ThereCanBeOnlyOne = ThereCanBeOnlyOne()

This creates a single global instance of the ThereCanBeOnlyOne class. As it has the same name as the class, the original class is effectively hidden. Using the normal method of creating a class instance - ThereCanBeOnlyOne() - you will receive the result of the instance’s __call__() function. Namely, itself.

Brilliant.

If, like me, you’re used to Ruby and PHP5, you may like to emulate the functionality of Ruby’s ‘method_missing()’ or PHP’s ‘__call()’ in Python.

If you’re not familiar with them, here’s a quick run-down. Imagine you have a class, Foo, which doesn’t implement the method ‘bar’. If you call Foo().bar(), you’ll get an exception. In Ruby (and PHP5) you can set up method_missing() as a member function to catch the request and handle it gracefully.

Method_missing is passed a string containing the name of the missing function, along with any function parameters. This opens the door to a range of interesting programming constructs when building frameworks or domain specific languages - you can create database lookups with their own syntax for example (see RoR’s ActiveRecord) or dynamically offer the named elements of a hash or dictionary as getter and setter functions of a class instance. If you like. (See the Zend framework for examples of this kind of behaviour.)

Python offers true named parameters (unlike Ruby), which Django makes good use of in a similar context, but I still missed method_missing.

I went on a bit of a hunt to find the functionality in Python. Although it doesn’t support it natively, I found a post on the Iffy Blog, detailing an implementation. It seemed a little heavyweight so here’s my condensed version.

"""
    MethodMissing is a mix-in style class giving Ruby-style 'method missing' functionality.

    >>> t = MethodMissing()
    >>> t.some_missing_method("alpha", "beta", gamma = "delta")
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "mook/ben_method_missing.py", line 19, in callable
        self.method_missing(attr, *args, **kwargs)
      File "mook/ben_method_missing.py", line 15, in method_missing
        raise NotImplementedError("Missing method %s called."%attr)
    NotImplementedError: Missing method some_missing_method called.
    >>> t = Test()
    >>> ret = t.no_such_method("foo", "foobar", foo = "bundy")
    Derived missing method no_such_method called with:
    args: ('foo', 'foobar')
    kwargs: {'foo': 'bundy'}
    >>> print ret
    return value
    >>> ret = t.existing()
    This method exists
    >>> print ret
    I exist
"""

class MethodMissing:
    def method_missing(self, attr, *args, **kwargs):
        """ Stub: override this function """
        raise NotImplementedError("Missing method %s called."%attr)

    def __getattr__(self, attr):
        def callable(*args, **kwargs):
            return self.method_missing(attr, *args, **kwargs)
        return callable

if __name__ == "__main__":

    print "Starting tests..."

    class Test(MethodMissing):
        def existing(self):
            print "This method exists"
            return "I exist"

        def method_missing(self, attr, *args, **kwargs):
            print "Derived missing method %s called with:"%attr
            print 'args:', args
            print 'kwargs:', kwargs
            return "return value"

    import doctest

    doctest.testmod()

Making friends

June 27th, 2008

I’ve been using Python for a few weeks now. Although I find some of the constructs unnecessarily cumbersome compared to Ruby, I’m definitely making friends with the language. It certainly hasn’t got in the way of my programming yet, in that way PHP and C# do.

So, I’ve written a simple blog. I need time to skin it up with the company colours and then you’ll see it here, replacing this one.

ShitTorrent iteration 1 is close to completion. It’s half-styled and missing ratings, but otherwise it’s good to go. I just need a spare second to complete it.

So what’s been taking my time? Well, I’ve been working on Hermes, a kind of <search_fodder>Capistrano for Django… A Capistrano for Python even.</search_fodder>. Hell… It could work on any project as long as you’re deploying to a POSIX server (Linux or example) and you’re not working on a Windows box.

That’s drawback 1. Drawback 2 is that it’s a work project. If I want to release it I’ll have to convince them that it’s a good idea to release it as open source. However, I can tell you that the pexpect library made it a breeze.

So, if anyone knows a Python library that can call remote SSH commands AND runs on Windows, I’d be only too happy to give it a re-write.

(If you don’t know, Capistrano is a Ruby application for remotely manipulating POSIX servers. It nicely automates the deployment of Rails apps for example, which is its big selling point.)

In my last post I said that I’d be developing a blog (while blogging about my progress) in Django. I’m still developing it, but it’s part of my job now - both as a test of the suitability of the framework for future projects and as a possible replacement for the system they’re using at the moment.

Blogging it would be a little problematic.

Instead, I’ve resurrected a personal project called ‘ShitTorrent’. Born from a drunk conversation with some friends, ShitTorrent will be a place to post your rants and ‘let it all out.’

Django looks like the perfect framework for it - it’s a dynamic, community-based but fundamentally simple website idea. After a bit more playing around with Python, we’ll make a start on the model/ORM layer…

Posted in Code, Python, Tech | No Comments »

Why am I here?

May 24th, 2008

So I did what I promised myself I would never do - I started up a Wordpress blog. Why is that so bad, you ask? Certainly I always meant to start a blog, and Wordpress seems to be a very capable program.

Well, apart from the fact that it doesn’t validate (yeuch), I’m a web developer and I promised myself a while back that I would only use hand-written web apps for my personal pages. I have some reasons for this beyond my innate stubborn nature, which I may go into in another blog entry. For now though, I found myself with a chicken and egg situation. I wanted to learn Django and blog the differences between it and Rails… But I had no blog software. Writing a blog would be a great first project for Django, as it can start out simple but also test out some advanced high level language features.

Clearly, something had to give.

Enter Wordpress, which I can use as a stopgap until my blog is production ready. At that point I will port all the posts over, so what you see here, with its off the shelf skin and basic (lack of) customisation, will hopefully be a fleeting thing, replaced with my own code and styling.
Or I’ll get disillusioned with Django and we’ll be back to square one. Time will tell.

Posted in Code, Python, Tech | No Comments »

OK, here’s a simple task. A function which returns an array of f(0) - f(x), where f(n) is the Fibonacci number of n. A simple solution should expose some of the language differences when using lists.

Let’s look at PHP first.

<?php
function fib_upto($x, $position = 0, $history=array())
{
    if ($x < 0) {
        throw new Exception(”Input out of range”);
    }
    if ($position <= 1) {
        $history[$position] = $position;
    } else {
        $history[$position] = $history[$position - 1] + $history[$position - 2];
    }
    if ($position < $x) {
        return fib_upto($x, $position + 1, $history);
    } else {
        return $history;
    }
}

echo implode(fib_upto(20), “,”);
?>

A ruby equivalent:


def fib_upto x, position = 0, history=[]
    raise “Input out of range” if x < 0
    if position <= 1
        history[position] = position
    else
        history[position] = history[position - 1] + history[position - 2]
    end
    if position < x
        fib_upto(x, position + 1, history)
    else
        history
    end
end

print fib_upto(20).join(”,”)

And now some Python:


def fib_upto(x, position = 0, history=[]):
    if x < 0: raise Exception(”Input out of range”)
    if position <= 1:
        history.append(position)
    else:
        history.append(history[position - 1] + history[position - 2])
    if position < x:
        return fib_upto(x, position + 1, history)
    else:
        return history

print “,”.join(map(str, fib_upto(20)))

As you can see, the Python script wins in terms of number of lines of code. The famous semantic whitespace makes braces and ‘end’ directives redundant, saving some lines of code. It also forces good coding style on developers, which is a Good Thing.

PHP is littered with unnecessary characters - ‘<?php’, ‘?>’, ‘$’, ‘{’ and ‘}’ in this case. They seem to get in the way of coding without really adding anything in the way of readability. PHP also forces you to use brackets around ‘if’ clauses.

Ruby appears to be the cleanest-looking code here. It may need ‘end’ commands to terminate blocks, but they start without the curly brace of PHP or the colon of Python. The ‘raise’ at the beginning of the function shows Ruby’s trick of appending a conditional to the end of a line, which is both readable and terse. Python can do this task in one line, but requires a colon to do so.

A subtle language difference regarding lists is shown by the Python command:

history.append(position)’

Attempting to assign a value to a member of a list which hasn’t been previously defined causes an error. Try changing the line to read ‘history[position] = position’ and see what happens.

Both PHP and Ruby can handle this, meaning lists are more flexible - but it could be argued that a Hash, or Dictionary in Python speak, would be better suited to that kind of use.

While PHP and Python require explicit ‘return’ commands, Ruby just returns the object resolved by the last line of executed code. A return can be used optionally (to pop out of a function for example) but in most cases it’s not required. This can lead to some very tight code if used correctly and encourages methods which can be chained together. It seems like a small thing, but I actually miss it a great deal when I work in PHP.

Coming to the last line, we’re joining the elements of the array together to make a string. PHP makes this easy (if quirky) with the ‘impolde’ command. Ruby handles it neatly and intuitively with a join method on the array. Python, on the other hand, has its join method on the string. This seems like a strange place to put it, as you’re in effect operating on the delimiter.

You’ll notice another layer of complexity here, added by a mapping function. Here we’re passing in ’str’ as a function to convert each element of the array into a string before operating on it with join.

It appears that join only works on arrays of strings in Python. Presumably, Ruby calls the ‘.to_s’ on each element behind the scenes to avoid this problem.

The mapping could be replaced with the following, more ‘modern’ Python constructs:

print “,”.join([str(x) for x in fib_upto(20)]) # using str(x) in a list comprehension.
or
print “,”.join(str(x) for x in fib_upto(20)) # using generator comprehension, avoiding an intermediate list. 

(Thanks go to SpiralX, my Python mentor, for these code fragments.)

Generators look like a very handy feature - readable and powerful. It looks like it’ll be fun learning to use them.

That’s all for now. Next time I’ll try generating Sierpinski and Pascal triangles, so we can see how the different languages handle loops.

I found myself with a rare couple of hours spare the other day, so I did something I’ve been meaning to do for a long time - I downloaded a copy of Python, a well-recommended book (Dive Into Python) and an IDE and started learning. My main goal is to start using Django, to see if it can offer any speed and functionality benefits over Rails, but I’ve heard so many good things about the language that It’d be nice to know it anyway.

I’ve decided to blog my observations. Initially I’ll be setting myself a number of tasks to solve in all three languages, then comparing and contrasting the resulting code.

Just one of those little oddities you notice along the way. In CSS,

overflow: hidden

doesn’t hide flash objects on Firefox. However,

overflow: auto

will hide the excess and give you scroll bars.

Spooky.

Junk

May 21st, 2008

So I come back from holiday to find a load of bills, statements and general postal chaff. Settling down to file them (and recycle as much as I can) I found these little gems:

  • My final bill from T-Mobile, packaged with a new copy of my contract to notify me of changes to my account.
  • Two separate envelopes from O2, one for each phone on my account. Each envelope contained two copies of the same post-card service advert.
  • An A4, stapled ‘green issues’ newsletter from the Co-operative Bank, printed on thick shiny card.

Almost all the envelopes in the pile had those annoying plastic windows, meaning I couldn’t just throw them into the recycling bin. I had to sit there carefully tearing each one out. Sigh.

Posted in Rants | No Comments »

:P

May 21st, 2008

First!