Dilbert

March 22, 2007 at 10:25 AM | categories: python, oldblog | View Comments

Tongue in cheek, but I quite like (based on occam's razor):
"Given a variety of options, the dumbest one is probably right" - applies to "which decision did management make"
(not to be taken seriously :)
Read and Post Comments

I have a cunning plan

March 09, 2007 at 07:31 PM | categories: python, oldblog | View Comments

I had a great idea today, and I've registered the domain for it just now. I'm probably going to knock up something quite quickly (I hope - time permitting, having a social life is restricting part time hacking somewhat :), but it's something that's probably useful for work, but also scratches a few itches as well. In short though, it's the beginnings of a possible answer to the question: How do you do a bigger piece of high quality film or TV in an open source way. That said, I don't want to restrict the tools to just an open source/creative commons approach, but I think this has some potential real mileage. More as I go on.
Read and Post Comments

Compiled Kamaelia - A Mini Axon that compiles to C++ using Shed Skin (+ one minor piece of assistance)

February 22, 2007 at 03:16 PM | categories: python, oldblog | View Comments

Well, after getting a mini axon standing" compiling using shedskin yesterday, I've taken the next steps to see if we can get a full mini-axon system compiling. The good news is that, with 1 piece of manual assistance, we can! As a result I have here a compiled version of a mini-axon system.
Yes, you heard right - we have a compilable to executable version of Kamaelia thanks to shedskin.

First of all, what manual change do we need to make? Well, due to the fact we activate various microprocesses in the same way, we need to warn the C++ compiler of this fact, and help shedskin out a bit. The code shedskin creates that's problematic is this:

  • int scheduler::activateMicroprocess(lambda2 some_gen, microprocess *some_obj) {
        __iter<int> *microthread;

        microthread = some_gen(some_obj);
        (this->newqueue)->append(microthread);
        return 0;
    }

This is the fixed code:

  • template<class Klass>
    int scheduler::activateMicroprocess(__iter<int> *(*some_gen)(Klass *), Klass *some_obj) {
        __iter<int> *microthread;

        microthread = some_gen(some_obj);
        (this->newqueue)->append(microthread);
        return 0;
    }

A corresponding change occurs in the generated .hpp file as well. The resulting code then compiles cleanly and runs correctly :-) Yay!

The mini-axon code looks like this:

  • class microprocess:
        def __init__(self,name="hello"):
            self.name = name
    #------------------
    def scheduler_main(zelf):
        result = 1 # force type of result to int
        for i in xrange(100):
            for current in zelf.active:
                yield 1
                try:
                    result = current.next()
                    if result is not -1:
                        zelf.newqueue.append(current)
                except StopIteration:
                    pass

            # This shenanigans is needed to allow the type checker to understand
            # The various types in this function...
            for a in xrange(len(zelf.active)): zelf.active.pop()
            for b in zelf.newqueue: zelf.active.append(b)
            for c in xrange(len(zelf.newqueue)): zelf.newqueue.pop()

    class scheduler(microprocess):
        def __init__(self):
            # super(.... not supported)
            microprocess.__init__(self)
            self.active = []
            self.newqueue = []

        def activateMicroprocess(self, some_gen, some_obj):
            microthread = some_gen(some_obj)
            self.newqueue.append(microthread)
    #------------------
    class component(microprocess):
        def __init__(self):
            microprocess.__init__(self)
            self.boxes = { "inbox" : [], "outbox": [] }
        def send(self, value, outboxname):
            self.boxes[outboxname].append(value)
        def recv(self, inboxname):
            result = self.boxes[inboxname][0]
            del self.boxes[inboxname][0]
            return result
        def dataReady(self, inboxname):
            return len(self.boxes[inboxname])
    #------------------
    def postman_main(zelf):
        while 1:
            yield 1
            if zelf.source.dataReady(zelf.sourcebox):
                d = zelf.source.recv(zelf.sourcebox)
                zelf.sink.send(d, zelf.sinkbox)

    class postman(microprocess):
        def __init__(self, source, sourcebox, sink, sinkbox):
            microprocess.__init__(self)
            self.source = source
            self.sourcebox = sourcebox
            self.sink = sink
            self.sinkbox = sinkbox
    #------------------
    def Producer_main(zelf):
        while 1:
            yield 1
            zelf.send(zelf.message, "outbox")

    class Producer(component):
        def __init__(self, message):
            component.__init__(self)
            self.message = message
    #------------------
    def Consumer_main(zelf):
        count = 0
        while 1:
            yield 1
            count += 1 # This is to show our data is changing :-)
            if zelf.dataReady("inbox"):
                data = zelf.recv("inbox")
                print data, count

    class Consumer(component):
        def __init__(self):
            component.__init__(self)
    #-------------------
    p = Producer("Hello World")
    c = Consumer()
    postie = postman(p, "outbox", c, "inbox")

    myscheduler = scheduler()
    myscheduler.activateMicroprocess(Consumer_main,c)
    myscheduler.activateMicroprocess(Producer_main,p)
    myscheduler.activateMicroprocess(postman_main,postie)

    MT = scheduler_main(myscheduler)
    for i in MT:
        pass

As you can see, this isn't really so very different from the usual code. (There's lots of sugar missing of course!)

Read and Post Comments

MiniAxon - Standing on Shed Skin - first steps towards a C++ Compiled Kamaelia working

February 21, 2007 at 02:20 PM | categories: python, oldblog | View Comments

Well, I looked at shedskin as I mentioned the other day, and now have this working locally. One thing we encourage people new to Kamaelia is to build their own mini-core of the system - Axon. This provides basic microprocesses, basic component communications and scheduling. Whilst this may sound hairy, having run the mini-axon tutorial past many new programmers, including the tutor list, it seems pretty OK. (The tutorial is pretty gentle and provides very small simple steps aimed at someone new to python) The rest of this post after the fold has the meat in.

The other handy thing hough is that this provides a neat mechanism for handling how to experiment with new systems written from scratch, such as Shed Skin. As a result, I've done this, and the first step towards a Kamaelia system is the ability to tag a generator with context, and run multiples of them. Along the way I've discovered many limitations of shed skin (which is spectacular software IMO), which is by no means a criticism, but to its credit this can be worked around. As a result here's a basic concurrency framework in python that compiles directly to very reable C++.

Limitation 1, shed skin generators can't be a method. Therefore any class related stuff must not have any generator in it! Thus our microthread class looks like this:
  • class microthread:
        def __init__(self,name="hello"):
            self.name = name
The name is a test to check differentiation is happening.

Our microthread now is then just a standalone generator, but takes a mutable argument as if its pretending to be in the class:
  • def mainG(zelf):
        i = 1
        while i < 10:
           yield zelf.name + ":" + str(i)
           i = i+1
Incidentally, the way you therefore create a mainG microthread is as follows:
  • mainG(microthread("name")
This looks a little ugly, but the important thing as far as I'm concerned is, it works. Spectacular :)

Limitation 2: Shedskin looks at an argument "self", and thinks "that's bogus in a class definition, I'll get rid of that". This causes problems here, which is why we have "zelf" instead.

Limitation 3: No list comprehensions, and also if you put too many function calls together like(this(sort(of(thing())))), then shed skin creates intermediary classses to help itself. As a result you need to be MUCH more explicit about things you want to happen if you want to avoid this foibles.

So we create our microthreads:
  • N = [ "One", "Two", "Three", "Four" ]
    MT = []
    for n in N:
        MT.append( microthread(n) )

Attach the generator behaviour to them and put them in a simple process list:
  • PS = []
    for M in MT:
        U = mainG(M)
        PS.append(U)
And finally we can have a simple manual scheduler to run them:
  • while 1:
        for P in PS:
            beta = P.next()
            print 'hello, world!', beta
That is then translated to C++ by shedskin which you can then compile and run and get the following output:
  • hello, world! One:1
    hello, world! Two:1
    hello, world! Three:1
    hello, world! Four:1
    hello, world! One:2
    hello, world! Two:2
    hello, world! Three:2
    hello, world! Four:2
    hello, world! One:3
    hello, world! Two:3
    hello, world! Three:3
    hello, world! Four:3
    hello, world! One:4
    hello, world! Two:4
    hello, world! Three:4
    hello, world! Four:4
    hello, world! One:5
    hello, world! Two:5
    hello, world! Three:5
    hello, world! Four:5
    hello, world! One:6
    hello, world! Two:6
    hello, world! Three:6
    hello, world! Four:6
    hello, world! One:7
    hello, world! Two:7
    hello, world! Three:7
    hello, world! Four:7
    hello, world! One:8
    hello, world! Two:8
    hello, world! Three:8
    hello, world! Four:8
    hello, world! One:9
    hello, world! Two:9
    hello, world! Three:9
    hello, world! Four:9
    terminate called after throwing an instance of '__shedskin__::StopIteration*'
    Aborted
This is exactly what I would expect, and is as far as I'm concerned absolutely spectacular on the part of Mark. Really, really cool work.

Now I'm having lunch, after lunch I'll see if I can get the rest of a mini-axon up and running. If so, this could be quite quite fun :-)

Read and Post Comments

Entertainment Manchester Review - Bollywood Mikado

February 18, 2007 at 05:17 PM | categories: python, oldblog | View Comments

Summary - We ruled!
Hearing of people enjoying the show is great, and makes all the hardwork worthwhile. If you still want to see the show, it's being put on again in Buxton for one night only - March 3rd.

Photos from the show:

Read and Post Comments

Kamaelia for P2P streaming ?

February 11, 2007 at 02:22 PM | categories: python, oldblog | View Comments

There was another post on comp.lang.python which asked essentially:

> I am 3 months old to python and I have done some small projects. I
> want to build a Peer to Peer streaming client

I wrote a reply back to the person directly and cc'd the kamaelia list, but the core of the reply is that the core of this relatively simple in Kamaelia, so I thought it worth posting here. The core of an actual peer looks like this:

Backplane("AUDIO").activate()

Pipeline( TCPClient( source_IP, source_port),
          PublishTo("AUDIO"),
).activate()

def PassOnAudio(): return SubscribeTo("AUDIO")

SimpleServer(protocol=PassOnAudio,port=source_port).run()

Whilst this clearly needs a source, and the core of that looks like this:
from Kamaelia.Audio.PyMedia.Input import Input  as _SoundInput

Backplane("SOURCE").activate()
Pipeline(
    _SoundInput( channels=1, sample_rate=8000, format="S16_LE" ),
    PublishTo("SOURCE"),
).activate()
def ServeSource(): return SubscribeTo("SOURCE")

SimpleServer(protocol=ServeSource,port=source_port).run()

Clearly there's lot's more to this, but that's the basic core you need. You can build QoS, buffering and multiple sources ontop of this.

The original reply is on sourceforge's archive, or will be when the archives update :)

Read and Post Comments

Things I need to look up

February 11, 2007 at 01:36 PM | categories: python, oldblog | View Comments

Two things struck me eye from comp.lang.python.announce that I need to look up at some point:
  • Shed Skin by Mark Dufur has a new release with initial support for iterators and generators. This strikes me as a really exciting, since it may mean that we can write a simple version of Kamaelia - ie a miniaxon - that works with shed skin. That opens up some really interesting options! I'll report back in the comments to this post the results of my experiments :)  (I need to reinstall dependencies first)
  • The other was Partial 1.0 by Martin v. Löwis which allows you to define a single class across multiple files. Whilst this probably looks odd I can see all sorts of interesting uses for this from the perspective of exogenous connectors. (Or put another for plugins)

Read and Post Comments

The Mikado - In the style of Bollywood -)

February 10, 2007 at 09:13 PM | categories: python, oldblog | View Comments

I'd like to invite anyone reading thing to come next week (its an ideal valentines day out :) and see a Bollywood inspired version of "The Mikado" at the Royal Northern College of Music (map). It's being put on by the award winning MUGSS society, and tickets start at a piffling £5 for concessions or start at £8 for the rest of us :) (more after the fold :)

Why would you want to see it?

It's going to be FANTASTIC, with a chorus of dozens and dancing numbers that just don't end. You'll never have seen The Mikado done this way nor never again. Where else can you see a giant elephant on stage in a light opera set in Japan? You can come and laugh at me on stage (I'm in the chorus) :) You will enjoy it, and anyone else you bring will too :)

When is it ?

From Valentine's day until the end of the week - Feb 14th - Feb 17th, at 7:30pm, also with a  matinee on the 17th at 2:30, so you can bring
the kids, who are bound to love it :)

The matinee will also feature BSL signing.

Where can I get tickets?

Well, it's probably too late for you to get them from me now (not necessarily though:) or book online using the RNCM's website.(or just turn up on the day). More info:

What's it about?

Well, The Mikado does have one of the more cogent plots of G&S, and its essentially a love story of hope, despair, and courage. More info:

Not interested? Please pass this on to someone who will be :)

Read and Post Comments

Upgrade to OpenSuSE 10.2, Topology Visualiser Fixed

February 10, 2007 at 04:54 PM | categories: python, oldblog | View Comments

Well, I recently upgrade from SuSE 10.1 to Open SuSE 10.2. The problem with this is the reason I normally use SuSE is because I personally want to focus on writing code, documents, etc. Well, what broke? Well, most of my video players had their libraries removed by the installer, and also firmware support for my wireless card was removed. That's not really any fun, but resolvable. Now I remember why I buy a distribution instead! Anyway, it's been useful for testing with python 2.5 (deprecation of string exceptions) and with updated packages. (Pygame has some minor behavioural differences meaning some minor bugfixes have been needed - this especially impacted the TopologyVisualiser. I've now fixed these issues :-)

The upgrade to python 2.5 has had a number of knockons. One of the minor ones being that raising string exceptions now causes deprecation warnings to be printed. For convenience, a number of subsystems have used string exceptions, for various reasons which now need revamping (generally old code BTW). This doesn't cause any major problems though, though it does encourage good practice prior to python 3.0.
Upgrading has overall been a good idea.

It also showed up an interesting problem to do with the topology visualiser. This is now a relatively old component and as a result uses pygame in a slightly unusual way. It as made before the PygameDisplay subsystem, which meant it accessed pygame directly. During 0.5.0, this was changed to use the PygameDisplay properly, but it still accessed the mixer. In earlier versions of pygame this problem was masked because it either failed silently or succeeded. However now it fails (which is useful to know!)

However, due to the work done in 0.5.0, this is a simple fix - we just remove the pygame.mixer.quit call from the TopologyViewer :-)

As a result that's now fixed. I'm planning on a doing a small screen cast demoing Compose as a result :) This also means that there will be a new point release coming shortly dealing with this.

Read and Post Comments

Glow in the Dark Dalek Stickers

February 02, 2007 at 11:56 PM | categories: python, oldblog | View Comments

Last year at OSCON I was lambasted. Was it my talk was bad? No. Was it because the demo broke? No, I recovered from that (I showed something else cool instead :). What was the piece of sacrilege I did? I had glow in the dark stickers of K9, a TARDIS, a Dalek and Cyberman on my laptop and I had been so thoughtless not to bring some for everyone. OK, the fact that I'd had the stickers on my laptop for months didn't wash. The fact they were freebies off the cover of Dr Who Adventures didn't wash either.

Anyway, in order to make up for it, here's a public service announcement: Dr Who Adventures magazine this week has glow in the dark DALEK!!! stickers on the front. Yes, all new glow in the dark stickers. They're even brighter than last years by the looks of things. (OK, there's also a very shiny K9 and a really large shiny Dalek Zek and a whole load of other stickers too, but I know it's the glow in the dark ones we all really wanted :-) ) Now to try and find out how to get a large supply of these for the next conference....

Read and Post Comments

« Previous Page -- Next Page »