<?xml version="1.0"?>
<rss version="2.0">
<channel>
  <title>Weiqi Gao&#039;s Observations - grails tag</title>
  <link>http://www.weiqigao.com/blog/tags/grails/</link>
  <description>Sharing My Experience...</description>
  <language>en</language>
  <copyright>Weiqi Gao</copyright>
  <lastBuildDate>Fri, 11 May 2012 12:48:36 GMT</lastBuildDate>
  <generator>Pebble (http://pebble.sourceforge.net)</generator>
  <docs>http://backend.userland.com/rss</docs>
  
  <image>
    <url>http://pebble.sourceforge.net/common/images/powered-by-pebble.gif</url>
    <title>Weiqi Gao&#039;s Observations</title>
    <link>http://www.weiqigao.com/blog/</link>
  </image>
  
  
  <item>
    <title>Jeff Brown&#039;s Probability Quiz: What Are The Chances ...</title>
    <link>http://www.weiqigao.com/blog/2009/08/03/jeff_browns_probability_quiz_what_are_the_chances.html</link>
    
      
        <description>
          &lt;p&gt;... Jeff is of course talking about &lt;a href= &#034;http://javajeff.blogspot.com/2009/07/grails-springsource-and-clojure.html&#034; &gt;Grails, SpringSource, and Clojure&lt;/a&gt;.  Near the end of the post, Jeff challenged his readers with a probability brain teaser:&lt;/p&gt;

&lt;blockquote&gt;
&lt;a href= &#034;http://javajeff.blogspot.com/2009/07/grails-springsource-and-clojure.html&#034; &gt;Jeff Brown&lt;/a&gt;: I am honestly not sure how many technologists work for SpringSource but for the sake of having a number to work with, lets say there are 50.  Lets also say that Clojure is interesting enough that 15% of JVM developers are interested in learning more about it.  I can&#039;t back that number up with any research, lets just go with it.  If 15% of JVM developers are interested in the language and you take a random group of 50 JVM developers (the 50 in question are certainly not 50 random developers, these are the edge cutters which probably makes them more likely to be interested in keeping an eye on what is new, but work with the idea that they are random)... Do the math.  No, really... Do the math.  Do the math to figure out the likelihood that 3 of the 50 would be interested in Clojure.  I challenge you to do the math in Clojure and post your solution in a comment here.  Do it in Scala,  Do it in Groovy.  Pick a JVM language and do the math.&lt;br&gt;
&lt;/blockquote&gt;

&lt;p&gt;My answer got a little bit too long for a comment on Jeff&#039;s blog.  So I&#039;m putting it here.&lt;/p&gt;

&lt;p&gt;First of all, Jeff, its probability, not mathematics.  They branched off a long time ago, just like computer science branched off more recently.  It&#039;s nevertheless an interesting problem to ponder about in a Saturday morning.  It also helps that I&#039;m married to a statistician.  Here&#039;s how the conversation went:&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Me&lt;/b&gt;: Jeff Brown blogged about an interesting probability problem.  (&lt;em&gt;Reading the problem&lt;/em&gt;)&lt;br/&gt;
&lt;b&gt;Her&lt;/b&gt;: The problem is not complete.  He didn&#039;t mention how many JVM developers there are.  The answer probably depends on it.&lt;br/&gt;
&lt;b&gt;Me&lt;/b&gt;: For the sake of argument, let&#039;s say there are 100 of them.&lt;br/&gt;
&lt;b&gt;Her&lt;/b&gt;: OK.  Then the problem is equivalent to the following:&lt;/p&gt;

&lt;p style=&#034;margin-left:3em&#034;&gt;&lt;b&gt;Problem&lt;/b&gt;: There is a jar of 100 balls. Among them 85 balls are black, and 15 balls are read.  A batch of 50 balls are selected at random from the jar.  A group of 3 balls are selected at random from the batch.  What is the probability that all 3 balls in the selected group are red?&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Me&lt;/b&gt;: That sounds like a probability problem the students could tackle.&lt;br/&gt;
&lt;b&gt;Her&lt;/b&gt;: You analyze the scenario into more concrete cases: What if the batch of 50 contains no red balls? 1 red ball? 2? 3?, ... Use the &lt;a href= &#034;http://en.wikipedia.org/wiki/Law_of_total_probability&#034; &gt;Law of Total Probability&lt;/a&gt;.  Here&#039;s the book!&lt;p&gt;

&lt;p&gt;(&lt;em&gt;Saturday morning turned into Sunday evening, and we finally have a chance to work the problem out.&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;We&#039;ll solve the probability problem by hand and reduce it to a computation problem that is as simple as possible, and then use the computing machinery.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Solution&lt;/b&gt;: We use the following letters to denote the various quantities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;i&gt;n&lt;/i&gt;&amp;mdash;the total number of balls&lt;/li&gt;
&lt;li&gt;&lt;i&gt;r&lt;/i&gt;&amp;mdash;the number of red balls&lt;/li&gt;
&lt;li&gt;&lt;i&gt;m&lt;/i&gt;&amp;mdash;the number of balls in the batch&lt;/li&gt;
&lt;li&gt;&lt;i&gt;k&lt;/i&gt;&amp;mdash;the number of balls in the group&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The event of selecting a batch of &lt;i&gt;m&lt;/i&gt; balls and then selecting exactly &lt;i&gt;k&lt;/i&gt; red balls from the &lt;i&gt;m&lt;/i&gt; can be decomposed to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;selecting a batch of &lt;i&gt;m&lt;/i&gt; balls &lt;span style=&#034;color:red&#034;&gt;containing exactly &lt;i&gt;k&lt;/i&gt; red balls&lt;/span&gt; and then selecting exactly &lt;i&gt;k&lt;/i&gt; red balls from the &lt;i&gt;m&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;selecting a batch of &lt;i&gt;m&lt;/i&gt; balls &lt;span style=&#034;color:red&#034;&gt;containing exactly &lt;i&gt;k + 1&lt;/i&gt; red balls&lt;/span&gt; and then selecting exactly &lt;i&gt;k&lt;/i&gt; red balls from the &lt;i&gt;m&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;li&gt;selecting a batch of &lt;i&gt;m&lt;/i&gt; balls &lt;span style=&#034;color:red&#034;&gt;containing exactly &lt;i&gt;r&lt;/i&gt; red balls&lt;/span&gt; and then selecting exactly &lt;i&gt;k&lt;/i&gt; red balls from the &lt;i&gt;m&lt;/i&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The law of total probability dictates that the probability of out target event is the sum of the products of the probabilities of each of the successive events in the above list:&lt;/p&gt;

&lt;center&gt;
&lt;i&gt;P = &lt;big&gt;&amp;Sigma;&lt;/big&gt;&lt;sub&gt;i = k&lt;/sub&gt;&lt;sup&gt;r&lt;/sup&gt; P(n, r; m, i) P(m, i; k, k)&lt;/i&gt;
&lt;/center&gt;

&lt;p&gt;where &lt;i&gt;P(n, r; m, i)&lt;/i&gt; is the probability of selecting &lt;i&gt;m&lt;/i&gt; balls from a jar of &lt;i&gt;n&lt;/i&gt; balls containing &lt;i&gt;r&lt;/i&gt; red balls and having exactly &lt;i&gt;i&lt;/i&gt; red balls in the selected batch.  The probability of this event is given by the formula&lt;/p&gt;

&lt;center&gt;
&lt;i&gt;P(n, r; m, i) = C(r, i) C(n - r, m - i) / C(n, m)&lt;/i&gt;
&lt;/center&gt;

&lt;p&gt;where &lt;i&gt;C(r, i)&lt;/i&gt; is the binomial coefficient.&lt;/p&gt;

&lt;p&gt;With the problem thus &lt;i&gt;solved&lt;/i&gt;, I went ahead to &#034;&lt;i&gt;Pick a JVM language and do the math.&lt;/i&gt;&#034;  Guess which language I picked? Java.  Yes, Java.  Not Clojure.  Not Scala.  Not Groovy, but the old dependable Java.  &#034;Why?&#034; you ask.  Because doing it in any other language would have taken me longer to get the results out.&lt;/p&gt;

&lt;p&gt;Here are the classes I wrote:&lt;/p&gt;

&lt;style type=&#034;text/css&#034;&gt;
.ln { color: rgb(0,0,0); font-weight: normal; font-style: normal; }
.s0 { color: rgb(0,0,128); font-weight: bold; }
.s1 { }
.s2 { color: rgb(0,128,0); font-weight: bold; }
.s3 { color: rgb(0,0,255); }
&lt;/style&gt;

&lt;TABLE CELLSPACING=0 CELLPADDING=5 COLS=1 WIDTH=&#034;100%&#034; BGCOLOR=&#034;#C0C0C0&#034; &gt;
&lt;TR&gt;&lt;TD&gt;&lt;CENTER&gt;
&lt;FONT FACE=&#034;Arial, Helvetica&#034; COLOR=&#034;#000000&#034;&gt;
Foo.java&lt;/FONT&gt;
&lt;/center&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TABLE&gt;
&lt;pre&gt;
&lt;a name=&#034;l1&#034;&gt;&lt;span class=&#034;ln&#034;&gt;1    &lt;/span&gt;&lt;/a&gt;&lt;span class=&#034;s0&#034;&gt;public class &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;Foo { 
&lt;a name=&#034;l2&#034;&gt;&lt;span class=&#034;ln&#034;&gt;2    &lt;/span&gt;&lt;/a&gt;  &lt;/span&gt;&lt;span class=&#034;s0&#034;&gt;private int &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;n; 
&lt;a name=&#034;l3&#034;&gt;&lt;span class=&#034;ln&#034;&gt;3    &lt;/span&gt;&lt;/a&gt;  &lt;/span&gt;&lt;span class=&#034;s0&#034;&gt;private int &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;r; 
&lt;a name=&#034;l4&#034;&gt;&lt;span class=&#034;ln&#034;&gt;4    &lt;/span&gt;&lt;/a&gt;  &lt;/span&gt;&lt;span class=&#034;s0&#034;&gt;private int &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;m; 
&lt;a name=&#034;l5&#034;&gt;&lt;span class=&#034;ln&#034;&gt;5    &lt;/span&gt;&lt;/a&gt;  &lt;/span&gt;&lt;span class=&#034;s0&#034;&gt;private int &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;k; 
&lt;a name=&#034;l6&#034;&gt;&lt;span class=&#034;ln&#034;&gt;6    &lt;/span&gt;&lt;/a&gt; 
&lt;a name=&#034;l7&#034;&gt;&lt;span class=&#034;ln&#034;&gt;7    &lt;/span&gt;&lt;/a&gt;  &lt;/span&gt;&lt;span class=&#034;s0&#034;&gt;public &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;Foo(&lt;/span&gt;&lt;span class=&#034;s0&#034;&gt;int &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;n, &lt;/span&gt;&lt;span class=&#034;s0&#034;&gt;int &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;r, &lt;/span&gt;&lt;span class=&#034;s0&#034;&gt;int &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;m, &lt;/span&gt;&lt;span class=&#034;s0&#034;&gt;int &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;k) { 
&lt;a name=&#034;l8&#034;&gt;&lt;span class=&#034;ln&#034;&gt;8    &lt;/span&gt;&lt;/a&gt;    &lt;/span&gt;&lt;span class=&#034;s0&#034;&gt;this&lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;.n = n; 
&lt;a name=&#034;l9&#034;&gt;&lt;span class=&#034;ln&#034;&gt;9    &lt;/span&gt;&lt;/a&gt;    &lt;/span&gt;&lt;span class=&#034;s0&#034;&gt;this&lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;.r = r; 
&lt;a name=&#034;l10&#034;&gt;&lt;span class=&#034;ln&#034;&gt;10   &lt;/span&gt;&lt;/a&gt;    &lt;/span&gt;&lt;span class=&#034;s0&#034;&gt;this&lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;.m = m; 
&lt;a name=&#034;l11&#034;&gt;&lt;span class=&#034;ln&#034;&gt;11   &lt;/span&gt;&lt;/a&gt;    &lt;/span&gt;&lt;span class=&#034;s0&#034;&gt;this&lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;.k = k; 
&lt;a name=&#034;l12&#034;&gt;&lt;span class=&#034;ln&#034;&gt;12   &lt;/span&gt;&lt;/a&gt;  } 
&lt;a name=&#034;l13&#034;&gt;&lt;span class=&#034;ln&#034;&gt;13   &lt;/span&gt;&lt;/a&gt; 
&lt;a name=&#034;l14&#034;&gt;&lt;span class=&#034;ln&#034;&gt;14   &lt;/span&gt;&lt;/a&gt;  &lt;/span&gt;&lt;span class=&#034;s0&#034;&gt;public static double &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;C(&lt;/span&gt;&lt;span class=&#034;s0&#034;&gt;int &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;n, &lt;/span&gt;&lt;span class=&#034;s0&#034;&gt;int &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;k) { 
&lt;a name=&#034;l15&#034;&gt;&lt;span class=&#034;ln&#034;&gt;15   &lt;/span&gt;&lt;/a&gt;    System.out.println(&lt;/span&gt;&lt;span class=&#034;s2&#034;&gt;&amp;quot;C(&amp;quot; &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;+ n + &lt;/span&gt;&lt;span class=&#034;s2&#034;&gt;&amp;quot;, &amp;quot; &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;+ k + &lt;/span&gt;&lt;span class=&#034;s2&#034;&gt;&amp;quot;) called.&amp;quot;&lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;); 
&lt;a name=&#034;l16&#034;&gt;&lt;span class=&#034;ln&#034;&gt;16   &lt;/span&gt;&lt;/a&gt;    &lt;/span&gt;&lt;span class=&#034;s0&#034;&gt;double &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;prod = &lt;/span&gt;&lt;span class=&#034;s3&#034;&gt;1.0&lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;; 
&lt;a name=&#034;l17&#034;&gt;&lt;span class=&#034;ln&#034;&gt;17   &lt;/span&gt;&lt;/a&gt;    &lt;/span&gt;&lt;span class=&#034;s0&#034;&gt;for &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;(&lt;/span&gt;&lt;span class=&#034;s0&#034;&gt;int &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;i = &lt;/span&gt;&lt;span class=&#034;s3&#034;&gt;1&lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;; i &amp;lt;= k; i++) { 
&lt;a name=&#034;l18&#034;&gt;&lt;span class=&#034;ln&#034;&gt;18   &lt;/span&gt;&lt;/a&gt;      prod *= ((&lt;/span&gt;&lt;span class=&#034;s0&#034;&gt;double&lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;) (n - i + &lt;/span&gt;&lt;span class=&#034;s3&#034;&gt;1&lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;)) / ((&lt;/span&gt;&lt;span class=&#034;s0&#034;&gt;double&lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;) i); 
&lt;a name=&#034;l19&#034;&gt;&lt;span class=&#034;ln&#034;&gt;19   &lt;/span&gt;&lt;/a&gt;      System.out.println(&lt;/span&gt;&lt;span class=&#034;s2&#034;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#034;s0&#034;&gt;\t&lt;/span&gt;&lt;span class=&#034;s2&#034;&gt;Iteration &amp;quot; &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;+ i + &lt;/span&gt;&lt;span class=&#034;s2&#034;&gt;&amp;quot;: prod = &amp;quot; &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;+ prod); 
&lt;a name=&#034;l20&#034;&gt;&lt;span class=&#034;ln&#034;&gt;20   &lt;/span&gt;&lt;/a&gt;    } 
&lt;a name=&#034;l21&#034;&gt;&lt;span class=&#034;ln&#034;&gt;21   &lt;/span&gt;&lt;/a&gt;    System.out.println(&lt;/span&gt;&lt;span class=&#034;s2&#034;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#034;s0&#034;&gt;\t&lt;/span&gt;&lt;span class=&#034;s2&#034;&gt;Returning &amp;quot; &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;+ prod); 
&lt;a name=&#034;l22&#034;&gt;&lt;span class=&#034;ln&#034;&gt;22   &lt;/span&gt;&lt;/a&gt;    &lt;/span&gt;&lt;span class=&#034;s0&#034;&gt;return &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;prod; 
&lt;a name=&#034;l23&#034;&gt;&lt;span class=&#034;ln&#034;&gt;23   &lt;/span&gt;&lt;/a&gt;  } 
&lt;a name=&#034;l24&#034;&gt;&lt;span class=&#034;ln&#034;&gt;24   &lt;/span&gt;&lt;/a&gt; 
&lt;a name=&#034;l25&#034;&gt;&lt;span class=&#034;ln&#034;&gt;25   &lt;/span&gt;&lt;/a&gt;  &lt;/span&gt;&lt;span class=&#034;s0&#034;&gt;public static double &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;P(&lt;/span&gt;&lt;span class=&#034;s0&#034;&gt;int &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;n, &lt;/span&gt;&lt;span class=&#034;s0&#034;&gt;int &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;r, &lt;/span&gt;&lt;span class=&#034;s0&#034;&gt;int &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;m, &lt;/span&gt;&lt;span class=&#034;s0&#034;&gt;int &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;i) { 
&lt;a name=&#034;l26&#034;&gt;&lt;span class=&#034;ln&#034;&gt;26   &lt;/span&gt;&lt;/a&gt;    System.out.println(&lt;/span&gt;&lt;span class=&#034;s2&#034;&gt;&amp;quot;P(&amp;quot; &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;+ n + &lt;/span&gt;&lt;span class=&#034;s2&#034;&gt;&amp;quot;, &amp;quot; &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;+ r + &lt;/span&gt;&lt;span class=&#034;s2&#034;&gt;&amp;quot;, &amp;quot; &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;+ m + &lt;/span&gt;&lt;span class=&#034;s2&#034;&gt;&amp;quot;, &amp;quot; &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;+ i + &lt;/span&gt;&lt;span class=&#034;s2&#034;&gt;&amp;quot;) called.&amp;quot;&lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;); 
&lt;a name=&#034;l27&#034;&gt;&lt;span class=&#034;ln&#034;&gt;27   &lt;/span&gt;&lt;/a&gt;    &lt;/span&gt;&lt;span class=&#034;s0&#034;&gt;double &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;retVal = C(r, i) * C(n - r, m - i) / C(n, m); 
&lt;a name=&#034;l28&#034;&gt;&lt;span class=&#034;ln&#034;&gt;28   &lt;/span&gt;&lt;/a&gt;    System.out.println(&lt;/span&gt;&lt;span class=&#034;s2&#034;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#034;s0&#034;&gt;\t&lt;/span&gt;&lt;span class=&#034;s2&#034;&gt;Returning &amp;quot; &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;+ retVal); 
&lt;a name=&#034;l29&#034;&gt;&lt;span class=&#034;ln&#034;&gt;29   &lt;/span&gt;&lt;/a&gt;    &lt;/span&gt;&lt;span class=&#034;s0&#034;&gt;return &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;retVal; 
&lt;a name=&#034;l30&#034;&gt;&lt;span class=&#034;ln&#034;&gt;30   &lt;/span&gt;&lt;/a&gt;  } 
&lt;a name=&#034;l31&#034;&gt;&lt;span class=&#034;ln&#034;&gt;31   &lt;/span&gt;&lt;/a&gt; 
&lt;a name=&#034;l32&#034;&gt;&lt;span class=&#034;ln&#034;&gt;32   &lt;/span&gt;&lt;/a&gt;  &lt;/span&gt;&lt;span class=&#034;s0&#034;&gt;public double &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;P() { 
&lt;a name=&#034;l33&#034;&gt;&lt;span class=&#034;ln&#034;&gt;33   &lt;/span&gt;&lt;/a&gt;    &lt;/span&gt;&lt;span class=&#034;s0&#034;&gt;double &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;sum = &lt;/span&gt;&lt;span class=&#034;s3&#034;&gt;0.0&lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;; 
&lt;a name=&#034;l34&#034;&gt;&lt;span class=&#034;ln&#034;&gt;34   &lt;/span&gt;&lt;/a&gt;    &lt;/span&gt;&lt;span class=&#034;s0&#034;&gt;for &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;(&lt;/span&gt;&lt;span class=&#034;s0&#034;&gt;int &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;i = k; i &amp;lt;= r; i++) { 
&lt;a name=&#034;l35&#034;&gt;&lt;span class=&#034;ln&#034;&gt;35   &lt;/span&gt;&lt;/a&gt;      sum += P(n, r, m, i) * P(m, i, k, k); 
&lt;a name=&#034;l36&#034;&gt;&lt;span class=&#034;ln&#034;&gt;36   &lt;/span&gt;&lt;/a&gt;    } 
&lt;a name=&#034;l37&#034;&gt;&lt;span class=&#034;ln&#034;&gt;37   &lt;/span&gt;&lt;/a&gt;    &lt;/span&gt;&lt;span class=&#034;s0&#034;&gt;return &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;sum; 
&lt;a name=&#034;l38&#034;&gt;&lt;span class=&#034;ln&#034;&gt;38   &lt;/span&gt;&lt;/a&gt;  } 
&lt;a name=&#034;l39&#034;&gt;&lt;span class=&#034;ln&#034;&gt;39   &lt;/span&gt;&lt;/a&gt;} 
&lt;a name=&#034;l40&#034;&gt;&lt;span class=&#034;ln&#034;&gt;40   &lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;TABLE CELLSPACING=0 CELLPADDING=5 COLS=1 WIDTH=&#034;100%&#034; BGCOLOR=&#034;#C0C0C0&#034; &gt;
&lt;TR&gt;&lt;TD&gt;&lt;CENTER&gt;
&lt;FONT FACE=&#034;Arial, Helvetica&#034; COLOR=&#034;#000000&#034;&gt;
Main.java&lt;/FONT&gt;
&lt;/center&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TABLE&gt;
&lt;pre&gt;
&lt;a name=&#034;l1&#034;&gt;&lt;span class=&#034;ln&#034;&gt;1    &lt;/span&gt;&lt;/a&gt;&lt;span class=&#034;s0&#034;&gt;public class &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;Main { 
&lt;a name=&#034;l2&#034;&gt;&lt;span class=&#034;ln&#034;&gt;2    &lt;/span&gt;&lt;/a&gt;  &lt;/span&gt;&lt;span class=&#034;s0&#034;&gt;public static void &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;main(String[] args) { 
&lt;a name=&#034;l3&#034;&gt;&lt;span class=&#034;ln&#034;&gt;3    &lt;/span&gt;&lt;/a&gt;    Foo foo = &lt;/span&gt;&lt;span class=&#034;s0&#034;&gt;new &lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;Foo(&lt;/span&gt;&lt;span class=&#034;s2&#034;&gt;100&lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;, &lt;/span&gt;&lt;span class=&#034;s2&#034;&gt;15&lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;, &lt;/span&gt;&lt;span class=&#034;s2&#034;&gt;50&lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;, &lt;/span&gt;&lt;span class=&#034;s2&#034;&gt;3&lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;); 
&lt;a name=&#034;l4&#034;&gt;&lt;span class=&#034;ln&#034;&gt;4    &lt;/span&gt;&lt;/a&gt;    System.out.println(foo.P()); 
&lt;a name=&#034;l5&#034;&gt;&lt;span class=&#034;ln&#034;&gt;5    &lt;/span&gt;&lt;/a&gt;    System.out.println(Foo.P(&lt;/span&gt;&lt;span class=&#034;s2&#034;&gt;100&lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;, &lt;/span&gt;&lt;span class=&#034;s2&#034;&gt;15&lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;, &lt;/span&gt;&lt;span class=&#034;s2&#034;&gt;3&lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;, &lt;/span&gt;&lt;span class=&#034;s2&#034;&gt;3&lt;/span&gt;&lt;span class=&#034;s1&#034;&gt;)); 
&lt;a name=&#034;l6&#034;&gt;&lt;span class=&#034;ln&#034;&gt;6    &lt;/span&gt;&lt;/a&gt;  } 
&lt;a name=&#034;l7&#034;&gt;&lt;span class=&#034;ln&#034;&gt;7    &lt;/span&gt;&lt;/a&gt;} 
&lt;a name=&#034;l8&#034;&gt;&lt;span class=&#034;ln&#034;&gt;8    &lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;According to my calculation, the probability of the event that Jeff described is 0.0028138528138528123 or 0.28% assuming there are 100 JVM programmers.&lt;/p&gt;

&lt;p&gt;There are two points that&#039;s worth mentioning:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The condition of there being 50 SpringSource programmers can be actually shown to be superfluous.  And the calculation can therefore be simplified to merely that of &lt;i&gt;P(100, 15; 3, 3)&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;It can be shown that &lt;i&gt;P(n, r, k, k)&lt;/i&gt; tends to &lt;i&gt;(r/n)^k&lt;/i&gt; as &lt;i&gt;n&lt;/i&gt; and &lt;i&gt;r&lt;/i&gt; grows to infinity while the ratio &lt;i&gt;r/n&lt;/i&gt; is kept constant.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;(&lt;em&gt;Now it&#039;s Monday morning.  After staring at the 0.28% probability for a while, I realized something...&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;What I calculated is not what Jeff wanted.  He clearly said he wanted &#034;the likelihood that 3 of the 50 would be interested in Clojure&#034;, or, in our language, &#034;the probability of selecting 50 balls that contains exactly 3 red balls.&#034;  That&#039;s &lt;i&gt;P(100, 15; 50, 3)&lt;/i&gt;, which is 0.009392308830476828 or 0.94%.&lt;/p&gt;  A simple experiment suggests that as &lt;i&gt;n&lt;/i&gt; and &lt;i&gt;r&lt;/i&gt; grows to infinity while the ratio &lt;i&gt;r/n&lt;/i&gt; is kept constant, the probability tends to 3.19%.&lt;/p&gt;

&lt;p&gt;(&lt;em&gt;It&#039;s Monday evening now.  And I again have doubts about if I solved the right problem.&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;Did Jeff mean &#034;the likelihood that at least 3 of the 50 would be interested in Clojure&#034;?  After all, from the description of the story I can&#039;t infer that the other 47 are not interested in Clojure.&lt;/p&gt;

&lt;p&gt;The probability of that would be&lt;/p&gt;

&lt;center&gt;
&lt;i&gt;&lt;big&gt;&amp;Sigma&lt;/big&gt;&lt;sub&gt;i = 3&lt;/sub&gt;&lt;sup&gt;15&lt;/sup&gt; P(100, 15; 50, i)&lt;/i&gt;
&lt;/center&gt;

&lt;p&gt;which turns out to be 99.8%.&lt;/p&gt;

&lt;p&gt;(&lt;em&gt;I think I&#039;ll turn my work in now.  Or I&#039;ll start doubt my solution again tomorrow morning.&lt;/em&gt;)&lt;/p&gt;


        </description>
      
      
    
    
    
    <comments>http://www.weiqigao.com/blog/2009/08/03/jeff_browns_probability_quiz_what_are_the_chances.html#comments</comments>
    <guid isPermaLink="true">http://www.weiqigao.com/blog/2009/08/03/jeff_browns_probability_quiz_what_are_the_chances.html</guid>
    <pubDate>Tue, 04 Aug 2009 02:40:08 GMT</pubDate>
  </item>
  
  <item>
    <title>Java News Brief (JNB): Introduction to Grails</title>
    <link>http://www.weiqigao.com/blog/2007/03/06/java_news_brief_jnb_introduction_to_grails.html</link>
    
      
        <description>
          &lt;p&gt;The &lt;a href= &#034;http://www.ociweb.com/jnb/jnbMar2007.html&#034; &gt;March issue&lt;/a&gt; of the &lt;a href= &#034;http://www.ociweb.com/jnb/&#034; &gt;Java News Brief (JNB)&lt;/a&gt; is out.  &lt;a href= &#034;http://javajeff.blogspot.com/&#034; &gt;Jeff Brown&lt;/a&gt; gives an introduction to &lt;a href= &#034;http://grails.org/&#034; &gt;Grails&lt;/a&gt;&amp;mdash;the &#034;framework for agile web development using Groovy and Java.&#034;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href= &#034;http://www.ociweb.com/jnb/jnbMar2007.html&#034; &gt;Jeff Brown&lt;/a&gt;: Grails is a remarkably flexible framework while maintaining an ease of use that is unparalleled by other web application frameworks targeted for the JVM. Use the exercises in this article as a jump start with Grails and have fun exploring the possibilities.&lt;/p&gt;
&lt;/blockquote&gt;
        </description>
      
      
    
    
    
    <comments>http://www.weiqigao.com/blog/2007/03/06/java_news_brief_jnb_introduction_to_grails.html#comments</comments>
    <guid isPermaLink="true">http://www.weiqigao.com/blog/2007/03/06/java_news_brief_jnb_introduction_to_grails.html</guid>
    <pubDate>Tue, 06 Mar 2007 17:49:08 GMT</pubDate>
  </item>
  
  <item>
    <title>Jeff Brown: An Introduction To Building Groovy Web Applications With Grails</title>
    <link>http://www.weiqigao.com/blog/2006/09/14/jeff_brown_an_introduction_to_building_groovy_web_applications_with_grails.html</link>
    
      
        <description>
          &lt;p&gt;I&#039;ll try to live blog today&#039;s St. Louis JUG meeting.  I have done this for the OCI internal Java and C++ lunches in the past.  Since the auditorium at &lt;a href= &#034;http://maps.google.com/maps?q=1+City+Place+Dr,+St+Louis,+MO+63141&amp;ie=UTF8&amp;oe=UTF-8&amp;client=firefox-a&amp;hl=en&amp;z=19&amp;ll=38.673361,-90.439756&amp;spn=0.001279,0.003291&amp;t=k&amp;om=1&#034; &gt;One City Place&lt;/a&gt;, where the JUG meets, has excellent WIFI, I thought I&#039;ll try to do the live blog here.&lt;/p&gt;

&lt;p&gt;The JUG usually starts with a Q&amp;amp;A session:&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Q&lt;/b&gt;: What&#039;s new in Java?&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Kyle Cordes&lt;/b&gt;: We are on the other side of the adoption curve.  There are enormous amount of money to be made.  Scripting languages is a playground where you can learn some of the new constructs, like closures.  These constructs are coming to a future version of Java.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Jay Meyer&lt;/b&gt;: The scripting support in Java 6 allows me to setup an enterprise ready server where you can deploy your applications written in a scripting language, such as Groovy, or JavaScript.  Now you have transactions, you have security, etc.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Q&lt;/b&gt;: What is a good Java job?&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Kyle Cordes&lt;/b&gt;: Software product work is more prestigious than IT work.  There are good jobs in both categories here in St. Louis.&lt;/p&gt;

&lt;p&gt;Jeff Brown is on stage to give today&#039;s Grails presentation.  First person is Jeff now.&lt;/p&gt;

&lt;p&gt;Ruby on Rails is new and fun.  A lot of Java developer looked into Ruby on Rails and asked if it is possible to duplicate it in the Java platform.  Grails meets that challenge.&lt;/p&gt;

&lt;p&gt;Groovy is not a perfect programming language.  But there are a lot of things in groovy that&#039;s cool.&lt;/p&gt;

&lt;p&gt;(Jeff starts Eclipse.)  Let me warn you that the Groovy plugin for Eclipse is flaky on a good day.&lt;/p&gt;

&lt;h4&gt;Groovy&lt;/h4&gt;

&lt;p&gt;In groovy, everything is an object.  The number 5 is an object, you can call times on it:&lt;/p&gt;

&lt;pre style=&#034;margin-left:3em&#034;&gt;class GroovyTest {
  static void main(args) {
    5.times { println it }
  }
}&lt;/pre&gt;

&lt;p&gt;In Groovy strings are surrounded in single quotes.  Groovy also has GStrings.  They are surrounded by double quotes.  You can do variable substitution within GStrings.&lt;/p&gt;

&lt;p&gt;Groovy support named parameter lists:&lt;/p&gt;

&lt;pre style=&#034;margin-left:3em&#034;&gt;class GroovyTest {
  String firstName
  String lastName
  Integer age

  static void main(args) {
    def gt = new Groovytest(firstName: &#039;Jeff&#039;, lastName: &#039;Brown&#039;)
    println gt.firstName
  }
}&lt;/pre&gt;

&lt;p&gt;All the places where your IDE will generate getter and setter code for you are suspicious.  In Groovy you don&#039;t need the boilerplate code.  When you declare a field, a getter and a setter is written for you.&lt;/p&gt;

&lt;p&gt;I can still write a getter, but only if I want to do something different.&lt;/p&gt;

&lt;p&gt;There are no package level members in groovy.&lt;/p&gt;

&lt;p&gt;No semi-colon is required.&lt;/p&gt;

&lt;p&gt;There is a really easy way to generate markups.&lt;/p&gt;

&lt;h4&gt;Grails&lt;/h4&gt;

&lt;p&gt;All right, on to the meat of the presentation.  What is Grails?  It&#039;s a MVC web framework for web apps.  It exploits the awesome power of Groovy.  It leverages proven staples: Hibernate, Spring, and Sitemesh.  It is excellent for those apps in the sweet spot.  And it is Fun, Fun, Fun&lt;/p&gt;

&lt;p&gt;The user mailing list is very active.  They are not hostile to Rails at all.  The communities are awesome.&lt;/p&gt;

&lt;p&gt;In the spirit of fun, I&#039;m going to give away &lt;strike&gt;an early access copy of a book that has not yet been written&amp;mdash;Grails In Action, by Graeme Rocher, the main developer of Grails, to be published by Manning in January 2007.  Four early access chapters are available already.&lt;/strike&gt; [I completely &lt;span style=&#034;color:red&#034;&gt;messed up the details&lt;/span&gt; here.  See &lt;a href= &#034;http://www.weiqigao.com/blog/2006/09/14/jeff_brown_an_introduction_to_building_groovy_web_applications_with_grails.html#comment1158419977573&#034; &gt;Jeff Brown&#039;s comment&lt;/a&gt; at the end of this post for the correct information.  My apologies to Jeff and Craeme.  &amp;ndash;Weiqi]&lt;/p&gt;

&lt;p&gt;Famous people loves grails.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;John Lennen:&lt;br/&gt;
&lt;br/&gt;
&#034;Imagine no config files&lt;br/&gt;
It&#039;s easy if you try&lt;br/&gt;
No action mappings&lt;br/&gt;
Man, that Grails is going to be fly.&#034;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;(Jeff runs a command &#034;grails create-app&#034; and things flow on the command shell.  Jeff then runs &#034;grails create-domain-class&#034; and entered &#034;Person&#034; and a class is generated.)&lt;/p&gt;

&lt;p&gt;Apparently Rails does something that makes it difficult to create your own domain classes.&lt;/p&gt;

&lt;p&gt;(Jeff runs the &#034;grails create-controller&#034; and entered &#034;PersonControler&#034;.)&lt;/p&gt;

&lt;p&gt;One of the things that is created is Eclipse project files.  (Jeff then imports the whole thing into Eclipse.)&lt;/p&gt;

&lt;p&gt;I&#039;m going to add some attributes to Person.  (Jeff adds firstName, lastName and age.)  I&#039;m going to add an attribute called scaffold&lt;/p&gt;

&lt;pre style=&#034;margin-left:3em&#034;&gt;def scaffold = true&lt;/pre&gt;

&lt;p&gt;This tells grails to generate our controller at runtime.&lt;/p&gt;

&lt;p&gt;(Starting Jetty web server, surfing to localhost:8080/javasigdemo, and things appear.)  Just like JSPs, the pages in Grails are written in GSPs, Groovy Server Pages.  They also need to be compiled the first time they are executed, just like JSPs.&lt;/p&gt;

&lt;p&gt;(Mario Aquino: Jeff, are you using a database?)  I&#039;m using HSQL DB.  I&#039;ll get to it in a moment.&lt;/p&gt;

&lt;p&gt;(Jeff adds several persons in the web app.)&lt;/p&gt;

&lt;p&gt;(Audience Member: What about the mixture of statically and dynamically typed variables?  Jeff Grigg: Static types makes the code run faster.)&lt;/p&gt;

&lt;p&gt;Famous people loves grails.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Batman and Robin:&lt;br/&gt;
&lt;br/&gt;
&#034;Holy productivity Batman!  What are we going to do with the free time.&#034;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The scaffolding in Grails is interesting.  The one we have been using all happens at runtime and are just like magic.  I can also tell Grails to generate all, in which case it will generate all the code beforehand.&lt;/p&gt;

&lt;p&gt;Looking at the controller:  All the code blocks are mapped to actions:&lt;/p&gt;

&lt;pre style=&#034;margin-left:3em&#034;&gt;def list = { [personList: Person.list(params) ] }&lt;/pre&gt;

&lt;p&gt;These code blocks are closures.&lt;/p&gt;

&lt;h4&gt;The &#034;M&#034;&lt;/h4&gt;

&lt;p&gt;The &#034;M&#034; in MVC are the domain classes.&lt;/p&gt;

&lt;p&gt;In your domain class, you can stick with POGOs (plain old Groovy objects.  You want your domain class to be free of view stuff.  However you may want validation logic in your domain classes.&lt;/p&gt;

&lt;p&gt;(Audience Member: When you change the code, what changes can be automatically picked up by the application?)  Grails will dynamically pick up a lot of changes in your application.  But not everything is picked up.  Domain model changes are not picked up.&lt;/p&gt;

&lt;p&gt;(Jeff shows validation at work.  Invalid fields are highlighted.)&lt;/p&gt;

&lt;h4&gt;The &#034;C&#034;&lt;/h4&gt;

&lt;p&gt;The &#034;C&#034; (controller) is the traffic cop.  It defines actions and navigates to the views.&lt;/p&gt;

&lt;p&gt;We don&#039;t see anything in the list code block that tells us where to go.  By convention, we go to list.gsp.  If you don&#039;t want the automatic thing to happen, you can call redirect.  (Jeff shows the URL associated with the delete button, something like &lt;tt&gt;http://localhost:8080/javasigdemo/person/delete/42&lt;/tt&gt;)&lt;/p&gt;

&lt;p&gt;(Kyle Cordes: Doing a GET on your delete URL deletes stuff.  Doesn&#039;t that make you go eeeeh?)&lt;/p&gt;

&lt;h4&gt;The &#034;V&#034;&lt;/h4&gt;

&lt;p&gt;The &#034;V&#034; is GSP&amp;mdash;Groovy Server Page.&lt;/p&gt;

&lt;p&gt;In GSP you can easily define custom tags.  You just define a closure.  And the tag can be used in your GSP pages.  No taglib XML files.&lt;/p&gt;

&lt;p&gt;Sitemesh is at play here.  Grails uses Sitemesh to layout the pages.&lt;/p&gt;

&lt;p&gt;There are a lot of tags built into Grails.  Logical, iterative, Ajax, form, etc.&lt;/p&gt;

&lt;p&gt;Famous people loves grails.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Mr. T:&lt;br/&gt;
&lt;br/&gt;
&#034;I pity the fool who has to maintain all of those TLD files.&#034;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;Hey Dude, Where Is My Data?&lt;/h4&gt;

&lt;p&gt;Grails generates configuration files &lt;tt&gt;*DataSource.groovy&lt;/tt&gt; where &lt;tt&gt;*&lt;/tt&gt; are: Development, Production, Test&lt;/p&gt;

&lt;p&gt;Grail uses HSQL DB&#039;s in memory relational database as the default database.  This can be easily changed.&lt;/p&gt;

&lt;p&gt;You can use a &lt;tt&gt;ApplicationBootStrap.groovy&lt;/tt&gt; class to to populate the database with sample data.&lt;/p&gt;

&lt;p&gt;Grails hooks your domain objects with Hibernate, which in turn hooks up with the actual database.  You don&#039;t have to write your Hibernate config files.&lt;/p&gt;

&lt;p&gt;(Jeff writes an ApplicationBootStrap class.)  This class is picked up when the application starts.  It populates the database.&lt;/p&gt;

&lt;p&gt;GORM is Groovy Object Relational Mapping.  Currently it is Hibernate based.  JPA support slated for 0.4.&lt;/p&gt;

&lt;h4&gt;Questions And Other Tidbits&lt;/h4&gt;

&lt;p&gt;(I asked about production or public websites running Grails.)  Every 7 minutes somebody asks this question on the mailing list.  It doesn&#039;t really make sense.  If what you need is in there, you can use it.  If not, not.&lt;/p&gt;

&lt;p&gt;Grails 0.3 will be out in a month or so.  It will have Sprint 2.0 integration.&lt;/p&gt;

&lt;p&gt;(Kyle Cordes: How do you measure the relative merits of Grails vs. JRuby on Rails?)  Groovy runs on the JVM, you can access all the Java core classes, leverage to use all the java classes you have written.  JRuby is a tool that allows Ruby to be run on the JVM.  Having alternatives is good.&lt;/p&gt;

&lt;p&gt;(Jeff Grigg: There is a mismatch between Ruby and the JVM.  The JRuby guys have to do a lot of tricky things to support Ruby language features such as adding methods to classes at run time.)

&lt;p&gt;Just this week, at Sun days, according to one source, Sun announced that Groovy is going to be a module in Java 7.&lt;/p&gt;

&lt;p&gt;Jeff wrapped up by giving away four ebooks on Grails.  First person is Weiqi now.&lt;/p&gt;

&lt;h4&gt;What To Think&lt;/h4&gt;

&lt;p&gt;I think Jeff&#039;s talk is excellent.  The audience participation makes it that much more interesting and lively.&lt;/p&gt;

&lt;p&gt;I&#039;m a little bit surprised by me own reaction.  I came into the meeting thinking Grails is nothing but a knock-off of Ruby on Rails, and my reaction to Ruby on Rails hasn&#039;t been all that positive (&#034;Rails is full of magic that I don&#039;t understand, will fall down somehow, etc.&#034;)&lt;/p&gt;

&lt;p&gt;However, after the talk, I feel that Grail is a reasonable web framework that learned a lot from Ruby on Rails yet remained true to the Java platform.  It makes use of the best ORM and other frameworks that the Java platform has to offer.  And has a reasonable chance of picking up mind share among the rank and file Java developers.  And it has a reasonable chance at succeeding with what it attempts to do.&lt;/p&gt;

&lt;p&gt;To be sure, Groovy is not the cleanestly designed language.  However it does mesh well with Java.  And it does offer features that makes Grail possible.  And most importantly, someone did something nice with Groovy.&lt;/p&gt;
        </description>
      
      
    
    
    
    <comments>http://www.weiqigao.com/blog/2006/09/14/jeff_brown_an_introduction_to_building_groovy_web_applications_with_grails.html#comments</comments>
    <guid isPermaLink="true">http://www.weiqigao.com/blog/2006/09/14/jeff_brown_an_introduction_to_building_groovy_web_applications_with_grails.html</guid>
    <pubDate>Fri, 15 Sep 2006 04:15:01 GMT</pubDate>
  </item>
  
  </channel>
</rss>

