SlideShare una empresa de Scribd logo
1 de 87
How Groovy Helps Ken Kousen Kousen IT, Inc. http://www.kousenit.com   [email_address] http://kousenit.wordpress.com
What is Groovy? ,[object Object],[object Object],[object Object]
Groovy ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Groovy Features ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Installing Groovy ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Groovy Editors ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Three Sample Problems ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Google Chart API ,[object Object],[object Object],[object Object],[object Object],[object Object]
Google Chart API ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Google Chart API ,[object Object],[object Object]
My Application ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
My Application ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Groovy Scripts and Classes ,[object Object],[object Object],[object Object],[object Object],[object Object]
google_chart.groovy package  chart class  Chart { def  base = 'http://chart.apis.google.com/chart' def  url = base + '?cht=p3&chs=500x150' def  imageTag // … more code to come … } def  chart =  new  Chart() chart.encodeMap() println  chart.imageTag
Interesting Features ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Interesting Features ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
More Fields def  data = [ 'Spring and Hibernate', 'EJB', 'J2EE', 'J2EE', 'Spring', 'XML', 'Spring', 'Spring', 'XML', 'XML', 'J2EE', 'WS', 'Struts', 'Spring', 'JS', 'WS', 'Ajax', 'WS', 'Portlets', 'Hibernate and EJB3', 'J2EE', 'OOAD', 'Java', 'Ajax', 'Ajax', 'Spring', 'Struts 2', 'XML and Java', 'Ajax and Java', 'Securing WS', 'JSF', 'Ajax', 'Ajax and Java', 'Ajax', 'J2EE', 'WS'] def  map = [:]
Lists and Maps ,[object Object],[object Object],[object Object],[object Object],[object Object]
Constructor Code Chart() { data. each  { name -> if  (name =~ (/Spring|Hibernate|Struts/)) { addToMap('Open Source') } if  (name =~ (/Ajax|JS/)) { addToMap('Ajax') } // … other categories … } }
Constructor Code ,[object Object],[object Object],[object Object],[object Object],[object Object]
Constructor Code ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
addToMap(label) def  addToMap(label) { map[label] = map.get(label,0) + 1 }
addToMap(label) ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
addToMap(label) ,[object Object],[object Object],[object Object]
Encoding ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
encodeMap() def  encodeMap() { List list = (('A'..'Z')+('a'..'z')+(0..9))  as  List String s = &quot;&chd=s:&quot; List keys = [] map. each  { k,v -> keys << k s += list[v] } // … more to come …
encodeMap() ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
encodeMap() String labels = &quot;&chl=&quot; +  keys. collect  { URLEncoder.encode(it,&quot;UTF-8&quot;) }. join ('|') url += s  // the query string, defined in the code above url += labels println  url  // might as well see it String urle = url.replaceAll(/&/,'&amp;') imageTag = &quot;<img src='${urle}' alt='Course distribution'/>&quot;
encodeMap() ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
encodeMap() ,[object Object],[object Object],[object Object],[object Object],[object Object]
Result ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Result
Google Chart Builder ,[object Object],[object Object],[object Object],[object Object],[object Object]
Baseball Data ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
boxscore.xml ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Java Approach ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Groovy Approach ,[object Object],[object Object],[object Object],[object Object],[object Object]
GetGameData.groovy class  GetGameData { def  day def  month def  year def  base = 'http://gd2.mlb.com/components/game/mlb/' // all teams in actual file def  abbrevs = [ ana:&quot;Los Angeles (A)&quot;,ari:&quot;Arizona&quot;,atl:&quot;Atlanta&quot;, bal:&quot;Baltimore&quot;,bos:&quot;Boston&quot;,cha:&quot;Chicago (A)&quot;, chn:&quot;Chicago (N)&quot;,cin:&quot;Cincinnati&quot;,cle:&quot;Cleveland&quot;, col:&quot;Colorado&quot;, was:&quot;Washington&quot;]
getGame() void  getGame(away, home, num) { println  &quot;$away at $home on ${month}/${day}/${year}&quot; def  url = base +  &quot;year_${year}/month_${month}/day_${day}/&quot; def  game = &quot;gid_${year}_${month}_${day}_&quot; + &quot;${away}mlb_${home}mlb_${num}/boxscore.xml&quot; def  boxscore =  new  XmlParser().parse(url + game)
getGame() def  awayName = boxscore.'@away_fname' def  awayScore = boxscore.linescore[0].'@away_team_runs' def  homeName = boxscore.'@home_fname' def  homeScore = boxscore.linescore[0].'@home_team_runs' println  &quot;$awayName $awayScore, $homeName $homeScore (game $num)&quot;
getGame() def  pitchers = boxscore.pitching.pitcher pitchers. each  { p -> if  (p.'@note' && p.'@note' =~ /W|L|S/) { println  &quot;  ${p.'@name'} ${p.'@note'}&quot; } }
Interesting Features ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Result (so far) bos at col on 10/28/2007 Boston Red Sox 4, Colorado Rockies 3 (game 1) Lester (W, 1-0) Papelbon (S, 3) Cook (L, 0-1)
Process the Data def  batters = boxscore.batting.batter for  (b  in  batters) { println  &quot;${b.'@name'} went ${b.'@h'} for ${b.'@ab'}&quot; } println  batters. size () + &quot; total batters&quot; println  'Total hits: ' + batters.'@h'*. toInteger ().sum()
Notes ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
More Processing println  &quot;Batters with at least one hit:&quot; println  batters. findAll  { it.'@h'. toInteger () > 0 }. collect  { it.'@name' + '(' + it.'@h' + ')' } }
List Processing ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
XML Builder ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Create HTML void  writeHtml(node) { def  away = node.'@away_sname‘ def  home = node.'@home_sname' def  name = &quot;$away at $home&quot; new  File(&quot;${away}${home}.html&quot;). withWriter  { w -> def  builder =  new  MarkupBuilder(w)
Notes ,[object Object],[object Object],[object Object]
Building HTML builder.html { head { title name } body { h1 name h2 node.'@date' node.batting. each  { batters -> def  team = batters.'@team_flag' + '_sname' h2 node.&quot;@${team}&quot;
Notes ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
More HTML table (border:'2') { tr { th 'Batter'; th 'AB'; th 'R'; th 'H' th 'RBI'; th 'BB'; th 'SO' } batters.batter. findAll  { it.'@pos' != 'P' }. each  { b -> tr { td b.'@name' + ' (' + b.'@pos' + ')' td b.'@ab'; td b.'@r'; td b.'@h' td b.'@rbi'; td b.'@bb'; td b.'@so' } }
Table, continued tr { td(style:'font-weight:bold','Totals') td batters.batter.'@ab'*. toInteger ().sum() td batters.batter.'@r'*. toInteger ().sum() td batters.batter.'@h'*. toInteger ().sum() td batters.batter.'@rbi'*. toInteger ().sum() td batters.batter.'@bb'*. toInteger ().sum() td batters.batter.'@so'*. toInteger ().sum() } }
Results ,[object Object],[object Object],[object Object]
HTML Boxscore
Screen Scraping ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Games for 5/5/2007
Find Games on Date void  getGames() { println  &quot;Games for ${month}/${day}/${year}&quot; def  url = base + &quot;year_${year}/month_${month}/day_${day}/&quot; def  gamePage =  new  URL(url).text def  pattern = /amp;quot;gid_${year}_${month}_${day}_(*)mlb_(*)mlb_()/
Notes ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Process HTML Page def  m = gamePage =~ pattern if  (m) { (0..<m. count ).eachWithIndex { line, i -> def  away = m[line][1] def  home = m[line][2] def  num = m[line][3] try  { getGame(away,home,num) }  catch  (Exception e) { println  abbrevs[away] + &quot; at &quot; +  abbrevs[home] + &quot; not started yet&quot; }  }  }
Notes ,[object Object],[object Object],[object Object],[object Object]
Results Games for 05/05/2007 Boston at Minnesota on 05/05/2007 Boston Red Sox 1, Minnesota Twins 2 (game 1) Tavarez (L, 1-3) Santana (W, 4-2) Nathan (S, 8) Chicago (A) at Los Angeles (A) on 05/05/2007 Chicago White Sox 6, Los Angeles Angels 3 (game 1) Garland (W, 1-2) Jenks (S, 9) Lackey (L, 4-3) …
Database Data ,[object Object],[object Object],[object Object],[object Object]
Training Data ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Training Data ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Side Issues ,[object Object],[object Object],[object Object],[object Object]
Sample CSV Data 75,5/14/2007,5/18/2007,Java Web Services,Lancaster,PA 76,5/21/2007,5/25/2007,Ajax and Struts,Philadelphia,PA 77,6/4/2007,6/12/2007,Java Web Services,McLean,VA 78,6/25/2007,6/29/2007,Portal Dev. Using RAD6,Enola,PA 80,7/9/2007,7/14/2007,Hibernate EJB3,Atlanta,GA 81,8/23/2007,8/23/2007,J2EE for Managers,Marlborough,CT
Process CSV Data class  Record { int  num; String startDate; String endDate String title; String city; String state Record(String[] s) { num = s[0].startsWith(&quot;#&quot;) ? 0 : s[0]. toInteger () startDate = s[1]; endDate = s[2] title = s[3]; city = s[4]; state = s[6] } String toString() { &quot;$title ($startDate -- $endDate) $city, $state&quot; }  }
Process CSV Data def  records = [] try  { def  dataFile =  new  File('Course_locations.csv') def  lines = dataFile. readLines () for  (line  in  lines) { elements = line.trim().split(',') records <<  new  Record(*elements) } }  catch  (FileNotFoundException e) { println  e } records.each { println it }
GroovyBeans ,[object Object],[object Object],[object Object],[object Object],[object Object]
Notes ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Geocoding ,[object Object],[object Object],[object Object],[object Object]
Using Google Geocoder def  key = ‘long_ugly_key' def  base = 'http://maps.google.com/maps/geo' def  city = 'Marlborough' def  state = 'CT' def  query = &quot;q=${city},+${state}&output=csv&key=${key}&quot; def  url_string = base + '?q=' +  ',+' + URLEncoder.encode(city,&quot;UTF-8&quot;) + ',+' + state + &quot;&output=csv&key=${key}&quot; def  results =  new  URL(url_string).text.split(',') def  latitude = results[-2].toDouble(); def  longitude = results[-1].toDouble(); println  &quot;(${latitude},${longitude})&quot; assert  &quot;(41.63256,-72.46315) == (${latitude},${longitude})&quot;
Google Geocoder ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
USGS Geocoder def  partialCsvRequest =  &quot;http://geocoder.us/service/csv/geocode?address=&quot; def  address = &quot;11 Emily Road, Marlborough, CT&quot; def  csvUrl =  new  URL(partialCsvRequest +  URLEncoder.encode(address)) def  csvResponse = csvUrl.text def  tokens = csvResponse.split(&quot;,&quot; ) println  &quot;Latitude: [${tokens[0]}]&quot; println  &quot;Longitude: [${tokens[1]}]&quot; println  &quot;Address: [${tokens[2]}]&quot; println  &quot;City: [${tokens[3]}]&quot; println  &quot;State: [${tokens[4]}]&quot; println  &quot;Zip: [${tokens[5]}]&quot;
TrainingCourse class  TrainingCourse { String title; Date startDate; Date endDate;  double  rate String toString() { def  nf = NumberFormat.currencyInstance &quot;(${title},(${startDate} - ${endDate}),${nf.format(rate)})&quot; } int  getLength() { (startDate..endDate). size () } double  getRevenue() { length * rate } }
Notes ,[object Object],[object Object],[object Object],[object Object],[object Object]
CourseProcessor.groovy class  CourseProcessor { def  courses = [] def  courseYearMap =  new  TreeMap() def  cal = Calendar.instance CourseProcessor() { def  USER = ‘xxx‘;  def  PASS = ‘xxx’;  def  URL = ‘xxx‘;  def  DRIVER = ‘xxx' def  conn = Sql.newInstance(URL,USER,PASS,DRIVER) conn.eachRow('select * from course') { row -> courses <<  new  TrainingCourse( title:row.title,startDate:row.start_date, endDate:row.end_date,rate:row.rate) }
Continuing… courses. each  { c -> cal.time = c.startDate def  year = cal.get(Calendar.YEAR) courseYearMap[year] = courseYearMap.get(year,[]) + c } }
Notes ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Printing Courses def  printYearMap() { def  nf = NumberFormat.currencyInstance courseYearMap. each  { year,courseList -> def  monthlyDays =  new   int [12] def  monthlyRev =  new   double [12] courseList. each  { course -> cal.time = course.startDate def  month = cal.get(Calendar.MONTH) for  (date  in  course.startDate..course.endDate) { monthlyDays[month] += 1 monthlyRev[month] += course.rate } }
Continuing def  days = (courseList*.length).sum() def  rev = (courseList*.revenue).sum() println   &quot;Totals for $year : ${days} days, ${nf.format(rev)}&quot;
Testing ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Testing ,[object Object],[object Object],[object Object]
Miscellaneous ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
References ,[object Object],[object Object],[object Object],[object Object],[object Object]

Más contenido relacionado

La actualidad más candente

La actualidad más candente (8)

Data types in c++
Data types in c++ Data types in c++
Data types in c++
 
basics of css
basics of cssbasics of css
basics of css
 
Compiler Construction | Lecture 12 | Virtual Machines
Compiler Construction | Lecture 12 | Virtual MachinesCompiler Construction | Lecture 12 | Virtual Machines
Compiler Construction | Lecture 12 | Virtual Machines
 
Javascript
JavascriptJavascript
Javascript
 
CS4200 2019 | Lecture 4 | Syntactic Services
CS4200 2019 | Lecture 4 | Syntactic ServicesCS4200 2019 | Lecture 4 | Syntactic Services
CS4200 2019 | Lecture 4 | Syntactic Services
 
2 R Tutorial Programming
2 R Tutorial Programming2 R Tutorial Programming
2 R Tutorial Programming
 
Power of functions in a typed world
Power of functions in a typed worldPower of functions in a typed world
Power of functions in a typed world
 
How Pony ORM translates Python generators to SQL queries
How Pony ORM translates Python generators to SQL queriesHow Pony ORM translates Python generators to SQL queries
How Pony ORM translates Python generators to SQL queries
 

Destacado

Iad2 0809 Q4 Hoorcollege 3: Documenteren Van Rijke Interactie
Iad2 0809 Q4 Hoorcollege 3: Documenteren Van Rijke InteractieIad2 0809 Q4 Hoorcollege 3: Documenteren Van Rijke Interactie
Iad2 0809 Q4 Hoorcollege 3: Documenteren Van Rijke Interactie
Hans Kemp
 
Zappos - Retailing Smarter Symposium - 6-25-09
Zappos - Retailing Smarter Symposium - 6-25-09Zappos - Retailing Smarter Symposium - 6-25-09
Zappos - Retailing Smarter Symposium - 6-25-09
zappos
 
Zappos - ETR - 03-24-09
Zappos - ETR -  03-24-09Zappos - ETR -  03-24-09
Zappos - ETR - 03-24-09
zappos
 
Zappos - UIE - 4-20-09
Zappos - UIE - 4-20-09Zappos - UIE - 4-20-09
Zappos - UIE - 4-20-09
zappos
 
Vocabulary MYP9
Vocabulary MYP9Vocabulary MYP9
Vocabulary MYP9
Corey Topf
 
Exemplary final interview
Exemplary final interviewExemplary final interview
Exemplary final interview
Corey Topf
 
Techo Club Seniors
Techo Club SeniorsTecho Club Seniors
Techo Club Seniors
Corey Topf
 
Iad1 0809 Q3 Hoorcollege 1 Structuur, Flow En Navigatie
Iad1 0809 Q3 Hoorcollege 1   Structuur, Flow En NavigatieIad1 0809 Q3 Hoorcollege 1   Structuur, Flow En Navigatie
Iad1 0809 Q3 Hoorcollege 1 Structuur, Flow En Navigatie
Hans Kemp
 
Versie 3 Nv Iad2 0910 Q1 Les 4 Patterns For Mobile
Versie 3 Nv  Iad2 0910 Q1 Les 4 Patterns For MobileVersie 3 Nv  Iad2 0910 Q1 Les 4 Patterns For Mobile
Versie 3 Nv Iad2 0910 Q1 Les 4 Patterns For Mobile
Hans Kemp
 
Week 17 Sponges
Week 17 SpongesWeek 17 Sponges
Week 17 Sponges
Corey Topf
 
Paper2 olympics copy
Paper2 olympics copyPaper2 olympics copy
Paper2 olympics copy
Corey Topf
 

Destacado (20)

Take a Groovy REST
Take a Groovy RESTTake a Groovy REST
Take a Groovy REST
 
Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with Groovy
 
Techo may16
Techo may16Techo may16
Techo may16
 
Beyond The Advertising 
Into The Unknown - The Future Business and Communicat...
Beyond The Advertising 
Into The Unknown - The Future Business and Communicat...Beyond The Advertising 
Into The Unknown - The Future Business and Communicat...
Beyond The Advertising 
Into The Unknown - The Future Business and Communicat...
 
Iad2 0809 Q4 Hoorcollege 3: Documenteren Van Rijke Interactie
Iad2 0809 Q4 Hoorcollege 3: Documenteren Van Rijke InteractieIad2 0809 Q4 Hoorcollege 3: Documenteren Van Rijke Interactie
Iad2 0809 Q4 Hoorcollege 3: Documenteren Van Rijke Interactie
 
Zappos - Retailing Smarter Symposium - 6-25-09
Zappos - Retailing Smarter Symposium - 6-25-09Zappos - Retailing Smarter Symposium - 6-25-09
Zappos - Retailing Smarter Symposium - 6-25-09
 
0809 Iad2 Q1 Hoorcollege1
0809 Iad2 Q1 Hoorcollege10809 Iad2 Q1 Hoorcollege1
0809 Iad2 Q1 Hoorcollege1
 
Zappos - ETR - 03-24-09
Zappos - ETR -  03-24-09Zappos - ETR -  03-24-09
Zappos - ETR - 03-24-09
 
Zappos - UIE - 4-20-09
Zappos - UIE - 4-20-09Zappos - UIE - 4-20-09
Zappos - UIE - 4-20-09
 
Vocabulary MYP9
Vocabulary MYP9Vocabulary MYP9
Vocabulary MYP9
 
Exemplary final interview
Exemplary final interviewExemplary final interview
Exemplary final interview
 
User Created Content deel I
User Created Content deel IUser Created Content deel I
User Created Content deel I
 
HOSHVA PR Meetup#1 - Reputation Institute
HOSHVA PR Meetup#1 - Reputation InstituteHOSHVA PR Meetup#1 - Reputation Institute
HOSHVA PR Meetup#1 - Reputation Institute
 
Review of the Pilot Courses
Review of the Pilot CoursesReview of the Pilot Courses
Review of the Pilot Courses
 
Techo Club Seniors
Techo Club SeniorsTecho Club Seniors
Techo Club Seniors
 
Iad1 0809 Q3 Hoorcollege 1 Structuur, Flow En Navigatie
Iad1 0809 Q3 Hoorcollege 1   Structuur, Flow En NavigatieIad1 0809 Q3 Hoorcollege 1   Structuur, Flow En Navigatie
Iad1 0809 Q3 Hoorcollege 1 Structuur, Flow En Navigatie
 
Cas 2015
Cas 2015Cas 2015
Cas 2015
 
Versie 3 Nv Iad2 0910 Q1 Les 4 Patterns For Mobile
Versie 3 Nv  Iad2 0910 Q1 Les 4 Patterns For MobileVersie 3 Nv  Iad2 0910 Q1 Les 4 Patterns For Mobile
Versie 3 Nv Iad2 0910 Q1 Les 4 Patterns For Mobile
 
Week 17 Sponges
Week 17 SpongesWeek 17 Sponges
Week 17 Sponges
 
Paper2 olympics copy
Paper2 olympics copyPaper2 olympics copy
Paper2 olympics copy
 

Similar a How Groovy Helps

Agile web development Groovy Grails with Netbeans
Agile web development Groovy Grails with NetbeansAgile web development Groovy Grails with Netbeans
Agile web development Groovy Grails with Netbeans
Carol McDonald
 
Ratpack - Classy and Compact Groovy Web Apps
Ratpack - Classy and Compact Groovy Web AppsRatpack - Classy and Compact Groovy Web Apps
Ratpack - Classy and Compact Groovy Web Apps
James Williams
 
Java script final presentation
Java script final presentationJava script final presentation
Java script final presentation
Adhoura Academy
 
ABCs of Programming_eBook Contents
ABCs of Programming_eBook ContentsABCs of Programming_eBook Contents
ABCs of Programming_eBook Contents
Ashley Menhennett
 
Modeling Patterns for JavaScript Browser-Based Games
Modeling Patterns for JavaScript Browser-Based GamesModeling Patterns for JavaScript Browser-Based Games
Modeling Patterns for JavaScript Browser-Based Games
Ray Toal
 
Introducing Modern Perl
Introducing Modern PerlIntroducing Modern Perl
Introducing Modern Perl
Dave Cross
 

Similar a How Groovy Helps (20)

Introduction To Groovy 2005
Introduction To Groovy 2005Introduction To Groovy 2005
Introduction To Groovy 2005
 
Real life-coffeescript
Real life-coffeescriptReal life-coffeescript
Real life-coffeescript
 
Agile web development Groovy Grails with Netbeans
Agile web development Groovy Grails with NetbeansAgile web development Groovy Grails with Netbeans
Agile web development Groovy Grails with Netbeans
 
Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008
 
Groovy Update - JavaPolis 2007
Groovy Update - JavaPolis 2007Groovy Update - JavaPolis 2007
Groovy Update - JavaPolis 2007
 
Plone For Developers - World Plone Day, 2009
Plone For Developers - World Plone Day, 2009Plone For Developers - World Plone Day, 2009
Plone For Developers - World Plone Day, 2009
 
Ratpack - Classy and Compact Groovy Web Apps
Ratpack - Classy and Compact Groovy Web AppsRatpack - Classy and Compact Groovy Web Apps
Ratpack - Classy and Compact Groovy Web Apps
 
Java script final presentation
Java script final presentationJava script final presentation
Java script final presentation
 
Grails 0.3-SNAPSHOT Presentation WJAX 2006 English
Grails 0.3-SNAPSHOT Presentation WJAX 2006 EnglishGrails 0.3-SNAPSHOT Presentation WJAX 2006 English
Grails 0.3-SNAPSHOT Presentation WJAX 2006 English
 
Code is not text! How graph technologies can help us to understand our code b...
Code is not text! How graph technologies can help us to understand our code b...Code is not text! How graph technologies can help us to understand our code b...
Code is not text! How graph technologies can help us to understand our code b...
 
ABCs of Programming_eBook Contents
ABCs of Programming_eBook ContentsABCs of Programming_eBook Contents
ABCs of Programming_eBook Contents
 
Svcc Building Rich Applications with Groovy's SwingBuilder
Svcc Building Rich Applications with Groovy's SwingBuilderSvcc Building Rich Applications with Groovy's SwingBuilder
Svcc Building Rich Applications with Groovy's SwingBuilder
 
Architecture | Busy Java Developers Guide to NoSQL | Ted Neward
Architecture | Busy Java Developers Guide to NoSQL | Ted NewardArchitecture | Busy Java Developers Guide to NoSQL | Ted Neward
Architecture | Busy Java Developers Guide to NoSQL | Ted Neward
 
Modeling Patterns for JavaScript Browser-Based Games
Modeling Patterns for JavaScript Browser-Based GamesModeling Patterns for JavaScript Browser-Based Games
Modeling Patterns for JavaScript Browser-Based Games
 
Google Gears
Google GearsGoogle Gears
Google Gears
 
PHP MySQL
PHP MySQLPHP MySQL
PHP MySQL
 
Introducing Modern Perl
Introducing Modern PerlIntroducing Modern Perl
Introducing Modern Perl
 
Template
TemplateTemplate
Template
 
An Introduction To jQuery
An Introduction To jQueryAn Introduction To jQuery
An Introduction To jQuery
 
Scripting Oracle Develop 2007
Scripting Oracle Develop 2007Scripting Oracle Develop 2007
Scripting Oracle Develop 2007
 

Último

Chandigarh Escorts Service 📞8868886958📞 Just📲 Call Nihal Chandigarh Call Girl...
Chandigarh Escorts Service 📞8868886958📞 Just📲 Call Nihal Chandigarh Call Girl...Chandigarh Escorts Service 📞8868886958📞 Just📲 Call Nihal Chandigarh Call Girl...
Chandigarh Escorts Service 📞8868886958📞 Just📲 Call Nihal Chandigarh Call Girl...
Sheetaleventcompany
 
FULL ENJOY Call Girls In Majnu Ka Tilla, Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Majnu Ka Tilla, Delhi Contact Us 8377877756FULL ENJOY Call Girls In Majnu Ka Tilla, Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Majnu Ka Tilla, Delhi Contact Us 8377877756
dollysharma2066
 
Call Girls Jp Nagar Just Call 👗 7737669865 👗 Top Class Call Girl Service Bang...
Call Girls Jp Nagar Just Call 👗 7737669865 👗 Top Class Call Girl Service Bang...Call Girls Jp Nagar Just Call 👗 7737669865 👗 Top Class Call Girl Service Bang...
Call Girls Jp Nagar Just Call 👗 7737669865 👗 Top Class Call Girl Service Bang...
amitlee9823
 
The Abortion pills for sale in Qatar@Doha [+27737758557] []Deira Dubai Kuwait
The Abortion pills for sale in Qatar@Doha [+27737758557] []Deira Dubai KuwaitThe Abortion pills for sale in Qatar@Doha [+27737758557] []Deira Dubai Kuwait
The Abortion pills for sale in Qatar@Doha [+27737758557] []Deira Dubai Kuwait
daisycvs
 
Nelamangala Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore...
Nelamangala Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore...Nelamangala Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore...
Nelamangala Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore...
amitlee9823
 
Call Girls Kengeri Satellite Town Just Call 👗 7737669865 👗 Top Class Call Gir...
Call Girls Kengeri Satellite Town Just Call 👗 7737669865 👗 Top Class Call Gir...Call Girls Kengeri Satellite Town Just Call 👗 7737669865 👗 Top Class Call Gir...
Call Girls Kengeri Satellite Town Just Call 👗 7737669865 👗 Top Class Call Gir...
amitlee9823
 
Call Girls Electronic City Just Call 👗 7737669865 👗 Top Class Call Girl Servi...
Call Girls Electronic City Just Call 👗 7737669865 👗 Top Class Call Girl Servi...Call Girls Electronic City Just Call 👗 7737669865 👗 Top Class Call Girl Servi...
Call Girls Electronic City Just Call 👗 7737669865 👗 Top Class Call Girl Servi...
amitlee9823
 
Call Girls In Majnu Ka Tilla 959961~3876 Shot 2000 Night 8000
Call Girls In Majnu Ka Tilla 959961~3876 Shot 2000 Night 8000Call Girls In Majnu Ka Tilla 959961~3876 Shot 2000 Night 8000
Call Girls In Majnu Ka Tilla 959961~3876 Shot 2000 Night 8000
dlhescort
 
Russian Call Girls In Gurgaon ❤️8448577510 ⊹Best Escorts Service In 24/7 Delh...
Russian Call Girls In Gurgaon ❤️8448577510 ⊹Best Escorts Service In 24/7 Delh...Russian Call Girls In Gurgaon ❤️8448577510 ⊹Best Escorts Service In 24/7 Delh...
Russian Call Girls In Gurgaon ❤️8448577510 ⊹Best Escorts Service In 24/7 Delh...
lizamodels9
 
Call Girls in Delhi, Escort Service Available 24x7 in Delhi 959961-/-3876
Call Girls in Delhi, Escort Service Available 24x7 in Delhi 959961-/-3876Call Girls in Delhi, Escort Service Available 24x7 in Delhi 959961-/-3876
Call Girls in Delhi, Escort Service Available 24x7 in Delhi 959961-/-3876
dlhescort
 

Último (20)

Uneak White's Personal Brand Exploration Presentation
Uneak White's Personal Brand Exploration PresentationUneak White's Personal Brand Exploration Presentation
Uneak White's Personal Brand Exploration Presentation
 
Chandigarh Escorts Service 📞8868886958📞 Just📲 Call Nihal Chandigarh Call Girl...
Chandigarh Escorts Service 📞8868886958📞 Just📲 Call Nihal Chandigarh Call Girl...Chandigarh Escorts Service 📞8868886958📞 Just📲 Call Nihal Chandigarh Call Girl...
Chandigarh Escorts Service 📞8868886958📞 Just📲 Call Nihal Chandigarh Call Girl...
 
Katrina Personal Brand Project and portfolio 1
Katrina Personal Brand Project and portfolio 1Katrina Personal Brand Project and portfolio 1
Katrina Personal Brand Project and portfolio 1
 
FULL ENJOY Call Girls In Majnu Ka Tilla, Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Majnu Ka Tilla, Delhi Contact Us 8377877756FULL ENJOY Call Girls In Majnu Ka Tilla, Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Majnu Ka Tilla, Delhi Contact Us 8377877756
 
Call Girls Service In Old Town Dubai ((0551707352)) Old Town Dubai Call Girl ...
Call Girls Service In Old Town Dubai ((0551707352)) Old Town Dubai Call Girl ...Call Girls Service In Old Town Dubai ((0551707352)) Old Town Dubai Call Girl ...
Call Girls Service In Old Town Dubai ((0551707352)) Old Town Dubai Call Girl ...
 
Call Girls Jp Nagar Just Call 👗 7737669865 👗 Top Class Call Girl Service Bang...
Call Girls Jp Nagar Just Call 👗 7737669865 👗 Top Class Call Girl Service Bang...Call Girls Jp Nagar Just Call 👗 7737669865 👗 Top Class Call Girl Service Bang...
Call Girls Jp Nagar Just Call 👗 7737669865 👗 Top Class Call Girl Service Bang...
 
The Abortion pills for sale in Qatar@Doha [+27737758557] []Deira Dubai Kuwait
The Abortion pills for sale in Qatar@Doha [+27737758557] []Deira Dubai KuwaitThe Abortion pills for sale in Qatar@Doha [+27737758557] []Deira Dubai Kuwait
The Abortion pills for sale in Qatar@Doha [+27737758557] []Deira Dubai Kuwait
 
Nelamangala Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore...
Nelamangala Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore...Nelamangala Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore...
Nelamangala Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore...
 
Call Girls Kengeri Satellite Town Just Call 👗 7737669865 👗 Top Class Call Gir...
Call Girls Kengeri Satellite Town Just Call 👗 7737669865 👗 Top Class Call Gir...Call Girls Kengeri Satellite Town Just Call 👗 7737669865 👗 Top Class Call Gir...
Call Girls Kengeri Satellite Town Just Call 👗 7737669865 👗 Top Class Call Gir...
 
👉Chandigarh Call Girls 👉9878799926👉Just Call👉Chandigarh Call Girl In Chandiga...
👉Chandigarh Call Girls 👉9878799926👉Just Call👉Chandigarh Call Girl In Chandiga...👉Chandigarh Call Girls 👉9878799926👉Just Call👉Chandigarh Call Girl In Chandiga...
👉Chandigarh Call Girls 👉9878799926👉Just Call👉Chandigarh Call Girl In Chandiga...
 
Call Girls Electronic City Just Call 👗 7737669865 👗 Top Class Call Girl Servi...
Call Girls Electronic City Just Call 👗 7737669865 👗 Top Class Call Girl Servi...Call Girls Electronic City Just Call 👗 7737669865 👗 Top Class Call Girl Servi...
Call Girls Electronic City Just Call 👗 7737669865 👗 Top Class Call Girl Servi...
 
Falcon's Invoice Discounting: Your Path to Prosperity
Falcon's Invoice Discounting: Your Path to ProsperityFalcon's Invoice Discounting: Your Path to Prosperity
Falcon's Invoice Discounting: Your Path to Prosperity
 
SEO Case Study: How I Increased SEO Traffic & Ranking by 50-60% in 6 Months
SEO Case Study: How I Increased SEO Traffic & Ranking by 50-60%  in 6 MonthsSEO Case Study: How I Increased SEO Traffic & Ranking by 50-60%  in 6 Months
SEO Case Study: How I Increased SEO Traffic & Ranking by 50-60% in 6 Months
 
Call Girls In Majnu Ka Tilla 959961~3876 Shot 2000 Night 8000
Call Girls In Majnu Ka Tilla 959961~3876 Shot 2000 Night 8000Call Girls In Majnu Ka Tilla 959961~3876 Shot 2000 Night 8000
Call Girls In Majnu Ka Tilla 959961~3876 Shot 2000 Night 8000
 
Call Girls Zirakpur👧 Book Now📱7837612180 📞👉Call Girl Service In Zirakpur No A...
Call Girls Zirakpur👧 Book Now📱7837612180 📞👉Call Girl Service In Zirakpur No A...Call Girls Zirakpur👧 Book Now📱7837612180 📞👉Call Girl Service In Zirakpur No A...
Call Girls Zirakpur👧 Book Now📱7837612180 📞👉Call Girl Service In Zirakpur No A...
 
Russian Call Girls In Gurgaon ❤️8448577510 ⊹Best Escorts Service In 24/7 Delh...
Russian Call Girls In Gurgaon ❤️8448577510 ⊹Best Escorts Service In 24/7 Delh...Russian Call Girls In Gurgaon ❤️8448577510 ⊹Best Escorts Service In 24/7 Delh...
Russian Call Girls In Gurgaon ❤️8448577510 ⊹Best Escorts Service In 24/7 Delh...
 
Call Girls in Delhi, Escort Service Available 24x7 in Delhi 959961-/-3876
Call Girls in Delhi, Escort Service Available 24x7 in Delhi 959961-/-3876Call Girls in Delhi, Escort Service Available 24x7 in Delhi 959961-/-3876
Call Girls in Delhi, Escort Service Available 24x7 in Delhi 959961-/-3876
 
The Path to Product Excellence: Avoiding Common Pitfalls and Enhancing Commun...
The Path to Product Excellence: Avoiding Common Pitfalls and Enhancing Commun...The Path to Product Excellence: Avoiding Common Pitfalls and Enhancing Commun...
The Path to Product Excellence: Avoiding Common Pitfalls and Enhancing Commun...
 
(Anamika) VIP Call Girls Napur Call Now 8617697112 Napur Escorts 24x7
(Anamika) VIP Call Girls Napur Call Now 8617697112 Napur Escorts 24x7(Anamika) VIP Call Girls Napur Call Now 8617697112 Napur Escorts 24x7
(Anamika) VIP Call Girls Napur Call Now 8617697112 Napur Escorts 24x7
 
Famous Olympic Siblings from the 21st Century
Famous Olympic Siblings from the 21st CenturyFamous Olympic Siblings from the 21st Century
Famous Olympic Siblings from the 21st Century
 

How Groovy Helps

  • 1. How Groovy Helps Ken Kousen Kousen IT, Inc. http://www.kousenit.com [email_address] http://kousenit.wordpress.com
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14. google_chart.groovy package chart class Chart { def base = 'http://chart.apis.google.com/chart' def url = base + '?cht=p3&chs=500x150' def imageTag // … more code to come … } def chart = new Chart() chart.encodeMap() println chart.imageTag
  • 15.
  • 16.
  • 17. More Fields def data = [ 'Spring and Hibernate', 'EJB', 'J2EE', 'J2EE', 'Spring', 'XML', 'Spring', 'Spring', 'XML', 'XML', 'J2EE', 'WS', 'Struts', 'Spring', 'JS', 'WS', 'Ajax', 'WS', 'Portlets', 'Hibernate and EJB3', 'J2EE', 'OOAD', 'Java', 'Ajax', 'Ajax', 'Spring', 'Struts 2', 'XML and Java', 'Ajax and Java', 'Securing WS', 'JSF', 'Ajax', 'Ajax and Java', 'Ajax', 'J2EE', 'WS'] def map = [:]
  • 18.
  • 19. Constructor Code Chart() { data. each { name -> if (name =~ (/Spring|Hibernate|Struts/)) { addToMap('Open Source') } if (name =~ (/Ajax|JS/)) { addToMap('Ajax') } // … other categories … } }
  • 20.
  • 21.
  • 22. addToMap(label) def addToMap(label) { map[label] = map.get(label,0) + 1 }
  • 23.
  • 24.
  • 25.
  • 26. encodeMap() def encodeMap() { List list = (('A'..'Z')+('a'..'z')+(0..9)) as List String s = &quot;&chd=s:&quot; List keys = [] map. each { k,v -> keys << k s += list[v] } // … more to come …
  • 27.
  • 28. encodeMap() String labels = &quot;&chl=&quot; + keys. collect { URLEncoder.encode(it,&quot;UTF-8&quot;) }. join ('|') url += s // the query string, defined in the code above url += labels println url // might as well see it String urle = url.replaceAll(/&/,'&amp;') imageTag = &quot;<img src='${urle}' alt='Course distribution'/>&quot;
  • 29.
  • 30.
  • 31.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38. GetGameData.groovy class GetGameData { def day def month def year def base = 'http://gd2.mlb.com/components/game/mlb/' // all teams in actual file def abbrevs = [ ana:&quot;Los Angeles (A)&quot;,ari:&quot;Arizona&quot;,atl:&quot;Atlanta&quot;, bal:&quot;Baltimore&quot;,bos:&quot;Boston&quot;,cha:&quot;Chicago (A)&quot;, chn:&quot;Chicago (N)&quot;,cin:&quot;Cincinnati&quot;,cle:&quot;Cleveland&quot;, col:&quot;Colorado&quot;, was:&quot;Washington&quot;]
  • 39. getGame() void getGame(away, home, num) { println &quot;$away at $home on ${month}/${day}/${year}&quot; def url = base + &quot;year_${year}/month_${month}/day_${day}/&quot; def game = &quot;gid_${year}_${month}_${day}_&quot; + &quot;${away}mlb_${home}mlb_${num}/boxscore.xml&quot; def boxscore = new XmlParser().parse(url + game)
  • 40. getGame() def awayName = boxscore.'@away_fname' def awayScore = boxscore.linescore[0].'@away_team_runs' def homeName = boxscore.'@home_fname' def homeScore = boxscore.linescore[0].'@home_team_runs' println &quot;$awayName $awayScore, $homeName $homeScore (game $num)&quot;
  • 41. getGame() def pitchers = boxscore.pitching.pitcher pitchers. each { p -> if (p.'@note' && p.'@note' =~ /W|L|S/) { println &quot; ${p.'@name'} ${p.'@note'}&quot; } }
  • 42.
  • 43. Result (so far) bos at col on 10/28/2007 Boston Red Sox 4, Colorado Rockies 3 (game 1) Lester (W, 1-0) Papelbon (S, 3) Cook (L, 0-1)
  • 44. Process the Data def batters = boxscore.batting.batter for (b in batters) { println &quot;${b.'@name'} went ${b.'@h'} for ${b.'@ab'}&quot; } println batters. size () + &quot; total batters&quot; println 'Total hits: ' + batters.'@h'*. toInteger ().sum()
  • 45.
  • 46. More Processing println &quot;Batters with at least one hit:&quot; println batters. findAll { it.'@h'. toInteger () > 0 }. collect { it.'@name' + '(' + it.'@h' + ')' } }
  • 47.
  • 48.
  • 49. Create HTML void writeHtml(node) { def away = node.'@away_sname‘ def home = node.'@home_sname' def name = &quot;$away at $home&quot; new File(&quot;${away}${home}.html&quot;). withWriter { w -> def builder = new MarkupBuilder(w)
  • 50.
  • 51. Building HTML builder.html { head { title name } body { h1 name h2 node.'@date' node.batting. each { batters -> def team = batters.'@team_flag' + '_sname' h2 node.&quot;@${team}&quot;
  • 52.
  • 53. More HTML table (border:'2') { tr { th 'Batter'; th 'AB'; th 'R'; th 'H' th 'RBI'; th 'BB'; th 'SO' } batters.batter. findAll { it.'@pos' != 'P' }. each { b -> tr { td b.'@name' + ' (' + b.'@pos' + ')' td b.'@ab'; td b.'@r'; td b.'@h' td b.'@rbi'; td b.'@bb'; td b.'@so' } }
  • 54. Table, continued tr { td(style:'font-weight:bold','Totals') td batters.batter.'@ab'*. toInteger ().sum() td batters.batter.'@r'*. toInteger ().sum() td batters.batter.'@h'*. toInteger ().sum() td batters.batter.'@rbi'*. toInteger ().sum() td batters.batter.'@bb'*. toInteger ().sum() td batters.batter.'@so'*. toInteger ().sum() } }
  • 55.
  • 57.
  • 59. Find Games on Date void getGames() { println &quot;Games for ${month}/${day}/${year}&quot; def url = base + &quot;year_${year}/month_${month}/day_${day}/&quot; def gamePage = new URL(url).text def pattern = /amp;quot;gid_${year}_${month}_${day}_(*)mlb_(*)mlb_()/
  • 60.
  • 61. Process HTML Page def m = gamePage =~ pattern if (m) { (0..<m. count ).eachWithIndex { line, i -> def away = m[line][1] def home = m[line][2] def num = m[line][3] try { getGame(away,home,num) } catch (Exception e) { println abbrevs[away] + &quot; at &quot; + abbrevs[home] + &quot; not started yet&quot; } } }
  • 62.
  • 63. Results Games for 05/05/2007 Boston at Minnesota on 05/05/2007 Boston Red Sox 1, Minnesota Twins 2 (game 1) Tavarez (L, 1-3) Santana (W, 4-2) Nathan (S, 8) Chicago (A) at Los Angeles (A) on 05/05/2007 Chicago White Sox 6, Los Angeles Angels 3 (game 1) Garland (W, 1-2) Jenks (S, 9) Lackey (L, 4-3) …
  • 64.
  • 65.
  • 66.
  • 67.
  • 68. Sample CSV Data 75,5/14/2007,5/18/2007,Java Web Services,Lancaster,PA 76,5/21/2007,5/25/2007,Ajax and Struts,Philadelphia,PA 77,6/4/2007,6/12/2007,Java Web Services,McLean,VA 78,6/25/2007,6/29/2007,Portal Dev. Using RAD6,Enola,PA 80,7/9/2007,7/14/2007,Hibernate EJB3,Atlanta,GA 81,8/23/2007,8/23/2007,J2EE for Managers,Marlborough,CT
  • 69. Process CSV Data class Record { int num; String startDate; String endDate String title; String city; String state Record(String[] s) { num = s[0].startsWith(&quot;#&quot;) ? 0 : s[0]. toInteger () startDate = s[1]; endDate = s[2] title = s[3]; city = s[4]; state = s[6] } String toString() { &quot;$title ($startDate -- $endDate) $city, $state&quot; } }
  • 70. Process CSV Data def records = [] try { def dataFile = new File('Course_locations.csv') def lines = dataFile. readLines () for (line in lines) { elements = line.trim().split(',') records << new Record(*elements) } } catch (FileNotFoundException e) { println e } records.each { println it }
  • 71.
  • 72.
  • 73.
  • 74. Using Google Geocoder def key = ‘long_ugly_key' def base = 'http://maps.google.com/maps/geo' def city = 'Marlborough' def state = 'CT' def query = &quot;q=${city},+${state}&output=csv&key=${key}&quot; def url_string = base + '?q=' + ',+' + URLEncoder.encode(city,&quot;UTF-8&quot;) + ',+' + state + &quot;&output=csv&key=${key}&quot; def results = new URL(url_string).text.split(',') def latitude = results[-2].toDouble(); def longitude = results[-1].toDouble(); println &quot;(${latitude},${longitude})&quot; assert &quot;(41.63256,-72.46315) == (${latitude},${longitude})&quot;
  • 75.
  • 76. USGS Geocoder def partialCsvRequest = &quot;http://geocoder.us/service/csv/geocode?address=&quot; def address = &quot;11 Emily Road, Marlborough, CT&quot; def csvUrl = new URL(partialCsvRequest + URLEncoder.encode(address)) def csvResponse = csvUrl.text def tokens = csvResponse.split(&quot;,&quot; ) println &quot;Latitude: [${tokens[0]}]&quot; println &quot;Longitude: [${tokens[1]}]&quot; println &quot;Address: [${tokens[2]}]&quot; println &quot;City: [${tokens[3]}]&quot; println &quot;State: [${tokens[4]}]&quot; println &quot;Zip: [${tokens[5]}]&quot;
  • 77. TrainingCourse class TrainingCourse { String title; Date startDate; Date endDate; double rate String toString() { def nf = NumberFormat.currencyInstance &quot;(${title},(${startDate} - ${endDate}),${nf.format(rate)})&quot; } int getLength() { (startDate..endDate). size () } double getRevenue() { length * rate } }
  • 78.
  • 79. CourseProcessor.groovy class CourseProcessor { def courses = [] def courseYearMap = new TreeMap() def cal = Calendar.instance CourseProcessor() { def USER = ‘xxx‘; def PASS = ‘xxx’; def URL = ‘xxx‘; def DRIVER = ‘xxx' def conn = Sql.newInstance(URL,USER,PASS,DRIVER) conn.eachRow('select * from course') { row -> courses << new TrainingCourse( title:row.title,startDate:row.start_date, endDate:row.end_date,rate:row.rate) }
  • 80. Continuing… courses. each { c -> cal.time = c.startDate def year = cal.get(Calendar.YEAR) courseYearMap[year] = courseYearMap.get(year,[]) + c } }
  • 81.
  • 82. Printing Courses def printYearMap() { def nf = NumberFormat.currencyInstance courseYearMap. each { year,courseList -> def monthlyDays = new int [12] def monthlyRev = new double [12] courseList. each { course -> cal.time = course.startDate def month = cal.get(Calendar.MONTH) for (date in course.startDate..course.endDate) { monthlyDays[month] += 1 monthlyRev[month] += course.rate } }
  • 83. Continuing def days = (courseList*.length).sum() def rev = (courseList*.revenue).sum() println &quot;Totals for $year : ${days} days, ${nf.format(rev)}&quot;
  • 84.
  • 85.
  • 86.
  • 87.