Archive for May, 2005

Graphing Your Taste in Music

Graphing Your Taste in Music

Came up with this idea a few days ago when I took a look at the Amazon Web Service. I had the idea that if I was to export my iTunes song list (File > Export Song List), and then pass each Artist/Album combination into the Amazon Web Service “Similarity Lookup” function, then I’d be able to build a graph of my musical taste. Such a graph could help you work out potential albums to purchase by creating different coloured nodes for currently unowned albums that would create many ‘edges’ when connected with owned album nodes. As a starting point, this post discusses the implementation of a perl script which takes an iTunes song dump, feeds it through the Amazon Web Service, and is finally output into an xml format which can be read by Prefuse (an interactive visualization toolkit).

While parsing the iTunes dump line by line, we need to get the Amazon ASIN for each album. We perform a query to find the best match from our ID3 tags; and save the result into a global hash. The following method affords us this functionality.

sub get_album {
    my $artist = shift;
    my $album = shift;
    my $result = shift;

    my $content = get("http://webservices.amazon.com/onca/xml?" .
      "Service=AWSECommerceService&SubscriptionId=" . KEY ."&" .
      "Operation=ItemSearch&SearchIndex=Music&Artist=$artist&" .
      "Title=$album&Version=2005-03-23");

    my $xp = XML::XPath->new(xml => $content);

    if ( ! $xp->find("//Error") ) {
        $$result{ARTIST} = $xp->findvalue("/ItemSearchResponse/
          Items/Item[1]/ItemAttributes/Artist”)->string_value;
        $$result{ALBUM} = $xp->findvalue(”/ItemSearchResponse/
          Items/Item[1]/ItemAttributes/Title”)->string_value;
        $$result{ASIN} = $xp->findvalue(”/ItemSearchResponse/
          Items/Item[1]/ASIN”)->string_value;
    }
}

Now once you’ve got the ASIN for an album; you can use Amazon to perform a similarity lookup which will return a list of ASINs that are deemed to be similar to the provided ASIN. This information also gets placed in our hash. The following method does the job…

sub get_related {
    my $asin = shift;
    my @r_ref = shift;
    my $related = \@r_ref;

    my $content = get("http://webservices.amazon.com/onca/xml?" .
      "Service=AWSECommerceService&SubscriptionId=" . KEY .
      "&Operation=SimilarityLookup&ItemId=$asin");

    my $xp = XML::XPath->new(xml => $content);

    if ( ! $xp->find("//Error") ) {
        for (my $i = 1; $i < = 20; $i++) {
            if ( ! $xp->find(”/SimilarityLookupResponse/
                      Items/Item[$i]“) ) {
                last;
            }

            @related = (@related,$xp->findvalue(
              “/SimilarityLookupResponse/Items/Item[$i]/ASIN”)
              ->string_value);
        }
    }
}

Having built a hash of all the album relations, I export the hash back out in the XML format required for Prefuse. I won’t put that source inlined in this post, but the full source for the application is available for download below. Now whilst I’d really like to enable the Java applet on this blog some time soon, for now I’m showing some screenshots of the applet and looking at the results.

The first picture below is the zoomed out version of all the albums in my iTunes DB that Amazon deems as being related to another item in my DB. Now whilst there are a number of sparse enteries, for the most part most of my music is related through a number of degrees of seperation to the rest of the Library.

The Sparse Zoomed out Library View

Now the great thing about the Prefuse undirected graph visualization tool is that it enables you to pass over nodes which it will highlight in red, and then have all neighbour nodes and edges light up in orange. This helps to visually disern some rather interesting information. If we zoom in a bit on the centre cluster and highlight what looks to be one of the more central nodes, we can see many neighbour nodes light up orange. It just so happens I’ve selected “Vertical Horizon” which encapsulates one genre of music I appreciate, so this result is as we’d expect!

Vertical Horizon Graphed

If we zoom in further again on that dense top right area of the grab we find it’s dominated by U2, REM, and Coldplay. This picture is zoomed in enough so that you can visually study the relationships between some of the various albums and their relationships as defined by Amazon.

U2 and neighbours Graphed

I’m going to be doing a bit more work on this at some point when I get the chance to add specially labelled nodes to the graph which would act as recommendations and will place the updates on this blog. In the meantime if you wish to play with the code yourself there are a few things to note.

  1. The code above is pretty close, but not exactly the same as the actual code available for download below. I’ve got a few sloppy bits in the real code which are designed to ignore temporary connection errors and to repeat till the instruction gets through. I know there are a few loose edges, it’s a proof of concept and I haven’t spent time tidying it yet.
  2. You’ll need an Amazon Web Developer key (free from http://www.amazon.com/gp/aws/registration/registration-form.html).
  3. You might need to strip the very first header line of your iTunes dump file. Having gone File > Export Song List, open it in notepad and remove the first line — I’ll fix this in the next release
  4. Once the program finishes running you’ll be left with a results.xml file. Head over to Prefuse for some nice visualisation tools.
  5. The code is released under the Creative Commons Licence. Essentially I don’t mind what you do with it, but it’s not for commercial use — not that I can see someone doing that!

Download the Perl Source for the “Amazon Music Relationship Finder 1.1″
Note: There were a few Unicode issues in version 1.0 that I’ve now fixed.

Think this is a neat idea or have ideas for extensions? Any comments or questions? Please post a comment below!

The css Zen Garden

The CSS Zen Garden

Before I get started talking about this really neat design site, I want to start off with a note that I absolutely despise “Flash”. The only good use for it, and even then it’s questionable, is animation. I’m sick of seeing a large number of sites having moving bits and pieces all over the place that are at locked width & height, with internal scrollbars and occassionally a nice interface. The biggest problem by far though is that Flash doesn’t respect the paradigms that we’re all used to from a browser. Want to open a link in a new window/tab? nup, Flash won’t let you do it. Want to have your site indexed properly by a search engine? good luck! Luckily most sites no longer have those ridiculous starting animations that serve absolutely no purpose but to chew bandwidth.

One good thing about Flash is that you can make more powerful web applications through a more response UI (well to a point). With all the disadvantages mentioned above, I’d encourage looking into XML Http if you need that sort of responsive UI as whilst it’s a bit harder, you don’t trample all over web standards.

The only other good thing that can be said about Flash is that you can make some very pretty interfaces. I think the css Zen Garden proves that beauty in design doesn’t need to come at the expense of common web paradigms. I’ve been into using XHTML/CSS for the last year or 2 now (a little bit slow off the mark but caught up quickly). Now for someone who hasn’t yet caught up, I think the css Zen Garden is the best response to the question “What makes XHTML/CSS better that HTML 4?”. The site shows the exact same piece of HTML, styled using various stylesheets submitted by users. There is some amazing eye-candy, but what’s more amazing is that the underlying HTML doesn’t change at all.

Some interesting design examples from the css zen garden:

http://www.csszengarden.com/?cssfile=/138/138.css&page=3
http://www.csszengarden.com/?cssfile=/133/133.css&page=3
http://www.csszengarden.com/?cssfile=/118/118.css&page=5
http://www.csszengarden.com/?cssfile=/100/100.css&page=7
http://www.csszengarden.com/?cssfile=/101/101.css&page=7
http://www.csszengarden.com/?cssfile=/094/094.css&page=8

FoxyTunes for iTunes/Firefox

FoxyTunes Control Bar

Just stumbled across a pretty neat Firefox extension called FoxyTunes. Essentially it adds a few buttons to the bottom of your Firefox window to allow moving back and forward in your playlist (amongst other things) without having to bring the iTunes window to the foreground.

Not sure if I’ll use it that much, but it’s small and neat enough that the convenience outweighs the screen space it occupies. Especially being as though I spend a lot of my time using Firefox, and listening to iTunes. FoxyTunes also supports a number of different players. Worth checking out.

XBox 2 Revealed!

The XBOX360 + accessories

The XBox360 is about to be revealed a week from now on MTV in Amercia, but a few photos have been leaked that show it in all its glory! The original photo is over at Engadget and is reproduced below. Whilst I think the XBox360 is a terrible name, I think visually that the console looks pretty amazing, although not necessarily in that shot.

A while ago this concept sketch was posted on XBox-Scene and it turns out that it’s pretty accurate when you compare it to the photo on Engadget. Gives a better idea of how it might look when active.

XBOX 360 Concept Art

Finally, a photo of the controller and remote is also available. Once again, check out XBox Scene :: More leaked pictures: Xbox360 Controller and Windows Media Center Remote.

Object Wrapper Distilled

Object Wrapper Distilled

Digging up an old post here from The Daily WTF titled A Wrapper Wrapper that I found amusing. Apparently someone had submitted this following snippet to be checked-in, taking OO Design Patterns that little bit far.

Now my favourite bit was the O’Reilly Book image rip off, posted later on by “Chris”. You can click on the thumbnail on the right to view the original version.

public class ObjectWrapper {
        private Object object;

        public ObjectWrapper(Object object) {
                this.object = object;
        }

        public Object getObject() {
                return object;
        }
}

Complete Apache/PHP/MySQL on Mac OSX

Complete Apache PackageI spent the day out at Font Factory yesterday helping them rebuild their new webserver - a dual processor Mac G5 running Mac OS X 10.3. At Font Factory we need a few different extensions for the site to run, and to save building from source, the last time I did this we fiddled with the Entropy PHP packages on OSX 10.2.8. Whilst it worked really well, this time around we decided to check out the Server Logistics Panther packages for Apache2, MySQL 4.0.21, and PHP 4.3.9.

Now I’m not going to write too much, but just wanted to say if you’re installing a (L)AMP setup on Mac OS X, I don’t think it could be much easier than using the packages from the Server Logistics guys. The administration preference frames are brilliant and the setup was just so easy. Read the instructions (they’re very short), install the preference panes, get MM-Cache going; and you’re done!

The only hitch that we had in the whole install was getting SSL working as we we’re getting a “[emerg] (13)Permission denied: couldn’t grab the accept mutex” error. I stumbled accross this page. Which suggested a fix to the problem by adding a variation of these following lines to the httpd.conf file.

AcceptMutex flock
LockFile /Library/Apache2/logs/httpd.lock

Anyway, I highly recommend the “Complete” packages from Server Logistics. Some excellent work!

Boot Debian from a USB Hard-Drive - Part 2

Boot Debian by USBThe last post discussed the creation of a USB2 HDD with Debian Linux installed which in this second part of the tutorial we’re going to try and boot via a USB2 PCMCIA card on a Latitude C640 which doesn’t support booting from a USB device in the BIOS. So to get started; plug in your USB HDD and boot into Windows.

At this point you might as well download w32Grub; which essentially allows you to run the Linux Grub bootloader from the boot.ini! Get it from http://www.skyjammer.com/files/knoppix/. Extract it such that you’ve got a folder called c:\boot, which contains a stage1, stage2 and grub folder.

You need to pull your kernel image and initrd image from the ext3 partition on your USB2 Linux Hard-Drive. There are a few ways of doing this, but I found the read-only EXT2IFS driver sufficient for the task. I’m not going to go into detail on how to use it; but once you mount your drive you should be able to copy /boot/usb26.img and /boot/vmlinuz into c:\boot.

You’ll now want to edit the grub config file at c:\boot\grub\menu.lst. My config file is pretty self explanatory, it is pasted below and should work for you.

timeout 10
default 2

# Fallback to the first entry.
fallback 0

title Windows XP
unhide (hd0,0)
rootnoverify (hd0,0)
chainloader +1

# For booting Linux
title Linux USB 2.0 External (Debian 2.6.7)
root (hd0,0)
kernel /boot/vmlinuz root=/dev/scsi/host0/bus0/target0/lun0/part1
initrd /boot/usb26.img

Next you’ll need to edit c:\boot.ini to add GRUB to the list of available boot options. Whilst I’ve seen some tutorials that allow you to boot into Linux directly from the boot.ini, I like the ability to configure things on the fly if something goes wrong in the boot process, and particularly in testing it’s extremely useful. Once again, my boot.ini is reproduced below.

[boot loader]
timeout=30
default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS
[operating systems]
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS=”Microsoft Windows XP
    Professional” /fastdetect /NoExecute=OptIn
c:\boot\stage1=”Linux USB2.0 External”

If all went to plan, you hopefully should be able to restart your computer now, opt for “Linux USB2.0 External” when prompted, and be using Debian from your external hard-drive! There is also the potential that it doesn’t work at all and you’ll spend a fraction of the hours I did pulling your hair out trying to make sure you built the initrd image correctly and that you’re calling Debian from the right boot pivot point. I’ve built a few areas into this tutorial to make life easier; I can only hope they do!

If you do follow any part of this tutorial (part 1 or 2) or have any troubles; please, please, please leave a comment on what you did different or a confirmation that it worked for you! More and more laptops are supporting booting from USB, so this tutorial will get less useful overtime; but I learn’t so much from the experience that I thought it was worth sharing and the effort was definitely worth it when I was having to do Perl/Mason and C++ development last year.