Posts for Friday, April 16, 2010

Printing a nicely formatted plaintext table of data in Clojure

I use this fairly often while data-munging, when I want to quickly view a list of hash-maps of data in a simple table format. Usually this is coming out of database. Maybe someone will find it useful.

(defn table
  "Given a seq of hash-maps, prints a plaintext table of the values of the hash-maps.
  If passed a list of keys, displays only those keys.  Otherwise displays all the
  keys in the first hash-map in the seq."
  ([xs]
     (table xs (keys (first xs))))
  ([xs ks]
     (when (seq xs)
       (let [f (fn [old-widths x]
                 (reduce (fn [new-widths k]
                           (let [length (inc (count (str (k x))))]
                             (if (> length (k new-widths 0))
                               (assoc new-widths k length)
                               new-widths)))
                         old-widths ks))
             widths (reduce f {} (conj xs (zipmap ks ks)))
             total-width (reduce + (vals widths))
             format-string (str "~{"
                                (reduce #(str %1 "~" (%2 widths) "A") "" ks)
                                "~}~%")]
         (cl-format true format-string (map str ks))
         (cl-format true "~{~A~}~%" (repeat total-width \-))
         (doseq [x xs]
           (cl-format true format-string (map x ks)))))))

Then you can do this:

user> (def data [{:name "Brian" :job "Code monkey" :age 29}
                 {:name "Bob" :job "Janitor" :age 97}
                 {:name "Johnny McLongname" :job "None" :age 3}])
#'user/data
user> (table data)
:name             :job        :age 
-----------------------------------
Brian             Code monkey 29   
Bob               Janitor     97   
Johnny McLongname None        3    
nil
user> (table data [:age :name])
:age :name             
-----------------------
29   Brian             
97   Bob               
3    Johnny McLongname 
nil

lessons from “Coders at work”

I already mentioned Coders at work in an earlier entry. The point of this one is not to write a review, but to make a note for myself of what I’ve gotten out of the book. I think I could do better to read more books with a pen and a pad so I have a better chance of exploiting the content.

So these are notes to myself. I wouldn’t take it upon myself to summarize a more general listing of notes that would somehow apply to the average person, because I think we’re all in very different places in the universe that is called “learning to program (well)”, and every person has to figure out for himself what he most needs to learn relative to where he now is.

Advice: Read code

Read other people’s code, “open black boxes“. This is something I never really do, I should start. Just take some codebase and check it out, get used to the practice. Reading code is not the easiest thing to get into, so here are some tips:

  1. First, get it to build.
    Sometimes everything you have to do to build it already teaches you a number of things about the codebase. And once you have it built, you can start making changes to it and try out little things dynamically.
  2. Read while building.
    Making builds for any codebase can be hairy and painful, so parallelize this activity with code reading. Great way to use the time you’d otherwise waste in between debugging the build.

Advice: Write unit tests for new library

You’ve found a library for something that you’ve never used before: how do you figure out how to use it? Write unit tests. Some libraries have bad unit tests (or no tests) to begin with, so it could be a way to improve it. In any case you can test your basic hypotheses of how the library works.

Ideas to investigate

  1. OO and classes vs prototypes (JavaScript).
  2. “There is a lack of reuse in OO because there is too much state inside”. Libraries must expose too much of their innards through APIs, functional programming model should be better at this.

Pointers

Articles:

  1. Richard P. Gabriel – Worse Is Better

Books:

  1. Douglas Crockford – JavaScript: The Good Parts
    In the absence of the book, Crockford’s lecture series on JavaScript is probably a good start.
  2. William Strunk, Jr. and E.B. White – The Elements of Style
    For writing better English.
  3. Steve McConnell – Code Complete
    On software engineering process and best practices.
  4. Gerald Weinberg – The Psychology of Computer Programming

Talks:

  1. Joshua Bloch – How to Design a Good API and Why it Matters
avatar

Notes on setting up Gentoo

I’m installing Gentoo on my laptop – here are some notes (for myself, really).

  • Gentoo installs the flash plugin to a path with “netscape” in it. There is a problem with this http://groups.google.com/group/opera.linux/browse_thread/thread/9e9a3c21cd413c2f/3949ce2e8f96f84a so we need to symlink the plugin to the opera plugin path.
avatar

Geotagging my Flickr photos

Tonight I finally got round to adding my photos to the Flickr mapping feature. I guess I got inspired by taking and uploading my first photo using Zonetags with my phone (Nokia 6680) and my Holux bluetooth GPS receiver.

Zonetags

Zonetags is a trivially easy-to-use beta-ish application for Series 60 Nokia smartphones that acts as a wrapper for the standard camera software. It can record the cell id (I think it uses the last known value if you’re not in reception) and attach it to each photo you take. You can also connect an external GPS device to add much more accurate longitude and latitude information to the photo. Once you have taken a photo you’re asked if you want to upload it to Flickr. If you do, Zonetags can optionally add action tags to do things like rotate your photos as well as suggestting extra tags based on your location and the tags that other people have given to nearby photos.

For example, when I uploaded a photo coming down from Snowdown at the weekend, “Caernarfon” and “United Kingdom” tags were added along with the geotagging and celltagging ones. Over time, this could get really smart.

Unfortunately, my camera can’t use my bluetooth GPS. I think as a workaround way of geotagging those photos, I might also take one with my phone and upload it with private permissions via Zonetags (to get the geotags into Flickr) and just replace the photo with the better camera shot when I get back to a computer. We’ll need to wait and see if that is too much of a pain in the arse to be practical when out in the hills though.

Flickr map

I’ve wanted something like this for a while now – being able to browse photos by location is nifty stuff. It’s super easy to get photos on the map (if you’re using a supported browser, of course…), but I find it is limited by the poor quality of the maps, at least for most of Scotland. Of course, Flickr can’t help this and it will improve given time, but it would all be so much cooler if the maps I use most were worth looking at! There are 3rd party apps that are more accurate or you can hand geotag the photos with the lat/longs yourself and import them instead, but I haven’t bothered looking at any of those options yet since my priority was to just get them all geotagged.

In some crazy alternate reality where I actually have some spare time, I will use the Flickr API in my desktop mapping software to give the same functionality in a faster and much more detailed environment. That’s after re-writing it so that it’s not just a prototype, adding in GPS tracklogging and a million other neat things… sigh.

The good

  • Flickr map is very cool, I like it
  • Zonetags is very cool, I like it

The bad

  • Yahoo! Maps isn’t as good as Google Maps
  • Yahoo! Maps is vastly inferior to Google Maps
  • Scotland has pish quality maps – ces’t la vie
  • Zonetags doesn’t allow you to change your mind and upload a photo you previously took with it – pretty poor
  • My phone/bluetooth/software combination only allows one phone -> bluetooth connection at a time

The ugly

  • The admin map interface doesn’t work in Opera – boo

From that list it looks like I’m not too positive about this stuff, but that couldn’t be further from the truth – it’s excellent and is going to keep getting better.

Update (26/10/2006)

I forgot to mention that I was a little annoyed that Flickr didn’t add geotag tags to my photos when I added them to the map. Last night I found this excellent bookmarklet which embeds Google Maps into Flickr, giving you much more accuracy. It totally rocks. Or, it will totally rock if it starts to work in Opera. For now it just rocks. It adds the geotags as well as giving your photos a link to Google Maps (you can see the singletrack!). There is a little discrepancy between Yahoo! and Google Maps (about 100-200m), but it is definitely preferable for me to use Google Maps for the forseeable future. Now I need to go back through my photos again…

avatar

Migrated blog software (yet again)

I’m checking out Mephisto just now, RSS/Atom readers might have just got some double posts – sorry! I’ve written some more mod_rewrite rules so most of the important old URLs should work fine and, to be honest, I don’t care about any of the more obscure ones.

Recently, I’ve hardly had any time to write here and I hate switching blog software – so why have I done it yet again? Mostly to abandon the downright abysmal Typo and Mephisto offered a simple migration process away from that. So far so good, but we’re a whole two hours in…

We’re also (thankfully!) at least considering using Rails for some projects at work and every little helps when getting back in the swing of things.

Posts for Thursday, April 15, 2010

avatar

Greek spammers email addresses blacklist

GrRBL
In the beginning of the year I announced my RBL for Greek spam emails. The blacklist is growing larger by the day, thanks to some really kind people forwarding me their Greek spam emails, and has reached more than 120 IP addresses of verified Greek spammers.This alone though is not enough.

Why
Some spammers use their aDSL lines which have dynamic IPs to send their massive email “newsletters”. These people are split into 2 sub-categories. The ones that use their own PC as an SMTP server and the ones who use their ISP’s mail server as SMTP. I’ve tried to complain to some of their ISPs…some replied back saying that they were willing to look into the issue (but did nothing at all in the end) and others did not even reply to me. For both sub-categories, GrRBL is ineffective since I can’t add dynamic IPs in the blacklist nor can I add the IPs of the email servers of those major Greek ISPs.

Another category of spammers is the one that uses their gmail/yahoo accounts to send their emails. GrRBL is ineffective for this category as well since I can’t add gmail/yahoo to the blacklist…

What
So there was no alternative but to gather all those email addresses of these 2 categories above and add them to a new blacklist, one that will contain email addresses. I use this blacklist with my spamassassin configuration to eliminate Greek spam that GrRBL can’t. Each time I receive (or someone forwards me) a new Greek spam, I add the “From:” email address to this new blacklist. This new blacklist grows far more aggressively than GrRBL since it’s a lot easier to gather the data and already has more than 140 addresses.

Distribution
There are two available formats of the blacklist, one ready for use by spamassassin and another one with clear formatting ready to be used even by SMTPs to drop these spam emails without even touching your inbox.
The blacklist is currently only distributed to a group of well trusted people and it is available only through rsync with a username/password.

I don’t want to make the list completely public yet, but if you are interested you can request it at the contact email of GrRBL and I will reply to you about accessing it.

Sidenote
If you need a good tool to check a host again some RBLs, adnsrblcheck by Yiorgos Adamopoulos is the way to go (and it includes GrRBL!)

What Happened?

Rant ahead!

Some of you might remember the blog post I wrote almost two years ago about what I do in front of my computer most of the time and why (if not you might want to read it now ;-)). Today I was thinking about how things were back then, and how my view on the whole Open Source topic has changed since.

The three main things I pointed out why I'm so attracted to being actively taking part in the Open Source movement by spending my free time on contributing stuff where fun, interesting people and the rewarding good feeling of getting cool things done and make them available to others.

Recently however, I spend less and less time contributing to projects. And I asked myself why and ultimately came to the conclusion that it's the people:

For me, the people are taking away the fun and without fun there's no reward EOL

Okay, you've read that correctly, now take a step back and let me explain. Of course I don't mean all you nice people I meet over the past years. I'm rather talking about the so called Open Source movement which I think has lost quite a bit of it's shiny glory.

For example, how can it possibly be that the decision of one distribution (I wont drop any names) to change a certain default setting, which every user can change back to his own preference in less than 10sec, can trigger a shitstorm of bad press and whining, about, you know, something you get FOR FSCKING FREE (I really had too allcaps this one, I'm sorry). And all that under the - you're taking away our freedom - flag. We can all agree that this was just one of the many examples how thankfull everyone is about the tools which are provided to us FOR FSCKING FREE and we use everyday to get shit done.

The most common counter argument I heard in the past when I wondered why it is the way it is was:

9 out of 10 people are assholes, just don't worry about them and carry on.

But that ain't that easy. Not with the recently periodically absence of fun and thus reward. The phases I had fun coding stuff compared to the days where I was completely unmotivated have shifted 180 degrees. 2 Years ago I was happily coding on an interesting project for days with one day of demotivation occuring every 2 or 3 weeks. Now I'm demotivated for weeks and experience a coding “high” only occasionally. Ever since that shift became more apparent to me I keep thinking about ways on how to escape this unpleasant situation. I mean, I care about the stuff I'm doing - or don't I?

One thing I tried was to setup a “coding day”. It was just one day of the week where I would try to get my stuff done, bugs fixed, features implemented and new stuff released. This worked for a couple of month. But that phase went away too. As of late I completely switched to what I call slide-mode.

slide.jpg

I simply let it happen and don't force myself to think about my Open Source contributions all that much. Just two weeks ago I had such a moment and a high kicked in and I spit out a good 1000 lines of code for something I had planned to do for a long time (and probably some more people are looking forward to too). Now that unfinished projects sits there, waiting to get finished, but I'm not the least motivated to do it.

Okay one could argue it's really just me, it has nothing to do with the people I talked earlier about. But I tend to disagree. Two years ago I was happy doing this stuff for people (and for myself of course) - today I feel I'm doing it mainly for myself (and for a small group of people). The problem with that is, I don't even use 90% of the stuff I'm maintaining. If I don't do it for the people who actually use that stuff, I do it for nobody, and spending time on “nobody” is quite a stupid thing to do if you ask me.

So, slide-mode isn't the only thing I try to escape my motivational low caused by my lack of understanding for the Open Source movement and it's unique way of showing appreciation for the people who put so much work in stuff (no, I'm not talking about me and yeah I'm exaggerating right now). I cut down the FOSS related blogs I've subscribed to 0. If something important happens I will get hit by the next shitstorm via any of my social networks anyway. You know, like Apple releases a new product, Ubuntu changes it's default search engine, Microsoft goes Open Source, Linus is happy with Kernel blobs, whatever.

Side note: Am I alone with the opinion that the overall reaction of the Open Source community to the release of the iPad was completely inappropriate? I mean, I don't like it either, but that doesn't entitle me to shit on everyone's head who ever got himself a Apple product. I thought we people in the Open Source community ought to be smart, right? From all the blog post I read about the topic maybe only one out of 10 didn't treat the average Apple user as a stupid low life monkey (not to mention twitter/identi.ca). Excuse me? In the world I grew up smart people had manners. Also you don't change anything by pointing a finger at someone and telling him he's a dumb fuck who knows nothing about what's good for the society. Well, that's another reason why I'm so unhappy with that whole Open Source thing and I'm not sure anymore if I want to associate myself with it that much at all.

So, what happens now? I keep sliding and continue doing things I'm really happy to spend time on. Tae Kwon Do is the one thing. The best thing about Sport is the reward which kicks in instantly and grows the more you progress. I'm also playing Eve Online since two month. Yes it's a MMPORG and I can literally feel all your fingers pointing in my direction. I would probably have quit playing it a month ago (my average motivation for any computer game is less than 3 days before I find it boring). But I found a group of nice people to hang out with in the game and there's absolutely no pressure and no need for me to be online 7 days a week (I usually play Friday/Sunday evenings if I have nothing better to do, which happens to be the time I would have spent coding stuff). Also the Summer is coming and I have prepped my bike already and I started to learn Korean. All those things give instant reward. None of it confronts with stuff I would have a hard time to just ignore. And I'm doing all of it for myself.

Right now I'm happy. But I sort of don't like where the Open Source community is heading.

This blog post was created on 2010-04-15 at 16:32 and last modified on 2010-04-15 at 16:37 by Michael Klier. It is tagged with brainfart, opensource.

avatar

Does anyone have the ruby-maemo source?

Tom Swindell (AKA alterego) created the Maemo bindings for Ruby and they’re great. I’m writing a couple of programs with them, including Nibbles, my feed reader. Unfortunately, Tom seems to have vanished and I’ve not been able to find the source code for the bindings anywhere. Does anyone have it? I’d really like a copy.

In other news, I hear that a new release of ruby-gtk2 is near. This is excellent as it will hopefully fix the battery life problem with the current bindings where Ruby/GTK programs (and, therefore, Ruby/Maemo programs) wake up 100 times a second regardless of what they’re doing. Happy days.

avatar

A Ruby binding to cracklib

Just released rubylibcrack as a gem (0.1.1). I developed this teeny-weeny binding to the *nix password strength checking library cracklib at my work. Big props to my work, they totally get open source and the way things should be done.

The gem has only been tested on Redhat, Fedora, Gentoo and Ubuntu (all 64bit, I think), but I’d love to hear how it fares on other platforms. Here’s a Gentoo ebuild for the package.

avatar

Gentoo on an Acer Aspire One

Since details seem to be all over the place for getting everything working with a non-Linpus Linux on the Aspire One, I decided I’d add another place!

This isn’t a complete guide, since I haven’t got time. These are only the unusual things or the things that I found tricky during my install. If I don’t mention something here, it’s because it “just worked” or was obvious.

Kernel

Attach .config.

I use vanilla-sources, which is the unpatched kernel from kernel.org. For this install I decided to use the latest release candidate in the hope that it would make life easier for getting the SDHC cards and wireless working.

Wireless card and LEDs

I’m using the ath5k driver from the kernel. I’ve only had a single problem (detailed below), but haven’t been to many wireless networks yet.

avatar

Ruby process management with Jobby

Jobby is a generic forking process manager written in Ruby, built with robustness as a primary goal from the start. It was initially developed for offloading long running background tasks from the webserver in Rails applications, but it turned out to be useful in its own right, so we extracted it to work more generally. It uses Unix sockets and a call to fork(), so won’t work on Windows or JRuby, but has been tested on several flavours of Linux and OS X. It is also copy-on-write friendly, should the Ruby interpretter that’s used support it.

If you prefer to read code than blog posts, server.rb does most of the heavy lifting.

After a long struggle of using the old BackgrounDRb, last year we finally threw in the towel. We checked out the alternatives, but nothing really fitted the bill. Since background job processing is quite central to some of our applications, we built our own. From the start we had some requirements:

  • Run jobs in parallel up to a maximum number or processes, then start queuing
  • Robust – it just had to be solid
  • Easy to manage – we hated those BackDRb scripts
  • Reliable logging
  • Able to get messages from the background processes

Jobby itself does not provide a mechanism for getting messages from the child processes. I’ll detail a jobby_rails plugin that handles that some other time.

Installing Jobby

gem install jobby will do the trick if for some reason you don’t hate gems. You can also check out the source from github.

Gentoo users can install Jobby from the Gentoo Ruby overlay. Note: I stopped using Gentoo sometime around March 2010. It might still be there.

How does it work?

Jobby is a command line program. It consists of a daemon that listens on a Unix socket and will fork when it receives a connection. The forked child either runs some Ruby code or executes some shell code, depending on how the daemon was started. When you call Jobby, you pass a single parameter to STDIN – this string is passed to the forked child. It could be an ID of some sort, a whole email, a marshalled object or whatever.

There is only one command used, jobby. When this is run it first checks for the existence of the daemon process listening on the socket. If it’s not there, it starts one (and then executes the child command). This is great because it makes daemon startup totally automatic and if the daemon should go down (this hasn’t happened to us yet in the months that we’ve been using it), the next request will start up a new one.

Stopping Jobby

There are two ways to stop the daemon, both using Unix signals. Issuing a USR1 initiates a “very friendly shutdown”, which will stop the daemon accepting any new connections but will allow it to finish the jobs in the queue before terminating. Issuing a TERM signal will stop the daemon forking, then issue a TERM signal to the child processes and terminate the daemon.

Other nifty stuff

When using Jobby to run Ruby code, you might want to have the children load a few libraries before they do any work. Repeating this every time is a pain, so you can instead pass a --prerun parameter to prerun some Ruby code in the daemon before any forking takes place. This will load the libraries (at least in this example) so that they are immediately available in the children when the fork occurs. If you’re using a copy-on-write friendly interpretter, like Ruby Enterprise Edition, you’ll get the memory saving benefits of that too.

You can run multiple Jobby daemons – just call each one by passing a different socket parameter. This is how you can run different code for different job types that you have.

To make your debugging life easier, the forked children will show up in process listings as jobby: /path/to/socket. The actual daemon process will show up as jobbyd: /path/to/socket.

Using Jobby with Rails

Jobby was designed for use in Rails applications, but was extracted since it is generally useful. This post only describes Jobby itself, which you can happilly use from a Rails app using a system call. Sometime I’ll get round to releasing and detailing a Rails plugin for Jobby that adds a communication layer to Jobby and makes Rails intergration nicer. We’re using it just now, but it’s not really releasable as it is. I decided that since the main Jobby code has been so stable for us, it made sense to release it now.

avatar

Ensuring epatch works correctly on embedded Gentoo

On my BeagleBoard, the ebuild messages were telling me that the patches had been applied successfully, but inspection of the code showed they hadn’t. It was a nasty problem to fix – it seems like a epatch wasn’t liking the cross-compiled bash.

After compiling bash natively and getting a another shell, the epatching was successful.

avatar

Nibbles 0.1 released

I’m pleased to say that I’ve just released version 0.1 of Nibbles, an alternative RSS and Atom feed reader for Maemo. A big thanks to the people who were kind enough to help out with the pre-release testing, you’ve been (and hopefully continue to be!) a great help.

Nibbles screenshot

Nibbles is quite stable, can parse a wide variety of feeds and is pretty bandwidth efficient. Nibbles is finger-friendly and does aim to be a good mobile feed reader, but things like downloading of full offline articles didn’t make it into this initial release (I have some working code for that, but it’s not working enough!). New users might want to know that the zoom in/out hardware buttons hide and show the feed and article lists.

Of course, since this is a first release, things aren’t perfect. The biggest problem for me that I think people should be aware of is that Nibbles uses too much battery power. This is detailed in bug #2342 and is really a problem with ruby-gtk2 rather than Nibbles. As I said, with some luck, the next ruby-gtk2 release will fix this.

You can install Nibbles from the project page.

avatar

Nibbles, a feed reader for Maemo

I don’t really get on with the supplied RSS reader on my N800. It doesn’t work like I expect and it lacks mobile features like offline reading that I’d like. So, I’m writing a feed reader for Maemo called Nibbles. It’s still very early stages, but there’s enough for a development release now, I think. Below is a screenshot of the current preview version, 0.0.4:

Nibbles screenshot

It seems to cope nicely with a wide variety of RSS and Atom feeds, despite my proof-of-concept code somehow making it into the app ;) .

Currently it’s quite bare of features and can be considered the simplest app that could work (for example, the feeds update at a fixed 30 mins). It will likely stay that way until I get a few bugs worked out and 0.1, the first ’stable’ version, released. After that, I’ll work on some more interesting new features. I’m still very open to suggestions though and all feedback is welcome, so please don’t be shy!

If you’d like to play along and help the development of a better feed reader for your internet tablet, use the .install file. Please report issues to the Maemo Garage tracker.

You can make Nibbles the default feed reader by editing /usr/share/applications/defaults.list. You need to set hildon-news_reader=nibbles.install. This will allow you to tap on the feed icon in a browser window and have the feed added to Nibbles.

I’ve only specified that the app will work in OS2008, but I’m pretty sure it’ll work in OS2007 too. Since I only have an OS2008 machine, I can’t test it easily. If anyone is still using OS2007 and would like to help, please do get in touch.

avatar

Creating RubyGems .debs for Maemo

I’m writing an application (more on that sometime soon) using the very nice Ruby bindings for Maemo. I’ve got some dependencies that are packaged as RubyGems that I wanted to be managed through the Application Manager, so I created some .debs for them. Here is their temporary home The rake, hpricot, feed-normalizer, simple-rss, atom and htmlentities gems are available in my repository. I didn’t create the rubygems and librubygems packages themselves – I was sent them, but couldn’t find them hosted elsewhere.

It took me a little while to suss out how to create the .debs so I’ve included the steps here in case anyone finds themselves in the same boat. This works for native Ruby gems and compiled C extensions.

  1. Install the gem inside Scratchbox. Irritatingly, “gem install example” doesn’t always want to do very much, so you may need to dowload the gem file and “gem install example-0.1.gem”.
  2. Make a new directory with the rubygems-<package>-<version> syntax (the rubygems- prefix seemed to make sense to me): mkdir rubygems-example-0.1</lil>
  3. cd rubygems-example-0.1/ ; mkdir gems specifications bin
  4. cp -r /targets/CHINOOK_ARMEL/var/lib/gems/1.8/gems/example-0.1/ gems
  5. cp /targets/CHINOOK_ARMEL/var/lib/gems/1.8/specifications/example-0.1.gemspec specifications/
  6. cp /targets/CHINOOK_ARMEL/var/lib/gems/1.8/bin/example bin/ (if there are any bins)
  7. Create a Makefile with this content (you will need to replace the spaces at the start of the lines with tabs):
    all:
    clean:
    install:
            mkdir -p $(DESTDIR)/var/lib/gems/1.8/gems/
            mkdir -p $(DESTDIR)/var/lib/gems/1.8/bin/     <------ REMOVE THIS LINE IF THERE ARE NO BINS
            mkdir -p $(DESTDIR)/var/lib/gems/1.8/specifications/
            cp -r gems/* $(DESTDIR)/var/lib/gems/1.8/gems/
            cp bin/* $(DESTDIR)/var/lib/gems/1.8/bin/     <------ REMOVE THIS LINE IF THERE ARE NO BINS
            cp specifications/* $(DESTDIR)/var/lib/gems/1.8/specifications/
    
  8. dh_make -e you@example.com then choose the type of package.
  9. Edit debian/control to suit. Make sure the section is something like user/Utilities, not just Utilities if you want the package to show in the Application Manager.
  10. dpkg-buildpackage -rfakeroot -b
  11. The parent directory should now contain rubygems-example_0.1-1_armel.deb

As a final note, /var/lib/gems/1.8/bin/ may not be in $PATH, so you'll need to deal with that if you have files in bin/.

avatar

Mercurial 0.9.5 for Maemo

I’m using Mercurial to track changes in my latest project, a GTK mapping application. I couldn’t find a build for my N800, so I made one myself. I’ll host a .deb until I get around to putting it on the garage or creating a repository.

Edit: I’ve started a garage project.

To install python2.5-runtime I needed to add repository.maemo.org to the application catalogue to satisfy some dependencies. Tested with OS2008 beta on an N800 only.

Posts for Wednesday, April 14, 2010

Installing Clojure with Emacs and SLIME: so easy, yet so hard

How do you install Clojure with SLIME/Emacs support? The answer is either really easy or really hard, depending.

Easy!

If you're new to Clojure and want to get it working fast, you are in luck. Go to swank-clojure's home on github and follow the directions to install it via ELPA. This is very easy and fast and it works.

If you want more documentation, there is (thankfully) a single, central, official-ish location where documentation for installing Clojure is slowly but surely accumulating. You can read about it at http://www.assembla.com/wiki/show/clojure/Getting_Started. This site includes instructions for Emacs, Netbeans, Eclipse, Maven, and everything else under the sun. This is a great resource, and attempts to solve the problem of out-of-date Clojure documentation. (This problem is natural given Clojure's young age and rapid growth, but it's painful for people trying to get started, I bet.)

Or is it...

This is all great. But if you want to do anything non-standard, you run into a bit of a wall. How do you install Clojure+SLIME on Windows? I find that sometimes it works, but sometimes things mysteriously fail, and I have no idea where even to begin to debug it, because there's so much automation going on in the background nowadays. What if you want to build a .emacs.d directory you can simply copy from one system to another and have everything work? (You can do this with most Emacs libs.)

Or how do you install and use a bleeding-edge Clojure or clojure-contrib tree with SLIME? There's good reason to want to, because it has some awesome new features, e.g. deftypes and protocols and rest-parameter destructuring. But most of the "official" methods of installing things give you stable versions of everything.

And then, you generally end up with a bunch of opaque .jar files, auto-downloaded all over your system, which isn't helpful if you want to hack on anything yourself. Most of these jars end up in ~/.m2 nowadays, I think? Used to be ~/.swank-clojure or ~/.clojure or something? And ~/.emacs.d/elpa gets stuff too? Color me continually confused.

The automated build tools we have nowadays (ELPA, Lein, Maven) are awesome when they work, but extremely painful when they fail or when you don't know which knobs to turn when you want to step slightly outside of the mainstream. This is incidental complexity if I ever saw it. While it's far more manual labor, I find it to be so much simpler to download things myself, build everything myself, put it all somewhere on my system myself, and configure Emacs to tell it where to find everything.

Well, this site is as close as I can find to good up-to-date documentation, and what I did to get set up was almost identical to this. But it will likely stop working in a month or two. There's also a recent thread on the Clojure mailing list which has some more tips (and valid complaints).

I will push my Emacs setup to my github repo once I get the kinks worked out. But if you want to get bleeding-edge everything working yourself, all I have to say is God help you, because it's largely unsupported. Be prepared to hack and patch until it works. I'm looking forward to the day when most of the kinks are worked out and things settle down a bit.

systems are too complicated, dammit!

I’m reading Peter Seibel’s book “Coders at work”. It’s a collection of interviews with famous programmers. This is the kind of book I really like, it’s not a technical book, but it’s a meta sort of book where these people tell you what they think about various relevant issues in the industry. And not just issues that concern them directly, but general trends too. It’s a very easy read, perfect for the plane or the airport.

There are 15 interviews and almost all these people started playing with computers sort of roughly before there were computers. So if there is a theme running through the book, it is this:

  1. Kids today don’t understand how the metal works.
  2. I don’t like all these layers of software.

I think it’s an understandable point of view coming from people who’ve written operating systems and compilers and coded assembly and machine code because there was nothing else available. But I don’t find it a very helpful perspective.

The basic complaint is this:

  1. Things used to be simple.
  2. Instead of remaining simple, they got complex, but not in a good way (ie. bad technical decisions).

I think this is an “argument from nostalgia”, essentially. Back in the days, systems were simpler. Today they are very complicated. And so we wish things were simpler. But this is because some people were present more or less at the “birth” of computer science. The field went from zero and just keeps expanding. That’s normal, though.

If a physicist said “I hate how when you discover a layer of particles, there’s always something smaller than that!” would people nod in agreement? I remember learning about atomic orbitals and not understanding them and I kept thinking “what was wrong with the Bohr model, that one was so much simpler and nicer?”

The difference between physics and computer science is that in physics there’s noone to blame for what is there. There is this sense of “nature is the goddess who bestows gifts upon us and we have the privilege to explore them“. In computer science we’re not trying to explain or discover anything, we make all this stuff up!

In physics there’s no way you can remove the complexity and be left with a simple system, the complexity is there at all levels. But in computers you can delete everything save for the kernel and you indeed have a simple system. (Better yet, delete the kernel too and install a simpler one that you wrote yourself.)

The fundamental difference, to me, is that there is someone to blame. There is noone to blame for atomic orbitals and “why do they have to be so complicated??“, but there is someone to blame for every programming language and every system. I don’t think for a minute that we wouldn’t do the same in physics if we had the chance, though.

What’s Plan B?

Of course, the difference between the physical sciences and computer science raises the old “is it a science?” question, but at any rate it is becoming more like physics in the sense of a top to bottom system that is difficult to understand at all levels.

In physics you don’t say things like “I would like to throw all this out and start over, make it simple“. This is something you can totally do in computers, but chances are you’re not gonna have much impact. Sometimes people bemoan how there hasn’t been any innovation in operating systems in 30 years. So go write your own, see how many people you can convince to use it.

In a way, the answer is right there. The fact that there aren’t any new operating systems taking over from the old ones, _means_ that the old ones have succeeded. They’ve successfully laid that layer of bricks that has proven to be a strong enough abstraction to move away from that layer in the system and focus our attention on something higher up. They’re not works of art in terms of simplicity and purity, but neither are layers of abstraction in physics. *ducks*

Complexity is often presented as a mistake, but the fact that we have all this complexity is not really an accident, it has to be there to do the kinds of things that we want to do.

Posts for Tuesday, April 13, 2010

how do you structure your python codebase?

One thing that’s awesome in python is having a small codebase that can fit in a single directory. It’s a comfy setting, everything is right there at your fingertips, no directory traversal needed to get a hold of a file.

Flat structure

Let’s check out one right now:

./frame.py
./master.py
./mystring.py
./page.py
./sentence.py
./user.py

Download this code: python_codebase_structure_flat.txt

And here’s the import relationship between them:

python_codebase_structure

Easy, straightforward. I can execute any one of the files by itself to make sure the syntax is correct or to run an “if __main__” style unit test on it.

Tree structure

But suppose the codebase is expanding and I decide I have to get a bit more structured? I devise a directory structure like this:

./media/book/__init__.py
./media/book/page.py
./media/book/sentence.py
./media/__init__.py
./media/master.py
./media/movie/frame.py
./media/movie/__init__.py
./media/mystring.py
./user.py

Download this code: python_codebase_structure_tree.txt

The same files, but now with __init__.py files all over the codebase to tell python to treat each directory as a package. And now my import statements have to be changed too, let’s see master:

# from:
import mystring
import page
# to:
import media.mystring
import media.book.page

Download this code: python_codebase_structure_master.py

Nice one. Okay, let’s see how this works now:

$ python user.py
page says hello!
sentence says hello!
frame says hello!
mystring says hello!
master says hello!

Download this code: python_codebase_structure_run_user.txt

user imports page and then master. The first 4 lines are due to page, which imports three modules, and finally we see master arriving at the scene. All the files it imports have already been imported, so python doesn’t redo those. Everything is in order.

As you can see, imports between modules in the tree work out just fine, page finds both the local sentence and the distant frame.

But if we run master it’s a different story:

$ python media/master.py
master says hello!
Traceback (most recent call last):
  File "media/master.py", line 3, in <module>
    import media.mystring
ImportError: No module named media.mystring

Download this code: python_codebase_structure_run_master.txt

And it doesn’t actually matter if we run master from media/ or run media/master from ., it’s the same result. And it’s the same story with page, which is deeper in the tree.

These modules, which used to be executable standalone, no longer are. :(

A hackish solution

So we need something. The nature of the problem is that once we traverse into media/, python no longer can see that there is a package called media, because it’s not found anywhere on sys.path. What if we could tell it?

The problem pops up when the module is being executed directly, in fact when __name__ == ‘__main__‘. So this is the case in which we need to do something differently.

Here’s the idea. We put a file in the root directory of the codebase, a file we can find that marks where the root is. Then, whenever we need to find the root, we traverse up the tree until we find it. The file is called .codebase_root. And for our special when-executed logic, we use a file called __path__ that we import conditionally. Here’s what it looks like:

import os
import sys
 
def find_codebase(mypath, codebase_rootfile):
    root, branch = mypath, 'nonempty'
    while branch:
        if os.path.exists(os.path.join(root, codebase_rootfile)):
            codebase_root = os.path.dirname(root)
            return codebase_root
        root, branch = os.path.split(root)
 
def main(codebase_rootfile):
    thisfile = os.path.abspath(sys.modules[__name__].__file__)
    mypath = os.path.dirname(thisfile)
    codebase_root = find_codebase(mypath, codebase_rootfile)
 
    if codebase_root:
        if codebase_root not in sys.path:
            sys.path.insert(0, codebase_root)
 
codebase_rootfile = '.codebase_root'
main(codebase_rootfile)

Download this code: python_codebase_structure_fix.py

So now, when we find ourselves in a module that’s somewhere inside the media/ package, we have this bit of special handling:

print "master says hello!"
 
if __name__ == '__main__':
    import __path__
import media.mystring
import media.book.page

Download this code: python_codebase_structure_master_new.py

Unfortunately, importing __path__ unconditionally breaks the case where the file is not being executed directly and I haven’t been able to figure out why, so it has to be done like this. :/

python_codebase_structure_treeYou end up with a tree looking as you can see in the screenshot.

I’ve pushed the example to Github so by all means have a look:

We pass the test, all the modules are executable standalone again. But I can’t say that it’s awesome to have to do it like this.

Posts for Monday, April 12, 2010

Welcome to Canada

I haven't had much time to blog lately because I was busy moving all my stuff to Canada. I'm finally here and starting to get settled a bit, so I thought I'd write about the culture shock, or lack thereof. Here are some differences and similarities between Canada and 'merka.

Differences

  1. In Canada people aren't very outwardly patriotic. You don't see Canadian flags plastered all over everything in sight. In the US there's a flag everywhere you look.

    Winner: Canada. I don't really need visual reminders of what country I'm in.

  2. US: Dollar bills. Canada: Dollar coins.

    Winner: US. You can't make origami out of coins.

  3. Sizes of fountain drinks at fast food places are vastly different. I got a "medium" at Tim Horton's and it was smaller than a typical "small" in the US. My wife says she ordered a large drink at McDonalds in the US and had to send it back because it was too big.

    Winner: Canada. Maybe this is one reason Canada has such a low level of obesity. Does anyone really need a liter of Pepsi with lunch?

  4. In Canada there's French all over everything. In the US there's Spanish all over everything. I find they appear in almost equal amounts between the countries.

    Winner: Draw. In BC you don't need to speak French, so I don't plan to learn it. Same with Spanish in the US.

  5. Canada is metric. Temperatures are in Celcius and speed limits are in km/h. The US is Imperial.

    Winner: Draw. Unit of measure for non-science purposes is a pretty arbitrary choice, so who cares?

  6. I have a queen now.

    Winner: Canada, because it's a still a novel concept to me. But most people in Canada don't really care about the queen, from what I can tell.

  7. In Canada they put vinegar on french fries.

    Winner: US. Seriously, come on now.

  8. Everything is way more expensive in Canada and there's lots of sales tax. Example: gasoline is $1.10/liter (over $4/gallon). In Oregon it was always $2-something per gallon. On the other hand, everything is clean and there's cheap universal health care and the social programs seem to keep crime down.

    Winner: Canada. What good is cheap gas if you're dead?

  9. They spell things strangely up here. Favourite, colour, centre.

    Winner: US, for our far more efficient use of vowels.

  10. My bank card for my Canadian bank can't be used as a credit card. Haven't seen that in the US for a decade or two.

    Winner: Draw. Almost everywhere in Canada takes debit cards anyways. Plus they have little portable debit machines so you can pay at your table in restaurants.

  11. No one owns guns. I have yet to fear for my life since I've gotten here.

    Winner: Canada. I imagine crime still sucks in the big cities, but here on the island it's nice.

  12. Most people in Canada seem to keep up to date on US and world news. People in the US don't even remember that Canada exists most of the time.

    Winner: Canada. Thanks for being educated.

  13. The last letter of the alphabet is now "ZED" instead of "ZEE".

    Winner: US. The alphabet song doesn't even rhyme if you say "zed" at the end.

  14. Gay marriage is legal here. Relatedly, there isn't a church on every street corner and I have yet to meet many overly religious people. Censorship on TV and radio is way less. I actually saw a TV show with "atheists vs. religious people" testing their IQs via trivia questions. You would never see that in America.

    Winner: Canada. The US can DIAF in this regard.

Similarities

  1. Drivers suck in Canada as much as or more than they suck in the US. Speeding and passing on the right without turn signals seems to be a national pastime.

  2. TV is mostly the same (i.e. not worth watching). There are mostly the same channels as the US other than Canada-only ones like CBC.

  3. Walmart and Starbucks are still everywhere. But so are Tim Horton's and Canadian Tire.

Honestly things aren't that different up here. Sometimes I forget I'm even in a new country, other than the streets being clean and everyone being polite all the time. It's been a good move.

avatar

Tech Tip #6: Reencode any video to ensure compatibility with Windows Media Player

Other very useful tip I picked up when doing video manipulation the other day that deserves its own post is reencoding any video so that it will work on a vanilla Windows Media Player (without any other codecs added). Windows Media Player is probably the most stubborn, pathetic video player the software world has ever seen and unfortunately if you produce a video for the general public to view, you need to make sure WMP is happy to play it.

The tool for such a job is obviously ffmpeg, but the suggested commands on the compatibility page of their site seem to compress the videos to a horrendous state at the same time, so after asking on their IRC channel on freenode this is the command that turned up:

ffmpeg -i input -acodec libmp3lame -ab 128k -vcodec msmpeg4v2 -qscale 3 output.avi

Wonderful. Now I can render to whatever I please and worry about compatibility later.

Related posts:

  1. Tech Tip #5: Rotate a video by 90 degrees with mencoder
  2. Tech tip #3: Rip audio from an .FLV file.
  3. Top 10 Windows Mobile Applications

Posts for Wednesday, April 7, 2010

On Functional Programming Languages

As a programming-language adept I’ve been studying the ideas, concepts and theory of functional programming (FP) and FP-related languages for about 2 years now, still learning new things everyday.

Recently a ‘FP User Group’ was started by some people at Ghent University, called GhentFPG, and the first meeting took place last thursday, with great interest from students, university employees as well as people working in the industry. You can find some more info in the GhentFPG Google Group or in the wiki (where you can also find the slides of the presentations given during the first meeting).

Some days ago someone new to FP posted a message on the mailing list, asking which language he should study, among other things.

Since I think my reply might be of general interest (also outside GhentFPG), I decided to post a copy on this blog as well (note I did add some extra markup). Comments welcome!

Based on my experience (which is biased, obviously):

  • Functional Programming is not only a language-related thing. FP
    languages do enforce you to apply functional paradigms, but you can
    easily follow these paradigms in lots of other (more mainstream?)
    languages as well: it is easier to learn people a paradigm using a
    language they already know, rather than telling them FP is really cool
    and useful and interesting, but requires them to learn a new
    language/toolchain/… first.

    Not talking about Java or C++ or something similar here, rather Python
    and Ruby.

  • If you’re into Java/C#/…, Scala is a really good introduction to FP:
    it allows you to write OOP code just like you do already, but also
    provides you lots of FP-related features, and pushes you gently into the
    FP approach. The book “Programming in Scala” by Odersky et al. (the main
    author of Scala) is IMO a really good intro to both Scala as well as the
    FP concepts it provides, not only showing them but also explaining
    gently why they’re useful, and why they’re ‘better’ than the approaches
    you’re taking already.

    The Scala type system is rather interesting as well.

    It’s the gentle path, so you want ;-) Learning Scala before reading
    Real World Haskell‘ certainly helped me a lot to understand the latter.

  • Haskell is an incredibly interesting language because of the concepts
    it adopted and types it provides, but it does require an immediate mind
    switch when coming from a non-OOP world (I once spent about 2 hours to
    explain a Java-guy how classes and instances in Haskell relate to
    classes and instances in Java, it wasn’t obvious). “Real World Haskell”
    is certainly worth a read (and if you read “Programming in Scala” as
    well, you’ll notice lots of similarities).

    I for one can read Haskell code pretty easily and learned lots of
    CS/math things thanks to learning it, but I’m (still) unable to write
    non-trivial code (I need some good project to get my hands dirty I
    guess).

  • Erlang is really interesting from a (very specific) feature
    perspective: high-availability, distributed computing, the actor system
    and the OTP library on top of it,…

    It’s a rather ‘old’ language, but I kind of like it. Some people do
    complain about the syntax, but once you figured out ‘,’, ‘;’ and ‘.’ are
    used almost the same as they are in ‘human’ written language, everything
    becomes obvious :-)

    Do note though Erlang is not a normal general-purpose language. You can
    code +- everything you want using it, but it’s really targeted to
    distributed/high-available/network applications. You most likely won’t
    use it to solve mathematical problems or write a game. It’s really good
    at what it’s built for though.

    One final note: please don’t ever make the mistake I made. If you know
    Erlang, and take a look at Scala (which also has an actor library in the
    standard distribution, as well as the more advanced Akka-library), don’t
    judge Scala as being a competitor for Erlang, they’re both completely
    different languages targeting different applications. ‘Scala’ is not
    about ’scalability’ as Erlang is (it’s a “Scalable Language”).

  • F# (and most likely OCaml as well, although I never used it though) is
    certainly worth a look as well. I only read 3/4th of a book on it, but
    it looks really promising and interesting.

  • There’s obviously all sorts of Lisp dialects. I have no opinion on
    them, never looked into any Lisp closely enough. I only wrote some
    Clojure (a Lisp-dialect for the JVM) code one day, but need to learn
    more about the Lisp-way of programming. Clojure seems to be interesting
    because of the deep integration of Software Transactional Memory (STM)
    in the language (yet another approach to concurrency ;-) ).

As for the IDE question: Vim and a decent terminal are all you need,
luckily none of the above languages require you to learn how to use a
toolchain which enforces you (or some magic IDE) to write 500 lines of
XML-based build ‘programs’ or other insanities.

My advice: pick some language, learn it, but make sure you don’t only
learn the language, but especially the concepts (type system,
higher-order stuff, list manipulation,…). Then pick some other
language and learn it as well (which will be easier since you got the
concepts already) and so on.

And read tons of papers available on the internet in between ;-) Even if
you don’t understand a paper completely, you’ll pick up some things
already, and re-reading it 2 weeks later helps a lot :-D

Just my .02,

Nicolas

avatar

Tech Tip #5: Rotate a video by 90 degrees with mencoder

I was recently doing some video editing work where the workflow was something like this: film in portrait, transfer to computer, rotate videos by 90 degrees, sequence together several videos, strip out background noise from entire video. Filming was done with a camera, sequencing was done by Kdenlive (I’ve previously only had experience with Blender’s VSE and I must say I was very happy with this new application), and the noise-stripping was done with Audacity. I must say I’m surprised at how fast this was all accomplished and kudos to all those developers who created these apps.

However one thing I didn’t know how to do was how to rotate the video by 90 degrees. Kdenlive can do it but it ends up being awkwardly stretched and I couldn’t figure out how to unstretch it. Luckily mencoder, which comes with the mplayer package, has got a few tricks up its sleeve.

More for my own records than for anybody else, here’s the command I used:

mencoder -vf rotate=2 -o output.avi -oac pcm -ovc lavc input.mov

As my input file was a .mov some of the sound wasn’t synchronised well after rotating, which was easily fixed by this option `-demuxer mov`. If you want to rotate clockwise instead of anticlockwise change `rotate=2` to `rotate=1`.

Related posts:

  1. Tech Tip #6: Reencode any video to ensure compatibility with Windows Media Player
  2. Tech tip #3: Rip audio from an .FLV file.
  3. Blender 2.5 Features Video

Posts for Monday, April 5, 2010

avatar

Rigging a machine.

Things have been going absurdly slow lately. No commits to WIPUP. No new ThoughtScore models (though a few more seconds of video have been added). Nothing open-source related (except for trying out the Ubuntu beta1 on a box). Even schoolwork has slowed.

Because I fully emphathise that people with a grip of things wouldn’t give a rat’s ass about my life, I decided to show some pictures of the trouble I’ve been having trying to rig Taras, one of the main characters in The ThoughtScore Project. Here are two statically posed shots of Taras:

The left shows him in his unrigged pose. The pose he was modeled in. The right shows him "looking" down, slightly bent forward with his left arm reaching towards you. Disregarding the fact that the lighting is completely faked (what is that suit reflecting, anyway?), we have two other major problems to deal with.

Problem Number One: His arm was not built to be in that pose. Not was any other part of his anatomy. When standing straight his arms are abnormally squashed in order to look natural in that one pose… and when in a dark environment. In any other scenario you’d see two spindly arms sticking out of a hunk of metal. The way it was designed, his shoulder "ball and socket" joint is more of a "plank of wood stuck on a block of wood" joint. It doesn’t fit nicely like a joint should.

Put simply, all of his joints (legs included) will have to be remodelled in order so that you don’t have gaping holes or bits of the suit intersecting when limbs are moved in their extremeties. Not an easy task.

Problem Number Two: The torso. The torso is made up of several different meshes. Each part fits together nicely in one way and one way only. If you look at the picture, you’ll see that when he leans forward, the upper torso covers the middle torso, which largely remains stationary, the groin panel shifts outwards slightly, and the piping all has to move to accomodate this change and not randomly stick out where it shouldn’t. Think of it like the parts of a steam engine.

Long story short, it’s going to be a PITA to rig that guy just to bend over. Heck, I don’t think you can bend over in a suit like that.

Normally I stubbornly plod down the road of "create first, learn later, fix and redo even later", but this time I think I’d better buy some of Blender’s training DVDs before continuing on ThoughtScore.

Related posts:

  1. ThoughtStall
  2. Kayaking in Langkawi!
  3. Blender 2.5 Features Video

Planet Larry is not officially affiliated with Gentoo Linux. Original artwork and logos copyright Gentoo Foundation. Yadda, yadda, yadda.