Category Archives: programming

30 Days of Geek: 05 – Quick nifty hacks you’re proud of.

As it turns out, probably about 90% of the coding that I do these days is in the form of nifty hacks. This is particularly because in research the impetus is not necessarily to have code that is reusable in a lot of situations, but rather to try out an idea quickly and then throw the code [1].

For example, just today, I needed a couple of images to put into my research poster for the conference I’m presenting at in a couple of days’ time. This involved drawing some rectangles over photos were faces had been detected by some other software. Basically, by having sufficient data in a format I had documented (in the form of other code) this was easy to extract. There are countless other things in my Honours thesis which looks somewhat like this — lots of experiments done with a tiny bit of Python code tying other big packages together.

The hacks that I’m proudest of are the ones which provide me with sufficient useful output that I can reuse their results, and not necessarily the code.

[1] Obviously, no code should ever be thrown away. When I say ‘throw away’, I mean something more along the lines of ‘ceasing maintainence’. This is because you can never know when a piece of code you’ve already written could be useful.

30 Days of Geek: 01 – Why do you consider yourself a geek?

Right, so for those of you who missed my announcement a couple of weeks ago, I’m taking part in the 30 Days of Geek blogging challenge throughout November. This is the first of those posts.

So this first of those posts. So, why do I consider myself a geek? I could list any number of stereotypical character traits, which I do see quite obviously in myself, but instead I’m going to go with just the one which sums up the most important issues nicely: Unhealthy obsession.

Let me explain. As I see it, the most important path to geekery is having a knowledge and understanding of a topic that exceeds that of other people you know. It tends to help if there is more than one such topic of which one has such a mastery.

I’ll start with the obvious first topic: I have an unhealthy obsession with computers. I learnt to program for the first time when I was 11 (MS QuickBasic 4.5 if I recall correctly) and I had a fascination for playing with settings on my family’s first Win98 machine (which resulted in doing a format/restore three times in the first six months of its ownership). Such tinkering left me in good stead for learning Linux a few years later: on the machine I had at the time, getting anything to work at all required hours browsing forums to find people with similar problems. Further to that, I could take the knowledge of how to solve these sorts of problems in Linux and apply them to new situations, frequently in an unrelated area of my system. I don’t think I’d have got anywhere near as far as I did without the unhealthy obsession with Linux I had at the time — this enabled me to spend weeks (when I had schoolwork to go on with) with a not-entirely-working computer, but fixing its problems.

So that’s probably the answer you expected to see. But it’s not just being good with computers that makes me a geek. This unhealthy obsession applies in other areas of interest. For example, I’m a keen follower of the Formula 1 motor racing series [1]. Whilst other people are content with just watching the races as they pop around, I spend ages learning the details which apply to each race — if I’ve a game where I can drive around a circuit to learn its layout I’ll do so. I’ll read Wikipedia so I can find out why people frequently crash at a given point on a track; and then I can relate the knowledge I’ve learnt from reading and gaming to the commentary of the race — which in turn feeds into a greater understanding of the race, which feeds into further learning about the event. Without the unhealthy obsession which comes with being a geek, I doubt I’d have the same level of interest (nor enjoyment) that I have.

So there, two examples of applied geekery, and how they relate to the my preferred reason for being a geek.

Up next, more in-depth questions. If I remember.

[1] Shock horror! I follow sports! Sorry if you think this disqualifies me.

Open Programming strikes again

I’m very pleased to announce that the LCA2011 organisers have accepted my proposal for the Open Programming Miniconf to be run at in Brisbane in January.  This is a new, improved, shorter-titled successor to the wildly successful Open Programming Languages Miniconf that was held in Wellington earlier this year.

From the proposal:

The Open Programming Miniconf is a single-day mini-conference about application development with Open Source tools.

Featuring talks on a wide range of topics and programming languages, this miniconf aims to bring together open source developers with presentations that share techniques, best practices and values amongst programmers of all open programming languages. OPM2011 will be held at 2011, at the QUT Gardens Point Campus in Brisbane in January.

Whilst the miniconf is yet to be officially announced, the proposal submission system is online at the miniconf website.  I look forward to seeing some awesome presentation proposals coming through in the coming weeks!

AUC /dev/world/2010 — I’m Presenting!

AUC /dev/world/2010, the Apple University Consortium’s conference for developers working on or with Mac or iOS devices is on again this year, on the 28th and 29th of September, in Melbourne.  Last year I presented a talk, and ran the conference’s lightning talks; the conference was fanstastic: the content was easily-accessible to staff and students from across the country, and catered to a very wide range of skill levels and familiarity with Apple frameworks.

This year, I’ll be presenting Awesome Things You’ve Missed in Python, a fast-paced, code-heavy recap of interesting features to hit the Python Programming language in the past few years.  My talk is not specific to Apple development, but will have a strong focus on techniques which are applicable to development with the PyObjC library.

If you’re on staff or are a student of an AUC member university (most Australian Universities are, as are a few Kiwi ones), registration is cheap ($100 for students), and all flights and accommodation are subsidised (to a generous limit).  If a fun two days of meeting interesting people and learning about development techniques with the latest technology available on Apple devices interests you, get in contact with your local AUCDF coordinator to register!

Pythonic UIs

I’ve just been reading Richard Jones’ current project, where he’s implementing a very Pythonic way of creating GUIs (for example, managing gui contexts using Python’s context managers). I’m very very excited, and I hope this sample code shows why:

with gui.form() as form: name = gui.row('Name', gui.text()) skill = gui.row('Skill level', gui.selection(['Awesome', 'Radical', 'Understated'])) @gui.submit('OK') def on_click(button): print 'Got name=%r'%name.value print 'Got skill=%r'%form['skill'].value gui.stop(0) @gui.cancel('Cancel') def on_click(button): gui.stop(1) 

Take a look at what this code does at Richard Jones’ weblog. It’s pretty awesome.

Cocomo: An experiment in metaprogramming in python

Friday saw the second edition of the UTAS Computing Society Lightning Talks, if you haven’t seen them already, I highly recommend that you check them out — this semester’s were at a very high standard indeed, and I wish I’d printed out more certificates for good talks :). My talk was a demonstration of using metaprogramming in Python, though that’s not what it seemed to be about.

An introduction

I went to the Apple University Consortium’s Cocoa Workshop at the University of New South Wales in February of this year, it was a heap of fun, and we learnt heaps whilst there. One of the key distinguising features of Cocoa is its use of verbose English method and attribute names, the idea being that each line of code should make a reasonable amount of sense when read aloud, hence:

NSString *str = [[NSString alloc] initWithString @"Hello World!"]

does indeed allocate memory to hold a string object, and initialises the newly-allocated memory with a string containing “Hello World!” (this code is highly redundant!). Supposedly such a naming scheme allows coders to write code that is easily maintainable by the original coder, and easily learnable by people who pick up the code for the first time.

On the other hand, my friends, collectively known as Maclab (named after the room at UTAS we inhabit) have developed a rather unique vocabularly, which in particular involves replacing as many words as possible with either ‘thrust’ or ‘fork’, so “Thrustingly thrust the forking forker” is not an uncommon utterance amongst my friends. If this is indeed their usual mode of conversation, then Cocoa’s way of identifying methods and attributes is not necessarily going to be a particularly intiuitive one. So, clearly, we need a version of cocoa that meets their needs.

The setup

So, conveniently, Apple provide a comprehensive version of the Cocoa API, thanks to the PyObjC project. We can therefore use the Python bindings for Cocoa facilitate our new version of Cocoa. Since Cocoa has a very consistent naming scheme, we can simply perform string replacement to translate from our maclab language to the standard cocoa language, using a routine somewhat like this:

 def translate(inp): ''' Translates an input string from key language to value language ''' for i in LANGUAGE: if i[0].islower(): inp = inp.replace(i, LANGUAGE[i]) inp = inp.replace(rtitle(i), rtitle(LANGUAGE[i])) else: inp = inp.replace(i, LANGUAGE[i]) return inp def rtitle(i): return i[0].upper() + i[1:] 

Here, LANGUAGE is a dictionary, with keys in the language code will be written in and values being the target language (in this case, Cocoa). There’s not all that much of a sophisticated nature going on in here. Now that we have a method by which we can translate our attribute accesses, we can get to the meat of the the code.

The implementation

To achieve the new API, we need to use a technique that I will call proxying. This involves the use of objects whose sole purpose is to intercept attribute accesses and calls to an underlying object. In this case, the point of intercepting the calls and accesses is to perform translation from our new objects to standard Cocoa objects. In Python we can do this by overriding the standard attribute access and call methods.

First up is __getattr__, the attribute accessor method — for this, we are passed a string; the name of the attribute that we’re looking for, which we translate, and then attempt to access upon the method on the underlying object (in this case, self.__u__). There is one slight hitch: in certain cases, we may not want to translate the attribute name. This is true, in particular, of the attribute that represents the underlying object. Hence we provide a REAL_ATTRS list, for which we use the default __getattr__ method for. This results in code that looks something like this:

 def __getattribute__(self,name): if name in REAL_ATTRS: return object.__getattribute__(self,name) else: new_objectname = "self.__u__.%s" % translate(name) new_object = eval(new_objectname) return CocomoProxy(new_object) 

Notice that we use eval to perform the lookup? It turns out that __getattr__ doesn’t work universally, whereas . notation does — so we use that for less failover.

Being able to call methods on the objects is important, but slightly more difficult — we want behaviour to be maintained, so we need to make sure that proper Cocoa objects are passed as arguments, rather than the Proxy objects that you may have originally dealt with. We can do this with Python’s argument unpacking — we build up a list of arguments, and unproxy them as necessary:

 def __call__(self,*a, **k): new_a = [i.__u__ if type(i) == CocomoProxy else i for i in a] new_k = dict( (translate(i), k[i].__u__ if type(k[i]) == CocomoProxy else k[i]) for i in k) return CocomoProxy(self.__u__(*new_a,**new_k)) 

We may also need to deal with iterators. This can be done using a standard generator function, thusly:

 def __iter__(self): for i in self.__u__: yield CocomoProxy(i) 

Finally, there may be legitimate reasons for extracting Cocoa objects, these include printing strings, so we provide an accessor method called no_really:

 def no_really(self): return self.__u__ 

And that’s the entire implementation! The final thing we need to do is provide a pre-proxied version of the base module for Cocoa. Let’s call it GypsyMagic.

The payoff

So now that we have a working bridge from Maclab English to Cocoa English, we can take this sample code that puts some stuff into an array, and then prints it:

 import AppKit hworld = AppKit.NSString.alloc().initWithString_("Hello, World!") arr = AppKit.NSMutableArray.alloc().init() arr.addObject_(hworld) arr.addObject_("Boop!") for i in arr: print i 

And write it in the far more palatable:

 from cocomo import GypsyMagic hworld = GypsyMagic.OGMouthWords.subsume().makeGogoWithMouthWords_("Hello, World!") arr = GypsyMagic.OGForkableTrinketHolder.subsume().makeGogo() arr.thrustinglyThrustForker_(hworld) arr.thrustinglyThrustForker_("Boop!") for i in arr: print i.no_really() 

If you’re interested in seeing how it all fits together, see Cocomo’s website.

Growing a Language

I was recently pointed at a talk given by Guy Steele (who, amongst other things, co-invented Scheme), given at the 1998 OOPSLA Conference, entitled Growing a Language.

In it, he talks about the need for Java to add features that will allow the language to grow as users add to it, specifically suggesting two features (one of which has been added, albeit poorly, and one of which is still yet to be implemented); but the real value of the talk is not what he says, but in how it is presented: whilst giving that away would be entirely unfair, I recommend watching at least the first 10 minutes of it, to allow you to figure out what’s going on.

So, if you get a spare hour in the near future, I suggest you watch it.

Fun with Sockets

Whilst doing some coding today for my semester research project I found a need to check for incoming data on a socket without taking any data out of the stream. Here’s the code I came up with:

 cp.sock.setblocking(False) try: cp.sock.recv(0) stuffwaiting = True except socket.error: stuffwaiting = False cp.sock.setblocking(True) 

This code works finely on Linux — you can only receive data if there is data to be received (even if you want to receive no data). Unfortunately, the code doesn’t port to Mac OS — you may receive as many bytes as there are in the socket’s buffer — if there are no bytes in the buffer, you can receive 0 bytes. Therefore, the following fix is necessary:

 cp.sock.setblocking(False) try: cp.sock.recv(1, socket.MSG_PEEK) stuffwaiting = True except socket.error: stuffwaiting = False cp.sock.setblocking(True) 

So, my question for Lazyweb is: is there a better way to do this?