Saturday 29 December 2007

Photographic Metadata

When I first started with an SLR camera, some 13 years ago, all camera magazines had the same advice for beginners: to improve your pictures, write down all the settings you used, such as aperture or shutter speed, so that you can go back to this information once you have the prints and understand why they came out the way they did. As a result, a serious photographer would always have a small notebook with him to write all this down. It was quite a time consuming process but essential for who wanted to improve. In this age of digital photography, it would seem sensible for the camera to store this information with the picture so that you can retrieve it later. And indeed they do, in metadata called EXIF data that is embedded in the image file. Software like Photoshop is able to read EXIF data but it's a bit overkill to fire Photoshop just to look at this data. And it would also be nice to be able to write scripts based on it, such as a script that selects all pictures taken at a particular focal length.

Such a tool exists: it's called, quite simply, ExifTool. The tool is written in Perl so should work on any system that has Perl installed. There is a package for Mac OS-X that makes it really trivial to install. A proper install on Linux is slightly more convoluted so here's how to do it on Ubuntu:

  1. Download the latest version from the web site, in my case version 7.08;
  2. Extract the content of the file:
    $ tar -xzf ./Image-ExifTool-7.08.tar.gz
    
  3. Install the Perl libraries so that they can be used by other Perl scripts:
    $ cd ./Image-ExifTool-7.08
    $ perl Makefile.PL
    $ make
    $ make test
    $ sudo make install
    
  4. Install the main script:
    $ sudo cp exiftool /usr/local/bin
    

Alternatively, you can use ExifTool directly from the directory where you extracted it if you just want to try it out. Using ExifTool in the command line is very easy, just call:

$ exiftool myfile.jpg

And it will output all the metadata tags it knows about. There are a number of options available, in particular, you can select what tags you want to see. It's all very well explained in the man page. And if you run exiftool without arguments, it will actually display said man page. So what sort of fun stuff can we do now? Here is an example that selects all the files with a .JPG extension in the current directory and below that are photographs taken with a focal length of 105mm:

$ for f in `find . -name "*.JPG"`; do
> if [ -n "`exiftool -FocalLength $f | grep '105.0mm'`" ]; then
> echo $f
> fi
> done

Note that ExifTool formats its output such that it prints out the name of the tag followed by a colon and the value. If you want to strip that name and only keep the value, you can do something like this:

$ exiftool -FocalLength myfile.jpg | sed 's/^[^:]*: //'

An interesting application, if you have a GPS receiver is to combine the GPS trace log with the EXIF time information to geo-tag your photographs. There are a number of links on the ExifTool web site that point to such utilities. Once geo-tagged, online photo sites like flickr will use this information to position the pictures on a map. Or more simply, to come back to what I was talking about at the beginning of this article, you could compare basic shot settings between pictures to understand why one is better than another.

Note that there are other tools than ExifTool to do this, some of them offer a graphic front-end that may be easier to use for those who are not comfortable with the command line, but ExifTool is by far the most complete and powerful. Just google for exif reader if you want to find other options.

Friday 21 December 2007

Zend Framework on XAMPP

I am currently experimenting with the Zend Framework, using XAMPP on a Windows laptop and following Rob Allen's excellent tutorial. With a default installation of XAMPP, you get a nasty Error 500 whenever you test your system. This is because XAMPP doesn't enable the Apache mod_rewrite extension by default. So here's how to do it. Find the Apache configuration file, called httpd.conf, which on my install is in C:\xampp\apache\conf and uncomment the following line:

LoadModule rewrite_module modules/mod_rewrite.so

Restart XAMPP and it should all work.

Saturday 15 December 2007

Road Rage

Why is it that being at the wheel of a car transforms most reasonable people in arrogant aggressive maniacs? I was just walking down the road when I saw this guy change lane, cutting off the driver behind in the process. Of course, the guy behind sounded his horn briefly to tell him he wasn't too happy about that manoeuvre. And what did the guy in front do as a result? Show him the finger. Well done for being an arse!

Friday 30 November 2007

Desktop Tower Defence

If you're in need of an addictive time waster, try Desktop Tower Defence. Don't be surprised if you end up spending a few hours and missing dinner blasting creepy things.

Via The Register

Free Rice

It all started with The Hunger Site and it seems there are more and more of those sites where you just have to click to help end world hunger or do some other good deed. FreeRice is another one of those but it adds an interesting twist: your clicks are based on a vocabulary game and they only count if you get the meaning of the words right. For every 3 correct answers, your vocab level goes up one and for every mistake it goes down one. The higher the level, the more difficult are the words you are given. The game is dead simple but very, very addictive and is also a great way to improve your vocabulary. So give it a go and see what level you can reach: the maximum is 50 and they reckon very few people go past 48.

Hidden Cost of Viruses

Computer viruses can cost you time and money, that's obvious: if your computer gets infected by a nasty virus, it can take ages to clean it, sometimes even requiring you to completely re-install your operating system from scratch. But there are other hidden costs to viruses and they can even cost you when your computer doesn't get infected. I have been discovering one of those costs on my new contract. I got given a nice laptop running Windows XP Pro (Vista? Who said Vista?) complete with corporate security software. And that's where the problem is: the virus scanner is configured to do a full scan every time I switch on the computer. So the routine in the morning is simple: arrive in the office, plug in the laptop, switch it on and go get a coffee. Then wait some more until it's finished thrashing the hard disk. End result: 15 minutes every morning.

Thursday 22 November 2007

Gmail Spam Filter

Gmail used to have the best spam filter ever: I would never get spam in my inbox. In fact, until a few weeks ago I would have been unable to say when was the last time I had pressed the Report Spam button. Unfortunately, over the past few weeks, I've been clicking on that button more and more, the last time being 5 minutes ago. I only get a few a day at the moment but the worrying thing is that they are all email that look like they should be blocked by the most brain dead of spam filters. Is something broken in the Googleplex? In their relentless attempts at blocking the more devious spam messages, did they accidentally break something in the code that was blocking the simple ones?

Saturday 17 November 2007

Online Christmas Shopping

I went out to central London to do some Christmas shopping today, as for once I decided to start early. It was such a bad experience because of the masses of people that I bought nothing and decided to do everything online from now on.

Friday 16 November 2007

Estate Agents' Reading Skills

After wondering at the Labour Party's members' reading skills, I now worry about the same skills with estate agents. I just had one of them trying to open my door in order to show a flat to a customer, when in fact he wanted the flat next door. Of course his keys didn't work. Now, my door has a big letter A on it, while the next door has a big letter B. This is meant as a clue that my flat is flat A, while flat B is next door. But apparently, that was way too complicated for him.

St Pancras International

I've been going through St Pancras station every week for 2 months or so. But when I came back to London yesterday, it no longer was St Pancras, it was St Pancras International, now that the Eurostar trains leave from there rather than Waterloo. I have to say the new station is large and impressive, of course full of shops in case you want to do a bit of shopping before getting on the train. It is amusing how they insist on the International bit though. Should Paris Gare du Nord be renamed Gare Internationale de Parid Nord?

Saturday 3 November 2007

DHCP and Dynamic DNS on Ubuntu Server

The cunning plan

I have broadband Internet at home and to connect to the outside world I use a Wi-Fi ADSL router. This router also acts as a DHCP and DNS server. The DHCP function is what allows any machine I connect to my home network to dynamically obtain an IP address. The DNS function is what resolves names into IP addresses, for example, the DNS will tell you that www.blogger.com is really called blogger.l.google.com and its address is 72.14.221.191. This is all well and good: when I switch on one of my computers and let it connect to the network, it will get its IP address from the router, which will also tell it to use the same router for names service queries. The router itself knows to delegate requests to my ISP's DNS so the new computer on the network has full access to the Internet. If I connect a second computer on the network, the same happens and both can have access to the Internet at the same time. Great! However, they don't know anything about each other. If I connect the two machines called nuuk and helsinki to my network, the DNS server is unable to tell either what the address of the other one is. This is because the DNS in the router is fairly basic and doesn't know to update its database when a new machine gets allocated an address by the DHCP service. Basically, we'd want a DHCP server that can communicate with the DNS server and tell it oy, I've got a new machine on the network, here's its name and the address I just allocated to it when a new machine comes online.

So what's a geek to do? Set up his own DHCP and DNS server obviously! And make them talk together. Luckily, I have an old workstation that I haven't used for many years and that I was planning to throw away: it's a bit dated but it should be exactly what I need for this. Then my recent experience with Ubuntu suggests that the recently released Ubuntu 7.10 Gutsy Gibbon Server Edition might be exactly what I need for the job. So let's get started.

The hardware

I said I had this dated workstation lying around. It's an 8 year old piece of kit that was originally built to run Red Hat Linux. It wasn't very good at it at the time because Linux was not quite ready for the desktop at the time but it was a wicked piece of kit at the time:

CPU
Dual 666 MHz Pentium III (Coppermine)
Memory
256 Mb
Storage
10 Gb SCSI hard disk: I got a SCSI controller rather than the cheaper IDE because I wanted to connect my SCSI negative scanner to it

There's plenty of horsepower for what we want to do, more than enough storage and the memory should be fine if the operating system we install on it is lightweight enough. This is where the Server Edition of Ubuntu comes into play: it's meant for server hardware and doesn't have the nice but memory hungry desktop front-end, it's all command line driven. No glitz, just useful stuff. This means that even the latest version of Ubuntu Server should be able to run comfortably within 256 Mb and there should be no need to fall back on an older version of the operating system.

Preparation

Before we start, there is a bit of planning to do. As the new server will be the authority in terms of assigning IP addresses on the network, it needs to have its own address fixed. We also need to decide on a range of addresses to allocate through DHCP. As the router is currently using the address 192.168.1.254, it makes sense to leave it as it is. Here is the network configuration I am aiming for:

ADSL router
192.168.1.254
New DHCP and DNS server
192.168.1.253 and I'll call it szczecin
DHCP address range
From 192.168.1.100 to 192.168.1.200
Domain name
home: no need to have an official domain name and in fact it's probably better if it's not something that could be a valid Internet domain

One thing I did before installing anything and that you may want to do as well is boot the new server with the desktop Ubuntu Live CD just to check that all the hardware is supported. The server edition is not a live CD so it doesn't give you the opportunity to check that before going ahead.

Installing Ubuntu

Let's plug everything together first: a monitor, a keyboard, no need for a mouse as it's all command line, power and VGA cables. And we might as well connect it to the network immediately so we'll need a network cable as well.

Start the machine, put the CD in the drive and follow the instructions. As usual with Ubuntu, it's quite easy. There are only a few things to be careful about:

  • When it asks how to partition the disk, choose the automatic option using the whole disk.
  • When it gets to network setup, cancel the DHCP client setup and configure the network manually. Give it the IP address chosen above and a name. When it asks for a DNS server, put its own address.
  • Don't forget to select DNS in the list of additional services you want to install. I would suggest you also install the SSH server to that you can connect to the machine remotely.

At the end of the installation, the machine pops the CD out and asks you to confirm a restart. No nice funky Ubuntu logo when it restarts, it's all text and you are faced with a command line login prompt. If you want to keep working from the console you can, or you can just connect from any other machine connected to the same network using SSH, provided you installed the SSH server obviously. So let's login to our new server.

Configuring a simple static DNS

The first step is to configure a simple static DNS service that is able to resolve names for the router and the new server. Ubuntu 7.10 comes with BIND 9.4.1 as a DNS server and I have used O'Reilly's DNS and BIND book as my reference. The copy I have is the 3rd edition rather than the 5th but it is more than adequate for my purpose.

The very first task is to make sure we have the necessary basics in /etc/hosts:

127.0.0.1       localhost
192.168.1.253   szczecin.home szczecin
192.168.1.254   gateway.home  gateway

Then we need to reproduce that in the BIND configuration. The first task is to find where the BIND configuration files are. On Ubuntu, you will find them in /etc/bind with a modular default set of files:

$ ls /etc/bind
db.0
db.127
db.255
db.empty
db.local
db.root
named.conf
named.conf.local
named.conf.options
rndc.key
zones.rfc1918

The main file, named.conf is constructed in such a way that for most simple installations, you should only have to change named.conf.local, which is exactly what we are going to do. But first, we need to create our database files. Let's start with the forward lookup, which we will name db.home

home.           IN SOA  szczecin.home. admin.email.address. (
                                1          ; serial
                                10800      ; refresh (3 hours)
                                3600       ; retry (1 hour)
                                604800     ; expire (1 week)
                                86400      ; minimum (1 day)
                                )
home.           IN NS   szczecin.home.

localhost.home. IN A    127.0.0.1

szczecin.home.  IN A    192.168.1.253
gateway.home.   IN A    192.168.1.254

The first entry specifies the Start Of Authority, identifying that our server is the best source of information for this zone. The admin.email.address. bit can be any admin email address you want to advertise, with the @ sign replaced by a dot. It doesn't have to be a valid address if you don't want it to be. The second entry identifies this machine as the name server for this zone. If you had multiple servers, you'd need one line per server. The following lines reflect what we have in /etc/hosts.

After that, we can work on the reverse lookup file, which will be named db.192.168.1:

1.168.192.in-addr.arpa.     IN SOA  szczecin.home. admin.email.address. (
                                1          ; serial
                                10800      ; refresh (3 hours)
                                3600       ; retry (1 hour)
                                604800     ; expire (1 week)
                                86400      ; minimum (1 day)
                                )
1.168.192.in-addr.arpa.     IN NS   szczecin.home.

253.1.168.192.in-addr.arpa. IN PTR  szczecin.home.
254.1.168.192.in-addr.arpa. IN PTR  gateway.home.

This file just defines the opposite mapping. The first two entries follow the same format that in the other file. Note how the IP addresses are back to front. The last two entries use the PTR record type rather than the A record type. We now need to declare those two database files in the BIND configuration. To do this, we just add the following to the end of the named.conf.local file:

zone "home" in {
        type master;
        file "/etc/bind/db.home";
};

zone "1.168.192.in-addr.arpa" in {
        type master;
        file "/etc/bind/db.192.168.1";
};

Note the semi-colons all over the place in the file, BIND doesn't like it if you forget them. We just need to restart the DNS for it to pick up the configuration:

$ sudo /etc/init.d/bind9 restart

If it doesn't start properly, the best way to identify what's wrong is to go have a look at the system log files. On Ubuntu, the DNS messages will be in /var/log/daemon.log. One last thing to do before we test our setup is to update the local resolver configuration by modifying /etc/resolv.conf. Remove all lines that start nameserver so that the local resolver automatically sends requests to the local BIND instance irrespective of the IP address of the machine. We should end up with a file that contains a single line:

domain home

And we can now use nslookup to verify that it's all working:

$ nslookup szczecin
Server:         127.0.0.1
Address:        127.0.0.1#53

Name:   szczecin.home
Address: 192.168.1.253

$ nslookup szczecin.home
Server:         127.0.0.1
Address:        127.0.0.1#53

Name:   szczecin.home
Address: 192.168.1.253

$ nslookup gateway
Server:         127.0.0.1
Address:        127.0.0.1#53

Name:   gateway.home
Address: 192.168.1.254

$ nslookup localhost
Server:         127.0.0.1
Address:        127.0.0.1#53

Name:   localhost.home
Address: 127.0.0.1

Installing the DHCP server

My reference for installing the DHCP server was an excellent article aimed at the Debian distribution by Adam Trickett. As Ubuntu is based on Debian, I didn't have much to change. In its default state, an Ubuntu installation doesn't include a DHCP server so we need to add it:

$ sudo apt-get install dhcp3-server

This will install the ISC DHCP server. It will ask you to insert the Ubuntu CD in the drive so just do so. It will then attempt to start the new DHCP server and fail saying that the configuration is incorrect, which is to be expected. Configuration files for this server can be found in /etc/dhcp3 and the one we are interested in is dhcpd.conf. Move the default version out of the way by renaming it and we will start anew with an empty file. Here is what I have on my system, based on Adam's article. I highlighted the lines that tell the DHCP server to update the DNS and what key file to use.

# Basic stuff to name the server and switch on updating
server-identifier       192.168.1.253;
ddns-updates            on;
ddns-update-style       interim;
ddns-domainname         "home.";
ddns-rev-domainname     "in-addr.arpa.";
# Ignore Windows FQDN updates
ignore                  client-updates;

# Include the key so that DHCP can authenticate itself to BIND9
include                 "/etc/bind/rndc.key";

# This is the communication zone
zone home. {
        primary 127.0.0.1;
        key rndc-key;
}

# Normal DHCP stuff
option domain-name              "home.";
option domain-name-servers      192.168.1.253;
option ip-forwarding            off;

default-lease-time              600;
max-lease-time                  7200;

# Tell the server it is authoritative on that subnet (essential)
authoritative;

subnet 192.168.1.0 netmask 255.255.255.0 {
        range                           192.168.1.100 192.168.1.200;
        option broadcast-address        192.168.1.255;
        option routers                  192.168.1.254;
        allow                           unknown-clients;

        zone 1.168.192.in-addr.arpa. {
                primary 192.168.1.253;
                key "rndc-key";
        }

        zone localdomain. {
                primary 192.168.1.253;
                key "rndc-key";
        }
}

Now that we've done that, we need to modify the DNS configuration so that it can accept the changes. But first, a quick note on the /etc/bind/rndc.key file. This file is automatically created when you install DNS on Ubuntu and should be fine for your installation. It is a key file that authenticates the DHCP server to the DNS server so that only the DHCP server is allowed to send updates. You don't want random people to be able to update your DNS database. Having said that, we need to modify the DNS configuration to accept the updates so back to /etc/bind. And while we are at it, let's have a look at this key file.

key "rndc-key" {
        algorithm hmac-md5;
        secret "some base 64 encoded secret key";
};

Note the name of the key on the first line, it may vary from one distribution to another so make a note of it. Then we need to add the control information to the DNS configuration. Rather than update named.conf, I decided to add the relevant code to the end of named.conf.options: it feels like the right place to put it but I suspect it doesn't really matter. So add this to the end of the file:

// allow localhost to perform updates
controls {
        inet 127.0.0.1 allow { localhost; } keys { "rndc-key"; };
};

Then we need to modify the zone definitions in the named.conf.local file. Here is what it looks like with changes highlighted:

zone "home" in {
        type master;
        file "/etc/bind/db.home";
        allow-update { key "rndc-key"; };
        notify yes;
};

zone "1.168.192.in-addr.arpa" in {
        type master;
        file "/etc/bind/db.192.168.1";
        allow-update { key "rndc-key"; };
        notify yes;
};

include "/etc/bind/rndc.key";

We're nearly there. The changes we just made mean two things: the DNS server needs to be able to update the content of the /etc/bind directory and the DHCP server needs to be able to read the key file /etc/bind/rndc.key. By default on Ubuntu, this won't work as the permissions around those files are fairly stringent. So let's change them. As the BIND configuration directory belongs to root:bind, we just need to give write access to the group for BIND to be able to write to it. To give the DHCP server access to the key file, the right thing to do would be to add the dhcpd user to the bind group but we can also make the file readable to everybody. Yes this is less secure but will be fine for a home installation.

$ sudo chmod g+w /etc/bind

$ sudo chmod +r /etc/bind/rndc.key

Now we just need to start DHCP and restart DNS.

$ sudo /etc/init.d/dhcp3-server start

$ sudo /etc/init.d/bind9 restart

Error messages will be in the same place as before if the services don't start properly. If all starts as exected, it's now time to go to the administration interface of the router and disable DHCP. We should not need it anymore.

Booting the clients

The proof of the pudding is in the eating and the proof of installing a server is in starting a number of clients to use the service. The first machine I tried with was my Ubuntu laptop called nuuk. To see what happens, tail the log file. You should see something like the following appear:

Nov  3 15:14:02 szczecin dhcpd: DHCPDISCOVER from 00:12:f0:1e:f4:79 via eth0
Nov  3 15:14:03 szczecin dhcpd: DHCPOFFER on 192.168.1.102 to 00:12:f0:1e:f4:79
(nuuk) via eth0
Nov  3 15:14:03 szczecin named[4771]: client 127.0.0.1#32773: updating zone
'home/IN': adding an RR at 'nuuk.home' A
Nov  3 15:14:03 szczecin named[4771]: client 127.0.0.1#32773: updating zone
'home/IN': adding an RR at 'nuuk.home' TXT
Nov  3 15:14:03 szczecin dhcpd: Added new forward map from nuuk.home. to
192.168.1.102
Nov  3 15:14:03 szczecin named[4771]: client 192.168.1.253#32773: updating zone
'1.168.192.in-addr.arpa/IN': deleting rrset at '102.1.168.192.in-addr.arpa' PTR
Nov  3 15:14:03 szczecin named[4771]: client 192.168.1.253#32773: updating zone
'1.168.192.in-addr.arpa/IN': adding an RR at '102.1.168.192.in-addr.arpa' PTR
Nov  3 15:14:03 szczecin dhcpd: added reverse map from 102.1.168.192.in-addr.arpa.
to nuuk.home.
Nov  3 15:14:03 szczecin dhcpd: Wrote 4 leases to leases file.
Nov  3 15:14:03 szczecin dhcpd: DHCPREQUEST for 192.168.1.102 (192.168.1.253) from
00:12:f0:1e:f4:79 (nuuk) via eth0
Nov  3 15:14:03 szczecin dhcpd: DHCPACK on 192.168.1.102 to 00:12:f0:1e:f4:79 (nuuk)
via eth0

If you don't see the message about updating the forward and reverse maps, it may be that your client machine is not configured to send its name to the DHCP server. For this to work on Ubuntu, you should have the following line in /etc/dhcp3/dhclient.conf:

send host-name "<hostname>";

Next on the list is my Apple PowerMac G5 called helsinki. A simple restart and it works like a charm: I can ping hesinki from nuuk or szczecin and the other way round, all machines can access the Internet, great! While we're talking about computer names, if you don't know how to change the machine's name under OS-X, here's how.

The next test is with my work's Windows XP laptop. All goes well: the Windows box gets an IP address and I can ping it from the other machines. However, I can't ping from the Windows box to the other ones unless I use the fully qualified domain name: that is I can ping nuuk.home but not nuuk. It looks like Windows ignores the domain information sent by DHCP. This is not a major problem as everything else works fine. I vaguely remember something about network settings on Windows that you have to change but. I'll have a look see if I can remember where it was when I can.

The final test is to start my Solaris Express laptop called mariehamn. It gets its IP address fine but doesn't seem to send its name to the server. So it can't be pinged. Everything else works though: it can ping all of the other machines, get to the Internet, etc. I suspect I need to find the equivalent of the /etc/dhcp3/dhclient.conf file on Solaris and change it so that it sends its name. It's probably hidden somewhere in the Network Auto-Magic configuration.

Conclusion

That was a bit convoluted but the excellent resources that are the O'Reilly DNS and BIND book and Adam's article made it significantly easier. Real system administrators would say that was a doodle and made way too easy by Ubuntu. I've learnt useful stuff on the way and I now have a good use for this old workstation. Speaking of which, it hasn't really been breaking a sweat so far: it's been close to 100% idle all the time, it has 114Mb RAM free out of 256 and the hard disk has seen virtually no activity. In other words, my 8 year old box is over spec'ed for this and I could get it to do a lot more server tasks. Should I mention that the server version of some other recent operating systems that shall remain nameless would not even start on such a machine? No, I'll leave that debate for another day.

For those who are wondering what scheme I use to name my computers, it all comes from a previous job and all machines are named after cities of the world, with a Scandinavian and Baltic theme so far: Helsinki, Szczecin, Nuuk and Mariehamn.

Sunday 28 October 2007

From Feisty to Gutsy

Ubuntu released the version 7.10 of their operating system 10 days ago, code named Gutsy Gibbon. As my laptop was on the previous release (Feisty Fawn, 7.04), when I booted it yesterday the install manager suggested I upgrade. I decided to do so, wondering how long it would take and how complicated it would be, my experience of other operating systems that shall remain nameless telling me that I could be in for the long haul. I shouldn't have worried: in typical Ubuntu fashion, it was dead easy: once I had clicked on the upgrade button, it did everything on its own, I just had to provide my password so that it could have root privileges. In fact, the only difference with a normal package update was that it took longer and the laptop had to be restarted once at the end of the process in order to boot under the new version.

Needless to say, I was impressed. If only all operating system upgrades could be that easy!

Saturday 27 October 2007

Geeky experiments with bash functions

return doesn't mean what you think it does

Modern UNIX shells like bash have the ability to define functions. Functions are a great way to factorise parts of code that you need to use in several areas of your script or isolate discrete pieces of logic. In most programming languages, one fundamental aspect of functions is that they can return a value which is the result of whatever computation they were doing. And indeed a shell like bash has a built in return command. But, hang on, if you read up on return, you realise that it can only return integer values. The reason for this is that return works the same way as exit: it sets the $? variable with the value given as argument, or 0 if no argument is given, and aborts the function. exit aborts the whole script instead. So, if you use return, use it to provide the calling code with an error code. This doesn't solve the original problem though: how can we return a value from a function, such as a character string?

As often with UNIX, the answer is deceptively simple and consistent with everything you know about scripts: just echo the value you want to return and call your function as if it was a full blown script, with inverted quotes or the $(...) construct, as in the example below.

#!/bin/bash

function f {
  echo "[ $1 ]"
  return 1
}

s=`f "abc"`
echo "\$?=$?"
echo "\$s=$s"

Save this in a file called fn.sh, make it executable and run it:

$ ./fn.sh
$?=1
$s=[ abc ]

As you can see, the $? special variable was set with the value 1 and the $s variable was updated with the result of the function.

Recursive fun

Once you know how to return a value from your function, the next thing you need is to know how to pass it some parameters. Once again, it works exactly the same as in a full blown script: you just use the $n positional variables. Recursion works as you expect as well. So let's demonstrate with a classic textbook example: a recursive factorial.

#!/bin/bash

function fact {
  if [ $# -lt 1 ]; then
    return 1
  elif [ $1 -lt 1 ]; then
    return 2
  elif [ $1 -eq 1 ]; then
    r=1
  else
    r=$(( $1 * `fact $(( $1 - 1 ))` ))
  fi
  echo "$r"
}

fact $1

Save it, run it and you should get something like the following. Don't give it too high a value though, we'll see why in a second: 10 should be enough to demonstrate that it works.

$ ./fact.sh 10
3628800

While we're here, let's have a quick look at this function as it has a couple of interesting constructs. It does the following:

  • check the number of parameters it has been passed, using the $# variable, and returns an error if less than 1,
  • check that the first parameter is positive, as a negative value is invalid and return an error code in this case,
  • check the termination condition of the recursion and set the result if we have reached that condition,
  • finally calculate the factorial by calling itself recursively.

Note the use of the $((...)) construct to do the relevant arithmetic calculations: one is needed inside the recursive call to the function, to tell ensure the value passed is the result if $1 - 1 rather than the three parameters $1, - and 1; another one is needed outside the call to calculate the product.

This script also proves that when using functions in this way, the variables defined inside the function are local and not overwritten by a subsequent call. This is because the use of the back quotes actually forks a new process in which the function is called. You can verify this by adding a sleep statement inside the function, running the script in the background and running ps:

$ ps
  PID  TT  STAT      TIME COMMAND
  394  p1  S      0:00.07 -bash
 2414  p1  S      0:00.01 /bin/bash ./fact.sh 10
 2415  p1  S      0:00.00 /bin/bash ./fact.sh 10
 2416  p1  S      0:00.00 /bin/bash ./fact.sh 10
 2417  p1  S      0:00.00 /bin/bash ./fact.sh 10
 2418  p1  S      0:00.00 /bin/bash ./fact.sh 10
 2419  p1  S      0:00.00 /bin/bash ./fact.sh 10
 2420  p1  S      0:00.00 /bin/bash ./fact.sh 10
 2421  p1  S      0:00.00 /bin/bash ./fact.sh 10
 2422  p1  S      0:00.00 /bin/bash ./fact.sh 10
 2423  p1  S      0:00.00 /bin/bash ./fact.sh 10
 2424  p1  S      0:00.00 sleep 5

Each child process has its own context and variables and doesn't interfere with the other ones. However, this means that you have to be extremely careful when using functions this way as you could quite easily spawn a large number of processes. Recursion in particular could be deadly.

Pipe dreams

Finally, if a function generally works like a script, can we pipe it? yes but if you want it to be on the consuming side of the pipe, you will need to adapt the function to take its input from stdin rather than a parameter. And you can even make it work so that it can do both. Here is a modified version of the very first script:

#!/bin/bash

function f {
  if [ $# -ge 1 ]; then
    echo "[ $1 ]"
  else
    while read line; do
      if [ -n "$line" ]; then
        echo `f "$line"`
      fi
    done
  fi
}

find ~ -type f -print | f

You could apply this construct to most functions: check if there are any parameters, in which case you can use them normally, otherwise read each input line and call the function recursively using the line as parameter. Don't forget to enclose it between quotes though, so that it is passed as a single parameter and blank lines don't trigger an infinite recursion. Run this script and you should get a list of all files in your home directory, with each file enclosed in square brackets.

That's it for functions. Please tell me if any of the examples above don't work for you. I have tested them on Ubuntu Linux, Sun Solaris Express and Mac OS-X so they should be fairly portable but you never know. They may not work with shells other than bash but feel free to experiment.

Tuesday 16 October 2007

British Gas Customer Service

Unusually, I was home early tonight. I got a knock on my door so I went and opened.

Hello, I am from British Gas, can I ask you a few questions?

Yes, sure.

Can I ask you why you cancelled your electricity contract with British Gas?

I never had electricity through British Gas, I only buy gas from you.

Ah... So you never had electricity supplied by us? And you would not be interested in buying electricity from us, in addition to gas?

No.

Why not? We have good prices, you could save a lot of money.

I am happy with my current supplier.

Ah... OK, thank you, good night!

So now British Gas know that I only buy gas and not electricity from them. That's progress. It's only taken them 6 years to realise.

Monday 15 October 2007

Labour Party's Reading Skills

I just got a call from a member of the Labour Party. I suppose they got my details from the Electoral Register. If so, said register clearly specifies that I am a French citizen. Therefore, asking me what party I was planning to vote for at the next General Election was quite senseless as I cannot vote for General Elections. Someone should teach the members of the Labour Party (and the others) basic skills like reading, that would save them quite a few phone calls.

Monday 24 September 2007

The Big 18-Month Mobile Contract Scam

If you buy a new mobile phone contract in the UK these days, chances are that the sales person you are going to talk to will try to sell you an 18 month contract rather than a 12 month one. Be extremely careful before you decide to take such a contract. Perks will include a free mobile phone and a slightly cheaper contract than the shorter one. The downside is that you can only upgrade your handset after 18 months rather than 12. Not a major problem you may think if you are not the type who needs the latest handset as soon as it comes out.

Think again. And ask the sales person what is the length of the manufacturer's warranty on the handset. Chances are, the warranty for the handset is 12 months. If your handset starts malfunctioning through no fault of your own while it is under warranty, or once you are eligible for an upgrade, the provider will replace it at no cost to you. However, if your handset plays up after the warranty has expired but before you are eligible for an upgrade, that is during the last 6 months of a typical 18 month contract, then the provider will not replace the handset and you will have to buy one yourself at full market price.

Of course all this is explained in the small print of your contract but no sales person will mention it to you without prompting. So don't forget to ask and if the warranty on the handset expires before you are eligible for an upgrade, don't take the contract.

I just got bitten by that interesting loophole with Vodafone and am now left with a malfunctioning handset for the last 3 months of my contract. Luckily the fault is not debilitating, it just means that the handset occasionally restarts while in the middle of a call, cutting the call short. Not a complete failure then, but still extremely annoying. Evidently, the second my current contract expires, I will go shopping around for a new contract and I will only stay with my current provider if they can offer me a significantly better deal than the competition.

As Vodafone's support told me, everybody else does the same because the handset's warranty is set by the manufacturer, not the network and they have no say in this. Well, maybe they should talk to the manufacturers and solve this loophole. The reason why it should be solved is because the handset is bundled with the contract. You don't buy the handset, you buy a contract to provide you with mobile phone services and you are given a handset as part of that contract to enable you to connect to the service. The cost of the handset is then included in the price you pay for the service and it should be completely covered by the service agreement for the duration of that agreement. In the case where you buy the handset separately, you buy a service and an electronic device to use with this service, there are two separate transactions and it is therefore sensible to treat them separately. Not when the handset is bundled with the service.

I may be barking at the wrong tree but I will definitely contact the Office of Fair Trading and ask them whether this practice is actually fair. I shall update this blog when I have an answer.

Sunday 23 September 2007

Bad Interface Design

Apple Computers are reknown for some of the best user interfaces. Like everybody else, they can occasionally get it wrong. I just had an amusing example of this. If you go to the HSBC web site and download any of their PDF documents such as their terms and conditions, you will notice that there is a slight bug that adds ;jsessionid= followed by a lot of gobbledygook at the end of the file name, after the extension, thus producing a file with an unusually long extension that OS-X doesn't recognise. So the first thing you'd want to do is change that file name and remove all the jsessionid malarkey at the end of the file name. When you do that, OS-X thinks you want to change the extension and are in risk of ending up with a file name it can't handle automatically. So it warns you and asks if you really want to do this, assuming you don't, as shown below:

Error dialogue with inaccessible button

Error dialogue with inaccessible button

In this example, you can just about see the other button pushed all the way left and therefore click on it as you really, really want to change that extension. But if you had just one more letter or if you changed the j in the ID for an M, the right button would be that little bit much wider and the left button would completely disappear. As you can't change the dialogue window's size, you're stuffed and you have no choice but to click on the highlighted button and leave your file name as is. The only way I found around this is to open the terminal and use the command line to change the name. That's one thing that OS-X has going for it: as it's UNIX underneath, you can always bypass the user interface when it gets in the way. On the other hand, that's not something that is very accessible to the average user.

There are a couple of solutions that Apple could apply to their dialogue boxes when such a problem occurs:

  • make the dialogue window's resizable and/or scrollable;
  • extend the window accordingly, although you'd get the same problem if you got to stupid extension lengths as long as the width of the screen;
  • make the buttons stack up and extend the window vertically.

The moral of the story is: when designing user interfaces, test them with very stupid values that make it break. Someone is bound to use such values one day or another, if only by accident.

Saturday 22 September 2007

Big Brother Sam

Wired News have an interesting article about screening at American airports and the type of information they collect. This strengthens my resolution not to fly to the United States until further notice. Not that I have anything to fear from such screening but I really think this is going too far. It looks like Uncle Sam is more and more turning into Big Brother Sam!

Tuesday 18 September 2007

Word of the Day

Dictionary.com's word of the day is potboiler. No, I didn't know it either. There you go, you learn something new every day.

Wednesday 22 August 2007

Cheap Taxi

I arrived in Sofia yesterday morning. The first thing I needed to do was find a hotel. James, whom I had met on the train already had one booked so we decided to go to his hotel and drop the bags there. If they had an extra room free for me, that'd be ideal, otherwise I'd go looking but without having to lug the bags around.

The first thing we did was have a coffee and pull out the map I had bought in Belgrade to have an idea where his hotel was. We found it easily right in the centre and estimated it was about 2 kilometres from the train station. That was easily walkable but we decided we really didn't want to carry the bags and we'd take a taxi. So once the coffee paid for, we went to the taxi rank.

As soon as we got to the taxi rank, we were approached by a guy who asked if we wanted a cheap taxi. Smelling a trap we asked how much it would be to the address we wanted to go to. He immediately answered 10 Euro, pulling his it's-very-far-away-you-know face. Even in London, they wouldn't attempt to charge you that much for a distance you could walk! We thanked him and went to an official taxi. We were in front of the hotel some 10 minutes later and got charged 4 Leva: 2 Euro.

Moral of the story: unlicensed taxi drivers have an interesting understanding of the word cheap.

Linguistic Gymnastics

If you ever want to learn Serbian, the good news is that it is a phonetic language: if you can read it, you can speak it and vice versa. The bad news is that is can be written using either the Latin or the Cyrillic alphabet so you may see signs in both scripts. For instance, Thank you can be written Hvala or Хвала. It can get very confusing when you have a map that uses the Latin alphabet but the street signs are all in Cyrillic. Then the even worse news is that Serbian extends both alphabets with extra letters that don't exist in the standard versions of either, such as Đ in the Latin script or Љ in the Cyrillic one. And then comes the practical question: what dictionary order is used? The Latin and Cyrillic alphabets have different dictionary orders so does it mean that when you buy a dictionary, the order the words are in depends on the alphabet it is published in? I'm not sure I want to know the answer.

Monday 20 August 2007

Impossible Connection

Sometimes you meet someone in the weirdest of situations and realise that you have the most unexpected of connections. Last night at the Belgrade Beer Fest, I met a couple of Serbian guys when we started discussing the blueberry flavoured beer I had just bought. Of course, they eventually asked me where I came from. When I said France, one of them asked me to be more precise. So I said I came from Brest, fully expecting to have to explain where it was. To my surprise, he said that he had been there. But the most surprising is the reason he went there: he just loved the poem Barbara from Jacques Prévert and wanted to see the town the poem was about so one day he was in France visiting family, he went all the way to Brest. How cool is that?

Off the Map Again

I thought that being unable to find maps of Belgrade when in Budapest was weird. Well, the same happens in Belgrade: nearly impossible to find a map of Sofia, the capital of Bulgaria, even though Serbia and Bulgaria share a border. You can easily find guide books and maps to go to the other end of the world or to war zones like Sudan but you can't find a map of the capital city of a neighbour country. I eventually succeeded in finding what I think was the one map in town after visiting half a dozen book stores.

When I questioned this state of affairs in Budapest, I was told by a friend that nobody ever went to Belgrade. Having now been there, I can confirm that Hungarians are very misguided: Belgrade is definitely worth visiting! So is it the same problem here about Sofia? Nobody ever goes there? And if yes, are Serbians misguided about their neighbour? I shall discover that tomorrow. Or is this attitude just the remnants of old conflicts between those countries that share a complex history?

Also, just for the record, Google Maps doesn't fare any better in providing a map of Sofia than it does in providing one of Belgrade: you just get a big grey blob labelled София.

Friday 17 August 2007

Serbian Border Controls

I got a fairly harsh reminder last night that Serbia is not part of the European Union. I was travelling on a night train from Budapest to Belgrade and there were six of us in the compartment, including a Greek couple who were going back home from Vienna. On the way out they had flown so no problem there. On the way back, they missed their flight and decided to travel by train rather than pay for a new plane ticket. To do this they needed to physically travel through Serbia and Macedonia. When Serbian border guards came on board they asked for passports. The guy had his but the girl only had a national ID card, as it is enough to travel all through the European Union. Unfortunately, that didn't cut it with the Serbian officials and they were asked off the train. I hope they found a way to get home and are not stuck in the middle of nowhere. So, when travelling to the Balkans, take your passport with you.

Thursday 16 August 2007

Off the Beaten Track

You know you're heading off the beaten track when it starts becoming difficult to find information on your destination. I am taking a night train to Belgrade tonight. That was easy: there are two trains a day from Budapest and it is easy to buy a ticket. You would expect a few more trains considering Serbia and Hungary share a border but two is better than nothing. Now finding a hotel was quite a challenge. Hotels.com has as choice of 4 while lastminute.com doesn't even have Serbia (nor Yugoslavia) listed in its list of countries. I eventually found one through a Serbian booking site (thank you, Google). I then wanted to have a look at a map of Belgrade so went to Google Maps to find... er... a big grey blob with the word Beograd in the middle of it (no thanks, Google). So 10 minutes ago, I stopped at a large bookshop in the hope of finding some sort of guide book or at least a map. They had one map. And when I say one, it's one copy. Now that I bought it, nobody can find anything on Belgrade in this shop anymore. They actually had more info on Baghdad! To top it off, my Lonely Planet phrase book for Eastern Europe is tellingly missing Serbian.

The next stop in my travels may prove interesting.

Blogger Languages

Blogger detects the preferred language of the computer you are using when presenting you with the main page. That's nice. However, even after you log in to write a new post, it keeps using the same language. It would be a tad more user friendly if it switched to my preferred language at that point. Luckily, the interface is not too complex so I just learnt that Publish Post is Bejegyzés közzététele in Hungarian.

Update: There actually is a drop down box on the main screen that enables you to choose the language but it's not that obvious.

Sziget

You have to give it to the Hungarians: they know how to organise a major music festival. Reserve a whole island in the middle of the Danube for the event, organise boats to take visitors there, put lots of stages, organise a camp site, invite lots of artists, make sure there's enough beer and food for everybody and last, but not least, sell the tickets cheap enough that people don't think twice about buying one. 8000 HUF (20 pounds) for a whole day when you can see dozens of groups live is nothing. When the main act of the day are The Killers, it's peanuts!

Monday 6 August 2007

4 Weeks at Sea

Århus, Kotka, Stockholm, Szczecin: I've been sailing on Sørlandet for the past 4 weeks and loving it. Unfortunately, it will be time to leave later today, to take a train to Berlin. It was a fantastic month. Photos and more comments will be forthcoming as soon as I can.

Saturday 30 June 2007

Charitable Search Engine

A news letter I recently received from the RNLI pointed me to a new search engine, MagicTaxi. According to the home page, MagicTaxi gives 50% of its advertising revenue to charity. So if you want to donate while you search, point your browser their way.

Cryptic Codes and Canon Lenses

As I have enough camera gear that a standard travel insurance will not cover it, I bought a special insurance just for the camera and associated bits and pieces. They require that I provide serial numbers for every item that is worth more than £200. So when I recently acquired a new EF 15mm f/2.8 Fisheye lens, I decided to add it to the insurance policy and went in search of the serial number. On the box, there is a sticker that specifies a serial number but, at first sight, it looks nothing like any of the codes on the lens itself. To start with, the lens has two codes: a numeric one and an alphanumeric one. Which one is the right one? After some digging on the net, I had the answer, so here's an illustration of it, with a couple of my lenses.

The numeric code is the actual serial number. On the EF 15mm f/2.8 Fisheye lens, it is located on the barrel, near the camera mount. On the EF24-105mm f/4 L IS USM lens, it is located on the bayonet flange.

Serial number on the barrel of the EF15mm f/2.8 Fisheye lens Serial number on the bayonet of the EF24-105mm f/4 L IS USM lens

Serial number on the EF15mm f/2.8 Fisheye and the EF24-105mm f/4 L IS USM

That same number is also available on the box the lens came in. On that box, there is a sticker with a bar code and a couple of numeric codes, with the title Lens No. At first sight, none of the codes on the sticker seem to really match what's on the lens. But looking closer, it appears that the serial number is the end part of the bottom code. It all makes sense now! What the other codes mean, I don't have the faintest idea.

Lens No sticker with serial number circled

Lens No sticker with circled serial number

I also found an explanation for the alphanumeric code that can be found on the lens. This is a manufacturing code. My fish-eye lens has a code that says UV0509.

  • The first letter, U, identifies the factory that produced the lens: Utsunomiya, in Japan.
  • The second letter, V identifies the year the lens was manufactured: 2007.
  • The following two digits identify the month the lens was manufactured: May.
  • The last two digits are an internal Canon batch number.
This manufacturing code enables Canon to identify a batch of lenses. For example, the first batches of the EF24-105mm f/4 L IS USM lens had an optical defect that produced serious flares. This code on the lens enabled owners to identify whether their lenses were part of any defective batch so that they could return it to Canon.

Manufacturing code on the EF15mm f/2.8 Fisheye lens

Manufacturing code on the EF15mm f/2.8 Fisheye

So there you go, that's what all those numbers mean on Canon lenses. I can now fill in my insurance policy properly.

Monday 25 June 2007

Journalistic Faux-Pas

Sports commentators are known for their sometimes amusing comparisons and comments. In an attempt to sound interesting, they often eschew good taste, common sense and simplicity to come up with the weirdest things, as demonstrated today in the BBC commentary of the Moya-Henman game:

Relief for Moya as Henman's groundstrokes are drawn to the net like papparazi to an intoxicated Jade Goody.

See what I mean?

Saturday 23 June 2007

Pure Brilliance

I got this picture entitled Pure Brilliance by email today. I completely agree with the title!

Man drinking a fountain of beer out of 5 glasses

Pure Brilliance!

From Zatte Vrienden.be apparently.

Sunday 17 June 2007

Ubuntu 7.04 on an IBM ThinkPad T42

I inherited this IBM (now Lenovo) ThinkPad T42 from a previous job. It's a great machine, built according to development specs: it's got a decent processor and lots of RAM and is a good desktop replacement. I had never really changed what was installed on it so it was still running its original operating system, Windows XP Professional, and it was still setup to connect to the company's domain. I was virtually never using it, having everything I needed on my Mac and being very happy with it. However, my Mac is a desktop computer and more and more I'd like to have a laptop I can use regularly but without the pain that goes with running Windows. I thought about buying myself a MacBook but then why would I buy another computer when I have a perfectly good one doing nothing? So I decided to see if this laptop could run a decent operating system. Ideally I'd like an OpenSolaris distribution because I know Solaris very well but there are currently no really tried and tested OpenSolaris distribution and Solaris has always had weak support for laptops. So I decided to go for Ubuntu as I've heard a lot of good things about that Linux distribution. I fired my browser at the web site and got downloading.

Download

The download of the latest Ubuntu distribution, 7.04, was a breeze. The mirror I choose, Ubuntu in the UK, was fast and I had an ISO image of the Live CD very quickly. It actually felt like it took longer to burn it on CD than to download it.

Boot

Ubuntu booted from CD without complaining. It took quite a long time to start up. Luckily, a progress bars come up very quickly to tell you that it's actually doing something useful. For some reason, the start procedure starts looking for stuff on the hard disk, as I had the hard disk LED full on for a long time. It then loads from the CD before worryingly switching to a blank screen for a few seconds. Then the desktop flash screen comes up, it initialises everything and you're in. Welcome to Ubuntu.

Sound

No need to test if the sound card works: the jingle you get on login told me immediately that all was well with the sound card. I still went through a few quick tests to confirm it was all fine. And it is, no configuration needed.

Display

Ubuntu automatically identified all the screen resolution that my video card supports and set itself to use the highest possible resolution. Once again, no configuration necessary.

Network

Wireless

I then tried to connect to the internet. To do this, I tried to set up the wireless network so that it would connect via my broadband router. Unfortunately, Ubuntu only supports WEP authentication. My router is configured to use WPA-PSK. So that didn't work. Nevermind, it's no worse than Windows that couldn't connect to that network either. I'll have to try on a WEP or unprotected network but I didn't feel like re-configuring my router tonight. So I decided to see if a cable connection would work properly.

Cable

I connected the cable and... nothing. I went through the network setup dialog, checked that the interface was defined in such a way that it would use DHCP. But still no luck. I tried setting a fixed IP address and still no luck. I tried to manually bring up the network interface through the command line and still no luck. Eventually, I decided to try what would happen if I configured the connection to be a roaming one. And lo and behold! It worked! So, in Ubuntu speak, a roaming connection is one you can connect and disconnect at will and it will notice when you do that. Exactly what I need for a laptop.

Software

The pre-installed stuff

Ubuntu comes with a decent software suite installed by default, in particular it includes software like OpenOffice.org, Firefox or GIMP. It all works out of the box.

Add/Remove dialog

Now, for a newbie, that's probably the best feature of Ubuntu. Like Windows, Ubuntu has an Add/Remove dialog to manage the software that is installed on the machine. But, unlike Windows, you can choose to add new software from a list downloaded from the internet. You want a project management tool similar to Microsoft Projects? No problem, you don't have to know what it's called, just browse in the list and select it. When you're done with your virtual shopping, click Apply and Ubuntu will download and install everything. Of course this only works for the open source and free software that is in the list but looking at said list, you're unlikely to ever need anything that's not on there. Of note, there is quite a large education section, which is nice.

Of course, this being a Linux distribution, there is much more software to choose from than what's in the list of supported packages offered on the list but then you would not benefit from the simple checkbox install it offers and the list is very comprehensive anyway.

Install to hard disk

Having played with Ubuntu sufficiently to know that I wouldn't miss Windows on that laptop, I decided to install it to hard disk. So I double-clicked the install icon on the desktop. After specifying my time zone and keyboard layout, I choose to use the full hard disk and blast Windows to oblivion. A nice touch on the keyboard layout screen is the ability to type text into a box to verify that you've choose the correct layout. The installer also asks you for the details of a user account it will create. After that, it does everything on its own without requiring manual input so I had a tea break. Ubuntu was quicker in installing itself than me in drinking my cup of tea.

Once everything is installed, you need to reboot without the CD so that it boots on the hard disk. The restart is very fast and once you've entered your user name and password, loading the desktop happens in a snap.

The first thing that Ubuntu does when you log in is to check for updates. As it was a fresh install from a CD, I had 60 updates to download so I mentally prepared myself for the long haul. Fool that I was! The update was significantly faster than any OS-X update I've seen. Compared to Windows Updates that recently took 5 hours to install 70 odd updates on a friend's computer, well... there's no comparison possible, they are in a different league.

After such a large update, Ubuntu needs to reboot but there is no pressure to do so, no nagging, as you have on Windows or OS-X. I restarted anyway and this is where it became scary. The computer started to boot, then the boot process forced an fsck on the main partition, presumably because it had never been done before, and failed, triggering the system to reboot once more. At that point I was getting quite worried that the system would fall in a heap, as I have seen so many versions of Linux do in the past. Luckily my fears were unfounded and a few seconds later it was up and running.

Power management

This being a laptop, I decided to check the power management features. The options about the notification area in the General tab are a bit confusing but otherwise everything you would expect is here: when to shut things down, screen luminosity, what happens when you close the lid, etc. with different settings whether you are on mains or battery. So I set everything the way I wanted, closed the dialog and pulled the mains cable out of the laptop. As you would expect, it immediately dimmed the screen and showed the battery charge icon in the status bar. Shutting the lid put it into sleep mode as expected and it woke up without a glitch when opening the lid again, reconnected to the network without any problem and was back in service in a few seconds.

Conclusion

Installing Ubuntu on this laptop was a revelation. It reconciled me with Linux after years of aborted tries. Apart from the network, the installation was a real breeze and could be performed by anybody. It's actually more straightforward than Windows, on a par with OS-X. The live CD means you can test drive it before committing to it and because it's a Linux distribution, you can always install it with a boot loader so that it shares the computer with other operating systems, although I didn't try that.

Compared to the competition, there are two things that set Ubuntu apart. The first is the Add/Remove software dialog as described above. The second is the blisteringly fast network connection. I don't know what the difference is in the network stack but Ubuntu is a joy to use on the internet. Browsing is extremely fast, much faster than on OS-X or Windows, and that's with the same web browser (Firefox) on all 3 operating systems.

How to create a colour palette from a photograph using Photoshop

Following a talk by John Hicks at @media2007, I was wondering how to derive a colour palette from a photograph in Photoshop. As I am a real Photoshop novice, I started by searching through the help and eventually came to a technique that involving transforming the image to indexed colour mode, reducing the number of colours and creating a swatch library from the resulting image. The results were quite poor and it was very cumbersome to do. There had to be a better way.

So I ditched the Photoshop manual and went googling. It took about 5 minutes to come up with the answer: pixelate the picture, as explained graphically on Upstart Blogger from the original article at YourTotalSite. Here is the result with one of my pictures:

Pixelated photograph to extract its colour palette

Pixelated photograph to extract its colour palette

The cool thing about this technique is that it is very fast and you can manipulate the resulting colour palette as an image. Of course, if you want to, you can always extract a swatch library out of it as you would have done in the original picture.

Update: Of course, as I had just published this article I had a brain wave and decided to check out fd's flickr toys. As you would expect, they have a palette generator that does exactly what it says on the tin and gives you a 15 colour palette with hexadecimal codes and an example CSS snippet.

Screenshot of fd's flickr toys palette generator output

Screenshot of fd's flickr toys palette generator output

Tuesday 12 June 2007

The Weakest Link

I asked my ISP what BT had done to rectify the problem on my broadband and got the following answer:

BT had changed the SNR margin and applied interleaving to your line to try and reduce errors in transmission. This did not seem to fix the issue though. The way your service is now delivered has changed from BT exchange equipment to our own LLU equipment.

So, in other words, BT is now completely out of the loop (literally) and it works great!

Monday 11 June 2007

Broadband purgatory

Any experienced network administrator will tell you: the worse problems are not when nothing works but when it sort of works but not quite. So when I started having performance problems with my broadband connection 6 weeks ago, I knew I was in trouble. How to explain the problem to my ISP's helpdesk? I could download pages, even though they sometimes timed out but I couldn't upload any file. So my flickr photo stream started to dry out.

Of course, the first reaction of my ISP was to blame my equipment. As I had the same problem on a Power Mac G5 running OS-X and an IBM laptop running Windows XP, with Firefox as well as Internet Explorer, whether I was connected with to the network wirelesly or with a cable, it quickly came apparent that the only potential culprit on my side was the broadband router. As I was due for an upgrade anyway, I bought a new one and proved that I still had the problem with two different routers.

Then followed the various requests for test outputs to see what could go wrong. All this was a very slow process as I could not test during the day while my ISP's helpdesk was only able to review the tests during working hours. So a routine set in: I do a test during the evening, they look at it the following day, they suggest something else, I do a new test, etc. I quickly became frustrated and ended up writing a shell script to automate calls to traceroute followed by ping in order to get any decent statistics. And, lo and behold! It then became obvious that, anywhere on my network I had no packet loss whatsoever, whereas as soon as I reached my ISP's first router, I had between 5% and 50% packet loss depending on packet size. Now, 5% loss is huge and definitely way too high for TCP/IP to function properly. 50% loss doesn't even bear thinking about. The most likely culprit was now my broadband line. So my ISP passed the call to BT and, miracle, my connection now works like a charm! It only took 6 weeks to get there.

It's scary how we get used to facilities such as broadband though. Those 6 weeks really felt more like 6 months of frustration. Every time I clicked a link or a button on a page, I had no guarantee that it would load properly. Interestingly enough, the pages that were most affected by the problem were pages that depended on AJAX, GMail in particular. I suspect that this is because, when a normal page fails to load completely, the only downside is missing images and suchlike. The page is still usable. But an AJAX page can be completely crippled when it can't load everything: some essential functionality is missing. In fact, I saw exactly the same problem at work recently on my current project: a web application that depends heavily on Javascript and is completely broken if some of the Javascript source files fail to load properly. So, there's a moral for all AJAX developers out there: one of the rules to follow to build bulletproof AJAX is to ensure that your application still works, even if some of the code fails to load.

Following this, I just created a project on SourceForge, where I will maintain the script I developed during this incident. Obviously, this assumes the project gets approved by SourceForge. Assuming it does, I hope this tool proves useful to others and if anybody can contribute by testing it on other operating systems such as Linux or Solaris and helping me make it generic enough to run on those, it'd be much appreciated.

Tuesday 17 April 2007

Grow Your Own Furniture

If you're in need of some new furniture and are happy to wait a few years, just grow it! Beautiful!

Recycle Your Jeans

You've got an old pair of jeans that you can't wear anymore but that you don't want to throw away? Recycle it... into a pair of cool sandals at recycleyourjeans.com. Only for girls at the moment but a collection for boys is in the offing.

Thursday 1 March 2007

Firefox Crop Circle

Lo and behold, the Firefox crop circle! Beautiful! Brought to you by cool dudes at the Oregon State University.

Via metacool and Bob Sutton's weblog.

The No Asshole rule

If you got your copy of metro this morning, you probably read the interview of Robert Sutton about his book The No Asshole Rule: Building a Civilized Workplace and Surviving One That Isn't. Searching for it on Google at lunchtime, I came across an interesting commentary by Guy Kawasaki that comes with a beautiful graph showing the number of Google hits returned when you search for a name followed by the word asshole (or arsehole in British English). I'll let you guess in what order come the words lawyer, Paris Hilton and George W. Bush.

Monday 26 February 2007

Typography

I just tried to simplify the typography for sans-serif text on this web site by limiting the choice of fonts to two: Lucida Grande and Lucida Sans Unicode, the former being available on Mac OS-X and the latter on Windows. The web site now looks much better on the Mac but not on my Windows laptop, presumably because the Mac has decent font anti-aliasing whereas the Windows laptop doesn't seem to know anything about anti-aliasing. I'll think about that conundrum later, it's time to go to bed.

Software Patents in the UK

Tony Blair had been busy answering petitions on the No 10 website recently and he has just replied to the one on software patents. The response is short, straight to the point and says that no patents should exist for inventions which make advances lying solely in the field of software. So in theory it's all good and it means that software patents are unenforceable in the UK. Of course, there will be a grey area for everything that is not purely software or depends on particular hardware. Mobile phones come to mind as such an example.

This is a step in the right direction. Let's hope a European directive or a future government doesn't contradict it now.

Sunday 25 February 2007

Blogger Labels

Google have apparently revamped the internals of Blogger and we now have the ability to add labels to each post, a feature that had been thoroughly missing up to now. I started doing that and added labels to my last 25 posts. I will try to keep doing it and categorise all the posts since the first one but it will take time, if I ever manage to do them all. As is not completely unexpected, the top label so far is technology. Worryingly, the second one is rants. Have I been that negative recently or is it just a sign that I use this weblog to vent my frustration?

WWF-UK Climate Change Campaign

WWF-UK are currently running a climate change campaign. This campaign includes a petition to Tony Blair, that you can sign online on the campaign page and is focused on precise, achievable aims. It is always fun to petition No 10 and this is for a good cause from a well respected charity so go ahead and add your name to the list, you know it makes sense.

Contacting Sainsbury's

Last week I went to the Sainsbury's in Richmond as it is the only place in my area where I can recycle drink cartons. When I got there, the recycling centre was drowned under plastic bottles because the plastic bins were full and people had been dropping their recycling next to them. I put my cartons in the proper bin (which wasn't full luckily) and when I came back home I decided to contact Sainsbury's and complain. I found the contact form quite easily on their website and filled it in, half expecting to get a half cooked excuse in response. But no, to my surprise I got an email on the Monday saying they had contacted the store's manager and they were emptying those bins every day. I even got the details of the manager so next time I go there, I can theoretically talk to him directly if need be. And then later this week I got a £10 Sainsbury's voucher through the post! Could it be that Sainsbury's are actually listening to their customers? I shall see next time I go if the plastic bottles recycling bank looks better maintained. And I shall spend my voucher.

Friday 16 February 2007

House Prices

Shock! Horror! Kensington & Chelsea has the highest average house price in the whole country according to the BBC. But more importantly, the source of the news is a very nifty web site called mouseprice.com where you can find everything about the housing market anywhere in England. Their house price heat map is really cool and an example of a great custom Google Maps application.

Tuesday 13 February 2007

Fairtrade Fashion Show

Fairtrade is not just about bananas, tea, chocolate and coffee any more. To demonstrate this, the Ealing Group is organising a fairtrade fashion show at St Paul’s Church, including 4 catwalk shows at 11.30, 1.00, 2.30 and 4pm. Tickets are £2 for adults and £1 for under 16’s at the door and each of them includes a raffle ticket.

There will also be 15 stalls with an amazing range of jewellery, clothes, accessories and homewares for sale. They are all from small companies who operate on ethical principles and who support workers in countries from Argentina to Zimbabwe!

Light refreshments will be on sale and there will be wine-tasting courtesy of the group’s main sponsors, the Co-op. All the proceeds will go towards the group’s work in promoting Fairtrade in Ealing.

Fairtrade Fashion Show poster

Tuesday 16 January 2007

OS-X Instant Messaging

Apart from iChat, that comes bundled with OS-X but can only connect to a limited number of networks, most OS-X versions of instant messaging clients, like MSN Messenger, are fairly poor compared to their PC counterparts. An interesting alternative I discovered recently is Adium. It is quite basic in terms os features so far but it can connect to an impressive list of networks, including MSN, Yahoo, Google Chat, ICQ and quite a few obscure ones, which means that you only ever need one chat client open. It currently doesn't support voice or video but it's definitely on their to-do list. Nor does it support extended animated smileys like MSN does, although you could argue that's rather a good thing. A very nice feature is the ability to use tabs rather than individual windows for each thread of discussion. You can even have a hybrid setting whereby you have one window per group of contacts and tabs inside each window. And of course, in typical open source geeky fashion, most settings can be changed through the preferences and you can completely customise it using AppleScript.

Sunday 14 January 2007

Tell me what you recycle...

Tuesday was the first day of the year the recycling green boxes were collected where I live. My box was full of the usual stuff: paper, a few bottles and cans, nothing special really. The boxes of some of my neighbours were vastly more interesting. The first one down the road contained its usual pile of newspapers, as the guy there seems to be an avid consumer of Sunday papers. He never has any bottles or cans in his box so I wonder if he ever eats in between the Sunday Times and the News of the World. The next one down had a box full of a dozen wine bottles. Obviously, there was some serious partying there! The next one down had a couple of large empty Quality Street chocolates boxes. There was some partying there as well but of a different kind.

Saturday 6 January 2007

Urinal Theft

We've all done it: sneakily hiding a glass or other piece of crockery in a bag while having a drink in a pub and take it home to complete our collection of pub memorabilia. One guy in Southampton went further and stole a urinal. He even wiped his fingerprints from the door to make it the perfect theft. Why would you ever go to that much trouble for a urinal... and then get caught on CCTV? Or is it that he doesn't have a B&Q close to where he lives?

Not bothered about voting

According to The Register, Americans are more concerned with the integrity of casino betting machines than electronic voting system. Maybe they should organise a lottery to elect their next president rather than bother with voting?