<?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-6669041857214331338</id><updated>2012-01-26T12:44:07.346-08:00</updated><category term='Grails'/><category term='agile'/><category term='Java'/><category term='IDE'/><category term='API'/><category term='Google'/><category term='Groovy'/><category term='documetation'/><title type='text'>make.go.now</title><subtitle type='html'>Ramblings about better living through software.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://zanthrash.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6669041857214331338/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://zanthrash.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Zan Thrash</name><uri>http://www.blogger.com/profile/11490463092837149298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>5</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6669041857214331338.post-6477781306541016594</id><published>2008-02-04T11:30:00.000-08:00</published><updated>2008-02-04T09:42:16.923-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='Google'/><category scheme='http://www.blogger.com/atom/ns#' term='Grails'/><title type='text'>Updated GoogleChart Plugin ver 0.4</title><content type='html'>A couple weeks ago I released a &lt;a href="http://www.blogger.com/http//zanthrash.blogspot.com/2008/01/groovy-chart-builder.html"&gt;GoolgeChartBuilder&lt;/a&gt; for the &lt;a href="http://code.google.com/apis/chart/"&gt;Google Charts API&lt;/a&gt;. At about the same time &lt;a href="http://www.jameswilliams.be/blog/entry/54;jsessionid=FA9F14C05405403BD0DCDCC3CC811875"&gt;James Williams&lt;/a&gt; released the &lt;a href="http://grails.codehaus.org/Google+Chart+Plugin"&gt;Google Chart Plugin&lt;/a&gt; for Grails.&lt;br /&gt;&lt;br /&gt;Up until now the Google Chart Plugin provided the Grails developer with a fantastic way to generate charts in the view layer (GSP) via a tag library.&lt;br /&gt;&lt;br /&gt;With the addition of the builder; the chart URLs can now be easily created in a domain, controller, or service object.  The builder functionally provides the opportunity to save the URL to a database or pre-fetch the image file and cache it on the server.&lt;br /&gt;&lt;br /&gt;The core functionally of the original builder remains intact and examples can be found &lt;a href="http://zanthrash.blogspot.com/2008/01/groovy-chart-builder.html"&gt;here&lt;/a&gt;, and documentation can be found &lt;a href="http://www.zanthrash.com/GoogleChartBuilder.html"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The names of the charts were changed to more closely tie the builder to the tag library.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6669041857214331338-6477781306541016594?l=zanthrash.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zanthrash.blogspot.com/feeds/6477781306541016594/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6669041857214331338&amp;postID=6477781306541016594' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6669041857214331338/posts/default/6477781306541016594'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6669041857214331338/posts/default/6477781306541016594'/><link rel='alternate' type='text/html' href='http://zanthrash.blogspot.com/2008/02/updated-googlechart-plugin-ver-04.html' title='Updated GoogleChart Plugin ver 0.4'/><author><name>Zan Thrash</name><uri>http://www.blogger.com/profile/11490463092837149298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6669041857214331338.post-3018238610308298282</id><published>2008-01-09T03:50:00.000-08:00</published><updated>2008-02-04T09:49:21.591-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='API'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='Google'/><category scheme='http://www.blogger.com/atom/ns#' term='Grails'/><title type='text'>Google Chart Builder</title><content type='html'>&lt;h3&gt;For Groovy and Grails&lt;/h3&gt;&lt;span style="font-weight: bold;"&gt;UPDATE:&lt;/span&gt; (2/4/2008) This builder has been added to the &lt;a href="http://grails.codehaus.org/Google+Chart+Plugin"&gt;Google Charts Plugin&lt;/a&gt; for Grails version 0.4&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;UPDATE&lt;/strong&gt;: Due to a conflict in Grails with the &lt;strong&gt;set&lt;/strong&gt; closure, it has been renamed to &lt;strong&gt;dataSet&lt;/strong&gt;.  The examples have been updated as well as the source code and tests.&lt;br /&gt;&lt;br /&gt;&lt;p&gt;A little while ago Google released a their &lt;a href="http://code.google.com/apis/chart/"&gt;Chart API&lt;/a&gt; into the wild. It’s basically allows a client to call a RESTful url and get a PNG image back of the chart. Very cool stuff.  After playing with it for a little bit I quickly realized that this RESTful approach was both very powerful and very annoying. I primarily do web development and if I’m creating a chart I want it to be on the fly and dynamic. Injecting data and labels into a potentially long url was not my idea of a good time. &lt;/p&gt;&lt;p&gt;Enter the GoogleChartBuilder (&lt;a href="http://zanthrash.com/GoogleChartBuilder-1.0.zip"&gt;Download Source&lt;/a&gt;).&lt;br /&gt;Written in &lt;a href="http://groovy.codehaus.org/"&gt;Groovy&lt;/a&gt; utilizing it’s fantastic &lt;a href="http://groovy.codehaus.org/BuilderSupport"&gt;BuilderSupport&lt;/a&gt; class.&lt;/p&gt;&lt;br /&gt;Here is an example on how to create a 3D Pie Chart:&lt;br /&gt;&lt;br /&gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;span style="font-family:monospace;"&gt;&lt;br /&gt;&lt;code&gt;def chart = new GoogleChartBuilder()&lt;br /&gt;def textList = (1..5).toList()&lt;br /&gt;def result = chart.pie3DChart{&lt;br /&gt;size(w:350, h:200)&lt;br /&gt;data(encoding:'text'){&lt;br /&gt; dataSet(textList)&lt;br /&gt;}&lt;br /&gt;labels{&lt;br /&gt; textList.each{ label(it) }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;result&lt;/code&gt; will yield this url string:  &lt;/p&gt;&lt;p&gt;&lt;strong&gt;http://chart.apis.google.com/chart?cht=p3&amp;amp;chs=350x200&amp;amp;chd=t:1,2,3,4,5&amp;amp;chl=1|2|3|4|5&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;Submit this URL and you will get the following chart:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_iAqJMcYqklk/R4TgfmQ62WI/AAAAAAAAAAM/9Ah8IXbNHHQ/s1600-h/3DPieChart.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; cursor: pointer;" src="http://bp2.blogger.com/_iAqJMcYqklk/R4TgfmQ62WI/AAAAAAAAAAM/9Ah8IXbNHHQ/s320/3DPieChart.png" alt="" id="BLOGGER_PHOTO_ID_5153490707070769506" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Here is an example on how to create a Horizontal Grouped Bar Chart:&lt;br /&gt;&lt;/p&gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;span style="font-family:monospace;"&gt;&lt;br /&gt;&lt;code&gt;def chart = new GoogleChartBuilder()&lt;br /&gt;result = chart.barChart(['horizontal', 'grouped']){&lt;br /&gt;  barSize(witdth:10, space:2)&lt;br /&gt;  size(w:350, h:200)&lt;br /&gt;  title(color:808080, size:16){&lt;br /&gt;      row('Chart 1')&lt;br /&gt;      row('Sampel bar chart')&lt;br /&gt;  }&lt;br /&gt;  data(encoding:'simple'){&lt;br /&gt;      dataSet((1..5).toList())&lt;br /&gt;      dataSet((5..1).toList())&lt;br /&gt;  }&lt;br /&gt;  colors{&lt;br /&gt;      color('66CC00')&lt;br /&gt;      color('3399ff')&lt;br /&gt;  }&lt;br /&gt;  legend{&lt;br /&gt;      label('Joy')&lt;br /&gt;      label('Pain')&lt;br /&gt;  }&lt;br /&gt;  axis(left:(1..5).toList(), bottom:[])&lt;br /&gt;  backgrounds{&lt;br /&gt;      background{&lt;br /&gt;          solid(color:'999999')&lt;br /&gt;      }&lt;br /&gt;      area{&lt;br /&gt;          gradient(angle:45, start:'CCCCCC', end:'999999')&lt;br /&gt;      }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;result&lt;/code&gt; will yield this url string:  &lt;/p&gt;&lt;p&gt;&lt;strong&gt;http://chart.apis.google.com/chart?cht=bhg&amp;amp;chbh=10,2&amp;amp;chs=350x200&amp;amp;chts=808080,16&amp;amp;&lt;br /&gt;chtt=Chart+1|Sampel+bar+chart&amp;amp;chd=s:BCDEF,FEDCB&amp;amp;chco=66CC00,3399ff&amp;amp;&lt;br /&gt;chdl=Joy|Pain&amp;amp;chxt=y,x&amp;amp;chxl=0:|1|2|3|4|5&amp;amp;chf=bg,s,999999|c,lg,45,CCCCCC,0,999999,1&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;Submit this URL and you will get the following chart:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_iAqJMcYqklk/R4Tiw2Q62XI/AAAAAAAAAAU/6jtYAb16wrA/s1600-h/HorzGroupedBarChart.png"&gt;&lt;img style="cursor: pointer;" src="http://bp3.blogger.com/_iAqJMcYqklk/R4Tiw2Q62XI/AAAAAAAAAAU/6jtYAb16wrA/s320/HorzGroupedBarChart.png" alt="" id="BLOGGER_PHOTO_ID_5153493202446768498" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here is an example on how to create a Line Chart:&lt;br /&gt;&lt;/p&gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;span style="font-family:monospace;"&gt;&lt;br /&gt;&lt;code&gt;def chart = new GoogleChartBuilder()&lt;br /&gt;result = chart.lineChart{&lt;br /&gt;  size(w:300, h:200)&lt;br /&gt;  title{&lt;br /&gt;      row('Joy vs. Pain')&lt;br /&gt;  }&lt;br /&gt;  data(encoding:'extended'){&lt;br /&gt;      dataSet([1,18,200,87,1090,44,3999])&lt;br /&gt;      dataSet([88,900,77,1,2998,4])&lt;br /&gt;  }&lt;br /&gt;  colors{&lt;br /&gt;      color('66CC00')&lt;br /&gt;      color('3399ff')&lt;br /&gt;  }&lt;br /&gt;  lineStyle(line1:[1,6,3])&lt;br /&gt;  legend{&lt;br /&gt;      label('Joy')&lt;br /&gt;      label('Pain')&lt;br /&gt;  }&lt;br /&gt;  axis(left:(1..5).toList(), bottom:[])&lt;br /&gt;  backgrounds{&lt;br /&gt;      background{&lt;br /&gt;          solid(color:'999999')&lt;br /&gt;      }&lt;br /&gt;      area{&lt;br /&gt;          gradient(angle:45, start:'CCCCCC', end:'999999')&lt;br /&gt;      }&lt;br /&gt;  }&lt;br /&gt;   markers{&lt;br /&gt;      rangeMarker(type:'horizontal', color:'FF0000', start:0.75, end:0.25)&lt;br /&gt;      rangeMarker(type:'vertical', color:'0000cc', start:0.7, end:0.71)&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;result&lt;/code&gt; will yield this url string:  &lt;/p&gt;&lt;p&gt;&lt;strong&gt;http://chart.apis.google.com/chart?cht=lc&amp;amp;chs=300x200&amp;amp;chtt=Joy+vs.+Pain&amp;amp;&lt;br /&gt;chd=e:ABASDIBXRCAs-f,BYOEBNABu2AE&amp;amp;chco=66CC00,3399ff&amp;amp;chls=1,6,3&amp;amp;&lt;br /&gt;chdl=Joy|Pain&amp;amp;chxt=y,x&amp;amp;chxl=0:|1|2|3|4|5&amp;amp;chf=bg,s,999999|c,lg,45,CCCCCC,0,999999,1&amp;amp;&lt;br /&gt;chm=r,FF0000,0,0.75,0.25|R,0000cc,0,0.7,0.71&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;Submit this URL and you will get the following chart:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_iAqJMcYqklk/R4TkamQ62YI/AAAAAAAAAAc/S9HB86hZaYk/s1600-h/LineChart.png"&gt;&lt;img style="cursor: pointer;" src="http://bp2.blogger.com/_iAqJMcYqklk/R4TkamQ62YI/AAAAAAAAAAc/S9HB86hZaYk/s320/LineChart.png" alt="" id="BLOGGER_PHOTO_ID_5153495019217934722" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The Google Charts API also allows for the creation of:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Scatter Point charts.&lt;/li&gt;&lt;li&gt;Venn Diagrams&lt;/li&gt;&lt;li&gt;2D pie charts&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Vertical Stacked Bar Charts&lt;/li&gt;&lt;li&gt;Vertical Grouped Bar Charts&lt;/li&gt;&lt;li&gt;Horizontal Stacked Bar Chars&lt;/li&gt;&lt;li&gt;Line XY Plot Chart&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;To see examples of these charts (&lt;a href="http://zanthrash.com/GoogleChartBuilder-1.0.zip"&gt;Download the source code&lt;/a&gt;) and run the test suite under the 'test' folder.  The following tests will have examples on how to use the Google Chart Builder and will also generate HTML files (in a folder named GoogleCharts under root)that contain the URL strings.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;PieChartTest.groovy&lt;/li&gt;&lt;li&gt;BarChartTest.groovy&lt;/li&gt;&lt;li&gt;ScatterPlotTest.groovy&lt;/li&gt;&lt;li&gt;VennDiagramTest.groovy&lt;/li&gt;&lt;li&gt;LineChartTest.groovy&lt;/li&gt;&lt;/ul&gt;These&lt;br /&gt;&lt;br /&gt;Documentation on the keywords that are used in the Google Chart Builder can be found in the 'docs' folder or &lt;a href="http://zanthrash.com/GoogleChartBuilder.html"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;As you can see the Google Charts API allows you do generate some pretty complicated charts.  However because of the RESTful nature of these charts the URLs can get out of hand very fast. My intention is to ease the pain in using this useful API.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6669041857214331338-3018238610308298282?l=zanthrash.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zanthrash.blogspot.com/feeds/3018238610308298282/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6669041857214331338&amp;postID=3018238610308298282' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6669041857214331338/posts/default/3018238610308298282'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6669041857214331338/posts/default/3018238610308298282'/><link rel='alternate' type='text/html' href='http://zanthrash.blogspot.com/2008/01/groovy-chart-builder.html' title='Google Chart Builder'/><author><name>Zan Thrash</name><uri>http://www.blogger.com/profile/11490463092837149298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp2.blogger.com/_iAqJMcYqklk/R4TgfmQ62WI/AAAAAAAAAAM/9Ah8IXbNHHQ/s72-c/3DPieChart.png' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6669041857214331338.post-9132932807638759908</id><published>2007-11-29T13:31:00.000-08:00</published><updated>2007-12-03T12:15:27.742-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IDE'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><title type='text'>Coding with Crayons</title><content type='html'>A while back I listened to a great &lt;a href="http://aboutgroovy.com/item/show/172"&gt;interview of Neal Ford speaking on DSL's&lt;/a&gt;.  In this interview Mr. Ford states that he&lt;br /&gt;&lt;blockquote&gt;"Would rather code Groovy in Vi than Java in IDEA"&lt;/blockquote&gt;&lt;br /&gt;At first when I heard this, it brought me pause, but I quickly deemed it not worthy of any additional thought. That is until recently, when I was forced to write a small, trivial application in Java...with pen and paper. The problem is stated below, and it had to compile and run. If I had my trusty IDE with intellisence, code completion, syntax highlighting, and refactoring I could have probably cranked out the solution in about a minute (it actually took me about 4 minutes when I tried, but there were unit tests involved).&lt;br /&gt;&lt;br /&gt;As a counterpoint I decided to solve the same problem in Groovy. To do the Groovy development I fired up TextMate on my Mac (but I could have just as easily used the ever crappy Notepad on Windows).&lt;br /&gt;&lt;br /&gt;What I came away from this exercise: How relient I had become on my IDE to make me an efficient and effective Java developer. Java is just to verbose and rigid of a language to code in pen and paper, even for a simple app. With Groovy I feel like I could break out the box of 64 Crayola Crayons and happily code away on some construction paper, run it through an OCR scanner and then execute it via the command line.  Joy!&lt;br /&gt;&lt;br /&gt;It also got me thinking of Mr. Fords original quote and I now appreciate what a profound statement that really was.&lt;br /&gt;&lt;br /&gt;PROBLEM:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;You have a List of letters (A-G)&lt;/li&gt;&lt;li&gt;Create a class and the necessary methods that do the following:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;In the list replace:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;B with C&lt;/li&gt;&lt;li&gt;D with X&lt;/li&gt;&lt;li&gt;X with Z&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;li&gt;The replacement should handle all transitive replacements&lt;/li&gt;&lt;li&gt;All duplicates in the list should be removed.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;My Java Solution:&lt;br /&gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;span style="font-family:monospace;"&gt;&lt;br /&gt;&lt;code&gt;import java.util.ArrayList;&lt;br /&gt;import java.util.HashMap;&lt;br /&gt;import java.util.Iterator;&lt;br /&gt;import java.util.List;&lt;br /&gt;import java.util.Map;&lt;br /&gt;&lt;br /&gt;public class ListSwapper {&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; public static void main(String[] args) {&lt;br /&gt;  ListSwapper swapper = new ListSwapper();&lt;br /&gt;  &lt;br /&gt;  List baseList = new ArrayList() {&lt;br /&gt;   {&lt;br /&gt;    add("A"); add("B"); add("C"); add("D");&lt;br /&gt;    add("E"); add("F"); add("G");&lt;br /&gt;   }&lt;br /&gt;  };&lt;br /&gt;  &lt;br /&gt;  List dedupedList = new ArrayList() {&lt;br /&gt;   {&lt;br /&gt;    add("A"); add("C"); add("Z");&lt;br /&gt;    add("E"); add("F"); add("G");&lt;br /&gt;   }&lt;br /&gt;  };&lt;br /&gt;  &lt;br /&gt;  List result = swapper.dedupe(swapper.swap(baseList));&lt;br /&gt;  &lt;br /&gt;  assert result.equals(dedupedList);&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; private Map&lt;string,&gt; map = new HashMap&lt;string,&gt;(){&lt;br /&gt;  {&lt;br /&gt;   put("B", "C"); put("D", "X"); put("X", "Z");&lt;br /&gt;  }&lt;br /&gt; };&lt;br /&gt; &lt;br /&gt; List swappedList = new ArrayList();&lt;br /&gt; &lt;br /&gt; public List swap(List baseList) {&lt;br /&gt;  for (Iterator iterator = baseList.iterator(); iterator.hasNext();) {&lt;br /&gt;   String letter = (String) iterator.next();&lt;br /&gt;   swapLetter(letter);&lt;br /&gt;  }&lt;br /&gt;  return swappedList;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; private void swapLetter(String letter) {&lt;br /&gt;  String swappedLetter = map.get(letter);&lt;br /&gt;  if (swappedLetter == null) {&lt;br /&gt;   swappedList.add(letter);&lt;br /&gt;  } else if (swappedLetter != null) {&lt;br /&gt;   swapLetter(swappedLetter);&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public List dedupe(List swappedList) {&lt;br /&gt;  for (int i = 0; i &lt; j =" i"&gt;&lt;/string,&gt;&lt;/string,&gt;&lt;/code&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;My Groovy Solution (This is a method-to-method replacement)&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;class Util {&lt;br /&gt; def myMap = ['B':'C' , 'D':'X', 'X':'Z']&lt;br /&gt; &lt;br /&gt; def swap(List list){&lt;br /&gt;  list.eachWithIndex {item, index -&gt;&lt;br /&gt;   list[index] = swap(item)&lt;br /&gt;  }&lt;br /&gt;  list&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; def swap(letter){&lt;br /&gt;  def newLetter = myMap.get(letter)&lt;br /&gt;  newLetter ? swap(newLetter) : letter&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; def prune(list){&lt;br /&gt;  list.unique()&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;def x = new Util()&lt;br /&gt;assert x.prune(x.swap(('A'..'G').toList())) == ["A", "C", "Z", "E", "F", "G"]&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;This code could probably be made Groovier. The prune(list) method seems a little unnecessary at this point.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6669041857214331338-9132932807638759908?l=zanthrash.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zanthrash.blogspot.com/feeds/9132932807638759908/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6669041857214331338&amp;postID=9132932807638759908' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6669041857214331338/posts/default/9132932807638759908'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6669041857214331338/posts/default/9132932807638759908'/><link rel='alternate' type='text/html' href='http://zanthrash.blogspot.com/2007/11/coding-with-crayons.html' title='Coding with Crayons'/><author><name>Zan Thrash</name><uri>http://www.blogger.com/profile/11490463092837149298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6669041857214331338.post-6675711964986299858</id><published>2007-05-15T09:44:00.000-07:00</published><updated>2007-05-15T10:23:43.726-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='documetation'/><title type='text'>Conversations Under a Waterfall :  Documentation</title><content type='html'>I don't know yet if this will be a on going series, but I have a lot of material to work with.  The current company that I am working at has fully embraced all of the best practices of software development that the 1970's has to offer.  That's right...they love their waterfall.  To be honest management loves the waterfall.  The developers simply "put up with it".  I don't know which is worse.  So as self proclaimed agile developer, I thought it would be fun to document some of the conversations that I have with my colleagues (the names and identities have been changed to protect the innocent).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Shout from over a cube wall: &lt;/span&gt;Does anyone know of a good Eclipse UML plugin?&lt;br /&gt;&lt;br /&gt;I get up to investigate the source of the question.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Me:&lt;/span&gt; What do you want to do with UML?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Andy (original shouter):&lt;/span&gt; Dave asked me to put together a proposal for the web service I just wrote.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Me:&lt;/span&gt; A proposal? For something you already implemented?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Andy:&lt;/span&gt; Yep.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Me:&lt;/span&gt; Is it in production?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Andy:&lt;/span&gt; Yep.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Me:&lt;/span&gt; So why do you need a proposal?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Andy&lt;/span&gt; (now appearing annoyed that I am asking him a bunch of questions that do not address his original question):  Dave needs to get Tom to sign off on the app, and he wont do it unless it is "fully" documented.  So Dave wants me to make the document so large that Tom wont want to read it.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Me:&lt;/span&gt; Does make any sense  you?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Andy:&lt;/span&gt; This is just the way it is.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I just walked away. I really wanted to help Andy, but more so I wanted him to be as upset as I was.  The fact that management, or anyone for that matter, would value his time, energy, and talent so little, as to make him knowingly produce something that has no attainable benefit to anyone is a shame.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6669041857214331338-6675711964986299858?l=zanthrash.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zanthrash.blogspot.com/feeds/6675711964986299858/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6669041857214331338&amp;postID=6675711964986299858' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6669041857214331338/posts/default/6675711964986299858'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6669041857214331338/posts/default/6675711964986299858'/><link rel='alternate' type='text/html' href='http://zanthrash.blogspot.com/2007/05/conversations-under-waterfall.html' title='Conversations Under a Waterfall :  Documentation'/><author><name>Zan Thrash</name><uri>http://www.blogger.com/profile/11490463092837149298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6669041857214331338.post-7305901528885393131</id><published>2007-04-03T12:11:00.000-07:00</published><updated>2007-05-03T12:58:14.861-07:00</updated><title type='text'>First Post</title><content type='html'>Until now I have made a conscious decision not to "blog". Mostly because I hate the word "Blog" and utterly loathe the word: "Blog-o-sphere".  But also because of time.   My plan for this medium is to use it to share my thoughts and experiences in the art and practice of software development, agility, and what I'm probably going to write about most...Groovy and Grails.  I've been playing with these languages/frameworks for a while now and am a big fan and look forward to sharing what I learn along the way.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6669041857214331338-7305901528885393131?l=zanthrash.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zanthrash.blogspot.com/feeds/7305901528885393131/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6669041857214331338&amp;postID=7305901528885393131' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6669041857214331338/posts/default/7305901528885393131'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6669041857214331338/posts/default/7305901528885393131'/><link rel='alternate' type='text/html' href='http://zanthrash.blogspot.com/2007/04/first-post.html' title='First Post'/><author><name>Zan Thrash</name><uri>http://www.blogger.com/profile/11490463092837149298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry></feed>
