Tuesday, March 31, 2009

100th post: Using Google Charts

This is my 100th blog entry! I would like to take this opportunity to thank everyone who has stopped by to read, comment or share something on this blog and make it a success. I started fahd.blog in August 2006 mainly to document my experiences with new technologies and also to share tips and tricks that I have learnt with the rest of the world. I don't plan to stop here, so stay tuned for more interesting posts!

In this post, I'm going to be using the Google Chart API to dynamically create charts illustrating the frequency of my blog posts over the last few years. This API allows you to specify all your data within a URL and have Google create the chart image for you.

Bar Chart
I'm going to draw a bar chart to show the number of posts per month, since 2006.
The chart parameters I will use are:

  • cht=bhs (horizontal bar chart)
  • chs=400x600 (size)
  • chd=t:5,6,2,2,2,2,3,7,... (data)
  • chds=0,10 (data scale - min/max)
  • chxt=x,y,x (axes)
  • chxl=0:|0|1|...|1:|Aug-06|Sep-06|...|2:||Number| (axis labels)
  • chco=76A4FB (colour)
  • chtt=Blog Posts by Month (title)
This generates the following image:

<img src="http://chart.apis.google.com/chart?cht=bhs&chbh=a&chs=400x600&chd=t:5,6,2,2,2,2,3,7,10,9,3,5,0,1,0,1,0,2,2,1,0,1,0,0,4,5,5,4,7,2,2,7&chds=0,10&chxt=x,y&chxl=0:|0|1|2|3|4|5|6|7|8|9|10|1:|Aug-06|Sep-06|Oct-06|Nov-06|Dec-06|Jan-07|Feb-07|Mar-07|Apr-07|May-07|Jun-07|Jul-07|Aug-07|Sep-07|Oct-07|Nov-07|Dec-07|Jan-08|Feb-08|Mar-08|Apr-08|May-08|Jun-08|Jul-08|Aug-08|Sep-08|Oct-08|Nov-08|Dec-08|Jan-09|Feb-09|Mar-09&chtt=Blog Posts by Month&chco=76A4FB"/>

Line Chart
Here's the same data put into a line chart.
The chart parameters I will use are:

  • cht=lc (line chart)
  • chs=400x300 (size)
  • chd=t:7,2,2,7,4,5,... (data)
  • chds=0,10 (data scale - min/max)
  • chxt=y,x (axes)
  • chxl=0:|0|1|...|1:|Aug-06|... (axis labels)
  • chco=80C65A (colour)
  • chm=o,FF0000,0,-1,5.0|V,3399CC,0,23,0.5 (circle each point; vertical line at peak)
  • chtt=Blog Posts by Month (title)
This generates the following image:

<img src="http://chart.apis.google.com/chart?cht=lc&chbh=a&chs=400x300&chco=80C65A&chds=0,10&chd=t:7,2,2,7,4,5,5,4,0,0,1,0,1,2,2,0,1,0,1,0,5,3,9,10,7,3,2,2,2,2,6,5&chxt=y,x&chxl=0:|0|1|2|3|4|5|6|7|8|9|10|1:|Aug-06|Apr-07|Nov-07|Jul-08|Mar-09&chm=o,FF0000,0,-1,5.0|V,3399CC,0,23,0.5&chtt=Blog Posts by Month"/>

Pie Chart
I'm going to use a Pie Chart to show the number of posts per year.
The chart parameters I will use are:

  • cht=p3 (3D pie chart)
  • chs=270x120 (size)
  • chd=t:22,21,44,13 (data)
  • chl=2006|2007|2008|2009 (label)
  • chtt=Blog Posts by Year (title)
This generates the following image:

<img src="http://chart.apis.google.com/chart?cht=p3&chs=270x120&chd=t:22,21,44,13&chl=2006|2007|2008|2009&chtt=Blog Posts by Year"/>

As can be seen above, the Chart API is very powerful and allows you to produce different types of charts and customise them with different styles. However, in my opinion, the API is not intuitive and the URLs are quite cryptic. I doubt I will remember how to use the API without having it open in front of me!

References:
Google Chart API

Monday, March 30, 2009

Named Pipes with mkfifo [Unix]

Named pipes are useful for inter-process communication. Unlike anonymous pipes, any number of readers and writers can use a named pipe. They are very useful for letting other processes know that something has happened e.g. a file has been created etc.

Creating a named pipe
You can create a named pipe using the mkfifo command, which creates a special pipe file that remains in place until it is removed. Since it is a type of file, you can use the rm command to remove it when you are done.

sharfah@firefly:~> mkfifo mypipe
sharfah@firefly:~> ls
mypipe|
Writing to a named pipe
Since a named pipe is just a special type of file, you can write to it just as you would normally write to a file. However, if there are no processes reading from the pipe, the write call will block.

The following example script writes numbers into the pipe. If there are no readers, it will block on line 5.

COUNT=1
while (true)
do
 echo Writer$$: $COUNT
 echo $COUNT > mypipe
 COUNT=`expr $COUNT + 1`
 sleep 1
done
Reading from a named pipe
Reading from a named pipe is the same as reading from a normal file. You can cat a named pipe, tail it or read it as follows:
while (true)
do
   read line < mypipe
   echo Reader$$: $line
done
Multiple readers
If you have multiple readers reading from the same pipe, only one of the readers will receive the output. This is illustrated with the following example, in which I have launched one writer and two readers:
sharfah@firefly:~> writer.sh& reader.sh& reader.sh&
Writer10500: 1 
Reader10501: 1 
Writer10500: 2 
Reader10502: 
Reader10501: 2 
Writer10500: 3 
Reader10501: 3 
Reader10502: 
Writer10500: 4 
Reader10501: 
Reader10502: 4 
Writer10500: 5 
Reader10502: 5 
Reader10501: 
Writer10500: 6 
Reader10501: 6 
Reader10502: 
Writer10500: 7 
Reader10502: 7 
Reader10501: 
Writer10500: 8 
Reader10502: 8 
Reader10501: 
Writer10500: 9 
Reader10501: 9 
Reader10502: 
Writer10500: 10 
Reader10502: 10 

Friday, March 20, 2009

Vertical Rush Results

Yesterday, I climbed Tower 42 with my team, "Are we there yet?". We got there at 11.30am, wearing our black, Vertical Rush t-shirts and our race numbers pinned on. Our chip timers were tied to our shoes. Then the race started. They let us off in small batches so that we wouldn't clog the stairwell. I started off quick, taking two stairs at a time, but by the time I got halfway, I felt my energy running out. I could hear my heart pounding in my chest and I changed to taking single stairs and dragging myself up using the banisters.

I finally made it to the top and staggered into the lounge where I was given a "goodie" bag containing a bottle of water, a disgusting banana energy gel and a Tower 42 mouse mat! There were no chairs, so I slumped onto the floor and enjoyed my water. It has never tasted so good!

We then had some team photos taken at the top, which I now have to buy! Sadly, they didn't allow any cameras or mobile phones into the race, so I wasn't able to take any pictures myself.

In the evening, there was a prize-giving ceremony at Gibson Hall where we found out our times and got a certificate for taking part. Nearly 600 people took part in the race and the fastest time was 00:04:22!

My Stats
Race Number: 5034
Gender Position: 341
Category: Financial
Category Position: 100
Club: Deutsche Bank
Chip Time: 00:09:10
Chip Position: 382

I'm also really proud about how much we raised for Shelter! Here is our Just Giving page: http://www.justgiving.com/reteamstairclimb

Monday, March 09, 2009

Vertical Rush

I've been crazy enough to sign up for Vertical Rush, a race to the top of Tower 42, the tallest building in the City of London. The event, which is going to take place on the 19th of March, involves running or walking 183m (600ft) up 920 stairs and 42 floors to the top of the tower. All of this is in aid of the vulnerably housed and homeless charity Shelter.

Tower 42 is the tallest building in the City of London

I'm not doing this alone. I have a team of four others from work and we're calling ourselves, "Are we there yet?". We've been climbing 400 stairs (24 floors) in our office every day for the last couple of months, but this is going to be a lot more painful!

Please help to motivate us to the top by sponsoring us through our Just Giving page: http://www.justgiving.com/reteamstairclimb

Stay tuned to find out how long it takes me to climb the tower!

Tuesday, March 03, 2009

Howto: Delete Empty Directories [Unix]

Consider the following directory structure:
/tmp
 |-->bar.txt
 |-->dir1/
 |-->dir2/
 |    |-->baz.txt
 |-->dir3/
 |-->foo.txt
There are two files called bar.txt and foo.txt, a non-empty directory called dir2 and two empty directories called dir1 and dir3.

This is how you can delete only the empty directories:

sharfah@starship:/tmp> unalias rmdir
sharfah@starship:/tmp> rmdir *
rmdir: directory "bar.txt": Path component not a directory
rmdir: directory "dir2": Directory not empty
rmdir: directory "foo.txt": Path component not a directory
You need to unalias rmdir just in case you have it aliased to "rm -rf"! You will notice that rmdir does not delete files or non-empty directories. Only dir1 and dir3 are deleted.

Another way to do it, using find:

sharfah@starship:/tmp> find . -type d -exec rmdir {} \;
rmdir: directory ".": Can't remove current directory or ..
rmdir: directory "./dir2": Directory not empty
Note that aliases aren't recognised by find, so even if you did have rmdir aliased, it would not use it.