Monday, 27 April 2009

Maven: replace a shell script with a Groovy script run by gmaven-plugin

I've never even heard of the gmaven-plugin before and just though this
looks quite awesome.

Text below is just cut and pasted from the Maven mailing list.

================================================================

PROBLEM:

At a customer site there is a custom, company-wide dictionary available for
spellchecking. This dictionary is managed in an proprietary application from
where you can export it. For the webapp we're building we need to transform this
dictionary into a very simple format: a single file with one
dictionary entry per line. The export format is somewhat special as
its spread over a bunch of files (one for each letter of the
alphabet), contains additional syllabication info, which we don't need
and also has some comments that have to be removed. The specifics of
the format aren't really that important here though...

After some testing I came up with the following short bash-script that fullfills
all my needs:

8<-----------------------------------------------------------
tmp_folder=target/dict
cls_folder=target/classes
mkdir -p $tmp_folder
mkdir -p $cls_folder

cat src/main/dictionary/*.lst > $tmp_folder/tmp1.dict
sed "s/[~?]//g" $tmp_folder/tmp1.dict > $tmp_folder/tmp2.dict
sed "s/ .*$//g" $tmp_folder/tmp2.dict > $tmp_folder/tmp3.dict
sort -u -o $cls_folder/my.dict $tmp_folder/tmp3.dict
8<-----------------------------------------------------------

(In other words: Take all files src/main/dictionary/*.lst, concat them into one
single file, match some strings with simple regexes and remove those, and
finally sort the dictionary entries and remove all duplicates.)

This script is then called from within maven with exec-maven-plugin. Afterwards
maven-jar-plugin wraps the file in a simple jar, so the dictionary can
be easily consumed in Java using
getClassLoader().getResourceAsStream().

Now all is well & nice and this script even performs sufficently given about 1.6
million dictionary entries (~38MB). But of course it's not really the
Maven way to do things, especially because it's not portable. You need
to have some kind of Unix-like enviroment in place for this script to
work.


SOLUTION:

Assuming the dictionary source files are already broken down by letters
of the alphabet, then the following 5 lines of code does most of it.
(Note that the sed scripts are pretty close to just a line by line
trim() and, of course, you may need to sort the file names.)

<plugin>
<groupId>org.codehaus.groovy.maven</groupId>
<artifactId>gmaven-plugin</artifactId>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<source>
<![CDATA[
new File( "target" ).mkdirs();
def resultfile = new File( "target/dictionary" );
new File("src/main/dictionary").eachFileMatch(~/.*\.lst/){ file ->
file.readLines().sort().each(){resultfile << it.trim() + "\n";}
}
]]>
</source>
</configuration>
</execution>
</executions>
</plugin>

Saturday, 18 April 2009

Wednesday, 18 March 2009

Gmail fixes "mark as unread" annoyance - you can now mark individual messages instead of the whole thread

Great to see that Google have fixed that issue where "Mark as unread"
marks *the whole thread* instead of just the specific message that you
wanted to mark as unread. I'm just surprised it took so long to get
it fixed.

http://gmailblog.blogspot.com/2009/03/small-but-helpful-change-to-mark-as.html

Tuesday, 17 March 2009

Jaxb notes: specifying a package for a classes generated from a schema

Use the <package> element of the <schemaBindings> binding declaration
to define the package name for the schema.

For example, the following defines the package name for all JAXB
classes generated from the simpleservice.xsd file:

<jaxb:bindings
xmlns:xs="http://www.w3.org/2001/XMLSchema"
schemaLocation="simpleservice.xsd"
node="/xs:schema">
<jaxb:schemaBindings>
<jaxb:package name="examples.jaxb"/>
</jaxb:schemaBindings>
</jaxb:bindings>


Taken from http://edocs.bea.com/wls/docs103/webserv/data_types.html#wp223112

Saturday, 7 March 2009

Getting a replacement power supply for Western Digital external drives - easy as pie

I very rarely get to actually praise a company for doing something beyond my expectations of service so here goes.

I've owned a 500GB WD Elements external hard drive for a little more than a year, and it stopped working about a month ago. I suspected the power supply was faulty, because I would plug it in, it would light up for half a second, then die out.

I was running out of disk space on my computer so I finally got around to looking for all the paperwork for it to make a warranty claim - the receipt, the warranty documents, etc. I went online, registered the product, adjusted the warranty dates by sending them a photo of my receipt, since there were a few weeks between the time of manufacture and the time of sale.

Then I rang Western Digital support and told them about my problem. The conversation went something like this:

Me: I've got a problem with the power supply of my external hard drive. It lights up for a moment after plugging in then goes out.

WD support: So what is the plug for your power supply. Is it 5-pin or something else?

Me: 5 pin. (I'd read on their support site that models made after sometime in 2008 used a different power supply and pin)

WD support: Okay, give me your name and address. You should get it in about two weeks.

Me: Do you need my registration number, or the model of hard drive I have.

WD: No, it doesn't matter what size of drive, it's just the plug that's different.

So they didn't even check if I actually had a registered drive. I could have been anyone or the item could have been out of warranty and would still have received a replacement power supply! Not that I'm complaining. Probably the chances of people doing that are quite unlikely anyway, so they decided to simplify the procedure.

The power supply arrived yesterday, Friday, 6 March. It was sent by FedEx from Singapore on 3 March. No questions, no rego check, no hassles. Just send it out when requested. WD support are f*king excellent!







Saturday, 8 November 2008

Re-ordering songs in a playlist in iTunes - you first need to click on the playlist number (1st column)

I haven't really had much to complain about when it comes to iTunes, until now.

I was preparing a CD songs for my son, and I had the songs in a playlist. The first group of songs I added was from a single CD, so that was easy enough. I added a few more songs later, and discovered that changing the order of the songs in a playlist can be a bit puzzling. Trying to drag around a song in the list, which normally you'd expect to be enough to change the sequence, had no effect. Googling it reveals that it doesn't work when the list of songs is already sorted on a column other than the first one, which is the list number. However, there is no indication anywhere in the interface that this restriction is in place!

Now from an implementation point of view, I can see why they don't allow it. For example, if the list of songs is sorted by Name, in ascending alphabetical order, allowing the songs to be dragged around and resequenced would be inconsistent with what the table widget is meant to
be doing.

But this is a totally inadequate user experience! If you can't drag and drop the songs while it's sorted on any of column after list number, then why couldn't they tell that to the user? There should be a drag/ drop event detectable from the GUI toolkit, so why couldn't they put in a condition like:

IF (song is being dragged and dropped) AND (songs are sorted on any
column from 2 onwards) THEN
SHOW MESSAGE "Click on 1st column before changing the order of the songs"

Unfortunately, iTunes has worked like this for a while (and so have complaints about it), so I don't think Apple will be making this operation a bit easier.

So to change the order of songs in an iTunes playlist, click on the first column to cancel out any other sorting on the list, before dragging the songs to the desired sequence.




NOTE: Make sure that the shuffle button in the bottom left is not clicked. (thanks Andrew!)

Thursday, 30 October 2008

Xpath info - don't use "/" at the end of a xpath query

Xpath info - don't use "/" at the end of a xpath query, otherwise
you'll get this error:

javax.xml.transform.TransformerException: A location step was expected
following the '/' or '//' token.


http://p2p.wrox.com/topic.asp?TOPIC_ID=8429

"A path expression never ends in "/", except for "/" used on its own
to refer to the root node."

Thursday, 11 September 2008

O'Reilly Maker




http://www.oreillymaker.com/link/19781/groping-for-admins/


I'm pretty sure I've come across it before but didn't have the requisite brain cells to come up with something.

The things you do at 2 in the AM....

Sunday, 20 July 2008

Problem upgrading firmware on Billion 7300G ADSL Modem? Try using Firefox. + Hidden config pages.



I was trying to upgrade my Billion 7300G modem to firmware ver. 1.36 using my iMac, and kept getting up to a certain point and then bomb out around at the 24% mark and return an alert/dialog box that just had:

http://192.168.1.254
Error!


Great, talk about informative error messages!

After a bit of Googling, I found out that this problem only occurs when performing the upgrade from Safari, and Billion have supposedly promised to fix this. I But there haven't been any more firmware updates after ver. 1.36 anyway. The only solution is to use another browser like Firefox.


On another note, I've also sorted out my issues with my wi-fi at home simply by boosting my wireless signal.

My modem/wifi router is in a room on the second floor, while my main computer, a 24" iMac, is downstairs. Now the problem was the iMac would keep losing the wi-fi connection when it came back from Sleep mode. After this any open tabs in Safari would no longer work, and the only workaround I've had was to turn off Airport, then turn it back on again.

The Billion has some hidden configuration pages, and going to http://192.168.1.254/wireless_txpower.asp shows the Wireless signal is only transmitting at 70% strength! Setting the value to 100% sorted out my issues.

Google's Blogger widget for Mac OSX is rubbish

I wanted a quicker way of making posts to Blogger, so I downloaded Google's Blogger widget. Absolute crap. You can't even put a link or an image. All you can do is enter plain, bold and italicised text.

The only thing I found interesting was that it encodes punctuation marks so you end up with &#39; instead of the (') character. But that's probably Blogger itself, and not the widget making those changes.

WTF? It's 2008, guys. I'm sure you can do better than this!

I've never been so insulted by Google Ads!



So how are we meant to describe musicthing's audience, based on these two ads? "Overweight and buys a lot of games and DVDs"?

Quotes from Anchorman: The Legend of Ron Burgundy

It all started with me trying to clean up my hard drive, remove some movie files taking up precious space. Then I started watching Anchorman: The Legend of Ron Burgundy. I wrote down one quote that I thought was cool (the one about "I have many leather bound books..") . Then another. And another. After about two hours I decided I'd better just post what I have, then do another post later. I wonder if there's already a Ron Burgundy quotes app on Facebook? The world needs one!

Yes, I realise this has probably all been done before, and I this is all wasted effort and I should've Googled it first... but what can I say? I felt the urge! It was a labour of love. :P

"I know what you're asking yourself - and the answer is yes, I have a nickname for my penis. It's called The Octagon. But I also nicknamed my testes. My left one is James Westfall, and my right one is Dr Kenneth Noisewater. You ladies play your cards right you might just get to meet the whole gang."

"People seem to like me because I am polite and rarely late. I like to eat ice cream and enjoy a nice pair of slacks. "

"We've been coming to the same party for twelve years now, and in no way is that depressing."

"I don't usually do this, but I felt compelled to tell you something. You have ... an absolutely ... breathtaking ... heinie. I mean, that thing is good. I wanna be friends with it."

"I'm very important. I have many leather-bound books and my apartment smells of rich mahogany."

"(to Baxter the dog)You're so wise. Like a miniature Buddha, covered in hair."

"(to Baxter the dog) You know I don't speak Spanish. In English, please."

"(to Baxter the dog) You pooped in the refrigerator - and you ate a whole wheel of cheese? How'd you do that?"

"Well, I could be wrong, but I believe Diversity is an old, old wooden ship that was used during the Civil war era."

"It is anchor-MAN, not anchor-LADY, and that is a scientific fact!"

"It's terrible! She has beautiful eyes and her hair smells like cinnamon!"

"I read somewhere that their periods attract bears. The bears can smell the menstruation."

"Hey! Where did you get those clothes? At the... toilet store?"

"I will smash your face into a car windshield, and then take your mother Dorothy Mantooth out for a nice seafood dinner, and never call her again!"

"You know those ratings systems are flawed. They don't take into account houses that have more than two television sets."

"Can't say one word? Even the guy who can't think says something, and you guys just stand there?"

"But I think my son is just going through a phase. I have no idea where he would've gotten hold of German pornography."

"But you and I are mature adults who've both seen our share of pornographic materials - oh, you never have? Of course you haven't, how stupid of me, neither have I. I was just speaking in generalities.... I'll stop by the school later Sister Margaret."

"What do you say we go out on a date? Have some chicken, maybe some sex. You know, see what happens."

"It's called Sex Panther, by Odeon. It's illegal in nine countries. Yep, it's made of bits of real panther. So you know it's good."

"They've done studies, you know. Sixty percent of the time it works every time."

"Its smells like a used diaper filled with indian food!

What is that? Smells like a turd covered in burnt hair!

Smells like Bigfoot's dick!"

"I would like to extend to you an invitation to the pants party....

The party.. with the pants....

Party with pants..."

"The only way to bag a classy lady is give her two tickets to the guns show... (kisses 'guns').. and see if she likes the goods"

"But now I am too hurt.. and shocked.. and offended.. and... hurt!"

"Veronica: Mr Burgundy, you have a massive erection.

Ron: Yes... I do... I'm sorry... it's... the pleats. Essentially an optical illusion... the pattern on the pants it's not flattering in the... the crotchular region. I'm actually taking them back right now."

"This is a mistake, he's very cute... No he's not, he's not, he's hairy."

"San Diego - drink it in, it always goes down smooth. It's a fact, it's the greatest city in the history of mankind. Discovered by the Germans in 1904, they named it San Diago, which, of course, in German means 'a whale's vagina.'"

"Ron: I don't know what it means. I'll be honest, I don't think anyone knows what it means. Scholars maintain that the translation was lost hundreds of years ago.

Veronica: Doesn't it mean Saint Diego?

Ron: No."

"We have a saying in my country about people like him - 'The coyote of the desert always likes to eat the heart of the young, when the blood drips down to the children for breakfast, lunch and dinner, and only the ribs will be broken in two.'"

"Well, I have one great passion that lives deep within my loins like a flaming, golden hawk."

"Wait.. what if just for tonight we weren't co-workers - we were just co-people.

You be a woman. I'll be a man. That's all."

"Veronica and I are trying this new fad called jogging. I believe its 'jogging' or 'yogging', it might be a soft 'J', I'm not sure. But apparently you just run for an extended period of time."

"I know that one day Veronica and I are gonna get married on top of a mountain. And there's gonna be flutes playing, and trombones and flowers and garlands of fresh herbs. And we will dance til the sun rises, and then our children will form a family band. And we will tour the countryside and you won't be invited!"

"It seems our youngest, Chris, was on something called 'acid', and was firing a bow and arrow into a crowd. You know how kids are."

"This city needs its news, and you're gonna deprive them of that because I have breasts? Exquisite breasts?"

"I'm in a glass case of emotion!"

"Why are you being this way? Why can't you just be proud of me as a peer and as my gentleman lover?"

"Veronica: You have man boobs.

Ron: You've got a dirty whorish mouth. I'm gonna punch you in the ovary, that's what I'm gonna do.

Veronica: Jazz flautist for little fairy boys.

Ron: Okay, you know what - that's uncalled for! I can't work with this woman."

"Ron: There's only one thing a man can do when he's suffering from a spiritual and existential funk.

Champ: Go to the zoo? Flip off the monkeys?

Ron: No. Buy new suits.

All: YAAY!!!"

More to come once I get the urge to surge. No, I don't know what that meant.

Let's end this post on a high note. I wanna talk about love.

"Brick: I love... carpet. I love... desk.

Ron: Brick, are you just looking at things in the office and saying that you love them?

Brick: I love lamp.

Ron: Do you really love the lamp or are you just saying it because you saw it?

Brick: I love lamp. I love lamp."

You stay classy, Information Superhighway.

Thanks for stopping by.

Saturday, 19 July 2008

Video interview with Adrian Utley of Portishead at sonicstate.com

Okay, so I really found this via good ole musicthing, but the more links to the interview the better! Still haven't decided whether I like Portishead's "Third" enough to get the CD.

Part 1:



Amazingly, his daughter actually sits still for this entire interview. I wonder if she's developed an affinity for modular synths by now. Bonus points for a really gritty sounding version of "I'm a little teapot". :P


Part 2:



More gear - mixing desks, drums

Part 3:



Mikes galore! And the el cheapo guitar used on "The Rip".

Monday, 26 May 2008

Java code to concatenate values from get__ methods of a class dynamically

Ended up discarding this code from a project, but this was a good
exercise to learn a little about Java reflection methods.

This was based on code from HashCodeBuilder in Apache commons-lang,
which can generate hashcodes via reflection - ie,
HashCodeBuilder.reflectionHashCode(this);


/**
* Given an object of type clazz, go through the fields in that
class and concatenate the
* values of all the fields, excluding the ones listed in excludedFields.
* This will only work on bean-type getter methods that 1. do not
have parameters
* and 2. return a String.
* This code does not do any lookup on inherited methods.
* @param object instance where we are getting field values from.
* @param clazz the Class of the object.
* @param builder StringBuilder object to contain our concatenated values.
* @param excludeMethods fields that are not to be included in our builder.
* @throws InvocationTargetException when an error occurs while
calling a method in our object.
*/
public static void concatenateFieldValues(Object object, Class
clazz, StringBuilder builder,
String[]
excludeMethods) throws InvocationTargetException
{

List excludedMethodList = excludeMethods != null ?
Arrays.asList(excludeMethods) : Collections.EMPTY_LIST;

Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods)
{
// only get values from public getter methods that are not
in exclusion list
if ((method.getName().indexOf("get") == 0)
&& !excludedMethodList.contains(method.getName())
&& (Modifier.isPublic(method.getModifiers()))
) {
try {

// this will only deal with bean-type get methods
without params
assert method.getParameterTypes().length == 0;

// TODO - shouldnt we explicitly check and throw
an exception here?
Object fieldValue = method.invoke(object);

if (fieldValue instanceof String) {

builder.append(StringUtils.remove(fieldValue.toString(), ' '));
}
} catch (InvocationTargetException e)
{
throw new InvocationTargetException(e, "Unable to
invoke the method: " + method.getName() +
" from
instance of: " + clazz.getName());
} catch (IllegalAccessException e) {
// this can't happen. Would get a Security exception instead
// throw a runtime exception in case the impossible happens.
throw new InternalError("Unexpected
IllegalAccessException");
}
}
}

}

Friday, 23 May 2008

Java generics - assigning a List<C> where type D implements interface D to a variable of List<D> - can't be done - AKA:Type Erasure ARRGH!

Java generics still confuse me.

A work colleague was asking me something about assigning typed lists
and it wasn't working the way
it would work if you were simply dealing with single variables.

Class C implements interface D.

Then we have a list of interface D.

Another class E has a method findAll() which returns a list of type C.

But we can't assign E.findAll() to a list of type D.


List<Comparable> listOne;

listOne.add("String");
listOne.add(new Long(1000));

BUT

listTwo = new ArrayList<Long>();

listTwo.add(new Long(33));

listOne = listTwo;

Error: "Incompatible types, Required List<java.lang.Comparable> Found:
List<java.util.List>"


Hmm... maybe we can cast the list?

listOne = (List<Comparable>) listTwo;

Error: Inconvertible types; cannot cast
'java.util.List<java.lang.Long>' to
'java.util.List<java.lang.Comparable>'

But why?

Maven IDEA plugin generating incorrect references in .ipr file in multi-module project

Is there a bug in the maven IDEA plugin when working with multi-module files?
I normally do most of my command-line work in the Cygwin environment, and
have not experienced this problem on my previous project, which was a
single-module project.


ERROR in parent project file:

- generated this when running mvn idea:idea under cygwin
- trying to open the project file results in error dialog box:
"Cannot load module file
'C:\work\Fads\C:\work\Fads\FeedProcessor\FeedProcessor.iml':
File C:\work\Fads\C:\work\Fads\FeedProcessor\FeedProcessor.iml does not exist.
Would you like to remove the module from the project?"

<modules>
<module fileurl="file://$PROJECT_DIR$/C:/work/FeedsProject/packaging/FeedsProject.iml"
filepath="$PROJECT_DIR$/C:/work/FeedsProject/packaging/FeedsProject.iml"
/>
<module fileurl="file://$PROJECT_DIR$/FadsParent.iml"
filepath="$PROJECT_DIR$/FadsParent.iml" />
<module fileurl="file://$PROJECT_DIR$/C:/work/FeedsProject/FeedProcessor/FeedProcessor.iml"
filepath="$PROJECT_DIR$/C:/work/FeedsProject/FeedProcessor/FeedProcessor.iml"
/>
<module fileurl="file://$PROJECT_DIR$/C:/work/FeedsProject/FileService/FileService.iml"
filepath="$PROJECT_DIR$/C:/work/FeedsProject/FileService/FileService.iml"
/>
</modules>

- the fix is to generate the IDEA project file under DOS - mvn idea:idea
- this file is correct.

<modules>
<module fileurl="file://$PROJECT_DIR$/packaging/FeedsProject.iml"
filepath="$PROJECT_DIR$/packaging/FeedsProject.iml" />
<module fileurl="file://$PROJECT_DIR$/FadsParent.iml"
filepath="$PROJECT_DIR$/FadsParent.iml" />
<module fileurl="file://$PROJECT_DIR$/FeedProcessor/FeedProcessor.iml"
filepath="$PROJECT_DIR$/FeedProcessor/FeedProcessor.iml" />
<module fileurl="file://$PROJECT_DIR$/FileService/FileService.iml"
filepath="$PROJECT_DIR$/FileService/FileService.iml" />
</modules>

Saturday, 3 May 2008

OutOfMemory error when using Findbugs plugin in Maven? Set the Maven heap size via MAVEN_OPTS

I was doing a "mvn site" and I got an OutOfMemory error at the stage
where it's using the Findbugs plugin:

[INFO] Generating "FindBugs Report" report.
[INFO] No effort provided, using default effort.
[INFO] Using FindBugs Version: 1.2.0
[INFO] No threshold provided, using default threshold.
[INFO] Debugging is Off
[INFO] No bug include filter.
[INFO] ------------------------------------------------------------------------
[ERROR] FATAL ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Java heap space
[INFO] ------------------------------------------------------------------------
[INFO] Trace
java.lang.OutOfMemoryError: Java heap space
at edu.umd.cs.findbugs.ba.vna.ValueNumberFrame.getUpdateableAvailableLoadMap(ValueNumberFrame.java:409)
at edu.umd.cs.findbugs.ba.vna.ValueNumberFrame.copyFrom(ValueNumberFrame.java:285)
at edu.umd.cs.findbugs.ba.FrameDataflowAnalysis.copy(FrameDataflowAnalysis.java:38)
at edu.umd.cs.findbugs.ba.vna.ValueNumberAnalysis.trans

After a bit of research, I set this variable to give enough memory to
Maven, and it fixed the problem. Obviously, change the Xmx value
depending on how much RAM you have to spare.

MAVEN_OPTS="-Xmx1024m -Xms128m -XX:MaxPermSize=512m"

Other posts have mentioned that it's actually setting a MaxPermSize
higher than the default value (32m) that makes the difference. So
let's test it by just setting the first two values:

MAVEN_OPTS="-Xmx1024m -Xms128m"

Actually, it works!

INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1 minute 11 seconds


Other people have recommended setting the plugin property
"maven.findbugs.jvmargs" but I have not tried this out yet. Now in my
pom.xml, I currently have:

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>1.1.1</version>
</plugin>

Which isn't actually the latest version anymore. Maybe the newest
version of the plugin - 1.2 has fixed it.. Let's change it to:

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>1.2</version>
</plugin>

But this time, let's NOT have anything in MAVEN_OPTS. Let's see if the
newer version can do it with the default java settings. Now run mvn
site again.

(Long delay follows). Oh great, more jars to download. WTF? castor?
openejb? xstream? Hardly a build goes by where I don't get yet another
surprise download due to transitive dependencies. Am glad we have
Artifactory set up at work, so only one person has to suffer the
delays of downloading each new jar file.

No dice. OutOfMemoryError again. Let's set our heap to a smaller
figure, compared to before, see if that's enough.

MAVEN_OPTS="-Xmx256m -Xms128m"

Works!

I think this last one can be a safe starting value to use if you ever
run into the OutOfMemory error Findbugs from inside maven. I was
surprised to find out that the default heap is only 32m when JVM is in
client mode, and 64m when in server mode. See here:
http://www.unixville.com/~moazam/stories/2004/05/17/maxpermsizeAndHowItRelatesToTheOverallHeap.html

Sunday, 20 April 2008

The Element Song: various versions

Got home at 2.30, after watching DJ Shadow + Cut Chemist at Luna Park
in the city... (http://au.youtube.com/results?search_query=dj+shadow+the+hard+sell) then checked my email... noticed a link about Tom Lehrer, who's famous for the Element Song, a crazy romp through the periodic table, sung to the tune of Gilbert and Sullivan's, "I Am the Very Model of a Modern Major-General" from Pirates of Penzance (thanks to Bob Funchess for the song title)

end result: just spent 30 minutes going through youtube, checking out
various versions of The Element Song.

Damn you Google blog!

http://googleblog.blogspot.com/2008/04/heres-to-tom-lehrer-elemental-geek.html

(and he also did that song about "silent e" for Electric Company! OMG.)

my faves so far:

the original (audio only):



http://au.youtube.com/watch?v=WNfx0FO4hzs&NR=1



great version at a talent show:



http://au.youtube.com/watch?v=9cbgAELAX18&feature=related

sung by a 4-yr old (who kinda sounds like Martin Price from the Simpsons):



http://au.youtube.com/watch?v=QWkVO6Bp8VM&feature=related




showing the elements' location in the table:



http://au.youtube.com/watch?v=WNfx0FO4hzs&NR=1




this isn't a version.. but still interesting rapping with *some* of
those elements..




http://au.youtube.com/watch?v=pmTXtbRR7c0&feature=related