Google recently release higher res imagery of Sydney (still no maps), which has inspired me to revamp my google maps tools using the new (still un-official, un-documented) API.
I've got what I think is a better UI (although I kind of suck at UI so other will probably disagree), and I've also made the NSW address lookup feature actually work.
I'd really like to start a community mapping projects that uses GPS tracks recorded by people to create a free vector map of Sydney, but it seems both hard and a lot of work, but you never know the power of procrastinating over a PhD!
Today I release the first version of nswgeo. It is a simple python script that queries the NSW Department of Lands GeoSpatialPortal to find the location of addresses in NSW.
That's right. We are hiring again, so if you are interested in hacking kernel level code, or writing and maintaining Python code, and are in need of a job please get in touch.
<rant>Why can't I do man g_assert? Why doesn't
GNOME provide man pages for glib?</rant>
Ok, I guess there are some good reasons, but from a user point of view
it is pretty frustrating. Of course man pages aren't that great
if you are trying to find a particular function that does what you
are after, but if you are trying to understand existing code
just being able to do man function_name is really
nice.
I guess I should stop ranting and start writing, but from initial glances on the intarweb it seems that people aren't that interested in man pages anyway.

It's interesting to see what headlines end up next to each other sometimes. I really like the Microsoft makes your passwords more secure, followed by the more security flaws in Windows.
So I was inspired (distracted) by the python functional programming module, and got to thinking couldn't things like partial application and function composition be a bit more natural in the syntax.
So it turns out that with decorators and a bit of evil introspection I came up with something that works (at least for functions that don't have keyword arguments). So you can do something like:
@Functional
def add(a, b): return a + b
add3 = add.add
assert(add3(1)(2)(3) == add3(1, 2, 3) == add3(1, 2)(3) == add3(1)(2, 3) == 6)
So what is the magic (or evilness)? Well first we (ab)use decorators to decorate things as Functional, which is you probably know, is just a shortcut for function = Functional(function).
The evil is in the Functional class:
class Functional:
def __init__(self, fn, nargs = None):
self.fn = fn
if not nargs:
_args, _, _, _ = inspect.getargspec(self.fn)
self.nargs = len(_args)
else:
self.nargs = nargs
def __call__(self, *args, **kargs):
if len(args) > self.nargs:
res = self.fn(*args[:self.nargs], **kargs)
if res.__class__ == Functional:
return res(*args[self.nargs:])
if type(res) != type((0,)):
res = (res, )
return res + args[self.nargs:]
elif len(args) == self.nargs:
return self.fn(*args, **kargs)
else:
def newfunc(*fargs, **fkeyw):
return self.fn(*(args + fargs))
newfunc.func = self.fn
newfunc.args = args
return Functional(newfunc, self.nargs - len(args))
def __getattr__(self, name):
if hasattr(self.fn, name):
return getattr(self.fn, name)
func_1 = self.fn
func_2 = globals()[name]
def composition(*args, **kwargs):
res = func_2(*args, **kwargs)
if type(res) != type((0,)):
res = (res, )
return self(*res)
return Functional(composition, func_2.nargs)
I totally abuse the __getattr__ method so that dot becomes a composition operator. This returns a new function (which is also Functional), which when called will pass on the return value from the first function to the second function. If the first function returns multiple results each of these is passed as arguments to the second function.
The real magic comes in the overload __call__, which is where
partial functions are hacked in. Basically if not enough arguments are
passed to the function is returns a new function that accumulates the
arguments already passed and once it gets enough calls the original function.
Of course the function returned from partial application is itself. The real
evil is in supporting the case add3(1, 2, 3) which means
we detect if too many arguments are passed and then call with only the first
arguments, then if the called function returns another functional we apply the remaining
arguments to it.
Oh yeah, I wouldn't use this in any real python code, as it is likely to confuse everyone!
Ok, pexif 0.4 is out (even after saying th other day that I wouldn't do any more releases for a while!), and I've updated the pyannodex 0.7.3 tarball to include a missing header file. (I didn't really think that deserved a version bump!).
I've released 0.7.3 of the pyannodex bindings. This fixes some bugs, importantly includes the config_unix.py script which is kind of essential for installing it. It also includes anxgrep.py tool.
pexif hits 0.3. Ok, there is now an easy way to get and set GPS coordinates on a photo, which was really my aim in writing this library in the first place. There is also a setgps.py and getgps.py script to do it on the command line.
I don't plan on doing any more major stuff to this library in the near future unless someone other than me is actually using it, so more than likely this will be the final pexif release. Itch scratched.