<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><description /><title>AsciiArmor</title><generator>Tumblr (3.0; @asciiarmor)</generator><link>http://www.asciiarmor.com/</link><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/Asciiarmor" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item><title>Lessons Learned from the GitHub Recommender Contest</title><description>I spent a few evenings last week working on a contest that &lt;a href="http://contest.github.com"&gt;GitHub&lt;/a&gt; is running to create a recommender engine for their site. Think &lt;a href="http://www.netflixprize.com/"&gt;Netflix Prize&lt;/a&gt; but much smaller scale. Their description:

&lt;blockquote&gt;
The 2009 GitHub contest is a simple recommendation engine contest. We have released a dataset of our watched repositories data and want to provide a list of recommended repositories for each of our users. Removed from the sample dataset are 4,788 watches - write an open source program to guess the highest percentage of those removed watches and you win our prize.
&lt;/blockquote&gt;


My objective wasn’t to place first, but to understand the problem more deeply. I distilled down a few observations and presented them at &lt;a href="http://www.barcamp.org/BarCampRDU"&gt;BarCampRDU&lt;/a&gt; on Saturday. The discussion was lively and the feedback was positive:
&lt;p&gt;&lt;/p&gt;

&lt;img src="http://files.asciiarmor.com/twitter_recommender.png"/&gt;&lt;br/&gt;
&lt;p&gt;&lt;/p&gt;
A few people asked for my notes, so here they are…

&lt;h3&gt;Lesson 1: Simple is Best&lt;/h3&gt;
&lt;img src="http://files.asciiarmor.com/step1.png"/&gt;&lt;br/&gt;&lt;p&gt;&lt;/p&gt; 
 
I started off my preparation for the contest by reading a few papers on recommender systems that seemed relevant. Armed with this info, I formulated an approach based on co-occurrence of repositories: Create a matrix of repositories and calculate the number of times a pair of repositories is followed by the same user. Then to generate a recommendation, walk through a users follows accumulating the most frequently co-occuring repositories that he was not following already. Merge the results together for each repository a user follows, based on highest co-occurrence to provide the top 10 list. This took a while to get working right and execution was very, very slow.
&lt;p&gt;&lt;/p&gt;
&lt;span&gt;&lt;a href="http://www2008.org/papers/pdf/p327-sigurbjornssonA.pdf"&gt;&lt;img src="http://files.asciiarmor.com/flickr_paper.png"/&gt;&lt;/a&gt; 
&lt;a href="http://www.pui.ch/phred/automated_tag_clustering/automated_tag_clustering.pdf"&gt;&lt;img src="http://files.asciiarmor.com/flickr_tag_cluster.png"/&gt;&lt;/a&gt;&lt;/span&gt;&lt;br/&gt;
&lt;p&gt;&lt;/p&gt;
It turns out this method wasn’t very effective. I was let down when my first score was just over 900 ( the top score at the time was over 2000). I then decided to take a closer look at both the data and at what everyone else was doing. Not all teams have their source checked in; this is particularly true of the top ranking teams. After some simple analysis on the data, I could see a clear problem: the data is sparse. As the plot below illustrates, most people follow a couple repositories and most repositories have just one or two followers.

&lt;img src="http://files.asciiarmor.com/repos.png"/&gt;&lt;br/&gt;&lt;small&gt;&lt;a href="http://files.asciiarmor.com/repos.sh"&gt;R Code for above chart&lt;/a&gt;&lt;/small&gt;
&lt;p&gt;&lt;/p&gt;
I also noticed that some submissions using very simple techniques ranked more than twice as high as my submission. One of the most effective methods was simply to walk up the repository fork history and add everything encountered. Another technique made use of the fact that repository owner can be derived from the repository name. If a user follows a single repository, all other repositories sharing the same owner are added. I altered my approach; using these simpler techniques.

&lt;p&gt;&lt;/p&gt;
&lt;img src="http://files.asciiarmor.com/scores.png"/&gt;&lt;br/&gt;&lt;small&gt;&lt;a href="http://files.asciiarmor.com/scores.sh"&gt;R Code for above chart&lt;/a&gt;&lt;/small&gt;

&lt;p&gt;&lt;/p&gt;
My entry, including code, can be found &lt;a href="http://contest.github.com/p/asciiarmor/gh_contest"&gt;here&lt;/a&gt;.

&lt;h3&gt;Lesson 2: Collaborate&lt;/h3&gt;

&lt;img src="http://files.asciiarmor.com/step2.2.png"/&gt;&lt;br/&gt;&lt;img src="http://files.asciiarmor.com/step2.1.png"/&gt;&lt;br/&gt;&lt;p&gt;&lt;/p&gt; 

Participants are collaborating both implicitly, through checked in code, and explicitly. The most clear example of this can be seen in &lt;a href="http://twitter.com/chebuctonian"&gt;@chebuctonian&lt;/a&gt; and &lt;a href="http://twitter.com/xlvector"&gt;@xlvector&lt;/a&gt; who are working closely together.
&lt;p&gt;&lt;/p&gt;
&lt;a href="http://www.nytimes.com/2009/07/28/technology/internet/28netflix.html?_r=1&amp;partner=rss&amp;emc=rss"&gt;This article&lt;/a&gt; in the NYTimes suggests that the lesson of collaboration was perhaps the most important that was learned in the Netflix Prize.

&lt;blockquote&gt;
The biggest lesson learned, according to members of the two top teams, was the power of collaboration. It was not a single insight, algorithm or concept that allowed both teams to surpass the goal Netflix, the movie rental company, set nearly three years ago: to improve the movie recommendations made by its internal software by at least 10 percent, as measured by predicted versus actual one-through-five-star ratings by customers.
&lt;/blockquote&gt;
  
&lt;h3&gt;Lesson 3: Have a method&lt;/h3&gt;

&lt;img src="http://files.asciiarmor.com/step3.png"/&gt;&lt;p&gt;&lt;/p&gt;
GitHub has done a nice job creating an automated scoring mechanism. As soon as results are committed via git, they are automatically scored and posted on the leaderboard. Top placing teams have created mechanisms to do similar tests offline without the commit phase, thus speeding up the testing of hypotheses. This allows for many ideas to be formulated and then systematically checked and ranked against previous findings. 


&lt;hr&gt;
&lt;p&gt;&lt;/p&gt;
A related point that we discussed at BarCampRDU was the efficacy of off-the shelf recommender systems. &lt;a href="http://www.directededge.com/"&gt;Directed Edge&lt;/a&gt;, for example, recently received funding. 

&lt;a href="http://www.directededge.com/"&gt;&lt;img src="http://files.asciiarmor.com/directed_edge.png"/&gt;&lt;/a&gt;&lt;br/&gt;
Directed Edge provides an API that can be called over HTTP to provide recommendations. However, a general-pupose system like this allows for no domain-specific parameters to be included in the analysis. In the case of the GitHub contest, there is no way to factor in fork-history or repository owners. These were far and away the most effective parametrs to include in the recommendation. I applied for a develpoper key to their web-service. If I get a key, I will run the GitHub dataset and see how it ranks. 
&lt;p&gt;&lt;/p&gt;

If I find time before the end of the month to revise my entry, I would like to refactor my code a more formalized &lt;a href="http://en.wikipedia.org/wiki/K-nearest_neighbor_algorithm"&gt;KNN&lt;/a&gt; approach where each parameter has a boost co-efficient. Then I would let the computer walk through various boost co-efficients using &lt;a href="http://en.wikipedia.org/wiki/Simulated_annealing"&gt;simulated annealing&lt;/a&gt;. I realize this goes counter to lesson #1, but it seems like the simplest competitive approach given what I know now. It also has the benefit of letting the computer do the work for you.
&lt;p&gt;&lt;/p&gt;
Once completed at the end of the month, it will be interesting to see both the methods used by different teams as well as how the code is put into use by GitHub.
&lt;br/&gt;
&lt;p&gt;&lt;/p&gt;
&lt;small&gt;Minifig photo credits: &lt;a href="http://www.flickr.com/photos/kwl/"&gt;kennymatic&lt;/a&gt; and &lt;a href="http://www.flickr.com/photos/m0php/"&gt;Craig Rodway&lt;/a&gt;&lt;/small&gt;&lt;img src="http://feeds.feedburner.com/~r/Asciiarmor/~4/F_ZZNSgx0s8" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Asciiarmor/~3/F_ZZNSgx0s8/163265720</link><guid isPermaLink="false">http://www.asciiarmor.com/post/163265720</guid><pubDate>Fri, 14 Aug 2009 23:42:00 -0400</pubDate><category>python</category><category>recommender</category><category>github</category><category>r</category><category>barcamprdu</category><feedburner:origLink>http://www.asciiarmor.com/post/163265720</feedburner:origLink></item><item><title>Excellent new book in the making: Computational Modeling and Complexity Science</title><description>&lt;center&gt;
&lt;a href="http://www.greenteapress.com/compmod/"&gt;&lt;img src="http://files.asciiarmor.com/cmcs.png"/&gt;&lt;/a&gt;  
&lt;a href="http://oreilly.com/catalog/9780596529321/"&gt;&lt;img src="http://files.asciiarmor.com/pci.gif"/&gt;&lt;/a&gt;
&lt;/center&gt;

Recently, in a &lt;a href="http://blog.kiwitobes.com/?p=59"&gt;post&lt;/a&gt; about his terrific, &lt;a href="http://oreilly.com/catalog/9780596529321/"&gt;Programming Collective Intelligence&lt;/a&gt;, &lt;a href="http://blog.kiwitobes.com/"&gt;Toby Segaran&lt;/a&gt; calls out the “excluded middle” of technical books. His goal with with PCI was to cover that middle ground - “showing concepts, implementation and applications all at once”. Its a truly great book that will stand the test of time. 

&lt;p&gt;&lt;/p&gt;
I’ve recently stumbled across another title that belongs in this middle ground: &lt;a href="http://www.greenteapress.com/compmod/"&gt;Computational Modeling and Complexity Science&lt;/a&gt; by &lt;a href="http://allendowney.com/"&gt;Allen B. Downey&lt;/a&gt;. He’s also the author &lt;a href="http://www.greenteapress.com/semaphores"&gt;The Little Book of Semaphores&lt;/a&gt;, &lt;a href="http://www.greenteapress.com/thinkpython/"&gt;Think Python: An Introduction to Software Design&lt;/a&gt;, &lt;a href="http://www.greenteapress.com/perl"&gt;Learning Perl the Hard Way&lt;/a&gt; and a few other titles; all self published and released under the GPL.

&lt;p&gt;&lt;/p&gt;
According to Downey, CMCS, is about “algorithms, intermediate Python programming and complexity science”. 

&lt;p&gt;&lt;/p&gt;
The book has a lot in common with PCI. Both:
	&lt;ul&gt;
&lt;li&gt;Use Python as a basis for all examples&lt;/li&gt;
	&lt;li&gt;Span academia and pragmatism with working examples&lt;/li&gt;
	&lt;li&gt;Maintain an easy to read narrative&lt;/li&gt;
	&lt;li&gt;Are just the right length ( so far! )&lt;/li&gt;
	&lt;/ul&gt;
CMCS gives just enough theory to provide context. The readability of the text is helped out with anecdotes from the lives of the referenced mathematicians. CMCS takes on analysis of social networks, queuing theory, stochastic modeling, cellular automata and a bunch of other great subjects.  
&lt;p&gt;&lt;/p&gt;

In &lt;a href="http://www.greenteapress.com/compmod/html/book008.html"&gt;Chapter 7, Self-organized Criticality&lt;/a&gt;, there is some coverage of modeling forest fires:
&lt;p&gt;&lt;/p&gt;

&lt;i&gt;
In 1992 Drossel and Schwabl proposed a cellular automaton that is an abstract model of a forest fire. Each cell is in one of three states: empty, occupied by a tree, or on fire.
&lt;p&gt;&lt;/p&gt;
The rules of the CA are:

&lt;ol&gt;
&lt;li&gt;An empty cell becomes occupied with probability p.&lt;/li&gt;
   &lt;li&gt;A cell with a tree will burn if any of its neighbors is on fire.&lt;/li&gt;
   &lt;li&gt;A cell with a tree will spontaneously burn, with probability f, even if none of its neighbors is on fire.&lt;/li&gt;
   &lt;li&gt;A cell with a burning tree becomes an empty cell in the next time step.&lt;/li&gt;
&lt;ol&gt;&lt;/ol&gt;
&lt;/ol&gt;&lt;/i&gt;
&lt;p&gt;&lt;/p&gt;

I couldn’t help pulling out &lt;a href="http://www.pythonware.com/products/pil/"&gt;PIL&lt;/a&gt; and gluing some Python together to try this out. Here’s what I came up with (converted to flash to keep filesize down):
&lt;center&gt;
&lt;object width="384" height="384"&gt;
&lt;param name="movie" value="http://files.asciiarmor.com/fire.swf"&gt;
&lt;embed src="http://files.asciiarmor.com/fire.swf" width="384" height="384"&gt;&lt;/embed&gt;&lt;/object&gt;
&lt;p&gt;&lt;/p&gt;
&lt;a href="http://files.asciiarmor.com/ffsim.py"&gt;source&lt;/a&gt; &lt;br/&gt;
&lt;/center&gt;

&lt;p&gt;&lt;/p&gt;
Much of the book us still under construction and none of the referenced source URLs I tried were functional. That said, one suggestion I do have is to make more use of existing Python libraries. As an a example, the chapter on graphs includes the implementation of basic graph datastructures. This is understandable since this will no doubt be used in undergraduate classrooms, but there should at least be a pointer to &lt;a href="https://networkx.lanl.gov/wiki"&gt;NetworkX&lt;/a&gt;; a battle-tested warhorse that the reader should be aware of.

&lt;p&gt;&lt;/p&gt;
It’s a great read so far and I’m looking forward to seeing how the book evolves.&lt;img src="http://feeds.feedburner.com/~r/Asciiarmor/~4/zIRT48YlVOE" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Asciiarmor/~3/zIRT48YlVOE/47131658</link><guid isPermaLink="false">http://www.asciiarmor.com/post/47131658</guid><pubDate>Sat, 23 Aug 2008 18:12:00 -0400</pubDate><category>publishing</category><category>python</category><category>java</category><feedburner:origLink>http://www.asciiarmor.com/post/47131658</feedburner:origLink></item><item><title>Beneath the Bare Metal: Using dynamic profiling tools like DTrace and VProbes</title><description>&lt;p&gt;&lt;img src="http://files.asciiarmor.com/barcamp2008.png"/&gt;&lt;br/&gt;&lt;br/&gt;
Just back from &lt;a href="http://barcamp.org/BarCampRDU"&gt;BarCampRDU&lt;/a&gt;. Lots of great sessions. I especially enjoyed &lt;a href="http://lucene.grantingersoll.com/"&gt;Grant Ingersoll’s&lt;/a&gt; presentations on &lt;a href="http://lucene.apache.org/mahout/"&gt;Mahout&lt;/a&gt; and &lt;a href="http://lucene.apache.org/solr/"&gt;Solr&lt;/a&gt;.
&lt;br/&gt;&lt;br/&gt;
I did a talk on use of dynamic tracing tools such as &lt;a href="http://x86vmm.blogspot.com/2007/09/presenting-vprobes.html"&gt;VProbes&lt;/a&gt; and &lt;a href="http://www.sun.com/bigadmin/content/dtrace/"&gt;DTrace&lt;/a&gt;.

FWIW: Here are some links I referenced in the talk.
&lt;br/&gt;&lt;br/&gt;&lt;h2&gt;DTrace&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.opensolaris.org/os/community/dtrace/dtracetoolkit/"&gt;DTrace Toolkit&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/6chLw2aodYQ&amp;hl=en&amp;fs=1"&gt;
&lt;param name="allowFullScreen" value="true"&gt;
&lt;embed src="http://www.youtube.com/v/6chLw2aodYQ&amp;hl=en&amp;fs=1" type="application/x-shockwave-flash" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;
&lt;br/&gt;&lt;br/&gt;&lt;h2&gt;VProbes&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://sourceforge.net/projects/vprobe-toolkit"&gt;VProbe Toolkit&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;embed src="http://blip.tv/play/Abq2dQA" type="application/x-shockwave-flash" width="640" height="510" allowscriptaccess="always" allowfullscreen="true"&gt;&lt;/embed&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Asciiarmor/~4/v6GX-mYoq-M" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Asciiarmor/~3/v6GX-mYoq-M/44487689</link><guid isPermaLink="false">http://www.asciiarmor.com/post/44487689</guid><pubDate>Sat, 02 Aug 2008 18:04:00 -0400</pubDate><category>barcamprdu</category><category>python</category><category>java</category><category>ruby</category><category>dtrace</category><category>vprobes</category><feedburner:origLink>http://www.asciiarmor.com/post/44487689</feedburner:origLink></item><item><title>Greg Kroah Hartman did a techtalk at Google recently. Some...</title><description>&lt;object width="400" height="336"&gt;&lt;param name="movie" value="http://www.youtube.com/v/L2SED6sewRw&amp;rel=0&amp;egm=0&amp;showinfo=0&amp;fs=1"&gt;&lt;/param&gt;&lt;param name="wmode" value="transparent"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/L2SED6sewRw&amp;rel=0&amp;egm=0&amp;showinfo=0&amp;fs=1" type="application/x-shockwave-flash" width="400" height="336" allowFullScreen="true" wmode="transparent"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;&lt;a href="http://www.kroah.com/linux/"&gt;Greg Kroah Hartman&lt;/a&gt; did a techtalk at Google recently. Some interesting stats related to the Linux 2.6.25 kernel development effort: 

&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;2399 contributers over last 1.5 years&lt;/li&gt;
&lt;li&gt;1/2 of these have done one patch, 1/4 did 2
&lt;/li&gt;
&lt;li&gt;9.2M Lines of Code&lt;/li&gt;
&lt;li&gt;10% year over year lines of code growth&lt;/li&gt;
&lt;li&gt;~55% of code in drivers - majority by a small bit, but not all drivers. &lt;/li&gt;
&lt;li&gt;Change rate of kernel code to driver code is proportional. &lt;i&gt;Translation: the core of OS is changing at a crazy rate.&lt;/i&gt;
&lt;/li&gt;
&lt;li&gt;New releases every 2.75 months or so&lt;/li&gt;
&lt;li&gt;9000 symbols and 12000 data structures inside the kernel (below the syscall layer)&lt;/li&gt;
&lt;li&gt;Rate of change is insane&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;4300 lines added&lt;/li&gt;
&lt;li&gt;1800 lines removed&lt;/li&gt;
&lt;li&gt;1500 lines modified&lt;/li&gt;
&lt;li&gt;&lt;h3&gt;PER DAY!!!&lt;/h3&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/Asciiarmor/~4/DXeyhXnAkJ8" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Asciiarmor/~3/DXeyhXnAkJ8/38021090</link><guid isPermaLink="false">http://www.asciiarmor.com/post/38021090</guid><pubDate>Wed, 11 Jun 2008 12:18:00 -0400</pubDate><feedburner:origLink>http://www.asciiarmor.com/post/38021090</feedburner:origLink></item><item><title>Pythonic API for Tumblr's web API checked in</title><description>&lt;p&gt;When my Wordpress blog got hacked, I decided it was time to port over to &lt;a href="http://www.tumblr.com"&gt;Tumblr&lt;/a&gt; and let them deal with hosting, patching, etc…  I put together a python script to import my exiting content via RSS. My original script grew into &lt;a href="http://code.google.com/p/python-tumblr/"&gt;python-tumblr&lt;/a&gt;.

Several samples are checked into SVN including one that uses Google Charts to visualize post type frequency.
&lt;br/&gt;&lt;/p&gt;
&lt;center&gt;&lt;a href="http://staff.tumblr.com"&gt;&lt;img src="http://files.asciiarmor.com/staff.png"/&gt;&lt;/a&gt;&lt;/center&gt;

&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;i&gt;Comments, feedback, patches welcome…&lt;/i&gt;&lt;img src="http://feeds.feedburner.com/~r/Asciiarmor/~4/vrQGIVt5s2I" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Asciiarmor/~3/vrQGIVt5s2I/37643776</link><guid isPermaLink="false">http://www.asciiarmor.com/post/37643776</guid><pubDate>Sun, 08 Jun 2008 15:55:00 -0400</pubDate><category>python</category><feedburner:origLink>http://www.asciiarmor.com/post/37643776</feedburner:origLink></item><item><title>Google Charts Gets Invader'd</title><description>&lt;p&gt;Playing with &lt;a href="http://code.google.com/apis/chart/"&gt;Google Chart API&lt;/a&gt; and &lt;a href="http://pygooglechart.slowchop.com/"&gt;PyGoogleChart&lt;/a&gt; this afternoon after reading the &lt;a href="http://google-code-updates.blogspot.com/2007/12/embed-charts-in-webpages-with-one-of.html"&gt;announcement&lt;/a&gt; last week.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;center&gt;&lt;img alt="Invader Chart" src="http://files.asciiarmor.com/chart.png"/&gt;&lt;/center&gt;
&lt;p&gt;A couple things to think about when using the API:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;b&gt;You will want to use a wrapper&lt;/b&gt; - Take one look at the &lt;a href="http://chart.apis.google.com/chart?cht=s&amp;chs=270x270&amp;chd=t:15.0,20.0,30.0,40.0,50.0,55.0,20.0,25.0,30.0,35.0,40.0,45.0,50.0,25.0,35.0,45.0,25.0,30.0,35.0,40.0,45.0,30.0,40.0,20.0,25.0,35.0,35.0,35.0,45.0,50.0%7C10.0,10.0,10.0,10.0,10.0,10.0,15.0,15.0,15.0,15.0,15.0,15.0,15.0,20.0,20.0,20.0,25.0,25.0,25.0,25.0,25.0,30.0,30.0,50.0,45.0,50.0,55.0,60.0,45.0,50.0%7C100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0&amp;chf=c,lg,90,aaaaaa,1,eeeeee,0&amp;chxt=y,x&amp;chxr=0,0,90%7C1,0,90&amp;chm=s,000000,0,1,10"&gt;link&lt;/a&gt; that generated the above graphic, and you’ll quickly see that this is not meant for humans. Maybe write your own wrapper around the bits that you are using. Maybe use one like &lt;a href="http://pygooglechart.slowchop.com/"&gt;PyGoogleChart&lt;/a&gt;.
&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;It’s not just for web apps&lt;/b&gt; - Charts can be cached for later use using curl or equivilent. NB: IANAL so review the &lt;a href="http://code.google.com/apis/chart/terms.html"&gt;Terms of Service&lt;/a&gt; and usage policy and make your own decision.
&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;You will have to normalize your data&lt;/b&gt; - The chart api docs talk quite a bit about reducing number of elements in your datasets. Another important thing to think about is the range. For instance if I wanted to chart the last few days closing values for the CAC 40 Index which varies from 5,547.21 to 5,750.92. I would have to first normalize the values to something under 4096 for Extended Encoding, under 100 for Text encoding and less than 62 for Simple Encoding. Then the y-axis labels would have to be adjusted to reflect the normalization. &lt;a href="http://chart.apis.google.com/chart?cht=lc&amp;chs=200x125&amp;chd=t:67.05,62.94,54.72,65.90,67.37,71.87,75.09,72.47,74.33,59.09&amp;chxt=y&amp;chxl=0:%7C5000%7C6000"&gt;Example&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It’s pretty clear we’ve only seen the beginning. People outside will find new and unanticipated ways of using the API and Google will continue to crank out new features. &lt;/p&gt;
&lt;p&gt;Inspiration for above:&lt;/p&gt;

&lt;center&gt;&lt;a href="http://www.flickr.com/photos/kateanth/2086676318/in/pool-spaceinvaders/"&gt;&lt;img src="http://farm3.static.flickr.com/2227/2086676318_bae7d16beb_m.jpg"/&gt;&lt;/a&gt;&lt;/center&gt;&lt;img src="http://feeds.feedburner.com/~r/Asciiarmor/~4/hKHI5tFOVyo" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Asciiarmor/~3/hKHI5tFOVyo/33736598</link><guid isPermaLink="false">http://www.asciiarmor.com/post/33736598</guid><pubDate>Sun, 16 Dec 2007 16:38:00 -0500</pubDate><category>python</category><feedburner:origLink>http://www.asciiarmor.com/post/33736598</feedburner:origLink></item><item><title>Luke 1.7 is out</title><description>&lt;center&gt;&lt;a href="http://www.getopt.org/luke/"&gt;&lt;img alt="Luke 1.7" src="http://files.asciiarmor.com/luke17.png"/&gt;&lt;/a&gt;&lt;/center&gt;
&lt;p&gt;After a year or so of shut-eye, &lt;a href="http://www.getopt.org/luke/"&gt;Luke&lt;/a&gt;, the &lt;a href="http://lucene.apache.org/"&gt;Lucene&lt;/a&gt; query tool, is back. New features listed below. Time to dust off some patches I’ve got for an earlier version and send them along for 1.8.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.getopt.org/luke/"&gt;Luke 1.7 features:&lt;br/&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Added pagination of results, especially useful for very large result sets.
&lt;/li&gt;
&lt;li&gt;Added support for new Field flags. They are now displayed in the Document details, and also can be set on edited documents.&lt;/li&gt;
&lt;li&gt;Added a function to add new documents to the index.
&lt;/li&gt;
&lt;li&gt;Low-level index operations (such as detecting unused files, index directory cleanup) use the newly exposed Lucene classes instead of duplicating their internals in Luke.
&lt;/li&gt;
&lt;li&gt;A side-effect of the above is the ability to properly cleanup all supported index formats, including the new lockless and single-norm indexes.
&lt;/li&gt;
&lt;li&gt;Added a function to copy the list of top terms to clipboard.
&lt;/li&gt;
&lt;li&gt;Added a function to copy the term vector to clipboard.
&lt;/li&gt;
&lt;li&gt;Added a function to close and/or re-open the current index.
&lt;/li&gt;
&lt;li&gt;In the Documents tab, pressing “First Term” now positions the term enumeration at the first term for the selected field.
&lt;/li&gt;
&lt;li&gt;Added a field vocabulary analysis plugin by Mark Harwood, with some modifications.
&lt;/li&gt;
&lt;li&gt;Overall UI cleanup - improved layout in some places, added graphics instead of ASCII art, etc.
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;i&gt;Nicely done Andrzej.&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;In other Lucene related news, it looks like some interesting things are brewing in the &lt;a href="http://wiki.apache.org/lucene-hadoop/"&gt;Hadoop&lt;/a&gt; project.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;
Hadoop is a framework for running applications on large clusters built of commodity hardware. The Hadoop framework transparently provides applications both reliability and data motion. Hadoop implements a computational paradigm named  Map/Reduce, where the application is divided into many small fragments of work, each of which may be executed or reexecuted on any node in the cluster. In addition, it provides a distributed file system (HDFS) that stores data on the compute nodes, providing very high aggregate bandwidth across the cluster. Both Map/Reduce and the distributed file system are designed so that node failures are automatically handled by the framework.
&lt;/p&gt;&lt;/blockquote&gt;&lt;img src="http://feeds.feedburner.com/~r/Asciiarmor/~4/FE1H7gmeFj4" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Asciiarmor/~3/FE1H7gmeFj4/33736599</link><guid isPermaLink="false">http://www.asciiarmor.com/post/33736599</guid><pubDate>Sat, 03 Mar 2007 20:18:00 -0500</pubDate><feedburner:origLink>http://www.asciiarmor.com/post/33736599</feedburner:origLink></item><item><title>The Definitive ANTLR Reference</title><description>&lt;center&gt;&lt;img src="http://files.asciiarmor.com/antlrworks.png"/&gt;&lt;/center&gt;
&lt;br/&gt;&lt;p&gt;As reported &lt;a href="http://kasparov.skife.org/blog/src/antlr-book.html"&gt;elsewhere&lt;/a&gt;, the Pragmatic guys have shepherded another great book through their process: &lt;a href="http://www.pragmaticprogrammer.com/titles/tpantlr/"&gt;The Definitive ANTLR Reference&lt;/a&gt;. Though not intended as a how-to, I’m finding it very readable.&lt;/p&gt;
&lt;p&gt;Last time I looked at ANTLR, the &lt;a href="http://www.antlr.org/works/index.html"&gt;ANTLRWorks&lt;/a&gt; tool ( pictured above ) didn’t exist. It’s got some quirky aspects and rough edges, but it makes exploring and learning by example a reality. &lt;i&gt;Recommended!&lt;/i&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Asciiarmor/~4/BuobLy0_b1E" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Asciiarmor/~3/BuobLy0_b1E/33736600</link><guid isPermaLink="false">http://www.asciiarmor.com/post/33736600</guid><pubDate>Sat, 24 Feb 2007 12:54:00 -0500</pubDate><feedburner:origLink>http://www.asciiarmor.com/post/33736600</feedburner:origLink></item><item><title>VIM Plugin for JavascriptLint</title><description>&lt;center&gt;&lt;img src="http://files.asciiarmor.com/jsl-vim.png"/&gt;&lt;/center&gt;
&lt;br/&gt;&lt;p&gt;I’ve put together a &lt;a href="http://www.vim.org"&gt;vim&lt;/a&gt; compiler plugin to provide quick access to &lt;a href="http://www.javascriptlint.com/"&gt;JavaScriptLint&lt;/a&gt; output. It will identify file, line and column of warnings and errors generated by jsl. &lt;/p&gt;
&lt;p&gt;Requirements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;vim 7+&lt;/li&gt;
&lt;li&gt;jsl in path&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Installation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Download vimball - &lt;a href="http://www.asciiarmor.com/blog/wp-content/uploads/2007/1/jsl.vba"&gt;jsl.vba&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Open vimball - vim jsl.vba&lt;/li&gt;
&lt;li&gt;Verify contents - :VimballList&lt;br/&gt;Should see:
&lt;pre&gt;
would extract &lt;plugin/jsl.vim&gt;: 1 lines
would extract &lt;compiler/jsl.vim&gt;: 22 lines
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Install - :so %&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Usage:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Open file - vim jsl-test.js&lt;/li&gt;
&lt;li&gt;Run JavaScriptLit - :make&lt;/li&gt;
&lt;li&gt;View output - :cope&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Feedback welcome…&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Asciiarmor/~4/Ge3fDzbQw5M" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Asciiarmor/~3/Ge3fDzbQw5M/33736601</link><guid isPermaLink="false">http://www.asciiarmor.com/post/33736601</guid><pubDate>Mon, 01 Jan 2007 14:21:00 -0500</pubDate><feedburner:origLink>http://www.asciiarmor.com/post/33736601</feedburner:origLink></item><item><title>Raleigh NFJS 2006</title><description>&lt;center&gt;&lt;img src="http://files.asciiarmor.com/nfjs.jpg"/&gt;&lt;/center&gt;
&lt;br/&gt;&lt;p&gt;Recently Jay brought his current lineup of speakers to town for the &lt;a href="http://www.nofluffjuststuff.com/" title="2006 NFJS Symposium Tour"&gt;2006 NFJS Symposium Tour&lt;/a&gt; . Lots of great speakers. Packed with nuts and bolts details. It was buzzword compliant, with plenty of talks on AJAX and Ruby. &lt;a href="http://blogs.relevancellc.com/" title="Justin Gehtland's"&gt;Justin Gehtland’s&lt;/a&gt; talks on hibernate were excellent and can be found on &lt;a href="http://www.codecite.com/" title="codecite"&gt;codecite&lt;/a&gt; . These are polished speakers who have given these sessions many times prior. &lt;a href="http://blogs.pragprog.com/cgi-bin/pragdave.cgi" title="Dave Thomas"&gt;Dave Thomas&lt;/a&gt; could make event the most prosaic topic engaging and entertaining. The rare bit of wit, humor and humanity go a long way in this field.Points that stood out:&lt;/p&gt;
&lt;h3&gt;Keep Track of Your Ideas&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://www.toolshed.com/blog/" title="       Andy Hunt "&gt;       Andy Hunt &lt;/a&gt;  talked at length about keeping track of the ideas that occur to you throughout the day. Method doesn’t really matter. Some techniques he proposed: spacepen and pad, voice memos on your cell phone, wiki or wiki modes in your editor. I’ve installed &lt;a href="http://www.vim.org/scripts/script.php?script_id=1018" title="potwiki "&gt;potwiki &lt;/a&gt;  to give it a try. Elsewhere on the web &lt;a href="http://www.creativethinking.net" title="Michael Michalko"&gt;Michael Michalko&lt;/a&gt;   seems to have a few things to say on this topic.&lt;/p&gt;
&lt;p&gt;I like Michalko’s suggestions for developing ideas once captured:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What can be SUBSTITUTED?  (Who else?  What else?  Other ingredient?  Other process?  Other power?  Other place?  Other approach?  Can you change the rules?)&lt;/li&gt;
&lt;li&gt;What can be COMBINED?  (How about a blend, an alloy, an assortment, an ensemble?  Combine units?  Combine purposes with something else?  Combine appeals?  Combine ideas?)&lt;/li&gt;
&lt;li&gt;What can I ADAPT from something else to the idea?  (What else is like this?  What other idea does this suggest?  Does the past offer a parallel?  What could I copy?  Whom could I emulate?)&lt;/li&gt;
&lt;li&gt;What can I MAGNIFY?  (What can be added?  More time?  Stronger?  Higher?  Longer?  Extra value?  Extra features?  Duplicate?  Multiply?  Exaggerate?)&lt;/li&gt;
&lt;li&gt;What can I MODIFY or change?  (What can be altered?  New twist?  Change meaning, color, motion, sound, odor, form, shape?  What other changes can be made?)&lt;/li&gt;
&lt;li&gt;Can I PUT the idea TO OTHER USES?  (New ways to use as?  Other uses if modified?  Can you make it do more things?  Other extensions?  Other spin-off?  Other markets?)&lt;/li&gt;
&lt;li&gt;What can be ELIMINATED?  (What to subtract?  Smaller?  Condensed?  Miniature?  Lower?  Shorter?  Lighter?  Omit?  Streamline?  Split up?  Understate?)&lt;/li&gt;
&lt;li&gt;What can be REARRANGED the parts?  (What other arrangement might be better?  Interchange components?  Other pattern?  Other layout?  Other sequence?  Transpose cause and effect?  Change pace?  Change schedule?)&lt;/li&gt;
&lt;li&gt;Can it be REVERSED?  (Transpose positive and negative?  How about opposites?  Turn it upside down?  Reverse roles?  Consider it backwards?  What if you did the unexpected?)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Class Oriented Development&lt;/h3&gt;
&lt;p&gt;During his keynote Dave Thomas took more than a few well-deserved pot-shots at the received wisdom in the software community. He ticked through some of the usual suspects: type safety, methodologies, backward compatibility. Simply stated, his thesis was: if you don’t a have direct and clear understanding of why you are doing something: stop doing it. One point that resonated with me was his characterization of Java and many other object-oriented languages as really class-oriented. We spend our days developing sophisticated class relationships and hierarchies. Is-a. Has-a. While these languages provide anemic support for actually orienting your development around objects; the heart and soul of your application at runtime. Few true hierararchical taxonomies exist in the real world. Classes were invented by stamp-collectors. Why are we trying to put the world into neat little boxes?&lt;/p&gt;
&lt;p&gt;This was of course a shameless plug for features like mix-ins that exist in many &lt;a href="http://www.ruby-lang.org/" title="modern programming languages"&gt;modern programming languages&lt;/a&gt;  . Either way this is an idea worth kicking around the block.&lt;/p&gt;
&lt;h3&gt;Learn By Doing&lt;/h3&gt;
&lt;p&gt;In his Refactoring your Wetware talk Andy Hunt drew on the example of surgerical residents who follow the pattern of observe, assist and perform. For surgeons there is no substitute for doing. The same is probably true for developers.&lt;/p&gt;
&lt;p&gt;Put down that book. Close Firefox. mkdir testapp&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Asciiarmor/~4/AJEc1oYn1Zg" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Asciiarmor/~3/AJEc1oYn1Zg/33736604</link><guid isPermaLink="false">http://www.asciiarmor.com/post/33736604</guid><pubDate>Wed, 21 Jun 2006 08:19:00 -0400</pubDate><feedburner:origLink>http://www.asciiarmor.com/post/33736604</feedburner:origLink></item><item><title>Vim7 Feature Roundup</title><description>&lt;p&gt;I noticed Emacs 22 &lt;a href="http://steve-yegge.blogspot.com/2006/06/shiny-and-new-emacs-22.html" title="getting some press"&gt;getting some press&lt;/a&gt;   lately. So figured it was time to spread a little &lt;a href="http://www.vim.org" title="vim7   love"&gt;vim7   love&lt;/a&gt;  .&lt;/p&gt;
&lt;p&gt;Here is a grab bag of features I noticed.&lt;/p&gt;

&lt;h3&gt;Omni Complete&lt;/h3&gt;
&lt;center&gt;&lt;img src="http://files.asciiarmor.com/vim7omnicomplete.png"/&gt;&lt;/center&gt;
&lt;br/&gt;&lt;p&gt;Completion now comes to vim. &lt;ctl-x&gt;&lt;ctl-o&gt; and vim does it’s best to complete the symbol. It’s not perfect. The implementations look like they are mostly regexp’ing around. No knowledge type systems. Based on the contents of $VIM/autoload it looks like there’s out of the box support for: XML, HTML, CSS, C, JavaScript, PHP, Python, Ruby, and SQL. Sorry Java!&lt;/p&gt;

&lt;h3&gt;Quoted Text Select&lt;/h3&gt;

&lt;center&gt;&lt;img src="http://files.asciiarmor.com/vim7quote.png"/&gt;&lt;/center&gt;
&lt;br/&gt;&lt;p&gt;New quoted text selection shortcuts while in select mode. With cursor in a string &lt;ctl-q&gt;i” will select all the text within double quotes. If you want the quotes &lt;ctl-q&gt;a” will do the trick.&lt;/p&gt;

&lt;h3&gt;:vimgrep&lt;/h3&gt;

&lt;center&gt;&lt;img src="http://files.asciiarmor.com/vim7cope.png"/&gt;&lt;/center&gt;
&lt;br/&gt;&lt;p&gt;Vim now comes out of the box with a grep implementation that works well with existing errorlist functionality.Recursively look for all the FIXME tags in the ruby source tree.:vimgrep /FIXME/j C:/ruby/src/**.rb&lt;/p&gt;
&lt;p&gt;View the hits and step through them&lt;/p&gt;
&lt;p&gt;:cope&lt;/p&gt;

&lt;h3&gt;Tabs&lt;/h3&gt;

&lt;center&gt;&lt;img src="http://files.asciiarmor.com/vim7tabs.png"/&gt;&lt;/center&gt;
&lt;br/&gt;&lt;p&gt;Enable this feature and you’ll feel like you walked into a room with 3 switches that control the same light. It looks nice, but when cycling through buffers with :bnext and you can see any buffer in any tab.  It’s there if you want it, but I suspect this will  largely go unused by most gvim people.To open a new tab:&lt;/p&gt;
&lt;p&gt;:tabnew&lt;/p&gt;

&lt;h3&gt;Spell Check&lt;/h3&gt;

&lt;center&gt;&lt;img src="http://files.asciiarmor.com/vim7spelling.png"/&gt;&lt;/center&gt;
&lt;br/&gt;&lt;p&gt;It’s 2006! I want a jetpack not spell checker!&lt;/p&gt;
&lt;p&gt;Nothing too surprising here. Ships with English support. You can grab OpenOffice dictionaries and use the :mkspell to convert it into something vim can cope with. Notice red squiggles under the spelling errors and blue under the punctuation errors.&lt;/p&gt;
&lt;p&gt;:setlocal spell spelllang=Fr_fr&lt;/p&gt;

&lt;h3&gt;Undo Branches&lt;/h3&gt;
&lt;center&gt;&lt;img src="http://files.asciiarmor.com/vim7undolist.png"/&gt;&lt;/center&gt;
&lt;br/&gt;&lt;p&gt;This is an excellent feature with a confusing name. Think of it as restore to any point in time during an edit session. It will save your bacon when you make some edits, undo a few levels, make some more edits and realize you wanted something back from before the undo. New commands support restoring to a text state based on time:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;g+ / g- This is like u / CTRL-R except it will walk across all changes over time. Good candidates for mapping.&lt;/li&gt;
&lt;li&gt;:earlier 5m Restore to state 5 minutes ago&lt;/li&gt;
&lt;li&gt;:later 1h Restore to state 1 hour later&lt;/li&gt;
&lt;li&gt;:undolist Show leaves in undo / redo tree&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;:MkVimball&lt;/h3&gt;
&lt;p&gt;Package and distribute plugins and vim macros into vba files with this new command. When opening vim will recognize the vba files and prompt to extract. Uninstall would be a nice addition.&lt;/p&gt;
&lt;h3&gt;:GetLatestVimScripts&lt;/h3&gt;
&lt;p&gt;A very lightweight package manager is now included. Make sure you have a version of wget in your path. Then create a file $VIM/getlatest/GetLatestScripts.dat that looks like:&lt;/p&gt;
&lt;p&gt;ScriptID SourceID Filename&lt;br/&gt;
————————–&lt;/p&gt;
&lt;p&gt;A call to :GetLatestVimScripts will then attempt to update all plugins aware of this new functionality.&lt;/p&gt;
&lt;p&gt;It will update the file with version and date information. Note that vim ships with more plugins than this, but GLVS, netrw and vimball are the only ones aware of this new feature.&lt;/p&gt;
&lt;p&gt;ScriptID SourceID Filename&lt;br/&gt;
————————–&lt;br/&gt;
642 5228 :AutoInstall: GetLatestVimScripts.vim&lt;br/&gt;
1075 5814 :AutoInstall: netrw.vim&lt;br/&gt;
1502 5828 :AutoInstall: vimball.vim&lt;/p&gt;

&lt;h3&gt;Script Enhancements&lt;/h3&gt;
&lt;p&gt;Vim’s macro language continues to evolve. Things like this are now possible:&lt;/p&gt;
&lt;p&gt;:let num = { 1: ‘one’, 2: ‘two’, 3: ‘three’ }&lt;br/&gt;
:echo num[2]&lt;/p&gt;
&lt;p&gt;One step closer to emacs convergence?&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Asciiarmor/~4/6DCwGEDo4Us" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Asciiarmor/~3/6DCwGEDo4Us/33736605</link><guid isPermaLink="false">http://www.asciiarmor.com/post/33736605</guid><pubDate>Tue, 13 Jun 2006 20:33:00 -0400</pubDate><feedburner:origLink>http://www.asciiarmor.com/post/33736605</feedburner:origLink></item><item><title>Music to code by!</title><description>&lt;center&gt;&lt;img src="http://files.asciiarmor.com/somafm.jpg"/&gt;&lt;/center&gt;
&lt;br/&gt;

The already great &lt;a href="http://www.somafm.com/"&gt;somafm&lt;/a&gt; just launched &lt;a href="http://www.somafm.com/spacestation.pls"&gt;space station soma&lt;/a&gt;.
&lt;p&gt;&lt;em&gt; Tune in, turn on, space out. Spaced-out ambient and mid-tempo electronica.&lt;/em&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Asciiarmor/~4/54lfd6gdguk" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Asciiarmor/~3/54lfd6gdguk/33736606</link><guid isPermaLink="false">http://www.asciiarmor.com/post/33736606</guid><pubDate>Wed, 22 Mar 2006 13:02:00 -0500</pubDate><feedburner:origLink>http://www.asciiarmor.com/post/33736606</feedburner:origLink></item><item><title>Aardvark'd: 12 Weeks With Geeks</title><description>&lt;center&gt;&lt;img src="http://files.asciiarmor.com/aardvarks.jpg"/&gt;&lt;/center&gt;
&lt;br/&gt;
I finished Joel’s Aardvark’d documentary last night. It captured the experiences of his 4 interns for 12 weeks. Pointing a camera at 4 guys typing for 3 months and editing that into something entertaining is non-trivial. I struggled to find the thesis, but there was plenty to like.
&lt;p&gt;Some observations:&lt;/p&gt;
&lt;p&gt;What it is:&lt;/p&gt;
&lt;p&gt;A little bit of advertising. Without being cynical, let’s be realistic. I paid $20 for this thing. Now I’m blogging about it. Mission accomplished.&lt;/p&gt;
&lt;p&gt;A look through the key-hole at this medium’s potential. Cameras and computers are cheap. There’s more of this type of thing to come and they will build it’s strengths.&lt;/p&gt;
&lt;p&gt;A tease for folks interested in the Y Combinator. Paul Graham’s work in Boston is briefly contrasted. Someone send a guy and a camera up there!&lt;/p&gt;
&lt;p&gt;What it might be:&lt;/p&gt;
&lt;p&gt;A HOWTO for companies starting internships. There more than a few lessons to be learned: find them housing, buy them a TV, let them get some skin in the game the first day by putting together their workspace, give them the same hardware as the rest of the team, give them a spec, etc…&lt;/p&gt;
&lt;p&gt;A depiction of the banality that comes along with software development. Long nights where the only thing interesting that happens is a cockroach crawling across the floor. Endless debates in the forums. The office manager / secretary provides us the view of some one looking in from the outside.&lt;/p&gt;
&lt;p&gt;What it wasn’t:&lt;/p&gt;
&lt;p&gt;A deep look into the journey of the intern; intern as Ubermensch; emerges from long dark 12 week tunnel having re-evaluated prior ideals.&lt;/p&gt;
&lt;p&gt;An insightful portrayal of the starts and stops of software development; the highs and lows; peaks and valleys. While some demos crashed and some bugs were found, the contrast between the intoxicating sensation of shipping and sober realities along the way went largely unaddressed.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Asciiarmor/~4/p60VztOX9EY" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Asciiarmor/~3/p60VztOX9EY/33736607</link><guid isPermaLink="false">http://www.asciiarmor.com/post/33736607</guid><pubDate>Tue, 06 Dec 2005 08:38:00 -0500</pubDate><feedburner:origLink>http://www.asciiarmor.com/post/33736607</feedburner:origLink></item><item><title>Book Review: Maven - A Developer's Notebook</title><description>&lt;center&gt;&lt;img src="http://files.asciiarmor.com/mavenadn.s.gif"/&gt;&lt;/center&gt;
&lt;br/&gt;&lt;a href="http://www.oreilly.com/catalog/mavenadn/"&gt;Maven: A Developer’s Notebook&lt;/a&gt; is a recently published book by &lt;a href="http://blogs.codehaus.org/people/vmassol/"&gt;Vincent Massol&lt;/a&gt; and Timothy O’Brien in O’Reilly’s Developer Notebook series. It fills a void in the market for a quality book on Maven. I had a chance to spend some time with Vincent while in Paris earlier in the summer; we talked about the book, his company: &lt;a href="http://www.pivolis.com/"&gt;Pivolis&lt;/a&gt;, the French language and every manner of other topics. I’ve just now taken the time read through the book and should have done so earlier. It’s excellent. Vincent’s passion and focus comes across loud and clear.
&lt;p&gt;According to O’Reilly’s site the Developer Notebook Series “is for early adopters of leading-edge technologies who want to get up to speed quickly on what they can do now with emerging technologies.” This book delivers on that promise, weighing in at under 200 pages, but providing the reader with more than enough to get them up and running quickly. It goes beyond the basics, covering customization via maven.xml, multiproject configuration, site customization, and plugin creation. A very practical set of labs are woven through the book as well; making the book suitable for use in a training class.&lt;/p&gt;
&lt;p&gt;It is published at an interesting time with Maven2 in alpha. The book targets Maven 1.x, but Vincent and Tim don’t ignore Maven2. They make frequent references to features Maven2 will offer and help prepare the reader for migration when Maven2 is production ready.&lt;/p&gt;
&lt;p&gt;The book comes along with a counterpart web site that offers up info on the book and additional content of interest to the reader: &lt;a href="http://www.mavenbook.org"&gt;&lt;a href="http://www.mavenbook.org"&gt;www.mavenbook.org&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Some areas for improvement:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Help the reader understand if Maven isn’t for them. When is it overkill? When would something else be a better choice? What are the alternatives?&lt;/li&gt;
&lt;li&gt;Additional coverage of XDoc; a poorly documented aspect of Maven that is generally learned by looking at other examples (read: cut and paste).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Three and half out of four stars. Great job…&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Asciiarmor/~4/3s7CYfN8ta8" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Asciiarmor/~3/3s7CYfN8ta8/33736608</link><guid isPermaLink="false">http://www.asciiarmor.com/post/33736608</guid><pubDate>Thu, 21 Jul 2005 07:33:00 -0400</pubDate><feedburner:origLink>http://www.asciiarmor.com/post/33736608</feedburner:origLink></item><item><title>DAX Checked into Subversion</title><description>&lt;p&gt;After a few months being off the air, the lights are back on. Relocation from the West Coast of the US to the East Coast, a month in France, selling a house, buying a house, and a new job have kept me a bit more occupied than I expected.&lt;/p&gt;
&lt;p&gt;I’ve finally taken the time to check in DAX to the Subversion repository &lt;a href="http://www.goshaky.com"&gt;Lars&lt;/a&gt; setup for me. Point your svn clients over to: &lt;a href="http://www.goshaky.com/svn/dax/"&gt;http://www.goshaky.com/svn/dax/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Some tiny changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Jar file naming is Maven compatible&lt;/li&gt;
&lt;li&gt;@Path is now @Match&lt;/li&gt;
&lt;li&gt;build.xml tidied up a bit&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A few suggestions have been sent along; I may get to some of these…&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use annotations for the POJO -&gt; XML mapping of simple Java types; mitigating the DOM4J dependancy.&lt;/li&gt;
&lt;li&gt;Support XPath2; perhaps via Saxon&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/Asciiarmor/~4/G2qmald0teY" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Asciiarmor/~3/G2qmald0teY/33736609</link><guid isPermaLink="false">http://www.asciiarmor.com/post/33736609</guid><pubDate>Tue, 05 Jul 2005 06:53:15 -0400</pubDate><feedburner:origLink>http://www.asciiarmor.com/post/33736609</feedburner:origLink></item><item><title>Introducing DAX: Declarative API for XML</title><description>&lt;p&gt;Inspired by &lt;a href="http://sellsbrothers.com/news/showTopic.aspx?ixTopic=1683"&gt;XSLTO&lt;/a&gt;, I’ve put together a bit of code to allow XSLT like tranformations from within Java. DAX glues together Java 5 annotations, Jaxen XPath and DOM4J to make possible the declarative style of processing shown below.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Getting Started&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Install JDK 5 and a recent flavor of Ant&lt;/li&gt;
&lt;li&gt;Download DAX &lt;a href="http://www.asciiarmor.com/resources/DAX.zip"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Extract and do an “ant test”&lt;/li&gt;
&lt;li&gt;“ant javadocs” for API guide&lt;/li&gt;
&lt;li&gt;Look at the dax.examples package for sample code&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;More postings to follow. &lt;em&gt;Stay tuned…&lt;/em&gt;&lt;/p&gt;
&lt;pre&gt;

public class BindingTransform extends Transformer {

	public List items = new ArrayList();
	private RSSItem currentItem;

	public BindingTransform() {
		// tell engine about anticipated namespace
		setNamespace("dc", "http://purl.org/dc/elements/1.1/");
	}

	public void init() {
		items.clear();
	}

	public void complete() {
		for (RSSItem i : items) {
			System.out.println(i.getTitle());
		}
	}

	@Path("//item")
	public void item(Node node) {
		currentItem = new RSSItem();
		items.add(currentItem);
		applyTemplates(node);
	}

	@Path("item/title")
		public void title(Node node) {
		currentItem.setTitle(node.getStringValue());
	}

	@Path("item/link")
		public void link(Node node) {
		currentItem.setLink(node.getStringValue());
	}

	@Path("item/description")
		public void description(Node node) {
		currentItem.setDescription(node.getStringValue());
	}

	@Path("item/dc:creator")
		public void creator(Node node) {
		currentItem.setCreator(node.getStringValue());
	}
}&lt;/pre&gt;&lt;img src="http://feeds.feedburner.com/~r/Asciiarmor/~4/fN9hpnl9q_g" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Asciiarmor/~3/fN9hpnl9q_g/33736611</link><guid isPermaLink="false">http://www.asciiarmor.com/post/33736611</guid><pubDate>Thu, 03 Mar 2005 02:28:00 -0500</pubDate><feedburner:origLink>http://www.asciiarmor.com/post/33736611</feedburner:origLink></item><item><title>What Great Java Developers Ought To Know ( stone soup version )</title><description>&lt;p&gt;What would a Java version of this post look like?&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.hanselman.com/blog/default,date,2005-02-21.aspx"&gt;What Great .NET Developers Ought To Know (More .NET Interview Questions)&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Asciiarmor/~4/sFCX8Lps-WI" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Asciiarmor/~3/sFCX8Lps-WI/33736612</link><guid isPermaLink="false">http://www.asciiarmor.com/post/33736612</guid><pubDate>Wed, 23 Feb 2005 01:13:34 -0500</pubDate><feedburner:origLink>http://www.asciiarmor.com/post/33736612</feedburner:origLink></item><item><title>XPath Performance Followup</title><description>&lt;p&gt;Shirasu has extended my XPath benchmarking work to include testing across object models.&lt;/p&gt;
&lt;p&gt;His observations:&lt;/p&gt;
&lt;blockquote&gt;
&lt;li&gt;Traversal of Jaxen is a bit slower than others.&lt;/li&gt;
&lt;li&gt;Performance of JXPath does not depend on object models generally. JXPath uses the original traversal mechanism (i.e. NodePointers), and this mesurement suggests that it does not use object model explicitly.&lt;/li&gt;
&lt;li&gt;Jaxen and Saxon in DOM is a bit slower than ones in JDOM and XOM.&lt;/li&gt;
&lt;li&gt;The following-sibling traversal of Saxon in DOM is a bit slow, but good in JDOM and XOM&lt;/li&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="http://www.k2.dion.ne.jp/~hirsh/xpath/engineComparison-en.html"&gt;Details in English&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.k2.dion.ne.jp/~hirsh/xpath/engineComparison.html"&gt;Details in Japanese&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Asciiarmor/~4/QMNhsUAn4lM" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Asciiarmor/~3/QMNhsUAn4lM/33736613</link><guid isPermaLink="false">http://www.asciiarmor.com/post/33736613</guid><pubDate>Thu, 20 Jan 2005 02:40:05 -0500</pubDate><feedburner:origLink>http://www.asciiarmor.com/post/33736613</feedburner:origLink></item><item><title>Tips for Computer Book Authors</title><description>&lt;p&gt;Over the last 18 months or so I’ve had the great experience of reviewing a handful of books in various stages of development. In doing so I noted several patterns that emerged and captured them here. &lt;em&gt;Enjoy!&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;Make sample code stand-alone test cases&lt;/h2&gt;
&lt;p&gt;Whether you are developing Python or PowerBuilder, chances are there is a unit-test framework available. Leverage these frameworks in creating your samples. It forces discipline upon the author to keep examples small and self-contained. More significantly, it provides code that will compile and be immediately useful to readers.&lt;/p&gt;
&lt;p&gt;Never underestimate the power of copy and paste.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.amazon.com/exec/obidos/ASIN/1932394281/"&gt;Lucene in Action&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://c2.com/cgi/wiki?TestingFramework"&gt;Testing Frameworks&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Develop reader personas&lt;/h2&gt;
&lt;p&gt;Writers face the challenge of crystallizing target readers. What is their level of education? What is their experience with the subject being presented? More importantly, writers face the less obvious question: Who are they not writing for? Poor attention to these questions manifests itself in the form of inconsistencies like: assuming the reader understands the quicksort algorithm but in the previous chapter explaining how to download and unzip a file.&lt;/p&gt;
&lt;p&gt;Borrow a technique from the design world to mitigate this challenge: Develop full-blown personas of your readers. Include photos. Include a work-history. Is this the type of person who wants to go home at 5PM or understand the subject from the inside out? What is their reading style? Make a few copies. Hang them on the wall where you write. Send them to your editors.&lt;/p&gt;
&lt;p&gt;Mercilessly challenge yourself: Is this something the readers already know? Is this something readers need additional foundation on?&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.cooper.com/newsletters/2001_07/perfecting_your_personas.htm"&gt;Perfecting Personas&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Define your value proposition&lt;/h2&gt;
&lt;p&gt;Odds are, your book is not the only one on the subject. In the planning stages of the book define your value proposition in clear terms. Send it to your editors. What does your book bring to the party that no other does? Does it consider common pitfalls? Does it describe internal implementation details? Is it aimed specifically at beginners or advanced readers? Is it a comprehensive treatise on a subject?&lt;/p&gt;
&lt;p&gt;Struggling to come up with your value proposition? Maybe the project isn’t such a great idea.&lt;/p&gt;
&lt;h2&gt;Consider various styles of reading&lt;/h2&gt;
&lt;p&gt;A small minority of your readers will make a front-to-back consideration of your manuscript. More readers look for answers to a specific problem. Still more read in an exploratory style, seeking an overall survey or looking for topics that interest them. Ask yourself: How do I serve these various types of readers? Devices such as “Best Practices” or “Pitfalls” beak-out boxes help capture the attention of explorers. A topical Q&amp;A summary can serve the answer seekers.&lt;/p&gt;
&lt;p&gt;Think about the guy at Borders flipping through your book on a rainy afternoon. Remember the frantic developer spilling cold coffee on your book as he works on solving a problem with a production system.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.amazon.com/exec/obidos/ASIN/1930110995/"&gt;JUnit In Action&lt;/a&gt;&lt;br/&gt;&lt;a href="http://www.amazon.com/exec/obidos/ASIN/0596007124/"&gt;Head First Design Patterns&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;“Don’t be too pleased with yourself.”&lt;/h2&gt;
&lt;p&gt;This one is borrowed from the style guide provided to writers of the Economist magazine. The idea’s relevance to programmers is emphasized in Larry Wall’s consideration of great virtues a programmer. In it he defines “Hubris” as:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;“Excessive pride, the sort of thing Zeus zaps you for. Also the quality that makes you write (and maintain) programs that other people won’t want to say bad things about. Hence, the third great virtue of a programmer. See also laziness and impatience. (p.607)”&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Self-confidence is a good thing; leave it unchecked and you will endear yourself to few readers. For whatever reasons, the industry breeds excessive self-assurance. Challenge yourself: Can use of the first person singular be reduced? Better yet, eliminated entirely? Do you see phrases like: “A naive programmer would…” or “Inexperienced users might…”?&lt;/p&gt;
&lt;p&gt;Respect your reader; they could probably teach you a thing or two.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://c2.com/cgi/wiki?LazinessImpatienceHubris"&gt;3 Traits&lt;/a&gt;&lt;br/&gt;&lt;a href="http://www.economist.com/research/styleGuide/index.cfm?page=673927"&gt;Economist Style Guide&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Leave your fingerprints on the manuscript&lt;/h2&gt;
&lt;p&gt;This is the corollary to “Don’t be too pleased with yourself”. Without being self-serving let your unique voice be heard. You represent a unique intersection of experience, education and ideas. Let this individuality come through. Have you been consulting for years and seen techniques succeed or fail. Tell readers about it! Have a relevant war story? Share it! Inject some personality; relentlessly combat a dry documentary style.&lt;/p&gt;
&lt;p&gt;If you are not consciously battling tedium, you have ceded to it.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.amazon.com/exec/obidos/ASIN/0764558315/"&gt;Enterprise Java w/o EJB&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Use a single problem domain for sample code&lt;/h2&gt;
&lt;p&gt;Don’t be seduced by metasyntactic variables. Pick a realistic problem domain and stick to it. Don’t switch from stock quotes in the first chapter to class scheduling in the second. Let your reader reap the benefits of investing time in understanding the problem domain. Note: This is not to say examples should be cumulative and dependent on prior chapters.&lt;/p&gt;
&lt;p&gt;Allow them to focus on the message and not the means to convey it.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.amazon.com/exec/obidos/ASIN/0596006969/"&gt;Hibernate: A Developer’s Notebook&lt;/a&gt;&lt;br/&gt;&lt;a href="http://en.wikipedia.org/wiki/Metasyntactic_variable"&gt;Metasyntactic Variables&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Say more by saying less&lt;/h2&gt;
&lt;p&gt;Keep your language simple and eliminate digressions. Simple words are the most powerful. “It was the best times, it was the worst of times…”. “In the beginning…”.  “We didn’t land on Plymouth Rock…” Unsparingly revise long and wordy sentences. Watch some DVD commentaries and listen to directors wax-nostalgic about scenes they deleted in the interest of producing a better film. Learn from them. Don’t make your book the next Ishtar. Unsympathetically delete sentences, paragraphs and chapters.&lt;/p&gt;
&lt;p&gt;You’ve got work to do if you can’t remember the last time you simplified a sentence or deleted a portion of your manuscript.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.amazon.com/exec/obidos/ASIN/0201616475/"&gt;Cryptography Decrypted&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Cite other works&lt;/h2&gt;
&lt;p&gt;Citations reinforce the hard work that went into the manuscript. More importantly they show readers where more can be learned on a specific topic. Subscribe to O’Reilly’s Safari service. Spend some time at a good book store. Work with your publisher to get copies of books they publish on related topics.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.amazon.com/exec/obidos/ASIN/0130206016/"&gt;Unix System Administration Book&lt;/a&gt;&lt;br/&gt;&lt;a href="http://www.amazon.com/exec/obidos/ASIN/0735619670/"&gt;Code Complete&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Communicate compromises&lt;/h2&gt;
&lt;p&gt;Every technology represents a series of compromises. Communicate these to the reader. Don’t make them learn the hard way. This isn’t a hammer for every nail. This isn’t a solution to every problem. Challenge yourself when outlining a topic: What are the relative merits the implementation? What were the alternatives? When should this technology not be employed? What would my readers benefit most for knowing?&lt;/p&gt;
&lt;p&gt;Prove to your reader you’re not a zealot.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.amazon.com/exec/obidos/ASIN/0321150406/"&gt;Effective XML&lt;/a&gt; ( particularly items 24,25,41 )&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Asciiarmor/~4/Tg1CXu2MPSg" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Asciiarmor/~3/Tg1CXu2MPSg/33736614</link><guid isPermaLink="false">http://www.asciiarmor.com/post/33736614</guid><pubDate>Fri, 14 Jan 2005 21:09:16 -0500</pubDate><feedburner:origLink>http://www.asciiarmor.com/post/33736614</feedburner:origLink></item><item><title>java.util.UUID mini-FAQ</title><description>&lt;p&gt;J2SE 1.5 gives us a new class to generate identifiers. Here are some details I found after writing a bit of code and doing some reading.&lt;/p&gt;
&lt;h3&gt;What is a UUID?&lt;/h3&gt;
&lt;p&gt;According to Wikipedia:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“…an identifier standard used in software construction, standardized by the Open Software Foundation (OSF) as part of the Distributed Computing Environment (DCE). The intent of UUIDs is to enable distributed systems to uniquely identify information without significant central coordination. Thus, anyone can create a UUID and use it to identify something with reasonable confidence that that identifier will never be unintentionally used by anyone for anything else. Information labelled with UUIDs can therefore be later combined into a single database without need to resolve name conflicts. The most widespread use of this standard is in Microsoft’s Globally Unique Identifiers (GUIDs) which implement this standard.&lt;/p&gt;
&lt;p&gt;A UUID is essentially a 16-byte number and in its canonical form a UUID may look like this:&lt;/p&gt;
&lt;p&gt;550E8400-E29B-11D4-A716-446655440000&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;How do I generate a new UUID?&lt;/h3&gt;
&lt;p&gt;Calling the randomUUID() factory method will give you a fresh instance. Calling toString() will provide a spec-compliant canonical string representation. See the testRandom method in the source below.&lt;/p&gt;
&lt;h3&gt;I thought these were called GUIDs. What is a UUID?&lt;/h3&gt;
&lt;p&gt;Per the draft spec referenced below these are synonymous:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;…UUIDs (Universally Unique IDentifier), also known as GUIDs (Globally&lt;br/&gt;
Unique IDentifier).&lt;/p&gt;&lt;/blockquote&gt;
&lt;h3&gt;I’m a Windows guy. Is this the same thing as CoCreateGuid?&lt;/h3&gt;
&lt;p&gt;According to MSDN the current version of CoCreateGuid also generates a ‘version 4′ random number based UUID.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The CoCreateGuid function calls the RPC function UuidCreate, which creates a GUID, a globally unique 128-bit integer. Use the CoCreateGuid function when you need an absolutely unique number that you will use as a persistent identifier in a distributed environment.To a very high degree of certainty, this function returns a unique value no other invocation, on the same or any other system (networked or not), should return the same value.&lt;/p&gt;
&lt;p&gt;For security reasons, it is often desirable to keep ethernet/token ring addresses on networks from becoming available outside a company or organization. In Windows XP/2000, the UuidCreate function generates a UUID that cannot be traced to the ethernet/token ring address of the computer on which it was generated. It also cannot be associated with other UUIDs created on the same computer. If you do not need this level of security, your application can use the UuidCreateSequential function, which behaves exactly as the UuidCreate function does on all other versions of the operating system.&lt;/p&gt;
&lt;p&gt;In Windows NT 4.0, Windows 95, DCOM release, and Windows 98, UuidCreate returns RPC_S_UUID_LOCAL_ONLY when the originating computer does not have an ethernet/token ring (IEEE 802.x) address. In this case, the generated UUID is a valid identifier, and is guaranteed to be unique among all UUIDs generated on the computer. However, the possibility exists that another computer without an ethernet/token ring address generated the identical UUID. Therefore you should never use this UUID to identify an object that is not strictly local to your computer. Computers with ethernet/token ring addresses generate UUIDs that are guaranteed to be globally unique.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;I thought UUIDs used the MAC address to guarantee uniqueness&lt;/h3&gt;
&lt;p&gt;The specification defines multiple types of UUIDs. Version 1 UUIDs include a MAC address. Version 4 UUIDs are generated from a large random number and do not include the MAC address. The implementation of java.util.UUID creates version 4 UUIDs. See the testVersion method in the source below.&lt;/p&gt;
&lt;h3&gt;So java.util.UUID can only generate version 4 UUIDs. Can it parse and handle the other types?&lt;/h3&gt;
&lt;p&gt;Yes. Using the fromString method you can instantiate and interrogate a UUID of version 1,2,3 or 4. See the testFromString method in the source below; note it’s a version 1 UUID.&lt;/p&gt;
&lt;h3&gt;The draft spec talks about multiple variant types of UUIDs. Which variant types are supported by java.util.UUID?&lt;/h3&gt;
&lt;p&gt;As indicated by the javadoc for getVariant(), java.util.UUID only supports variant type 2.&lt;/p&gt;
&lt;h3&gt;I like the idea of using the MAC address. What makes version 4 UUIDs better?&lt;/h3&gt;
&lt;p&gt;Using a version 4 UUID could save you &lt;a href="http://www.theregister.co.uk/2002/05/01/melissa_virus_author_jailed/"&gt; 20 months in a United States Federal Prison&lt;/a&gt;. Evidently the writer of the Melissa worm was tracked down in part by the MAC address in a UUID.&lt;/p&gt;
&lt;h3&gt;So these version 4 UUIDs are basically random numbers. Won’t my UUID collide with someone elses?&lt;/h3&gt;
&lt;p&gt;There are 122 significant bits in a type 4 UUID. 2&lt;sup&gt;122&lt;/sup&gt; is a *very* large number. Assuming a random distribution of these bits, the probability of collission is *very* low. How is the “randomness” determined?&lt;/p&gt;
&lt;p&gt;Under the hood java.util.UUID is creating an instance of SecureRandom and using that to generate new UUIDs. If you are using the default Sun provider and default java.security file, you are using a SHA1PRNG ( Pseudo Random Number Generator based on Secure Hash Algorigthm 1 ) seeded from the operating system.&lt;/p&gt;
&lt;p&gt;java.security&lt;/p&gt;
&lt;pre&gt;#
# Select the source of seed data for SecureRandom. By default an
# attempt is made to use the entropy gathering device specified by
# the securerandom.source property. If an exception occurs when
# accessing the URL then the traditional system/thread activity
# algorithm is used.
#
# On Solaris and Linux systems, if file:/dev/urandom is specified and it
# exists, a special SecureRandom implementation is activated by default.
# This "NativePRNG" reads random bytes directly from /dev/urandom.
#
# On Windows systems, the URLs file:/dev/random and file:/dev/urandom
# enables use of the Microsoft CryptoAPI seed functionality.
#
securerandom.source=file:/dev/urandom&lt;/pre&gt;
&lt;p&gt;On WinTel platforms this may map down to &lt;a href="http://blogs.msdn.com/fvicaria/archive/2004/10/06/238862.aspx"&gt;hardware&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;More on &lt;a href="http://triumvir.org/rng/"&gt;randomness&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;I want to preserve backward JDK compatibilty. I’ll just use java.rmi.server.UID. Cool?&lt;/h3&gt;
&lt;p&gt;Probably a bad idea. Per the docs this gives you 2&lt;sup&gt;16&lt;/sup&gt; significant digits. It is also makes no provision for the system clock being set backward.&lt;/p&gt;
&lt;h3&gt;What other options do I have?&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://jakarta.apache.org/commons/sandbox/id/"&gt;commons-id&lt;/a&gt; is a general purpose identifier generator capable of generating UUIDs.&lt;/p&gt;
&lt;h3&gt;Where can I read more about UUIDs?&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://www.ietf.org/internet-drafts/draft-mealling-uuid-urn-04.txt"&gt;Current Draft Specification&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Sample Code&lt;/h2&gt;
&lt;pre&gt;import java.util.UUID;
&lt;cr&gt;  import junit.framework.TestCase;
public class UUIDTest extends TestCase {  	
	public void testRandom() { 		
		UUID a = UUID.randomUUID();
		UUID b = UUID.randomUUID();
		assertFalse(a.equals(b));
	}  	

	public void testVariant() { 		
		UUID a = UUID.randomUUID();
		assertEquals(a.variant(), 2);
	}  	

	public void testVersion() { 		
		UUID a1 = UUID.randomUUID();
		assertEquals(a1.version(), 4);
		// here is a version 1 UUID plucked from my own HKLMSoftwareClasses 		
		// for history of UUIDs ending in 444553540000 		
		// &lt;a href="http://blogs.msdn.com/oldnewthing/archive/2004/02/11/71307.aspx#71356"&gt;http://blogs.msdn.com/oldnewthing/archive/2004/02/11/71307.aspx#71356&lt;/a&gt; 		
		UUID a2 = UUID.fromString("d27cdb6e-ae6d-11cf-96b8-444553540000");
		assertEquals(a2.variant(), 2);
		assertEquals(a2.version(), 1);
	}  	

	public void testFromString() { 		
		String s = "d27cdb6e-ae6d-11cf-96b8-444553540000";
		UUID a = UUID.fromString(s);
		assertEquals(a.toString(), s);
	}  	

	public void testVersionFromCommonsTestCase() {  		
		// these UUIDs are from commons-id 		
		UUID v1 = UUID.fromString("3051a8d7-aea7-1801-e0bf-bc539dd60cf3");
		UUID v2 = UUID.fromString("3051a8d7-aea7-2801-e0bf-bc539dd60cf3");
		UUID v3 = UUID.fromString("3051a8d7-aea7-3801-e0bf-bc539dd60cf3");
		UUID v4 = UUID.fromString("3051a8d7-aea7-4801-e0bf-bc539dd60cf3");

		//UUID v5 = UUID.fromString("3051a8d7-aea7-3801-e0bf-bc539dd60cf3");
		assertEquals(1, v1.version());
		assertEquals(2, v2.version());
		assertEquals(3, v3.version());
		assertEquals(4, v4.version());

		// java.util.UUID doesn't support version 5 UUIDs while commons-id does 		
		//assertEquals(5, v5.version());
	} 
}
&lt;/cr&gt;&lt;/pre&gt;&lt;img src="http://feeds.feedburner.com/~r/Asciiarmor/~4/vEWcjtmMEmw" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Asciiarmor/~3/vEWcjtmMEmw/33736615</link><guid isPermaLink="false">http://www.asciiarmor.com/post/33736615</guid><pubDate>Tue, 04 Jan 2005 02:15:00 -0500</pubDate><feedburner:origLink>http://www.asciiarmor.com/post/33736615</feedburner:origLink></item></channel></rss>
