<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6813476980165976394</id><updated>2011-12-23T19:23:55.633-08:00</updated><category term='google app engine'/><category term='jQuery'/><category term='blogger'/><category term='javascript'/><category term='java'/><category term='sql'/><category term='biogroovy'/><category term='groovy'/><category term='h2'/><category term='groovlet'/><category term='perl'/><category term='Processing'/><category term='AJAX'/><category term='canvas'/><category term='command line'/><category term='csv'/><category term='processing.js'/><category term='bioinformatics'/><category term='Gibbs sampling'/><category term='MCMC'/><category term='database'/><category term='HTML5'/><title type='text'>The Bayesian Conspiracy</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://bayesianconspiracy.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6813476980165976394/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://bayesianconspiracy.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>James Durbin</name><uri>http://www.blogger.com/profile/02881091854353753739</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-n4yWF1vlZsM/Th_5FmbKhYI/AAAAAAAAAvE/uUsPcuOaRiQ/s220/10534_1122758594569_1395223040_30315740_3644162_n.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>14</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6813476980165976394.post-6772416092586617658</id><published>2011-09-08T22:43:00.000-07:00</published><updated>2011-12-23T19:22:43.412-08:00</updated><title type='text'>A tooltip class for HTML5 canvas written with Processing.js</title><content type='html'>The visualization code I'm writing using &lt;a href="http://processingjs.org/"&gt;Processing.js&lt;/a&gt; needs a tooltip to display some information depending on where your mouse is in the canvas.  Although there are many tooltip options for webpage elements, I didn't find any that I could easily use with Processing.js to generate tooltips dependent on the mouse position in the canvas. After a few frustrating attempts with various libraries I finally just took &lt;a href="http://bocoup.com/processing-js/docs/index.php?page=Rounded%20Corners%20with%20Processing.js"&gt;this&lt;/a&gt; rounded corners demo by F1LT3R. and hacked together a ToolTip class of my own that works with Processing.js.  I think it's pretty nice for a quick hack.&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;The tooltip has variable transparency, detects in and out of canvas state, and adjusts itself when the tooltip approaches a canvas edge.  It has a clipping mode for static canvas images and a non-clipping mode for use with canvas animations.  Although I haven't tested it, this library should work just as well with the java-based &lt;a href="http://processing.org/"&gt;Processing&lt;/a&gt;.   A demo of the tooltip is below, along with a nice HTML5 background animation that was also written in Processing.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #9b9d8b;"&gt;&lt;small&gt; &lt;i&gt;&lt;b&gt;Mouse over the canvas to make the tooltip appear.&lt;/b&gt; Click on the canvas to give it focus.  Press 'r' to randomize background animation. Press 'a' to cycle through alpha levels.  Press 'c' to randomize tip color. &lt;/i&gt;&lt;/small&gt;&lt;/span&gt;&lt;br /&gt;&lt;script data-processing-target="pjs" type="application/processing"&gt;/* @pjs pauseOnBlur="true"; */  void roundedRect(int left, int top, int width, int height, int roundness){ beginShape();                 vertex(left + roundness, top);  vertex(left + width - roundness, top);  bezierVertex(left + width - roundness, top,               left + width, top,               left + width, top + roundness);                            vertex(left + width, top + roundness);  vertex(left + width, top + height - roundness);  bezierVertex(left + width, top + height - roundness,               left + width, top + height,               left + width - roundness, top + height);          vertex(left + width - roundness, top + height);  vertex(left + roundness, top + height);          bezierVertex(left + roundness, top + height,               left, top + height,               left, top + height - roundness);          vertex(left, top + height - roundness);  vertex(left, top + roundness);  bezierVertex(left, top + roundness,               left, top,               left + roundness, top);         endShape();}/**** A class to display a tooltip in a nice bubble. **/class ToolTip{ String mText;  int x; int y;   boolean doClip = true;  int myWidth; int fontSize = 16; int totalHeight = 0;  int rectWidthMargin; int rectHeightMargin;   int shadowOffset = 8;   color tbackground = color(80,150,0,200);  Pfont ttfont;  // Saved part of image that will be painted over by tooltip.. static PImage clip = null; static int clipx; static int clipy;  void setBackground(color c){  tbackground = c; }    ToolTip(_x,_y,tttext){  x = _x;  y = _y;  mText = tttext;  ttfont = createFont("Arial",20,true);  textFont(ttfont,fontSize);        // Figure out text size... font metrics don't seem quite right, at least on Chrome  String lines[] = split(mText,"\n");  int maxWidth = 0;  totalHeight = 0;  for(int i = 0;i &lt; lines.length;i++){   totalHeight += fontSize;   String line = lines[i];   myWidth = textWidth(line);   if (int(myWidth) &gt; int(maxWidth)){    maxWidth = myWidth;   }  }  myWidth = int(maxWidth);   }  void restoreClip(){  imageMode(CORNER);  image(clip,clipx,clipy); }  void hide(){  restoreClip(); }   void drawText(String mText,int x,int y,int fontSize){   // Print the text to screen   fill(255);  xindent = int(myWidth*(10/128));  yindent = int(fontSize*(10/128));   text(mText,x+xindent, y-yindent); } void drawBalloon(int x,int y, int w,int h){  w = int(w);  h = int(h);  rectWidthMargin = int(w*(10/64));  rectHeightMargin = int(h*(10/64));  rounding = int(h*(10/64));  //size(200,100);  strokeWeight(2);  stroke(0,0,0,10);    fill(0,0,0,50);  roundedRect(x+shadowOffset+2,y+shadowOffset+2,w+rectWidthMargin,h+rectHeightMargin,rounding)       stroke(255,255,255,200);    fill(tbackground);  roundedRect(x,y, w+rectWidthMargin, h+rectHeightMargin,rounding)  // Highlight x,y coords... at top left...  //fill(0,0,255);  //rect(x,y,4,4); }     void display(){      if ((clip != null) &amp;&amp; (doClip)){   restoreClip();  }    // x and y are mouse coordinates, so determine where tip should be relative to that...         int bx = int(x+5);  int by = int(y-totalHeight);    rectRight = bx+myWidth +20;  rectTop = by-totalHeight+30;    rectWidthMargin = int(myWidth*(10/64));  rectHeightMargin = int(totalHeight*(10/64));    if (rectRight &gt;= width){   bx = int(x-5-myWidth-rectWidthMargin);   }     if (rectTop &lt;= 0){   by = int(y+totalHeight+rectHeightMargin);  }       // Grab whatever is going to be behind our tooltip...  imageMode(CORNER);  clip = get(bx-20,by-20,myWidth+rectWidthMargin+60,totalHeight+rectHeightMargin+60);  clipx = bx-20;  clipy = by-20;      //bx = x+10;  //by = y - totalHeight;      drawBalloon(bx,by-fontSize,myWidth,totalHeight);      drawText(mText,bx,by,fontSize) }}int r1;int g1;int b1;int r2;int g2;int b2;color start;color finish;float amt=0.01;int tooltipR=80;int tooltipG=150;int tooltipB=0;int tooltipAlpha=200;public class Sommet{  int x;  int y;  int iterX;  int iterY; color c;     public Sommet(int _x,int _y){    x = _x;    y = _y;    iterX = (int)random(-5,5);    iterY = (int)random(-5,5);  c = lerpColor(start,finish,amt);  amt+=0.02;  if (amt &gt;=1) amt =0;  }     public void update(){    x+=iterX;    if(x&gt;800) {x=0;}    if(x&lt;0)   {x=600;}                y+=iterY;    if(y&gt;600) {y=0;}       if(y&lt;0)   {y=600;}         }     public void draw(){    //fill(210, 230, 250);  fill(c);    stroke(100,150,250);    ellipse(x,y,15,15);  }     public boolean closeEnough(Sommet s){    PVector v1 = new PVector(this.x, this.y);    PVector v2 = new PVector(s.x, s.y);    if(v1.dist(v2) &lt; 100){      return true;    }    else{      return false;    } }} List list;boolean isMouseIn = false; void setup() {  //setup function called initially, only once  size(590, 300);  frameRate(30);  smooth();    create();} void create(){  randomSeed(millis()); r1 = int(round(random(0,1))*255); g1 = int(round(random(0,1))*255); b1 = int(round(random(0,1))*255); randomSeed(millis()); r2 = int(round(random(0,1))*255); g2 = int(round(random(0,1))*255); b2 = int(round(random(0,1))*255); start=color(r1,g1,b1); finish = color(random(255),random(255),random(255));  list = new ArrayList(); background(51);  //set background white  for(int i=0; i&lt;50; i++){    list.add(new Sommet((int)random(0,800), (int)random(0,600)));  }  }void keyPressed(){ if ((key == 'r') || (key == 'R')){  create(); }  if (key == 'a'){  tooltipAlpha +=10;  if (tooltipAlpha &gt;= 255) tooltipAlpha = 0; }  if (key == 'c'){  tooltipR = int(random(255));  tooltipG = int(random(255));  tooltipB = int(random(255)); } }void draw() {  //draw function loops       background(51);    for(int i=0; i&lt;50; i++){   Sommet s1 = (Sommet)list.get(i);      for(int j=0; j&lt;50; j++){        if(i!=j){          Sommet s2 = (Sommet)list.get(j);          if( s1.closeEnough(s2)){      //linecolor = lerp(s1.c,s2.c,0.1);            //stroke(linecolor);        stroke(100,150,250);            line(s1.x,s1.y,s2.x, s2.y);          }        }      }         }  // Draw dots after lines so lines appear behind dots.   for(int i = 0;i &lt; 50;i++){   Sommet s1 = (Sommet)list.get(i);    s1.draw();     s1.update();  }  // Display tooltip  x = mouseX;  y = mouseY;  if (isMouseIn){   String tipText = "Alpha: "+tooltipAlpha+"\nR: "+tooltipR+"  G: "+tooltipG+"  B: "+tooltipB+"\nmouseX= "+x+" mouseY= "+y;    toolTip = new ToolTip(x,y,tipText);   toolTip.setBackground(color(tooltipR,tooltipG,tooltipB,tooltipAlpha));   toolTip.clip=false;   toolTip.display();  }}void mouseOver(){ isMouseIn = true;}void mouseOut(){ isMouseIn = false;;}&lt;/script&gt;&lt;canvas id="pjs"&gt; &lt;/canvas&gt;&lt;br /&gt;&lt;br /&gt;You can &lt;a href="https://gist.github.com/1205509"&gt;download ToolTip.pde and test code&lt;/a&gt; from github:gist.  ToolTip.pde has instructions in it's header.    The use of this tooltip isn't limited to Processing sketches.  Since processingjs pde files are converted to pure javascript before execution, you can also use this tooltip, as well as any other &lt;a href="http://processingjs.org/"&gt;Processing.js&lt;/a&gt; library, in javascript code that writes to the canvas.  The &lt;a href="http://processingjs.org/reference/articles/jsQuickStart"&gt;Processing QuickStart for JavaScript Developers&lt;/a&gt; gives examples of how to use Processing.js libraries with pure javascript and libraries like &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt; (which, incidentally, was written by the same person who created Processing.js).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6813476980165976394-6772416092586617658?l=bayesianconspiracy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bayesianconspiracy.blogspot.com/feeds/6772416092586617658/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6813476980165976394&amp;postID=6772416092586617658' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6813476980165976394/posts/default/6772416092586617658'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6813476980165976394/posts/default/6772416092586617658'/><link rel='alternate' type='text/html' href='http://bayesianconspiracy.blogspot.com/2011/09/tooltip-class-for-html5-canvas-written.html' title='A tooltip class for HTML5 canvas written with Processing.js'/><author><name>James Durbin</name><uri>http://www.blogger.com/profile/02881091854353753739</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-n4yWF1vlZsM/Th_5FmbKhYI/AAAAAAAAAvE/uUsPcuOaRiQ/s220/10534_1122758594569_1395223040_30315740_3644162_n.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6813476980165976394.post-1307348320266960374</id><published>2011-09-02T00:14:00.000-07:00</published><updated>2011-12-23T19:22:52.022-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='blogger'/><category scheme='http://www.blogger.com/atom/ns#' term='Processing'/><category scheme='http://www.blogger.com/atom/ns#' term='processing.js'/><category scheme='http://www.blogger.com/atom/ns#' term='HTML5'/><category scheme='http://www.blogger.com/atom/ns#' term='canvas'/><title type='text'>Processing.js first impression</title><content type='html'>I've been playing around with &lt;a href="http://processingjs.org/"&gt;Processing.js&lt;/a&gt; to produce visualizations of some genomics data.    The Java based &lt;a href="http://processing.org/"&gt;Processing&lt;/a&gt; language/environment was originally developed by the noted data visualization guru &lt;a href="http://benfry.com/"&gt;Ben Fry&lt;/a&gt; and graphic artist &lt;a href="http://reas.com/"&gt;Casey Reas&lt;/a&gt;.  Processing.js is a port of the Processing language and libraries to javascript and the HTML 5 canvas by none other than &lt;a href="http://ejohn.org/"&gt;John Resig&lt;/a&gt;, the creator of the &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt; javascript library.   I was skeptical at first that Processing.js would be anything but a pale shadow of it's Processing predecessor, but after using it for a bit I have to say that I am impressed.&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;Most of the Processing sketches one can find scattered around the web and on such sites as &lt;a href="http://www.openprocessing.org/"&gt;Open Processing&lt;/a&gt; just work.   Here, for example, is a sketch from the examples on Processing.org called &lt;a href="http://processing.org/learning/topics/reflection2.html"&gt;reflection2.&lt;/a&gt; &lt;i&gt;Click on image to launch another ball.  Once the canvas element has focus, type 'r' to draw a new ground.&lt;/i&gt;:&lt;br /&gt;&lt;script type="application/processing"&gt;Orb orb;PVector velocity;float gravity = .05, damping = 0.8;int segments = 40;Ground[] ground = new Ground[segments];float[] peakHeights = new float[segments+1];color green1 = color(181,207,107);color green2 = color(206,219,156);color green3 = color(140,162,82);color green4 = color(100,107,74);color gray = color(238,238,238);color[] colors = { color(51,51,255), color(51,255,51), color(255,51,51), color(102,255,255), color(255,255,51), color(51,255,255), color(255,51,255)};void setup(){  background(51);  size(590, 120);  smooth();  orb = new Orb(80,0, 3);  velocity = new PVector(1,4);  // Calculate ground peak heights   for (int i=0; i&lt;peakHeights.length; i++){    peakHeights[i] = random(height-40, height-15);  }  /* Float value required for segment width (segs)   calculations so the ground spans the entire    display window, regardless of segment number. */  float segs = segments;  for (int i=0; i&lt;segments; i++){    ground[i]  = new Ground(width/segs*i, peakHeights[i],    width/segs*(i+1), peakHeights[i+1]);  }}void keyPressed(){ if ((key == 'r') || (key == 'R')){  // Calculate ground peak heights    for (int i=0; i&lt;peakHeights.length; i++){     peakHeights[i] = random(height-40, height-15);   }   /* Float value required for segment width (segs)    calculations so the ground spans the entire     display window, regardless of segment number. */   float segs = segments;   for (int i=0; i&lt;segments; i++){     ground[i]  = new Ground(width/segs*i, peakHeights[i],      width/segs*(i+1), peakHeights[i+1]);   } }}void mouseClicked(){ float x = random(0,500); orb = new Orb(x,0,3); float dx = random(1,4); float dy = random(0.5,2); velocity = new PVector(dx,dy);}void draw(){  // Background  noStroke();  //fill(51, 15);  fill(51,30);  rect(0, 0, width, height);  // Move orb  orb.x += velocity.x;  velocity.y += gravity;  orb.y += velocity.y;  // Draw ground  fill(green4);  beginShape();  for (int i=0; i&lt;segments; i++){    vertex(ground[i].x1, ground[i].y1);    vertex(ground[i].x2, ground[i].y2);  }  vertex(ground[segments-1].x2, height);  vertex(ground[0].x1, height);  endShape(CLOSE);  // Draw orb  noStroke();  fill(orb.c);  ellipse(orb.x, orb.y, orb.r*2, orb.r*2);  // Collision detection  checkWallCollision();  for (int i=0; i&lt;segments; i++){    checkGroundCollision(ground[i]);  }}void checkWallCollision(){  if (orb.x &gt; width-orb.r){    orb.x = width-orb.r;    velocity.x *= -1;    velocity.x *= damping;  }   else if (orb.x &lt; orb.r){    orb.x = orb.r;    velocity.x *= -1;    velocity.x *= damping;  }}void checkGroundCollision(Ground groundSegment) {  // Get difference between orb and ground  float deltaX = orb.x - groundSegment.x;  float deltaY = orb.y - groundSegment.y;  // Precalculate trig values  float cosine = cos(groundSegment.rot);  float sine = sin(groundSegment.rot);  /* Rotate ground and velocity to allow    orthogonal collision calculations */  float groundXTemp = cosine * deltaX + sine * deltaY;  float groundYTemp = cosine * deltaY - sine * deltaX;  float velocityXTemp = cosine * velocity.x + sine * velocity.y;  float velocityYTemp = cosine * velocity.y - sine * velocity.x;  /* Ground collision - check for surface    collision and also that orb is within    left/rights bounds of ground segment */  if (groundYTemp &gt; -orb.r &amp;&amp;    orb.x &gt; groundSegment.x1 &amp;&amp;    orb.x &lt; groundSegment.x2 ){    // keep orb from going into ground    groundYTemp = -orb.r;    // bounce and slow down orb    velocityYTemp *= -1.0;    velocityYTemp *= damping;  }  // Reset ground, velocity and orb  deltaX = cosine * groundXTemp - sine * groundYTemp;  deltaY = cosine * groundYTemp + sine * groundXTemp;  velocity.x = cosine * velocityXTemp - sine * velocityYTemp;  velocity.y = cosine * velocityYTemp + sine * velocityXTemp;  orb.x = groundSegment.x + deltaX;  orb.y = groundSegment.y + deltaY;}class Ground {  float x1, y1, x2, y2;    float x, y, len, rot;  // Default constructor  Ground(){  }  // Constructor  Ground(float x1, float y1, float x2, float y2) {    this.x1 = x1;    this.y1 = y1;    this.x2 = x2;    this.y2 = y2;    x = (x1+x2)/2;    y = (y1+y2)/2;    len = dist(x1, y1, x2, y2);    rot = atan2((y2-y1), (x2-x1));  }}class Orb{  float x, y, r; color c;  // Default constructor  Orb() {   }  Orb(float x, float y, float r) {    this.x = x;    this.y = y;    this.r = r;  cidx = int(random(0,7));  c = colors[cidx];  }}&lt;/script&gt;&lt;canvas height="100" width="200"&gt;&lt;/canvas&gt;&lt;br /&gt;&lt;br /&gt;The only requirement for this sketch to work is a browser that supports the HTML5 canvas.  While it's not close to the speed of Processing compiled to JVM bytecode, the performance isn't bad at all and seems more than adequate for a wide range of visualization tasks.  This is a testimony to the performance work that has been going into browser javascript engines as well as to the efforts put into optimizing processing.js itself.   Embedding processing.js scripts in blogger, as I have done here, also turns out to be quite easy.  Just add a script tag to grab the processing.js library to an (old style) blogger template and another script tag embedded in the post containing the processing code (view source to see both tags).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6813476980165976394-1307348320266960374?l=bayesianconspiracy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bayesianconspiracy.blogspot.com/feeds/1307348320266960374/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6813476980165976394&amp;postID=1307348320266960374' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6813476980165976394/posts/default/1307348320266960374'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6813476980165976394/posts/default/1307348320266960374'/><link rel='alternate' type='text/html' href='http://bayesianconspiracy.blogspot.com/2011/09/embedding-processingjs-scripts-in.html' title='Processing.js first impression'/><author><name>James Durbin</name><uri>http://www.blogger.com/profile/02881091854353753739</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-n4yWF1vlZsM/Th_5FmbKhYI/AAAAAAAAAvE/uUsPcuOaRiQ/s220/10534_1122758594569_1395223040_30315740_3644162_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6813476980165976394.post-5772487574056468028</id><published>2011-07-25T17:32:00.001-07:00</published><updated>2011-12-23T19:23:10.180-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Gibbs sampling'/><category scheme='http://www.blogger.com/atom/ns#' term='MCMC'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>Gibbs sampler in Groovy</title><content type='html'>I recently read a couple of nice articles by Darren Wilkinson about implementing MCMC in various languages.  The posts are &lt;a href="http://darrenjw.wordpress.com/2010/04/28/mcmc-programming-in-r-python-java-and-c/"&gt;here &lt;/a&gt; and &lt;a href="http://darrenjw.wordpress.com/2011/07/16/gibbs-sampler-in-various-languages-revisited/"&gt;here&lt;/a&gt;.    Wilkinson apparently uses, or is considering using, Python for a lot of prototyping and C for a lot of his actual MCMC runs.  However, since he feels that Java is in some ways nicer than C,  and almost as fast, he has been using Java some also for the final MCMC runs.   I thought I'd see how Groovy performed on this task. &lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;  A Groovy version of Wilkinson's Gibbs sampler is given here:  &lt;br /&gt;&lt;br /&gt;&lt;pre class="textmate-source blogbb"&gt;&lt;span class="source source_groovy"&gt;#&lt;span class="keyword keyword_operator keyword_operator_logical keyword_operator_logical_groovy"&gt;!&lt;/span&gt;&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;/&lt;/span&gt;usr&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;/&lt;/span&gt;bin&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;/&lt;/span&gt;env groovy &lt;br /&gt;&lt;br /&gt;&lt;span class="meta meta_import meta_import_groovy"&gt;&lt;span class="keyword keyword_other keyword_other_class-fns keyword_other_class-fns_groovy"&gt;import&lt;/span&gt; &lt;span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_groovy"&gt;static&lt;/span&gt;&lt;/span&gt; &lt;span class="storage storage_type storage_type_groovy"&gt;java.lang.Math&lt;/span&gt;.&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;*&lt;/span&gt;&lt;br /&gt;&lt;span class="meta meta_import meta_import_groovy"&gt;&lt;span class="keyword keyword_other keyword_other_class-fns keyword_other_class-fns_groovy"&gt;import&lt;/span&gt; &lt;span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_groovy"&gt;cern.jet.random.tdouble.engine.*&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="meta meta_import meta_import_groovy"&gt;&lt;span class="keyword keyword_other keyword_other_class-fns keyword_other_class-fns_groovy"&gt;import&lt;/span&gt; &lt;span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_groovy"&gt;cern.jet.random.tdouble.*&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;N=&lt;span class="constant constant_numeric constant_numeric_groovy"&gt;20000&lt;/span&gt;&lt;br /&gt;thin=&lt;span class="constant constant_numeric constant_numeric_groovy"&gt;500&lt;/span&gt;&lt;br /&gt;rngEngine= &lt;span class="keyword keyword_other keyword_other_class-fns keyword_other_class-fns_groovy"&gt;new&lt;/span&gt; &lt;span class="storage storage_type storage_type_groovy"&gt;DoubleMersenneTwister&lt;/span&gt;(&lt;span class="keyword keyword_other keyword_other_class-fns keyword_other_class-fns_groovy"&gt;new&lt;/span&gt; &lt;span class="support support_type support_type_built-ins support_type_built-ins_groovy"&gt;Date&lt;/span&gt;())&lt;br /&gt;rngN= &lt;span class="keyword keyword_other keyword_other_class-fns keyword_other_class-fns_groovy"&gt;new&lt;/span&gt; &lt;span class="storage storage_type storage_type_groovy"&gt;Normal&lt;/span&gt;(&lt;span class="constant constant_numeric constant_numeric_groovy"&gt;0.0&lt;/span&gt;,&lt;span class="constant constant_numeric constant_numeric_groovy"&gt;1.0&lt;/span&gt;,rngEngine)&lt;br /&gt;rngG= &lt;span class="keyword keyword_other keyword_other_class-fns keyword_other_class-fns_groovy"&gt;new&lt;/span&gt; &lt;span class="storage storage_type storage_type_groovy"&gt;Gamma&lt;/span&gt;(&lt;span class="constant constant_numeric constant_numeric_groovy"&gt;1.0&lt;/span&gt;,&lt;span class="constant constant_numeric constant_numeric_groovy"&gt;1.0&lt;/span&gt;,rngEngine)&lt;br /&gt;x=y=&lt;span class="constant constant_numeric constant_numeric_groovy"&gt;0.0&lt;/span&gt;&lt;br /&gt;println(&lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;"Iter x y"&lt;/span&gt;)&lt;br /&gt;&lt;span class="keyword keyword_control keyword_control_groovy"&gt;for&lt;/span&gt;(i in &lt;span class="constant constant_numeric constant_numeric_groovy"&gt;1&lt;/span&gt;..N){&lt;br /&gt;  &lt;span class="keyword keyword_control keyword_control_groovy"&gt;for&lt;/span&gt;(j in &lt;span class="constant constant_numeric constant_numeric_groovy"&gt;1&lt;/span&gt;..thin){&lt;br /&gt;    x=rngG.nextDouble(&lt;span class="constant constant_numeric constant_numeric_groovy"&gt;3.0&lt;/span&gt;,y&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;*&lt;/span&gt;y&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;+&lt;/span&gt;&lt;span class="constant constant_numeric constant_numeric_groovy"&gt;4&lt;/span&gt;)&lt;br /&gt;    y=rngN.nextDouble(&lt;span class="constant constant_numeric constant_numeric_groovy"&gt;1.0&lt;/span&gt;&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;/&lt;/span&gt;(x&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;+&lt;/span&gt;&lt;span class="constant constant_numeric constant_numeric_groovy"&gt;1&lt;/span&gt;),&lt;span class="constant constant_numeric constant_numeric_groovy"&gt;1.0&lt;/span&gt;&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;/&lt;/span&gt;sqrt(x&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;+&lt;/span&gt;&lt;span class="constant constant_numeric constant_numeric_groovy"&gt;1&lt;/span&gt;))&lt;br /&gt;  }&lt;br /&gt;  println(&lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;"$i $x $y"&lt;/span&gt;)&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;You'd run it like:&lt;br /&gt;&lt;pre class="textmate-source blogbb"&gt;./Gibbs.gv &amp;gt; data.tab&lt;/pre&gt;&lt;br /&gt;On a Macbook Pro 2.2 GHz Intel Core 2 Duo, comparing Wilkinson's Java (1.6.1) and Python (2.7.2) versions with my Groovy (1.8.0) version, I get the following times: &lt;br /&gt;&lt;ul&gt;&lt;li&gt; java: 5.23 sec&lt;/li&gt;&lt;li&gt; python: 1m49s &lt;/li&gt;&lt;li&gt; groovy: 16.5s&lt;/li&gt;&lt;/ul&gt;Not bad for a dynamic scripting language!  Now, there are lots of things one can do to speed up the Python code, from using pypy to calling native functions and so on, so this is nowhere close to optimal for Python but,  if you're going to ultimately translate your prototype into Java or C anyway, why bother with Python at all when you can rapid-prototype in Groovy then do the simple translation to Java, using the same libraries, later?  Moreover, at one third the speed of Java, many times you won't even need to bother with the final speed-up step.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6813476980165976394-5772487574056468028?l=bayesianconspiracy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bayesianconspiracy.blogspot.com/feeds/5772487574056468028/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6813476980165976394&amp;postID=5772487574056468028' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6813476980165976394/posts/default/5772487574056468028'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6813476980165976394/posts/default/5772487574056468028'/><link rel='alternate' type='text/html' href='http://bayesianconspiracy.blogspot.com/2011/07/gibbs-sampler-in-groovy_25.html' title='Gibbs sampler in Groovy'/><author><name>James Durbin</name><uri>http://www.blogger.com/profile/02881091854353753739</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-n4yWF1vlZsM/Th_5FmbKhYI/AAAAAAAAAvE/uUsPcuOaRiQ/s220/10534_1122758594569_1395223040_30315740_3644162_n.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6813476980165976394.post-963686348587173472</id><published>2010-07-05T22:33:00.000-07:00</published><updated>2011-12-23T19:23:20.576-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='groovlet'/><category scheme='http://www.blogger.com/atom/ns#' term='AJAX'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>Using Groovlets in jQuery tutorial.</title><content type='html'>I've been learning a little about jQuery by going through the &lt;a href="http://docs.jquery.com/Tutorials:Getting_Started_with_jQuery"&gt; excellent jQuery tutorial&lt;/a&gt; over at the &lt;a href="http://docs.jquery.com/Main_Page"&gt;jQuery Docs page&lt;/a&gt;.  The examples use php for server side code, but since I'm more familiar with Servlets/&lt;a href="http://groovy.codehaus.org/Groovlets"&gt;Groovlets&lt;/a&gt;, I decided do the server side code as a Groovlet.&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;First, the setup.   After &lt;a href="http://developer.apple.com/internet/java/tomcat1.html"&gt;installing Tomcat&lt;/a&gt;, I created a sub-directory under webapps called sandbox.  In sandbox, I created a sandbox/WEB-INF directory with a lib sub directory.  I copied all of /usr/local/groovy/lib/ to sandbox/WEB-INF/lib/, though only some of it is needed.  I then put the following web.xml file under sandbox/WEB-INF/&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;pre class="textmate-source blogbb"&gt;&lt;span class="text text_xml"&gt;&lt;span class="meta meta_tag meta_tag_xml"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;lt;&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_localname entity_name_tag_localname_xml"&gt;web-app&lt;/span&gt; &lt;span class="entity entity_other entity_other_attribute-name entity_other_attribute-name_localname entity_other_attribute-name_localname_xml"&gt;xmlns&lt;/span&gt;=&lt;span class="string string_quoted string_quoted_double string_quoted_double_xml"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_xml"&gt;"&lt;/span&gt;http://java.sun.com/xml/ns/javaee&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_xml"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;  xmlns:xsi=&lt;span class="string string_quoted string_quoted_double string_quoted_double_xml"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_xml"&gt;"&lt;/span&gt;http://www.w3.org/2001/XMLSchema-instance&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_xml"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;  xsi:schemaLocation=&lt;span class="string string_quoted string_quoted_double string_quoted_double_xml"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_xml"&gt;"&lt;/span&gt;http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_xml"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;  version=&lt;span class="string string_quoted string_quoted_double string_quoted_double_xml"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_xml"&gt;"&lt;/span&gt;2.5&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_xml"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class="meta meta_tag meta_tag_xml"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;lt;&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_localname entity_name_tag_localname_xml"&gt;display-name&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Groove&lt;span class="meta meta_tag meta_tag_xml"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_localname entity_name_tag_localname_xml"&gt;display-name&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="meta meta_tag meta_tag_xml"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;lt;&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_localname entity_name_tag_localname_xml"&gt;servlet&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;      &lt;span class="meta meta_tag meta_tag_xml"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;lt;&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_localname entity_name_tag_localname_xml"&gt;servlet-name&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;GroovyServlet&lt;span class="meta meta_tag meta_tag_xml"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_localname entity_name_tag_localname_xml"&gt;servlet-name&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;      &lt;span class="meta meta_tag meta_tag_xml"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;lt;&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_localname entity_name_tag_localname_xml"&gt;servlet-class&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;groovy.servlet.GroovyServlet&lt;span class="meta meta_tag meta_tag_xml"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_localname entity_name_tag_localname_xml"&gt;servlet-class&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="meta meta_tag meta_tag_xml"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_localname entity_name_tag_localname_xml"&gt;servlet&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="meta meta_tag meta_tag_xml"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;lt;&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_localname entity_name_tag_localname_xml"&gt;servlet&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="meta meta_tag meta_tag_xml"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;lt;&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_localname entity_name_tag_localname_xml"&gt;servlet-name&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;GroovyTemplate&lt;span class="meta meta_tag meta_tag_xml"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_localname entity_name_tag_localname_xml"&gt;servlet-name&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="meta meta_tag meta_tag_xml"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;lt;&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_localname entity_name_tag_localname_xml"&gt;servlet-class&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;groovy.servlet.TemplateServlet&lt;span class="meta meta_tag meta_tag_xml"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_localname entity_name_tag_localname_xml"&gt;servlet-class&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;    &lt;br /&gt;  &lt;span class="meta meta_tag meta_tag_xml"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_localname entity_name_tag_localname_xml"&gt;servlet&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="meta meta_tag meta_tag_xml"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;lt;&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_localname entity_name_tag_localname_xml"&gt;servlet-mapping&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="meta meta_tag meta_tag_xml"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;lt;&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_localname entity_name_tag_localname_xml"&gt;servlet-name&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;GroovyServlet&lt;span class="meta meta_tag meta_tag_xml"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_localname entity_name_tag_localname_xml"&gt;servlet-name&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="meta meta_tag meta_tag_xml"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;lt;&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_localname entity_name_tag_localname_xml"&gt;url-pattern&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;*.groovy&lt;span class="meta meta_tag meta_tag_xml"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_localname entity_name_tag_localname_xml"&gt;url-pattern&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="meta meta_tag meta_tag_xml"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_localname entity_name_tag_localname_xml"&gt;servlet-mapping&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="meta meta_tag meta_tag_xml"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;lt;&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_localname entity_name_tag_localname_xml"&gt;servlet-mapping&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="meta meta_tag meta_tag_xml"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;lt;&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_localname entity_name_tag_localname_xml"&gt;servlet-name&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;GroovyTemplate&lt;span class="meta meta_tag meta_tag_xml"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_localname entity_name_tag_localname_xml"&gt;servlet-name&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="meta meta_tag meta_tag_xml"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;lt;&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_localname entity_name_tag_localname_xml"&gt;url-pattern&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;*.gsp&lt;span class="meta meta_tag meta_tag_xml"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_localname entity_name_tag_localname_xml"&gt;url-pattern&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="meta meta_tag meta_tag_xml"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_localname entity_name_tag_localname_xml"&gt;servlet-mapping&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="meta meta_tag meta_tag_xml"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_localname entity_name_tag_localname_xml"&gt;web-app&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_xml"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;This web.xml will tell Tomcat to use groovy.servlet.GroovyServlet to handle *.groovy files.  From then on, any .groovy files you put under /sandbox (or any subdirectories thereof) will be compiled as a &lt;a href="http://groovy.codehaus.org/Groovlets"&gt;Groovlet&lt;/a&gt; by Tomcat.  &lt;br /&gt;&lt;br /&gt;I then downloaded the &lt;a href="http://docs.jquery.com/images/c/c7/Jquery-starterkit.zip"&gt;jquery-starterkit&lt;/a&gt; from the jquery site and unpacked it into sandbox/jqstarterkit.   In jqstarterkit are a number of files, custom.js, rate.php, screen.css, and starterkit.html.   You will need to &lt;a href="http://code.jquery.com/jquery-1.4.2.min.js"&gt;download jquery itself&lt;/a&gt; into /sandbox/jqstarterkit/ and rename it to /sandbox/jqstarterkit/jquery.min.js.  Then &lt;a href="http://docs.jquery.com/Tutorials:Getting_Started_with_jQuery"&gt;go through the tutorial&lt;/a&gt;, editing custom.js to include the custom bits of jQuery javascript in the tutorial, seeing the results in:&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;http://localhost:8080/sandbox/jqstarterkit/starterkit.html&lt;/div&gt;&lt;br /&gt;When you get to the part about rate.php, simply replace rate.php with rate.groovy in the custom.js script, like so:&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;pre class="textmate-source blogbb"&gt;&lt;span class="source source_js"&gt;jQuery&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;(&lt;/span&gt;&lt;span class="support support_class support_class_js"&gt;document&lt;/span&gt;&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;)&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;ready&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;(&lt;/span&gt;&lt;span class="storage storage_type storage_type_js"&gt;function&lt;/span&gt;&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;()&lt;/span&gt;&lt;span class="meta meta_brace meta_brace_curly meta_brace_curly_js"&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js"&gt;//&lt;/span&gt; generate markup&lt;/span&gt;  &lt;span class="keyword keyword_operator keyword_operator_js"&gt;$&lt;/span&gt;&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;(&lt;/span&gt;&lt;span class="string string_quoted string_quoted_double string_quoted_double_js"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js"&gt;"&lt;/span&gt;#rating&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;)&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;append&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;(&lt;/span&gt;&lt;span class="string string_quoted string_quoted_double string_quoted_double_js"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js"&gt;"&lt;/span&gt; Please rate: &lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;)&lt;/span&gt;&lt;span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="keyword keyword_control keyword_control_js"&gt;for&lt;/span&gt; &lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;(&lt;/span&gt; &lt;span class="storage storage_type storage_type_js"&gt;var&lt;/span&gt; i &lt;span class="keyword keyword_operator keyword_operator_js"&gt;=&lt;/span&gt; &lt;span class="constant constant_numeric constant_numeric_js"&gt;1&lt;/span&gt;&lt;span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js"&gt;;&lt;/span&gt; i &lt;span class="keyword keyword_operator keyword_operator_js"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="constant constant_numeric constant_numeric_js"&gt;10&lt;/span&gt;&lt;span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js"&gt;;&lt;/span&gt; i&lt;span class="keyword keyword_operator keyword_operator_js"&gt;++&lt;/span&gt; &lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword keyword_operator keyword_operator_js"&gt;$&lt;/span&gt;&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;(&lt;/span&gt;&lt;span class="string string_quoted string_quoted_double string_quoted_double_js"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js"&gt;"&lt;/span&gt;#rating&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;)&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;append&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;(&lt;/span&gt;&lt;span class="string string_quoted string_quoted_double string_quoted_double_js"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js"&gt;"&lt;/span&gt;&amp;lt;a href='#'&amp;gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_js"&gt;+&lt;/span&gt; i &lt;span class="keyword keyword_operator keyword_operator_js"&gt;+&lt;/span&gt; &lt;span class="string string_quoted string_quoted_double string_quoted_double_js"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js"&gt;"&lt;/span&gt;&amp;lt;/a&amp;gt; &lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;)&lt;/span&gt;&lt;span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js"&gt;//&lt;/span&gt; add markup to container and apply click handlers to anchors&lt;/span&gt;  &lt;span class="keyword keyword_operator keyword_operator_js"&gt;$&lt;/span&gt;&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;(&lt;/span&gt;&lt;span class="string string_quoted string_quoted_double string_quoted_double_js"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js"&gt;"&lt;/span&gt;#rating a&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;)&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;&lt;span class="support support_function support_function_dom support_function_dom_js"&gt;click&lt;/span&gt;&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;(&lt;/span&gt;&lt;span class="storage storage_type storage_type_js"&gt;function&lt;/span&gt;&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;(&lt;/span&gt;e&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;)&lt;/span&gt;&lt;span class="meta meta_brace meta_brace_curly meta_brace_curly_js"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js"&gt;//&lt;/span&gt; stop normal link click&lt;/span&gt;    e&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;preventDefault&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;()&lt;/span&gt;&lt;span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js"&gt;//&lt;/span&gt; send request&lt;/span&gt;    &lt;span class="keyword keyword_operator keyword_operator_js"&gt;$&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;post&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;(&lt;/span&gt;&lt;span class="string string_quoted string_quoted_double string_quoted_double_js"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js"&gt;"&lt;/span&gt;rate.groovy&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js"&gt;, &lt;/span&gt;&lt;span class="meta meta_brace meta_brace_curly meta_brace_curly_js"&gt;{&lt;/span&gt;rating: &lt;span class="keyword keyword_operator keyword_operator_js"&gt;$&lt;/span&gt;&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;(&lt;/span&gt;&lt;span class="variable variable_language variable_language_js"&gt;this&lt;/span&gt;&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;)&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;html&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;()&lt;/span&gt;&lt;span class="meta meta_brace meta_brace_curly meta_brace_curly_js"&gt;}&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js"&gt;, &lt;/span&gt;&lt;span class="storage storage_type storage_type_js"&gt;function&lt;/span&gt;&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;(&lt;/span&gt;xml&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;)&lt;/span&gt; &lt;span class="meta meta_brace meta_brace_curly meta_brace_curly_js"&gt;{&lt;/span&gt;&lt;br /&gt;      &lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js"&gt;//&lt;/span&gt; format and output result&lt;/span&gt;      &lt;span class="keyword keyword_operator keyword_operator_js"&gt;$&lt;/span&gt;&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;(&lt;/span&gt;&lt;span class="string string_quoted string_quoted_double string_quoted_double_js"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js"&gt;"&lt;/span&gt;#rating&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;)&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;html&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;(&lt;/span&gt;&lt;br /&gt;        &lt;span class="string string_quoted string_quoted_double string_quoted_double_js"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js"&gt;"&lt;/span&gt;Thanks for rating, current average: &lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_js"&gt;+&lt;/span&gt;&lt;br /&gt;        &lt;span class="keyword keyword_operator keyword_operator_js"&gt;$&lt;/span&gt;&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;(&lt;/span&gt;&lt;span class="string string_quoted string_quoted_double string_quoted_double_js"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js"&gt;"&lt;/span&gt;average&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js"&gt;, &lt;/span&gt;xml&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;)&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;&lt;span class="support support_constant support_constant_dom support_constant_dom_js"&gt;text&lt;/span&gt;&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;()&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_js"&gt;+&lt;/span&gt;&lt;br /&gt;        &lt;span class="string string_quoted string_quoted_double string_quoted_double_js"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js"&gt;"&lt;/span&gt;, number of votes: &lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_js"&gt;+&lt;/span&gt;&lt;br /&gt;        &lt;span class="keyword keyword_operator keyword_operator_js"&gt;$&lt;/span&gt;&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;(&lt;/span&gt;&lt;span class="string string_quoted string_quoted_double string_quoted_double_js"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js"&gt;"&lt;/span&gt;count&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js"&gt;, &lt;/span&gt;xml&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;)&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;&lt;span class="support support_constant support_constant_dom support_constant_dom_js"&gt;text&lt;/span&gt;&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;()&lt;/span&gt;&lt;br /&gt;      &lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;)&lt;/span&gt;&lt;span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class="meta meta_brace meta_brace_curly meta_brace_curly_js"&gt;}&lt;/span&gt;&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;)&lt;/span&gt;&lt;span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js"&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class="meta meta_brace meta_brace_curly meta_brace_curly_js"&gt;}&lt;/span&gt;&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;)&lt;/span&gt;&lt;span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="meta meta_brace meta_brace_curly meta_brace_curly_js"&gt;}&lt;/span&gt;&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;)&lt;/span&gt;&lt;span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Then, create a file rate.groovy with the following contents:&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;pre class="textmate-source blogbb"&gt;&lt;span class="source source_groovy"&gt;&lt;br /&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;// Simple AJAX groovlet... takes a rating from a jQuery $.post()&lt;/span&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;// saves it to a file, computes the running average, then &lt;/span&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;// returns a status line in XML format...&lt;/span&gt;&lt;br /&gt;rating = request.getParameter(&lt;span class="string string_quoted string_quoted_single string_quoted_single_groovy"&gt;'rating'&lt;/span&gt;)&lt;br /&gt;f = &lt;span class="keyword keyword_other keyword_other_class-fns keyword_other_class-fns_groovy"&gt;new&lt;/span&gt; &lt;span class="support support_type support_type_built-ins support_type_built-ins_groovy"&gt;File&lt;/span&gt;(&lt;span class="string string_quoted string_quoted_single string_quoted_single_groovy"&gt;'sandbox/jqstarterkit/ratings.dat'&lt;/span&gt;)&lt;br /&gt;f &lt;span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_groovy"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;"$rating&lt;span class="constant constant_character constant_character_escape constant_character_escape_groovy"&gt;\n&lt;/span&gt;"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;// Now, read in the file and compute number of ratings&lt;/span&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;// and average rating...&lt;/span&gt;sum = &lt;span class="constant constant_numeric constant_numeric_groovy"&gt;0&lt;/span&gt;;&lt;br /&gt;count = &lt;span class="constant constant_numeric constant_numeric_groovy"&gt;0&lt;/span&gt;;&lt;br /&gt;f.eachLine{&lt;br /&gt;  sum&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;+&lt;/span&gt;= (it as &lt;span class="storage storage_type storage_type_groovy"&gt;int&lt;/span&gt;)&lt;br /&gt;  count&lt;span class="keyword keyword_operator keyword_operator_increment-decrement keyword_operator_increment-decrement_groovy"&gt;++&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;avg = (&lt;span class="storage storage_type storage_type_groovy"&gt;double&lt;/span&gt;)sum&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;/&lt;/span&gt;(&lt;span class="storage storage_type storage_type_groovy"&gt;double&lt;/span&gt;)count&lt;br /&gt;&lt;br /&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;// Report result back to jQuery&lt;/span&gt;&lt;br /&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;// In Groovlet, html is bound to new MarkupBuilder(out) by default&lt;/span&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;// so the following bit of markup substitutes for this string:&lt;/span&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;//  out&amp;lt;&amp;lt;"""&lt;/span&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;//  &amp;lt;ratings&amp;gt;&lt;/span&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;//    &amp;lt;average&amp;gt;$avg&amp;lt;/average&amp;gt;&lt;/span&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;//    &amp;lt;count&amp;gt;$count&amp;lt;/count&amp;gt;&lt;/span&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;//  &amp;lt;/ratings&amp;gt;"""&lt;/span&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;// &lt;/span&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;// out itself is bound to response.getOutputStream()&lt;/span&gt;html.ratings(){&lt;br /&gt;  average(&lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;"$avg"&lt;/span&gt;)&lt;br /&gt;  count(&lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;"$count"&lt;/span&gt;)&lt;br /&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;When a .groovy file is interpreted as a Groovlet, several variables are pre-bound.  request, for example, is bound to ServeletRequest.  See the full list of bindings in the &lt;a href="http://groovy.codehaus.org/Groovlets"&gt;Groovlet docs&lt;/a&gt;.   It took me a bit of trial and error to get all of this right and working.  Hopefully this boilerplate will help someone else get up and going even quicker.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6813476980165976394-963686348587173472?l=bayesianconspiracy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bayesianconspiracy.blogspot.com/feeds/963686348587173472/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6813476980165976394&amp;postID=963686348587173472' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6813476980165976394/posts/default/963686348587173472'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6813476980165976394/posts/default/963686348587173472'/><link rel='alternate' type='text/html' href='http://bayesianconspiracy.blogspot.com/2010/07/using-groovlets-in-jquery-tutorial.html' title='Using Groovlets in jQuery tutorial.'/><author><name>James Durbin</name><uri>http://www.blogger.com/profile/02881091854353753739</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-n4yWF1vlZsM/Th_5FmbKhYI/AAAAAAAAAvE/uUsPcuOaRiQ/s220/10534_1122758594569_1395223040_30315740_3644162_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6813476980165976394.post-1997999346832093685</id><published>2010-03-27T16:49:00.000-07:00</published><updated>2010-03-31T17:18:13.780-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sql'/><category scheme='http://www.blogger.com/atom/ns#' term='csv'/><category scheme='http://www.blogger.com/atom/ns#' term='h2'/><category scheme='http://www.blogger.com/atom/ns#' term='command line'/><category scheme='http://www.blogger.com/atom/ns#' term='database'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>gcsvsql</title><content type='html'>I have encapsulated the ideas from the last post into a single script that will allow you to perform SQL queries on CSV files from the command line as though those CSV files were existing database tables in MYSQL or something.    &lt;br /&gt;&lt;br /&gt;With gcsvsql, you can do things like: &lt;pre class="textmate-source blogbb"&gt;&lt;span class="source source_groovy"&gt;&lt;span class="string string_quoted string_quoted_single string_quoted_single_groovy"&gt;&lt;br /&gt;gcsvsql "select * from people.csv where age &amp;gt; 40"&lt;br /&gt;gcsvsql "select name,score from people.csv where age &amp;gt;40"&lt;br /&gt;gcsvsql "select name,score from people.csv where age &amp;lt;50 and score &amp;gt; 100"&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;Full path names should work fine: &lt;pre class="textmate-source blogbb"&gt;&lt;span class="source source_groovy"&gt;&lt;span class="string string_quoted string_quoted_single string_quoted_single_groovy"&gt; &lt;br /&gt;gcsvsql "select * from /users/data/people.csv where age &amp;gt; 40"&lt;br /&gt;gcsvsql "select people.name from /users/data/people.csv where age &amp;gt; 40"&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;You can even do queries with sum and average and so on like:&lt;pre class="textmate-source blogbb"&gt;&lt;span class="source source_groovy"&gt;&lt;span class="string string_quoted string_quoted_single string_quoted_single_groovy"&gt;&lt;br /&gt;gcsvsql "select sum(score) from people.csv where age &amp;lt; 40"&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;If children.csv is a file with same key name as people, then you can join query like: &lt;pre class="textmate-source blogbb"&gt;&lt;span class="source source_groovy"&gt;&lt;span class="string string_quoted string_quoted_single string_quoted_single_groovy"&gt;  &lt;br /&gt;gcsvsql "select people.name,children.child from people.csv,children.csv where people.name=children.name"&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;You can also enter the query on multiple lines like:&lt;pre class="textmate-source blogbb"&gt;&lt;span class="source source_groovy"&gt;&lt;span class="string string_quoted string_quoted_single string_quoted_single_groovy"&gt; &lt;br /&gt;gcsvsql "&lt;br /&gt;&amp;gt; select people.name,children.child&lt;br /&gt;&amp;gt; from people.csv,children.csv&lt;br /&gt;&amp;gt; where people.name=children.name and people.age &amp;lt; 40"&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;If this sounds interesting or useful to you, get more details and download the script over at the &lt;a href="http://code.google.com/p/gcsvsql/"&gt; Google code project for gcsvsql&lt;/a&gt;&lt;br /&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6813476980165976394-1997999346832093685?l=bayesianconspiracy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bayesianconspiracy.blogspot.com/feeds/1997999346832093685/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6813476980165976394&amp;postID=1997999346832093685' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6813476980165976394/posts/default/1997999346832093685'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6813476980165976394/posts/default/1997999346832093685'/><link rel='alternate' type='text/html' href='http://bayesianconspiracy.blogspot.com/2010/03/gcsvsql.html' title='gcsvsql'/><author><name>James Durbin</name><uri>http://www.blogger.com/profile/02881091854353753739</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-n4yWF1vlZsM/Th_5FmbKhYI/AAAAAAAAAvE/uUsPcuOaRiQ/s220/10534_1122758594569_1395223040_30315740_3644162_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6813476980165976394.post-696183084720009910</id><published>2010-02-05T00:29:00.001-08:00</published><updated>2010-03-31T17:16:31.521-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sql'/><category scheme='http://www.blogger.com/atom/ns#' term='csv'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='h2'/><category scheme='http://www.blogger.com/atom/ns#' term='database'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>Executing arbitrary SQL on CSV files.</title><content type='html'>My life is full of comma separated value files.  A common occurrence is to be given a csv file of data and want to explore it a little bit to see what is there, or to extract several columns of data out of the csv file and create a new csv file, or grab only certain columns of data and certain rows of data and create a new csv file.   Quite often I find that I even need to join one csv file with another csv file.    Each time I'm faced with this task I find that what I want is to do execute sql statements on the csv file itself.  After ages of writing one-off scripts to process files like these, I finally looked into actually treating csv files as databases.   It turns out that the &lt;a href="http://www.h2database.com/html/main.html"&gt;h2 database engine&lt;/a&gt; has good support for both in-memory databases and csv file importing.   With Groovy, it's very nice.   Simply &lt;a href="http://www.h2database.com/html/download.html"&gt;download the h2 database jar&lt;/a&gt; and drop it in your ~/.groovy/lib/ directory.    Then you can write code like this:&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;pre class="textmate-source blogbb"&gt;&lt;span class="source source_groovy"&gt;#&lt;span class="keyword keyword_operator keyword_operator_logical keyword_operator_logical_groovy"&gt;!&lt;/span&gt;&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;/&lt;/span&gt;usr&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;/&lt;/span&gt;bin&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;/&lt;/span&gt;env groovy&lt;br /&gt;&lt;br /&gt;&lt;span class="meta meta_import meta_import_groovy"&gt;&lt;span class="keyword keyword_other keyword_other_class-fns keyword_other_class-fns_groovy"&gt;import&lt;/span&gt; &lt;span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_groovy"&gt;groovy.sql.Sql&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="meta meta_import meta_import_groovy"&gt;&lt;span class="keyword keyword_other keyword_other_class-fns keyword_other_class-fns_groovy"&gt;import&lt;/span&gt; &lt;span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_groovy"&gt;org.h2.Driver&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;// Create an h2 jdbc in-memory database,&lt;br /&gt;&lt;/span&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;// calling it what you like, here db1&lt;br /&gt;&lt;/span&gt;&lt;span class="storage storage_modifier storage_modifier_access-control storage_modifier_access-control_groovy"&gt;def&lt;/span&gt; db = &lt;span class="storage storage_type storage_type_groovy"&gt;Sql&lt;/span&gt;.newInstance(&lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;"jdbc:h2:mem:db1"&lt;/span&gt;,&lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;"org.h2.Driver"&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;// Create a table from your csv file... &lt;br /&gt;&lt;/span&gt;db.execute(&lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;"create table people as select * from csvread('people.csv')"&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;// Execute a normal sql query on this table...&lt;br /&gt;&lt;/span&gt;db.eachRow(&lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;"select * from people where age &amp;lt; 40"&lt;/span&gt;){row&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;-&lt;/span&gt;&lt;span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_groovy"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt; println row&lt;br /&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;If you want to create a new csv file from your query, you will have to do a tiny bit more work.  First you will need to extract the column headings of your query from the metadata, and then you will need to collect the rows into comma separated list.  It's easy boiler-plate once you know how.   Here is an example:&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;pre class="textmate-source blogbb"&gt;&lt;span class="source source_groovy"&gt;#&lt;span class="keyword keyword_operator keyword_operator_logical keyword_operator_logical_groovy"&gt;!&lt;/span&gt;&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;/&lt;/span&gt;usr&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;/&lt;/span&gt;bin&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;/&lt;/span&gt;env groovy &lt;br /&gt;&lt;br /&gt;&lt;span class="meta meta_import meta_import_groovy"&gt;&lt;span class="keyword keyword_other keyword_other_class-fns keyword_other_class-fns_groovy"&gt;import&lt;/span&gt; &lt;span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_groovy"&gt;groovy.sql.Sql&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="meta meta_import meta_import_groovy"&gt;&lt;span class="keyword keyword_other keyword_other_class-fns keyword_other_class-fns_groovy"&gt;import&lt;/span&gt; &lt;span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_groovy"&gt;org.h2.Driver&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;// Create an h2 jdbc in-memory database, &lt;br /&gt;&lt;/span&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;// calling it what you like, here db1 &lt;br /&gt;&lt;/span&gt;&lt;span class="storage storage_modifier storage_modifier_access-control storage_modifier_access-control_groovy"&gt;def&lt;/span&gt; db = &lt;span class="storage storage_type storage_type_groovy"&gt;Sql&lt;/span&gt;.newInstance(&lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;"jdbc:h2:mem:db1"&lt;/span&gt;,&lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;"org.h2.Driver"&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;// Create a table from your csv file...  &lt;br /&gt;&lt;/span&gt;db.execute(&lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;"create table people as select * from csvread('people.csv')"&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;// Get the column headings...&lt;br /&gt;&lt;/span&gt;db.eachRow(&lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;"select * from people where age &amp;lt; 40 limit 1"&lt;/span&gt;){row&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;-&lt;/span&gt;&lt;span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_groovy"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  meta = row.getMetaData()&lt;br /&gt;  numCols = meta.getColumnCount()&lt;br /&gt;  headings = (&lt;span class="constant constant_numeric constant_numeric_groovy"&gt;1&lt;/span&gt;..numCols).collect{meta.getColumnLabel(it)}&lt;br /&gt;  println headings.join(&lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;","&lt;/span&gt;)&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;// Execute a normal sql query on this table...&lt;br /&gt;&lt;/span&gt;db.eachRow(&lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;"select * from people where age &amp;lt; 40"&lt;/span&gt;){row&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;-&lt;/span&gt;&lt;span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_groovy"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  meta = row.getMetaData()&lt;br /&gt;  numCols = meta.getColumnCount()&lt;br /&gt;  vals = (&lt;span class="constant constant_numeric constant_numeric_groovy"&gt;0&lt;/span&gt;..&lt;span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_groovy"&gt;&amp;lt;&lt;/span&gt;numCols).collect{row[it]}&lt;br /&gt;  println vals.join(&lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;","&lt;/span&gt;)&lt;br /&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;The h2 database engine pretty quick too.   I can query a 100k file (both read it in as a table and do select on it) in about 5 seconds using code like that above.&lt;br /&gt;&lt;br /&gt;Finally, to do a join on two csv files, you only need to create the two files and execute the sql, like: &lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;pre class="textmate-source blogbb"&gt;&lt;span class="source source_groovy"&gt;#&lt;span class="keyword keyword_operator keyword_operator_logical keyword_operator_logical_groovy"&gt;!&lt;/span&gt;&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;/&lt;/span&gt;usr&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;/&lt;/span&gt;bin&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;/&lt;/span&gt;env groovy &lt;br /&gt;&lt;br /&gt;&lt;span class="meta meta_import meta_import_groovy"&gt;&lt;span class="keyword keyword_other keyword_other_class-fns keyword_other_class-fns_groovy"&gt;import&lt;/span&gt; &lt;span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_groovy"&gt;groovy.sql.Sql&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="meta meta_import meta_import_groovy"&gt;&lt;span class="keyword keyword_other keyword_other_class-fns keyword_other_class-fns_groovy"&gt;import&lt;/span&gt; &lt;span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_groovy"&gt;org.h2.Driver&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;// mem says in-memory db, and call it what you like, here db1 &lt;br /&gt;&lt;/span&gt;&lt;span class="storage storage_modifier storage_modifier_access-control storage_modifier_access-control_groovy"&gt;def&lt;/span&gt; sql = &lt;span class="storage storage_type storage_type_groovy"&gt;Sql&lt;/span&gt;.newInstance(&lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;"jdbc:h2:mem:db1"&lt;/span&gt;,&lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;"org.h2.Driver"&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;// Create the first table...  &lt;br /&gt;&lt;/span&gt;sql.execute(&lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;"create table people as select * from csvread('people.csv')"&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;// Create the second table...&lt;br /&gt;&lt;/span&gt;sql.execute(&lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;"create table children as select * from csvread('children.csv')"&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;sql.eachRow(&lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;"""&lt;br /&gt;select people.name,children.child,people.age&lt;br /&gt;from people,children &lt;br /&gt;where people.name=children.name and people.age &amp;gt; 40&lt;br /&gt;"""&lt;/span&gt;){result&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;-&lt;/span&gt;&lt;span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_groovy"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;  meta = result.getMetaData()&lt;br /&gt;  cols = meta.getColumnCount()&lt;br /&gt;  vals = (&lt;span class="constant constant_numeric constant_numeric_groovy"&gt;0&lt;/span&gt;..&lt;span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_groovy"&gt;&amp;lt;&lt;/span&gt;cols).collect{result[it]}&lt;br /&gt;  println vals.join(&lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;","&lt;/span&gt;)  &lt;br /&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6813476980165976394-696183084720009910?l=bayesianconspiracy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bayesianconspiracy.blogspot.com/feeds/696183084720009910/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6813476980165976394&amp;postID=696183084720009910' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6813476980165976394/posts/default/696183084720009910'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6813476980165976394/posts/default/696183084720009910'/><link rel='alternate' type='text/html' href='http://bayesianconspiracy.blogspot.com/2010/02/executing-arbitrary-sql-on-csv-files.html' title='Executing arbitrary SQL on CSV files.'/><author><name>James Durbin</name><uri>http://www.blogger.com/profile/02881091854353753739</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-n4yWF1vlZsM/Th_5FmbKhYI/AAAAAAAAAvE/uUsPcuOaRiQ/s220/10534_1122758594569_1395223040_30315740_3644162_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6813476980165976394.post-9076492179798761829</id><published>2010-01-21T16:43:00.000-08:00</published><updated>2010-01-21T17:05:39.846-08:00</updated><title type='text'>Groovy++</title><content type='html'>I just ran across this &lt;a href="http://groovy.dzone.com/articles/how-come-groovy-overperform"&gt;article on Groovy++ performance.&lt;/a&gt; Groovy++, it turns out,  is a project to implement a static compilation of Groovy.   This article reports a 6x performance boost for the low price of adding a few keywords.  Very few, it turns out. We're not talking manually defining all of the static types, as in Java, but in telling the Groovy++ compiler to fix the types during compile/runtime.   I'm hedging with compile/runtime since, honestly, I only discovered this project a few minutes ago and haven't had a chance to really dig into the details of how it works.  The project is &lt;a href="http://code.google.com/p/groovypptest/"&gt;hosted on Google Code &lt;/a&gt; and, although it isn't open source yet, it's slated to become open source soon.    A decent introduction to the developer and the rational can be found &lt;a href="http://groovy.dzone.com/articles/groovy-and-static-compilation"&gt;in this article.&lt;/a&gt;  &lt;br /&gt;&lt;br /&gt;I'll have more to say about this once I get a chance to really check it out, but in the mean time it's something worth watching.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6813476980165976394-9076492179798761829?l=bayesianconspiracy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bayesianconspiracy.blogspot.com/feeds/9076492179798761829/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6813476980165976394&amp;postID=9076492179798761829' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6813476980165976394/posts/default/9076492179798761829'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6813476980165976394/posts/default/9076492179798761829'/><link rel='alternate' type='text/html' href='http://bayesianconspiracy.blogspot.com/2010/01/groovy.html' title='Groovy++'/><author><name>James Durbin</name><uri>http://www.blogger.com/profile/02881091854353753739</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-n4yWF1vlZsM/Th_5FmbKhYI/AAAAAAAAAvE/uUsPcuOaRiQ/s220/10534_1122758594569_1395223040_30315740_3644162_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6813476980165976394.post-575072207646552851</id><published>2009-10-24T13:48:00.001-07:00</published><updated>2010-03-29T10:14:00.461-07:00</updated><title type='text'>Create/open OmniOutliner notebooks from command line.</title><content type='html'>I like to use &lt;a href="http://www.omnigroup.com/applications/omnioutliner/"&gt;OmniOutliner&lt;/a&gt; as a lab notebook, and I like to be able to create/open notebooks from the command line.  The OS X 'open' command will open an existing file, but I didn't see any obvious way to run OmniOutliner from the command line and tell it to create a new file.  So I created an empty OmniOutliner file and dropped in ~/Documents/template, then wrote a little script to copy that template and open it if it doesn't exist, or open the pre-existing file if it does.    Simple and effective. &lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;pre class="textmate-source blogbb"&gt;&lt;span class="source source_groovy"&gt;#&lt;span class="keyword keyword_operator keyword_operator_logical keyword_operator_logical_groovy"&gt;!&lt;/span&gt;&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;/&lt;/span&gt;usr&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;/&lt;/span&gt;bin&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;/&lt;/span&gt;env groovy &lt;br /&gt;&lt;span class="comment comment_block comment_block_documentation comment_block_documentation_groovy"&gt;/********************************************&lt;br /&gt;*  A simple little script to open up a file in OmniOutliner&lt;br /&gt;*  creating a default file if the file does not already exist. &lt;br /&gt;* &lt;br /&gt;*  Run it like:&lt;br /&gt;* &lt;br /&gt;*  omni newNotebook&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="storage storage_modifier storage_modifier_access-control storage_modifier_access-control_groovy"&gt;def&lt;/span&gt; omniFile&lt;br /&gt;&lt;span class="keyword keyword_control keyword_control_groovy"&gt;if&lt;/span&gt; (args[&lt;span class="constant constant_numeric constant_numeric_groovy"&gt;0&lt;/span&gt;].contains(&lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;".oo3"&lt;/span&gt;)){&lt;br /&gt;  omniFile = args[&lt;span class="constant constant_numeric constant_numeric_groovy"&gt;0&lt;/span&gt;]&lt;br /&gt;}&lt;span class="keyword keyword_control keyword_control_groovy"&gt;else&lt;/span&gt;{&lt;br /&gt;  omniFile = &lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;"${args[0]}.oo3"&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;// Get our home directory..&lt;br /&gt;&lt;/span&gt;env = &lt;span class="support support_type support_type_built-ins support_type_built-ins_groovy"&gt;System&lt;/span&gt;.getenv()&lt;br /&gt;home = env[&lt;span class="string string_quoted string_quoted_single string_quoted_single_groovy"&gt;'HOME'&lt;/span&gt;]&lt;br /&gt;&lt;br /&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;// If there is no omni outline file there, copy a template over...&lt;br /&gt;&lt;/span&gt;&lt;span class="keyword keyword_control keyword_control_groovy"&gt;if&lt;/span&gt; (&lt;span class="keyword keyword_operator keyword_operator_logical keyword_operator_logical_groovy"&gt;!&lt;/span&gt;(&lt;span class="keyword keyword_other keyword_other_class-fns keyword_other_class-fns_groovy"&gt;new&lt;/span&gt; &lt;span class="support support_type support_type_built-ins support_type_built-ins_groovy"&gt;File&lt;/span&gt;(omniFile).exists())){&lt;br /&gt;  &lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;"cp -r $home/Documents/templates/OOTemplate.oo3/ ${omniFile}"&lt;/span&gt;.execute()&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;// Open the desired file..&lt;br /&gt;&lt;/span&gt;&lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;"open ${omniFile}"&lt;/span&gt;.execute()&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6813476980165976394-575072207646552851?l=bayesianconspiracy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bayesianconspiracy.blogspot.com/feeds/575072207646552851/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6813476980165976394&amp;postID=575072207646552851' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6813476980165976394/posts/default/575072207646552851'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6813476980165976394/posts/default/575072207646552851'/><link rel='alternate' type='text/html' href='http://bayesianconspiracy.blogspot.com/2009/10/createopen-omnioutliner-notebooks-from.html' title='Create/open OmniOutliner notebooks from command line.'/><author><name>James Durbin</name><uri>http://www.blogger.com/profile/02881091854353753739</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-n4yWF1vlZsM/Th_5FmbKhYI/AAAAAAAAAvE/uUsPcuOaRiQ/s220/10534_1122758594569_1395223040_30315740_3644162_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6813476980165976394.post-2940166598537749505</id><published>2009-10-10T00:28:00.000-07:00</published><updated>2010-03-29T10:14:47.687-07:00</updated><title type='text'>Weka: getting predictions from cross validation</title><content type='html'>A &lt;a href="http://forums.pentaho.org/showthread.php?t=62182"&gt;common question&lt;/a&gt; in &lt;a href="http://www.cs.waikato.ac.nz/ml/weka/"&gt;weka&lt;/a&gt; forums is how to keep track of instances with names.  Weka does not have a name field for instances, so to keep track of instances one has to create a string ID attribute that has the name of each instance.  The catch, though, is that most classifiers don't work with string attributes, and you wouldn't want to classify on the ID anyway.    The official solution then is to delete the ID attribute before calling the classifier.  Of course, if you delete the ID, you loose the names for your instances!  Oof!  The solution is to use the meta.FilteredClassifier classifier with the RemoveType filter as the filter.  When you hand a FilteredClassifier off to Evaluation, it will apply the filter before sending it to the classifier, but will keep track of the relationship between the source Instances (with the ID) and the filtered set sent to the classifier.   Great.   Now what if you want to know how instances were classified during your cross-validation?   The API for extracting those classifications is not obvious, but it's easy enough once you know where to look.  In Evaluate.crossValidateModel() you pass in a StringBuffer to hold the predictions.  This can then be parsed to obtain the predictions and the instance names they go with.   Source code to do this below: &lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;pre class="textmate-source blogbb"&gt;&lt;span class="source source_groovy"&gt;#&lt;span class="keyword keyword_operator keyword_operator_logical keyword_operator_logical_groovy"&gt;!&lt;/span&gt;&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;/&lt;/span&gt;usr&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;/&lt;/span&gt;bin&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;/&lt;/span&gt;env groovy &lt;br /&gt;&lt;br /&gt;&lt;span class="meta meta_import meta_import_groovy"&gt;&lt;span class="keyword keyword_other keyword_other_class-fns keyword_other_class-fns_groovy"&gt;import&lt;/span&gt; &lt;span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_groovy"&gt;weka.core.*&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="meta meta_import meta_import_groovy"&gt;&lt;span class="keyword keyword_other keyword_other_class-fns keyword_other_class-fns_groovy"&gt;import&lt;/span&gt; &lt;span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_groovy"&gt;weka.core.converters.ConverterUtils.DataSource&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="meta meta_import meta_import_groovy"&gt;&lt;span class="keyword keyword_other keyword_other_class-fns keyword_other_class-fns_groovy"&gt;import&lt;/span&gt; &lt;span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_groovy"&gt;weka.filters.unsupervised.attribute.RemoveType&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="meta meta_import meta_import_groovy"&gt;&lt;span class="keyword keyword_other keyword_other_class-fns keyword_other_class-fns_groovy"&gt;import&lt;/span&gt; &lt;span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_groovy"&gt;weka.classifiers.*&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="meta meta_import meta_import_groovy"&gt;&lt;span class="keyword keyword_other keyword_other_class-fns keyword_other_class-fns_groovy"&gt;import&lt;/span&gt; &lt;span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_groovy"&gt;weka.classifiers.meta.FilteredClassifier&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="meta meta_import meta_import_groovy"&gt;&lt;span class="keyword keyword_other keyword_other_class-fns keyword_other_class-fns_groovy"&gt;import&lt;/span&gt; &lt;span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_groovy"&gt;weka.classifiers.evaluation.*&lt;/span&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="meta meta_import meta_import_groovy"&gt;&lt;span class="keyword keyword_other keyword_other_class-fns keyword_other_class-fns_groovy"&gt;import&lt;/span&gt; &lt;span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_groovy"&gt;java.util.Random&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;arffName = args[&lt;span class="constant constant_numeric constant_numeric_groovy"&gt;0&lt;/span&gt;]&lt;br /&gt;&lt;br /&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;// Read arff file...&lt;br /&gt;&lt;/span&gt;data = &lt;span class="support support_type support_type_built-ins support_type_built-ins_groovy"&gt;DataSource&lt;/span&gt;.read(arffName)&lt;br /&gt;&lt;br /&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;// Pick out the class attribute..&lt;br /&gt;&lt;/span&gt;data.setClassIndex(data.numAttributes() &lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;-&lt;/span&gt;&lt;span class="constant constant_numeric constant_numeric_groovy"&gt;1&lt;/span&gt;)&lt;br /&gt;  &lt;br /&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;// Create a classifier from the name...&lt;br /&gt;&lt;/span&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;// By using filtered classifer to remove ID, the cross-validation&lt;br /&gt;&lt;/span&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;// wrapper will keep the original dataset and keep track of the mapping &lt;br /&gt;&lt;/span&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;// between the original and the folds (minus ID). &lt;br /&gt;&lt;/span&gt;classifier = &lt;br /&gt;&lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;"""weka.classifiers.meta.FilteredClassifier &lt;br /&gt;      -F weka.filters.unsupervised.attribute.RemoveType &lt;br /&gt;      -W weka.classifiers.misc.HyperPipes"""&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;options = &lt;span class="storage storage_type storage_type_groovy"&gt;Utils&lt;/span&gt;.splitOptions(classifier)&lt;br /&gt;classname = options[&lt;span class="constant constant_numeric constant_numeric_groovy"&gt;0&lt;/span&gt;]&lt;br /&gt;options[&lt;span class="constant constant_numeric constant_numeric_groovy"&gt;0&lt;/span&gt;] = &lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;""&lt;/span&gt;&lt;br /&gt;classifier = &lt;span class="storage storage_type storage_type_groovy"&gt;Classifier&lt;/span&gt;.forName(classname,options) &lt;br /&gt;&lt;br /&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;// Perform cross-validation of the model..&lt;br /&gt;&lt;/span&gt;eval = &lt;span class="keyword keyword_other keyword_other_class-fns keyword_other_class-fns_groovy"&gt;new&lt;/span&gt; &lt;span class="storage storage_type storage_type_groovy"&gt;Evaluation&lt;/span&gt;(data)&lt;br /&gt;predictions = &lt;span class="keyword keyword_other keyword_other_class-fns keyword_other_class-fns_groovy"&gt;new&lt;/span&gt; &lt;span class="support support_type support_type_built-ins support_type_built-ins_groovy"&gt;StringBuffer&lt;/span&gt;()&lt;br /&gt;eval.crossValidateModel(classifier,data,cvFolds = &lt;span class="constant constant_numeric constant_numeric_groovy"&gt;5&lt;/span&gt;,&lt;br /&gt;  &lt;span class="keyword keyword_other keyword_other_class-fns keyword_other_class-fns_groovy"&gt;new&lt;/span&gt; &lt;span class="support support_type support_type_built-ins support_type_built-ins_groovy"&gt;Random&lt;/span&gt;(&lt;span class="constant constant_numeric constant_numeric_groovy"&gt;1&lt;/span&gt;),predictions,&lt;br /&gt;  &lt;span class="keyword keyword_other keyword_other_class-fns keyword_other_class-fns_groovy"&gt;new&lt;/span&gt; &lt;span class="storage storage_type storage_type_groovy"&gt;Range&lt;/span&gt;(&lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;"first,last"&lt;/span&gt;),&lt;span class="constant constant_language constant_language_groovy"&gt;false&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;lines = predictions.toString().split(&lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;"&lt;span class="constant constant_character constant_character_escape constant_character_escape_groovy"&gt;\n&lt;/span&gt;"&lt;/span&gt;)&lt;br /&gt;  &lt;br /&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;// Output of predictions looks like:  &lt;br /&gt;&lt;/span&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;// inst#     actual  predicted error prediction (ID)&lt;br /&gt;&lt;/span&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;//     1      1:low      1:low       1 (P1)&lt;br /&gt;&lt;/span&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;//     2     2:high      1:low   +   0.5 (P6)&lt;br /&gt;&lt;/span&gt;&lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;//     3     2:high     2:high       1 (P0)&lt;br /&gt;&lt;/span&gt;lines[&lt;span class="constant constant_numeric constant_numeric_groovy"&gt;1&lt;/span&gt;..&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;-&lt;/span&gt;&lt;span class="constant constant_numeric constant_numeric_groovy"&gt;1&lt;/span&gt;].&lt;span class="keyword keyword_groovy keyword_groovy_misc"&gt;each&lt;/span&gt;{line&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;-&lt;/span&gt;&lt;span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_groovy"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_groovy"&gt;// Parse out fields we're interested in..      &lt;br /&gt;&lt;/span&gt;  m = line =~ &lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;/&lt;/span&gt;\d:(\w&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;+&lt;/span&gt;).&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;*&lt;/span&gt;\d:(\w&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;+&lt;/span&gt;).&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;*&lt;/span&gt;\((\w&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;+&lt;/span&gt;)\)&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;/&lt;/span&gt;&lt;br /&gt;  actual = m[&lt;span class="constant constant_numeric constant_numeric_groovy"&gt;0&lt;/span&gt;][&lt;span class="constant constant_numeric constant_numeric_groovy"&gt;1&lt;/span&gt;]&lt;br /&gt;  predicted = m[&lt;span class="constant constant_numeric constant_numeric_groovy"&gt;0&lt;/span&gt;][&lt;span class="constant constant_numeric constant_numeric_groovy"&gt;2&lt;/span&gt;]&lt;br /&gt;  sample = m[&lt;span class="constant constant_numeric constant_numeric_groovy"&gt;0&lt;/span&gt;][&lt;span class="constant constant_numeric constant_numeric_groovy"&gt;3&lt;/span&gt;]&lt;br /&gt;  println actual&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;+&lt;/span&gt;&lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;"&lt;span class="constant constant_character constant_character_escape constant_character_escape_groovy"&gt;\t&lt;/span&gt;"&lt;/span&gt;&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;+&lt;/span&gt;predicted&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;+&lt;/span&gt;&lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;"&lt;span class="constant constant_character constant_character_escape constant_character_escape_groovy"&gt;\t&lt;/span&gt;"&lt;/span&gt;&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;+&lt;/span&gt;sample&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;+&lt;/span&gt;&lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;"&lt;span class="constant constant_character constant_character_escape constant_character_escape_groovy"&gt;\t&lt;/span&gt;"&lt;/span&gt;&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;+&lt;/span&gt;&lt;span class="keyword keyword_operator keyword_operator_logical keyword_operator_logical_groovy"&gt;!&lt;/span&gt;line.contains(&lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;"+"&lt;/span&gt;)&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6813476980165976394-2940166598537749505?l=bayesianconspiracy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bayesianconspiracy.blogspot.com/feeds/2940166598537749505/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6813476980165976394&amp;postID=2940166598537749505' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6813476980165976394/posts/default/2940166598537749505'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6813476980165976394/posts/default/2940166598537749505'/><link rel='alternate' type='text/html' href='http://bayesianconspiracy.blogspot.com/2009/10/usr-bin-env-groovy-import-weka_10.html' title='Weka: getting predictions from cross validation'/><author><name>James Durbin</name><uri>http://www.blogger.com/profile/02881091854353753739</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-n4yWF1vlZsM/Th_5FmbKhYI/AAAAAAAAAvE/uUsPcuOaRiQ/s220/10534_1122758594569_1395223040_30315740_3644162_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6813476980165976394.post-138366495172596082</id><published>2009-04-08T01:13:00.000-07:00</published><updated>2009-04-08T01:31:40.189-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='google app engine'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>Groovy in Google App Engine</title><content type='html'>I'm quite excited that Google has added Java as a supported language in &lt;a href="http://code.google.com/appengine/"&gt;Google App Engine&lt;/a&gt;.   Google App Engine is a free (up to a certain quota) service from Google where Google hosts your web app and handles all the issues involved in making it scalable and so on.  Check out the &lt;a href="http://code.google.com/appengine/"&gt;Google App Engine site&lt;/a&gt; for more info.   Google App Engine has been out for awhile but until a couple of days ago it only supported Python as a development language.  Python is fine, so far as it goes, but outside of Google itself Python has nowhere near the base of web application support that Java does.  I expect Java support to really blow the lid off of Google App Engine.   In supporting Java, Google also supports a number of java based frameworks and JVM based languages.   Most notable for me is support for writing a &lt;a href="http://blog.springsource.com/2009/04/07/write-your-google-app-engine-applications-in-groovy/"&gt;Google app engine app in Groovy&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6813476980165976394-138366495172596082?l=bayesianconspiracy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bayesianconspiracy.blogspot.com/feeds/138366495172596082/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6813476980165976394&amp;postID=138366495172596082' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6813476980165976394/posts/default/138366495172596082'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6813476980165976394/posts/default/138366495172596082'/><link rel='alternate' type='text/html' href='http://bayesianconspiracy.blogspot.com/2009/04/groovy-in-google-app-engine.html' title='Groovy in Google App Engine'/><author><name>James Durbin</name><uri>http://www.blogger.com/profile/02881091854353753739</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-n4yWF1vlZsM/Th_5FmbKhYI/AAAAAAAAAvE/uUsPcuOaRiQ/s220/10534_1122758594569_1395223040_30315740_3644162_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6813476980165976394.post-7669304549905574225</id><published>2009-03-14T14:19:00.000-07:00</published><updated>2009-03-14T15:03:58.933-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>Invalid duplicate class definition</title><content type='html'>&lt;blockquote&gt;"Invalid duplicate class definition...One of the classes is a explicit generated class using the class statement, the other is a class generated from the script body based on the file name. Solutions are to change the file name or to change the class name. "&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;When I was first learning Groovy I would get this error from time to time.  It was puzzling to me because sometimes I'd get this error, and sometimes it would seem like the same situation and I wouldn't.    It seemed quite random to me when the error would crop up.  When it did,  I'd usually just rename the class and go on, resolving to figure it out later.    To save you the trouble, here's what is happening. &lt;br /&gt;&lt;br /&gt;Groovy has two ways to treat a .groovy file:  either as a &lt;b&gt;script&lt;/b&gt;, or as a &lt;b&gt;class definition file&lt;/b&gt;.   If it is a script you can not have a class by the same name as the file.  If it is a class definition file you can.    It is very easy to tell whether a .groovy file is going to be treated as a script or as a class definition file.   If there is any code outside a class statement in the file (other than imports), it is a script.    What is happening is that if there is any code to be executed in the file then Groovy needs a containing class for that code.  Groovy will implicitly create a containing class with the name of the file.   So if you have a file called  Grapher.groovy that has some code in it that isn't inside a class definition, Groovy will create an implicit containing class called Grapher.   This means that &lt;b&gt;&lt;i&gt;the script file&lt;/i&gt;&lt;/b&gt; Grapher.groovy can not itself contain a class called Grapher because that would be a duplicate class definition, thus the error. If, on the other hand, all you do in the file Grapher.groovy is define the class Grapher (and any number of other classes), then Groovy will treat that file as simply a collection of class definitions, there will be no implicit containing class, and there is no problem having a class called Grapher inside the &lt;b&gt;&lt;i&gt;class definition file &lt;/b&gt;&lt;/i&gt; Grapher.groovy.   &lt;br /&gt;&lt;br /&gt;It's worth mentioning that the script version of Grapher.groovy will be compiled into a class called Grapher that extends groovy.lang.Script.  In the other case, when Grapher.groovy merely defines classes, one of which is Grapher, that Grapher class will be compiled into a class that implements groovy.lang.GroovyObject. &lt;br /&gt;&lt;br /&gt;I'm sure this is all explained somewhere in the Groovy documentation, but it didn't soak in to me until I read this &lt;a href="http://www.nabble.com/Why-I'm-getting-MultipleCompilationErrorsException-exception--td21525418.html"&gt;Nabble post&lt;/a&gt; from which I extracted this explanation.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6813476980165976394-7669304549905574225?l=bayesianconspiracy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bayesianconspiracy.blogspot.com/feeds/7669304549905574225/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6813476980165976394&amp;postID=7669304549905574225' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6813476980165976394/posts/default/7669304549905574225'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6813476980165976394/posts/default/7669304549905574225'/><link rel='alternate' type='text/html' href='http://bayesianconspiracy.blogspot.com/2009/03/invalid-duplicate-class-definition.html' title='Invalid duplicate class definition'/><author><name>James Durbin</name><uri>http://www.blogger.com/profile/02881091854353753739</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-n4yWF1vlZsM/Th_5FmbKhYI/AAAAAAAAAvE/uUsPcuOaRiQ/s220/10534_1122758594569_1395223040_30315740_3644162_n.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6813476980165976394.post-4907043643354373011</id><published>2009-03-09T12:30:00.000-07:00</published><updated>2009-03-13T00:19:39.794-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bioinformatics'/><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>Groovy compared to Perl</title><content type='html'>If you are a bioinformatics person considering taking up Groovy as an alternative to Perl, you will naturally wonder how the two compare on a range of simple tasks.   Luckily, there is a great set of examples over at &lt;a href="http://pleac.sourceforge.net/"&gt; PLEAC &lt;/a&gt; (Programming Language Examples Alike Cookbook).   Most bioinformatics Perl programmers have probably seen the &lt;a href="http://oreilly.com/catalog/9780596003135/?CMP=AFC-ak_book&amp;ATT=Perl+Cookbook"&gt;Perl Cookbook&lt;/a&gt; by Tom Christiansen &amp; Nathan Torkington.   The aim of &lt;a href="http://pleac.sourceforge.net/"&gt; PLEAC &lt;/a&gt; is to implement all of the solutions found in the Perl Cookbook in other languages.   The Groovy examples are 100% complete, so you can see how every Perl cookbook solution could be performed in Groovy.   &lt;a href="http://pleac.sourceforge.net/pleac_groovy/index.html"&gt;Go have a look!&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6813476980165976394-4907043643354373011?l=bayesianconspiracy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bayesianconspiracy.blogspot.com/feeds/4907043643354373011/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6813476980165976394&amp;postID=4907043643354373011' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6813476980165976394/posts/default/4907043643354373011'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6813476980165976394/posts/default/4907043643354373011'/><link rel='alternate' type='text/html' href='http://bayesianconspiracy.blogspot.com/2009/03/groovy-compared-to-perl.html' title='Groovy compared to Perl'/><author><name>James Durbin</name><uri>http://www.blogger.com/profile/02881091854353753739</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-n4yWF1vlZsM/Th_5FmbKhYI/AAAAAAAAAvE/uUsPcuOaRiQ/s220/10534_1122758594569_1395223040_30315740_3644162_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6813476980165976394.post-5991645327299066241</id><published>2009-03-09T12:11:00.001-07:00</published><updated>2009-03-13T00:20:33.688-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bioinformatics'/><category scheme='http://www.blogger.com/atom/ns#' term='biogroovy'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>Groovy for bioinformatics.</title><content type='html'>I'll have a lot to say about Groovy for bioinformatics in this blog. Until I have time to write some posts on the topic here is Mark Fortner's brief comparison of how &lt;a href="http://www.jroller.com/phidias/entry/biogroovy"&gt;Groovy stacks up to Perl&lt;/a&gt; for bioinformatics.  Mark has also set up a &lt;a href="http://biogroovy.open-bio.org/wiki/Main_Page"&gt;BioGroovy project wiki&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6813476980165976394-5991645327299066241?l=bayesianconspiracy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bayesianconspiracy.blogspot.com/feeds/5991645327299066241/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6813476980165976394&amp;postID=5991645327299066241' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6813476980165976394/posts/default/5991645327299066241'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6813476980165976394/posts/default/5991645327299066241'/><link rel='alternate' type='text/html' href='http://bayesianconspiracy.blogspot.com/2009/03/groovy-for-bioinformatics.html' title='Groovy for bioinformatics.'/><author><name>James Durbin</name><uri>http://www.blogger.com/profile/02881091854353753739</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-n4yWF1vlZsM/Th_5FmbKhYI/AAAAAAAAAvE/uUsPcuOaRiQ/s220/10534_1122758594569_1395223040_30315740_3644162_n.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6813476980165976394.post-6649810342267441351</id><published>2007-06-05T13:12:00.000-07:00</published><updated>2009-03-13T11:22:05.484-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='bioinformatics'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>Groovy is groovy. Groovy is Java.</title><content type='html'>&lt;a href="http://groovy.codehaus.org/"&gt;Groovy&lt;/a&gt; is groovy.    At least for me.   Groovy is also Java, like quick and dirty Java all dripping with syntatic sugar.   If you know Java you essentially know 80% of what there is to know about Groovy because underneath it's all Java objects and the syntax is roughly a superset of Java.  Most Java programs will run, unaltered, as Groovy programs.  Although Groovy's dynamic features, powerful language constructs, and other goodness will grow on you,  a Java programmer can approach Groovy initially as if it were simply a kind of Java that can be executed without compiling and with the option to soft focus some of the details.  &lt;br /&gt;&lt;br /&gt;For example, here is a dumb little Groovy script that I wrote to convert a comma separated file into a tab separated file.   &lt;br /&gt;&lt;br /&gt;&lt;hr width="60%"&gt;&lt;br /&gt;&lt;pre class="textmate-source blogbb"&gt;&lt;span class="source source_groovy"&gt;#&lt;span class="keyword keyword_operator keyword_operator_logical keyword_operator_logical_groovy"&gt;!&lt;/span&gt;&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;/&lt;/span&gt;usr&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;/&lt;/span&gt;bin&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;/&lt;/span&gt;env groovy&lt;br /&gt;&lt;br /&gt;&lt;span class="keyword keyword_control keyword_control_groovy"&gt;for&lt;/span&gt;(line in &lt;span class="support support_type support_type_built-ins support_type_built-ins_groovy"&gt;System&lt;/span&gt;.in.readLines()){&lt;br /&gt;  bits = line.split(&lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;","&lt;/span&gt;);&lt;br /&gt;  &lt;span class="keyword keyword_control keyword_control_groovy"&gt;for&lt;/span&gt;(bit in bits){&lt;br /&gt;    print bit&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;+&lt;/span&gt;&lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;"&lt;span class="constant constant_character constant_character_escape constant_character_escape_groovy"&gt;\t&lt;/span&gt;"&lt;/span&gt;;&lt;br /&gt;  }&lt;br /&gt;  println &lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;""&lt;/span&gt;;&lt;br /&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;hr width="60%"&gt;&lt;br /&gt;&lt;br /&gt;This is something I wrote on the first day I was learning Groovy so it is not idiomatic Groovy.  Groovy can be much more succinct than this.  A Perl person might prefer a command line one-liner like:&lt;br /&gt;&lt;br /&gt;&lt;pre class="textmate-source blogbb"&gt;&lt;span class="text text_plain"&gt;&lt;span class="meta meta_paragraph meta_paragraph_text"&gt;cat test.tab | groovy -pe '(line =~/\t/).replaceAll(",")'&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;Nonetheless, this little script shows how one can come to Groovy gently from Java.   First, that's a complete Groovy program.  If it were Java, there'd have to be more, the declaration of a containing class, for example.  Groovy provides an implicit containing class with the name of the file.    You'd also have to be more fastidious about declaring the types of variables.  Groovy works out types during runtime.  The types Groovy eventually assigns to variables will be Java types.  &lt;em&gt;line&lt;/em&gt; and &lt;em&gt;bits&lt;/em&gt;, for example, will resolve to java.lang.String, and all the functionality of java.lang.String is there for you just like you remember it.    Also, unlike a Java program, Groovy scripts don't need compiling (if you need to, though, you can compile Groovy to a .class file to use in a Java program).   You can just run the file like a Perl script, for example:&lt;br /&gt;&lt;br /&gt;&lt;pre class="textmate-source blogbb"&gt;&lt;span class="source source_groovy"&gt;cat data.txt | comma2tab  &lt;span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_groovy"&gt;&amp;gt;&lt;/span&gt; data.tab&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So you can see that you get that sort of Perl-like hack-together-something-quick quality: no compiling, direct execution of the source file (via shebang or the command line interface), rapid edit/test cycle, and stripped down verbosity.    Suppose I also wanted to add a date tag to each line.  When I was doing my scripting with Perl I'd have to grind to a halt while I looked up various Perl date APIs.   Obviously, if 99% of my code were scripting Perl I'd probably already know that, but my code is more like 10% C++, 65% Java, and 25% scripting.   As a result, I'm much more likely to already know the Java API for something than the Perl API.   With Groovy I can add date functionality without having to learn any new API's,  I can just use the Java one I already know:  &lt;br /&gt;&lt;br&gt;&lt;br /&gt;&lt;hr width="60%"&gt;&lt;br /&gt;&lt;pre class="textmate-source blogbb"&gt;&lt;span class="source source_groovy"&gt;#&lt;span class="keyword keyword_operator keyword_operator_logical keyword_operator_logical_groovy"&gt;!&lt;/span&gt;&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;/&lt;/span&gt;usr&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;/&lt;/span&gt;bin&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;/&lt;/span&gt;env groovy  &lt;br /&gt;  &lt;br /&gt;date = &lt;span class="keyword keyword_other keyword_other_class-fns keyword_other_class-fns_groovy"&gt;new&lt;/span&gt; &lt;span class="support support_type support_type_built-ins support_type_built-ins_groovy"&gt;Date&lt;/span&gt;();  &lt;br /&gt;&lt;span class="keyword keyword_control keyword_control_groovy"&gt;for&lt;/span&gt;(line in &lt;span class="support support_type support_type_built-ins support_type_built-ins_groovy"&gt;System&lt;/span&gt;.in.readLines()){  &lt;br /&gt;  println date.toString()&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;+&lt;/span&gt;&lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;"&lt;span class="constant constant_character constant_character_escape constant_character_escape_groovy"&gt;\t&lt;/span&gt;"&lt;/span&gt;;  &lt;br /&gt;  bits = line.split(&lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;","&lt;/span&gt;);  &lt;br /&gt;  &lt;span class="keyword keyword_control keyword_control_groovy"&gt;for&lt;/span&gt;(bit in bits){  &lt;br /&gt;    print bit&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_groovy"&gt;+&lt;/span&gt;&lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;"&lt;span class="constant constant_character constant_character_escape constant_character_escape_groovy"&gt;\t&lt;/span&gt;"&lt;/span&gt;;  &lt;br /&gt;  }  &lt;br /&gt;  println &lt;span class="string string_quoted string_quoted_double string_quoted_double_groovy"&gt;""&lt;/span&gt;;  &lt;br /&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;hr width="60%"&gt;&lt;br /&gt;That print is, by the way, System.out.println, it' just lets you use the shorthand if you like.  You don't have to though.  With a simple import, you can use any of your own Java classes just as easily.  Drop any external library into your CLASSPATH, or a jar into your ~/groovy/lib directory, and you have ready access to that functionality too. You can even hack together simple GUI's in just a few lines of code.&lt;br /&gt;&lt;br /&gt;Given that I have worked on several  pure-Java projects in the past few years, Groovy really fills a niche for me.   Working in bioinformatics  I have a lot of need for scripting, to create quick and dirty one-off programs to crunch some data or do some bulk operation, something someone wants today and will never use again.    I also have a fair bit of need for production quality webpages, for computation intensive algorithms, and for GUI visualization tools.   The combination of Groovy+Java nicely fills all of these needs for me.   I can write my high quality webpages in Java (or &lt;a href="http://www.grails.org/"&gt;Grails&lt;/a&gt;), my computation intensive algorithms in Java (which has become performance competitive in the past few years, within 2x of C [3]), my GUI visualization tools in Groovy/Java/Swing, and my one-off scripts and pipeline glue in Groovy.   One set of libraries and API's to master to do all my work.   The ability to share code across all the kinds of work I do.   All my code is cross platform. It's like having my cake and eating it too!  &lt;br /&gt;&lt;br /&gt;If you know Java, you owe it to yourself to try Groovy.   If you find yourself writing one kind of software in one language, another in a different language, you owe it to yourself to try Groovy.   The rest of you, you should probably try it too.   &lt;br /&gt;&lt;br /&gt; &lt;br /&gt;[1] &lt;a href="http://www.bright-green.com/downloads/SixThings.pdf"&gt;Six Things Groovy Can Do For You&lt;/a&gt;&lt;br /&gt;[2] &lt;a href="http://www-128.ibm.com/developerworks/views/java/libraryview.jsp?search_by=practically+groovy:"&gt;IBM Groovy articles&lt;/a&gt;&lt;br /&gt;[3] &lt;a href="http://shootout.alioth.debian.org/u32q/benchmark.php?test=all&amp;lang=all&amp;box=1"&gt;1.8x median, behind only C++, C, and ATS&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6813476980165976394-6649810342267441351?l=bayesianconspiracy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bayesianconspiracy.blogspot.com/feeds/6649810342267441351/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6813476980165976394&amp;postID=6649810342267441351' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6813476980165976394/posts/default/6649810342267441351'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6813476980165976394/posts/default/6649810342267441351'/><link rel='alternate' type='text/html' href='http://bayesianconspiracy.blogspot.com/2007/06/groovy-is-well-pretty-groovy.html' title='Groovy is groovy. Groovy is Java.'/><author><name>James Durbin</name><uri>http://www.blogger.com/profile/02881091854353753739</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-n4yWF1vlZsM/Th_5FmbKhYI/AAAAAAAAAvE/uUsPcuOaRiQ/s220/10534_1122758594569_1395223040_30315740_3644162_n.jpg'/></author><thr:total>0</thr:total></entry></feed>
