- (https://b-ark.ca/SSi_SS)
Well, yet another long blogging hiatus. So what’s so important that I would take the time to author yet another scintillating installment? Why, a knitting project, of course!
- (https://b-ark.ca/AYgsAs)
A little something for the Movember fundraising drive, this is a custom design that I came up with by taking the game graphics and converting them to a pattern.
Review: Last Chance to See
New York Times bestselling author Douglas Adams and zoologist Mark Carwardine take off around the world in search of exotic, endangered creatures.
Join them as they encounter the animal kingdom in its stunning beauty, astonishing variety, and imminent peril: the giant Komodo dragon of Indonesia, the helpless but loveable Kakapo of New Zealand, the blind river dolphins of China, the white rhinos of Zaire, the rare birds of Mauritius island in the Indian Ocean. Hilarious and poignant—as only Douglas Adams can be—Last Chance to See is an entertaining and arresting odyssey through the Earth’s magnificent wildlife galaxy.
Douglas Adams is, of course, most famous for his work on the Hitchhiker’s Guide to the Galaxy books, but if there was one piece not related to HHGTTG by DNA that I wish people would read, it would be this one.
Mr. Adams was deeply fascinated with the natural world, and this love for the world around him absolutely shines through in this book, wherein Mr. Adams records his experiences traveling the world, encountering various endangered species in their natural habitat. His wonderful observational skills, and more importantly, incredible talent for putting those observations on paper in his wry, witty way, allow him to truly draw the reader into his experiences, and to feel his awe and reverence for the things he, well, had a rare chance to see.
At once sad and hopeful, I think some of his best writing is done in this volume.
Mr. Adams has said he was most proud of this book. If you ask me, he was right to be.
Update (2020-02-26):
Now, eight years later, I have to admit, this book still leaves me feeling incredibly bitter sweet.
On the one hand, the Kakapo has seen genuine success, with the Kakapo Recovery programme demonstrating the power of intense intervention to save endangered species. On the other hand, the Northern white rhinoceros is now completely extinct, having disappeared in the wild and died off in captivity.
I will forever be sad that Douglas Adams died as young as he did. However, I can’t help but wonder how he’d feel if he saw how little progress we’ve collectively made in honouring and protecting the world in which we live.
A Vim Tip - localvimrc
Inspired by vim: revisited, I thought I’d finally get around to writing up another blog post, this time focused on one of my favorite Vim plugins: localvimrc.
As even the most basic Vim user knows, Vim, upon startup, sources a file in the user’s home directory called .vimrc (sometimes _vimrc or other variants, depending on the platform). Traditionally, this file is used to store user customizations to Vim. We’re talking things like settings, user-defined functions, and a whole raft of other stuff. But it has a rather annoying limitation: it’s global. Of course, it’s possible to condition a lot of settings based on filetype and so forth, but ultimately this isn’t useful if you want to be able to specify settings at a project-level (for example, build settings, search paths, fold settings, etc). And this is where the localvimrc plugin comes in.
With localvimrc loaded, Vim, upon opening a new file or switching buffers, will search up through the directory hierarchy, starting from the location of the file, to find a file named .lvimrc. If such a file is found, the file is sourced just like any other vimrc file. So now, you can place those project-specific configuration items in a .lvimrc in the top-level folder of your project, and voila!, you’re good to go.
Of course, this alone is pretty damned useful, but there’s another somewhat less obvious but handy feature of localvimrc files: they make it possible to find the root directory of your project. And that is exceptionally useful for a few purposes:
- You can set up CommandT to always search from the top of your project, regardless of where you invoked Vim. I love this because I tend to navigate around in the shell and then edit files willy-nilly.
- You can configure project-level build commands which understand how to jump to the top of your project to run them.
- You can set up the Vim search path so that gf always works.
- You can load up project-wide cscope and ctags files.
- Probably lots of other stuff.
So, how does this work? Well, below is a sample of one of my lvimrc files:
if (!exists("g:loaded_lvimrc")) let g:loaded_lvimrc = 1 let s:rcpath = expand("<sfile>:p:h") exec "map <leader>t :CommandTFlush<cr>\\|:CommandT " . s:rcpath . "<cr>" exec "set path=" . s:rcpath . "/**" endif
The first thing you’ll notice is the guard. The lvimrc file is loaded whenever a buffer switch occurs, so this allows you to control which things are evaluated every time the file is sourced and which are only executed once.
Anyway, the real magic is in the subsequent lines. First, we use the expand() command to get the canonical path to the file being sourced (remember, this is our .lvimrc file, so this will be the top-level directory of our project). Then, we use that information to remap the CommandT command to run from the top-level project directory. Nice!
And, as I mentioned, you can do a lot of other things here. You can see the second line sets up our search path so we can gf to files in the project, as an example. Personally, I actually created a function in my .vimrc file called LocalVimRCLoadedHook(rcpath) that contains a lot of standardized logic for handling projects. You can find samples of all that on my Vim-Config GitHub Project.
- (https://b-ark.ca/CSuakk)
Lovely open-work baby blanket I did in the round. I believe this is the first piece I’ve done in this style and it turned out great!
Knitting Space Invaders
I’m working on some secret Movember-related projects, in the hopes of doing a little fundraising through auctioning, and as part of that I needed the sprites for Space Invaders, so I can chart ‘em out. Well, here they are, in case anyone else needs ‘em:
Of course, each of these characters has some variations, as they animate a bit, but these are the basic characters, minus the UFO of course.
Fun with Open Data
A Simple Problem
So, recently I found myself struggling with a very simple problem: I kept missing our darn garbage pickup date. Yeah, sure, the city sends out a little printed schedule, and it usually makes it to my refrigerator, but given that requires I actually pay attention to the silly thing, it doesn’t end up helping me much.
Now, in the past, I’ve solved this problem by manually punching the pickup dates into Google Calendar. This works, but it’s tedious, error prone, and whenever the new schedule comes out, I have to do it all over again. And if it wasn’t clear, I’m lazy. Real lazy. So last time around I simply didn’t get around to doing it.
And so I miss the pickup dates.
Obviously what I really wanted was an iCalendar formatted file that I could just subscribe to in Google Calendar, at which point I could move on with my life. But, alas, to my knowledge no such resource exists.
An Idea Is Formed
Well, I found myself discussing this with my officemate, Steve, and he pointed out that the pickup schedule is, in fact, available online in raw form as part of the City of Edmonton’s Open Data Catalog. The Open Data Catalogue is a remarkable resource. In it you can find a staggering amount of data about the city, provided in a simple, machine-readable form, and browseable online. It’s really very cool, and it feels like a resource just waiting to be tapped.
Anyway, back to the topic at hand, it turns out the pickup schedule is available right in the catalogue, albeit in a fairly raw form. At this point, the answer seemed obvious: write a tool which could consume this data, and produce an iCal file as output. I could then subscribe to the generated calendar, and voila! No more missed garbage days!
Why Can’t Things Be Easy?
Unfortunately, things got a little tricky once we started digging into the data. It turns out that the city is subdivided into a series of zones. Each of these zones then has one or more garbage pickup days, and so one’s individual pickup schedule varies based on your geographic location in the city. As such, the pickup schedule data is organized as a simple table as follows:
Zone Day Date So, now we have a problem: how do we determine the zone and day for a given household?
Well, it turns out the city provides the zone/day data as a geographic overlay, in the form of a KML data file. KML is a rather complex XML dialect which can be used to represent geographic data, and is used in, among other placed, Google Maps, Google Earth, and so forth. But, it’s a standard, and there are standard tools for handling it, so a gold star for the city!
Alright, so now we have the geographic data, we just need to parse that file, and then based on household location, identify the appropriate zone and day, and extract the correct schedule information. This should be easy…
A Solution
The first question was one of language. I knew I needed a few things:
- Access to a decent web framework, so I could quickly slap together a (preferably REST) web service.
- Something to parse the KML data.
- Something to do point-in-polygon tests, so that, given the boundaries of a zone and a household lat/long, I could determine if the household was in that zone.
- A CSV library would be handy (this is the form the schedule data takes).
- A library for generating iCalendar files.
And, in addition, given this was a quick learning project, I figured it’d be nice to choose something I haven’t written much code in. In the end, I settled on Python, and in particular:
- CherryPy - A simple, lightweight web framework with support for REST built in.
- libkml - A KML library with (poorly documented) Python bindings.
- RosettaCode RayCasting Algorithm - Code that implements the standard raycasting point-in-polygon test (I could’ve written this myself, but… why?)
- Python’s standard CSV module.
- vobject - A python library for parsing and generating iCalendar files.
Now, it turns out the hardest bit was in ingesting the KML file. The libkml bindings, while functional, are awful. They aren’t terribly pythonic, they’re horribly documented, and the examples and tests provide no coverage of the API. As a result, I ended up reading a lot of SWIG binding definition files, in order to determine the method calls available in the object model provided. But, eventually, I was able to figure out how to extract both the zone metadata (name, day, etc), and the polygon definitions, and with that, it was fairly easy to write a small library to identify a household zone based on their latitude and longitude.
After that, the rest was really pretty easy: the code determines the user’s zone, downloads the schedule data in CSV form, identifies the rows for that household, and then spits out an iCalendar file containing that schedule data. Voila, done! The service is available here:
http://api.b-ark.ca/garbage/schedule?latitude=&longitude=
Just enter your lat/long, and you should get a valid iCal file back. Nice! And even better, it took me roughly a day to slap the whole thing together.
Getting Fancy
Upon posting about this on Google+, another friend of mine pointed out that it was rather onerous to expect the user to go look up the lat/long of their household in order to use the service. This got me thinking of alternatives… wouldn’t it be great if the user could just provide their address, and the service could do the rest?
Well, happy days, it turns out Google offers a free REST API for geocoding (the technical term for the process of mapping an address to a latitude/longitude pair (or vice versa)). Just hit the service with a street address, and they’ll hand you back geographic data in the form of a JSON or XML document. Nice!
About ten lines of code later (with the help of Python’s minidom module), I had a service which could take an address, get the lat/long automatically, and return the appropriate iCal file. You can hit this version here:
http://api.b-ark.ca/garbage/schedule?address=
Just append your address to the URL, and you could get an iCal file back. Thanks Google!
Update:
BTW, if you want to take a look at the (quite simple) code, you can check it out on github.