Categories
Groovy

Spaceships, Elvis, and Groovy inject

When I first started learning Groovy, I took to collect pretty quickly. The current trend of adopting “functional programming” practices works well in Groovy, though the names of the methods are somewhat surprising. For example, collect is like map, findAll is the equivalent of filter, and inject is the proposed replacement for reduce (or whatever the similar process is for your favorite language).

As a trivial example, in Groovy you can write:
[sourcecode language=”groovy”]
(1..20).collect { it * 2 } // double them all
.findAll { it % 3 == 0 } // find the doubles divisible by 3
.sum() // add them up
[/sourcecode]
which is a functional style, even though Groovy is an object-oriented language.

Notice, however, that I didn’t use inject. That’s not an accident, of course. For years, while I “got” collect and findAll, I never found a usage for inject that couldn’t be done in an easier way. The inject version of the above example would be:
[sourcecode language=”groovy”]
(1..20).collect { it * 2 } // double them all
.findAll { it % 3 == 0 } // find the doubles divisible by 3
.inject(0) { acc, val -> acc + val } // add them up
[/sourcecode]
That seems like a lot of work compared to the sum method, especially when I always had trouble remembering exactly what the arguments to the closure meant.

That changed recently. One of the examples I use when teaching Groovy to Java developers is do some basic sorting. I like that example, because it shows not only how easy it is to replace anonymous inner classes with closures, but also because it shows how much the Groovy JDK simplifies coding.

As a preface to my example, consider making an ArrayList of strings:
[sourcecode language=”groovy”]
def strings = ‘this is a list of strings’.split()
assert strings.class == java.lang.String[]
[/sourcecode]
The split method splits the string at spaces by default, and returns, sadly, a string array. What I want is a List, and converting an array into a List is a special blend of Java awkwardness and verbosity, though the code isn’t too bad once you’ve seen it.

The conversion is trivial in Groovy, however.
[sourcecode language=”groovy”]
List strings = ‘this is a list of strings’.split()
assert strings.class == java.util.ArrayList
[/sourcecode]
Just replace def with the datatype you want, and Groovy will do its best to do the conversion for you. 🙂

To sort a list, Java has the various static sort methods in the java.util.Collections class. The sort method with no arguments does the natural, alphabetical (more properly, lexicographical, where there capital letters come before the lowercase letters) sort.

[sourcecode language=”groovy”]
List strings = ‘this is a list of strings’.split()
Collections.sort() // natural sort (alphabetical)
assert strings == [‘a’, ‘is’, ‘list’, ‘of’, ‘strings’, ‘this’]
[/sourcecode]
This sorts the strings in place (a destructive sort) and returns void, so to see the actual sort you have to print it.

How do you test this? I wrote an assert that hardwired the results, because I knew what they had to be. That’s hardly generalizable, however, and this is where inject comes in.

Have you ever looked at the definition of inject in the GroovyDocs? Here it is, from the class org.codehaus.groovy.runtime.DefaultGroovyMethods.

public static T inject(E[] self, U initialValue, @ClosureParams(value=FromString.class,options=”U,E”) Closure closure)

Iterates through the given array, passing in the initial value to the closure along with the first item. The result is passed back (injected) into the closure along with the second item. The new result is injected back into the closure along with the third item and so on until all elements of the array have been used. Also known as foldLeft in functional parlance.

Parameters:
self – an Object[]
initialValue – some initial value
closure – a closure

Returns:
the result of the last closure call

You would be forgiven for being seriously confused right now. I’ve been using Groovy since about 2007 and if I didn’t already know what inject did, I’d be seriously confused, too.

The DefaultGroovyMethods class contains lots of methods that are added to the library at runtime via Groovy metaprogramming. In this case, the inject method is added to collection (the first argument above). The second argument to inject is an initial value. An initial value to what, you say? The third argument to inject is a closure, and it takes two arguments, and the second argument to inject is the initial value of the first argument of the closure. The subsequent values to that argument are the result of the closure. The second argument to the closure is each element of the collection, in turn.

I expect that almost nobody actually read that last paragraph. Or, more likely, you started it and abandoned it somewhere in the middle. I can hardly blame you.

As usual, the indefatigable Mr. Haki comes to the rescue. Here is one of his examples:

[sourcecode language=”groovy”]
(1..4).inject(0) { result, i ->
println "$result + $i = ${result + i}"
result + i
}
[/sourcecode]
and the output is:

0 + 1 = 1
1 + 2 = 3
3 + 3 = 6
6 + 4 = 10

The value of result starts at the initial value (here, 0), and is assigned the result of each execution of the closure.

That’s the sort (no pun intended) of example I’d seen before, and because I always associated inject with accumulators, I never actually needed it. After all, the Groovy JDK adds a sum method already.

The key is to note that the value of “result” is actually whatever is returned from the closure (Mr. Haki’s second example illustrates this beautifully — seriously, go read his post). This actually makes it easy to use to test the sort.

Try this out for size:
[sourcecode language=”groovy”]
List strings = ‘this is a list of strings’.split()
Collections.sort(strings)
strings.inject(”) { prev, curr ->
println "prev: $prev, curr: $curr"
assert prev <= curr
curr // value of ‘prev’ during next iteration
}
[/sourcecode]
The result is:

prev: , curr: a
prev: a, curr: is
prev: is, curr: list
prev: list, curr: of
prev: of, curr: strings
prev: strings, curr: this

Since the closure returns the current value, that becomes the value of prev during the next iteration.

Actually, this can be simplified too. As of Groovy 1.8, there’s now an inject method that leaves out the initialization value. When you call it, the first two elements of the collection become the first two arguments of inject. In other words, now I can do this:
[sourcecode language=”groovy”]
List strings = ‘this is a list of strings’.split()
Collections.sort(strings)
strings.inject { prev, curr ->
println "prev: $prev, curr: $curr"
assert prev <= curr
curr // value of ‘prev’ during next iteration
}
[/sourcecode]
The output now is:

prev: a, curr: is
prev: is, curr: list
prev: list, curr: of
prev: of, curr: strings
prev: strings, curr: this

Sweet. Now I have a real, live use case for inject. 🙂 I promised you more, however. The title of this post refers to Elvis and spaceships, too.

Assume you want to sort the strings by length. In Java, when you can’t modify the class to be sorted (String), you use the two-argument sort method in Collections. The second argument is of type java.util.Comparator, which gives rise to the dreaded anonymous inner class monster:
[sourcecode language=”groovy”]
List strings = ‘this is a list of strings’.split()
Collections.sort(strings, new Comparator<String>()) { // R: Holy anonymous inner class, Batman!
int compare(String s1, String s2) { // B: Yes, Robin, with generics and everything.
s1.size() <=> s2.size() // R: Gosh, gee, and a spaceship!
}
})
assert strings == [‘a’, ‘is’, ‘of’, ‘this’, ‘list’, ‘strings’]
assert strings*.size() == [1, 2, 2, 4, 4, 7] // R: Holy spread-dot operator, too!
// B: Dude, seriously, get a grip.
[/sourcecode]
The spaceship operator returns -1, 0, or 1 when the left side is less than, equal to, or greater than the right side. It’s like a comparator, except the values are fixed to -1, 0, and 1.

The nice thing about the spread-dot operator here is that it doesn’t care whether the resulting strings are also alphabetical or not. The fact that equals length strings were also sorted alphabetically is just a side effect of the algorithm.

One of the common idioms in the Groovy JDK is to take static methods in Java and make them instance methods in Groovy. Here, the sort method is a static method in the Collections class. The Groovy JDK makes it an instance method in Collection (singular).

[sourcecode language=”groovy”]
List strings = ‘this is a list of strings’.split()
strings.sort { s1, s2 -> s1.size() <=> s2.size() } // R: Holy closure coercion, Batman!
// B: No, the instance method takes a closure.
// Seriously, did you remember your ADHD meds today?
assert strings*.size() == [1, 2, 2, 4, 4, 7]
[/sourcecode]

The sort method in Groovy is now an instance method, which takes a one- or two-argument closure. The two-argument variety is implemented like a traditional comparator, meaning you return negative, zero, or positive as usual.

Even better, the one-argument version of sort says, in effect, transform each element into a number and Groovy will sort the numbers and use that as a way to sort the collection.

[sourcecode language=”groovy”]
List strings = ‘this is a list of strings’.split()
strings.sort { it.size() } // R: Everything is awesome!
assert strings*.size() == [1, 2, 2, 4, 4, 7] // B: Shut up kid, or you’ll find yourself floating home.
[/sourcecode]

Here’s the best part. What if you want to sort by length, and then sort equal lengths reverse alphabetically? (I’ll use reverse alpha because the length sort also did alphabetical by accident).

Now I can use Elvis and spaceships together:

[sourcecode language=”groovy”]
List strings = ‘this is a list of strings’.split()
strings.sort { s1, s2 ->
s1.size() <=> s2.size() ?: s2 <=> s1
}
[/sourcecode]

The Elvis operator says if the result is true by the Groovy Truth, use it, else use a default. Here it means do the length comparison and if the result is non-zero, we’re good. Otherwise do the (reverse) alphabetical comparison.

R: So that’s Elvis being carried back to his home planet by two tandem spaceships, right? Meaning it’s the fat Elvis from the 70s and not the thin Elvis from the 50s?
B: BAM! POW! OOF!

Here, finally, is a test based on inject for that sort:
[sourcecode language=”groovy”]
strings.inject { prev, curr ->
assert prev.size() <= curr.size()
if (prev.size() == curr.size()) {
assert prev >= curr
}
curr
}
[/sourcecode]

There you have it: Elvis, spaceships, and inject all in a dozen lines of code. Now you add that to your Groovy utility belt.

(B: POW! BAM! OOF!)

Categories
Groovy

The Reason The Internet Was Invented, or, Cat Pictures FTW

I’ll report about the SpringOne2GX conference soon, but I’m fighting a cold at the moment and the medication has put me in a rather bleary state. Thus, the following bit of random Groovy whimsy…

In this post, I’ll use Groovy to access a publicly available RESTful web service, parse the downloaded data, and build a GUI to hold the resulting images. The code will demonstrate the Groovy JDK, maps, the collect method, I/O processing, and the builder pattern, all to achieve its ultimate goal: looking at cat pictures.

A Flickring Light In The Darkness

There are many so-called RESTful web services available to the general public. Despite the name, however, most only support GET requests. This isn’t terribly surprising, since POST, PUT, and DELETE would require some kind of transaction, and security, and all sorts of protection against the sort of damage reminiscent of YouTube comments[1].

Examples of that sort of services include Open Weather Map (http://openweathermap.org/api), Currency Exchange Rates (http://openexchangerates.org), the Bing[2] Maps REST services (http://msdn.microsoft.com/en-us/library/ff701713.aspx), the Google Maps Geocoder (https://developers.google.com/maps/documentation/geocoding/) and the source for this article, Flickr (https://secure.flickr.com/services/developer). Each supports HTTP GET requests only.

If a RESTful web service only supports GET requests, does that make it a GETful service? If so, and it’s also stateless, does that make it a FORGETful web service? Thank you, thank you. Try the veal, and please remember to tip your wait staff.

Believe it or not, Flickr used to be the definitive site for image sharing, and some people still use it. Access requires a key, which means you need to register with Yahoo!, another web site that used to matter long, long ago when the web was shiny and new.

Why use it here? It’s available, it’s free, and, most important of all, it’s got cat pictures.

Feeling Groovy

Groovy is one of the new family of languages that compiles to bytecodes for the Java Virtual Machine. It’s simpler than Java, yet much more powerful, and has an easy learning curve for existing Java developers. It’s cool in its own right, and also forms the basis of interesting projects like Grails and Gradle.

Hey, I even wrote a Java/Groovy integration book about it.

Now on to the Groovy. Let’s assume you register and receive your special key. Save it in a file called flickr_key.txt, so you can access it this way:

[sourcecode language=”groovy”]
String key = new File(‘flickr_key.txt’).text
[/sourcecode]

Accessing a property (like text here) in Groovy is the same as invoking the corresponding getter or setter method. Here, the Groovy JDK adds the getText method to File, which returns the contents of the file.

The base URL for the web service is:

[sourcecode language=”groovy”]
String endPoint = ‘https://api.flickr.com/services/rest?&#8217;
[/sourcecode]

I included the “?” because I want to append the generated query string to the end point to get the complete URL.

The Flickr API uses a query string with a lot of parameters. Here I add them to a Groovy map.

[sourcecode language=”groovy”]
def params = [method: ‘flickr.photos.search’, api_key: key,
format: ‘json’, tags: ‘cat’, nojsoncallback: 1,
media: ‘photos’, per_page: 6]
[/sourcecode]

I’m calling the flickr.photos.search method with the api_key. I want JSON data back, but not as a JSON callback, and I want photo data using the cat tag. It’s not terribly complicated, but there are a lot of parameters.

The cool part is that a Groovy map like this can be converted to a query string using a very common idiom. The collect method applied to a map generates a list by applying a closure to each element of the original list. Therefore I can generate the query string thusly:

[sourcecode language=”groovy”]
def qs = params.collect { k,v -> "$k=$v" }.join(‘&’)
[/sourcecode]

The two-argument closure takes each key/value pair and returns a string where the key equals the value. Then the join method applied to the list creates a string whose entries are separated by ampersands.

That means the whole URL is defined by "$endPoint$qs". I can then use the toURL method from the Groovy JDK to convert the string to a URL[3], and the text parameter invokes getText, returning the total response.

I can now use the cool JsonOutput.prettyPrint(txt) method to format the output and write it to a file.

[sourcecode language=”groovy”]
File f = new File(‘cats.json’)
if (f) f.delete()
f << jsonTxt
println JsonOutput.prettyPrint(jsonTxt)
[/sourcecode]

Here’s a sample from that output:

[sourcecode language=”javascript”]
{
"photos": {
"page": 1,
"pages": 882777,
"perpage": 6,
"total": "5296661",
"photo": [
{
"id": "15077663928",
"owner": "125421155@N06",
"secret": "dc605f2671",
"server": "3837",
"farm": 4,
"title": "Mornings with bb kitty",
"ispublic": 1,
"isfriend": 0,
"isfamily": 0
},
{ … },
{ … },
{ … },
{ … },
{ … }
]
},
"stat": "ok"
}
[/sourcecode]

From JSON to Cat Pictures

Each photo block has the components necessary to assemble the URL to retrieve it, which is way more complicated than it needs to be but is still doable. Here’s the code for that part.

[sourcecode language=”groovy”]
def json = new JsonSlurper().parseText(jsonTxt)
def urls = json.photos.photo.collect { p ->
"http://farm${p.farm}.staticflickr.com/${p.server}/${p.id}_${p.secret}.jpg"
}
[/sourcecode]

The JsonSlurper has a parseText method that converts the received JSON string into a Groovy map. Then walking the map by calling json.photos.photo gets all the photo objects, and the collect block converts each of them into a URL.

All that remains is to access all the photo URLs and populate a simple GUI with them. One simple way to do that is to use Groovy’s SwingBuilder class.

[sourcecode language=”groovy”]
new SwingBuilder().edt {
frame(title:’Cat pictures’, visible: true, pack: true,
defaultCloseOperation: WindowConstants.EXIT_ON_CLOSE,
layout:new GridLayout(0, 2)) {
urls[0..5].each { String url ->
label(icon:new ImageIcon(url.toURL()))
}
}
}
[/sourcecode]

The SwingBuilder has an edt method, which builds the UI on the event dispatch thread. The frame “method” instantiates a JFrame with the given title, makes it visible, and packs it as small as possible. The GUI uses a GridLayout to make two columns of equally-spaced elements, each of which is a JLabel that contains an ImageIcon with the individual photo URLs.

The result is a display of the most recent six pictures tagged cat in Flickr, which can result in almost anything[4].

Here’s a sample view:

Cat-pictures

Don’t ask me about the monkey. I have no idea what that’s about either.

So what have we learned?

  1. Groovy maps can be converted to query strings using a closure and the join method
  2. The Groovy JDK adds methods to Java library classes that you wished were there all along
  3. Groovy builders can make Swing programming almost, but not quite, pretty cool
  4. I can haz kitteh pics

The entire script from this article is part of a GitHub repository called IntroGroovy. Drill down to the src/main/groovy/flickr directory. You’ll need to add your own Flickr key, but after that, go for it. Just don’t be surprised, apparently, if you get monkeys or tractors mixed in with your cat pictures.

I suppose now I should go and reimplement the whole script in LOLCODE.


1. Okay, that’s a little harsh. Nothing could be as awful as YouTube comments. Or perhaps the correct response to that is, “I didn’t know YouTube supported comments.” If that’s your answer, I SO wish I was you.
2. Come on, stop laughing. I get it: “If you don’t remember what Bing is, just Google it”. Ha ha.
3. What did you expect toURL to convert the string into, a tomato? That would be pretty cool, actually. Now I wish I had that method. Of course, Groovy is an open source project…​
4. Usually it’s cats, but once I got a bunch of tractors, which confused me until I realized they were manufactured by Caterpillar.
Categories
Groovy

SpringOne2GX, Day Minus 3

Yes, that’s a minus sign, because the event in question hasn’t happened yet. This is my first report from the upcoming SpringOne2GX conference, which starts in Dallas, TX next Monday, 9/8/14 (or 8/9/14 for my non-US-based friends). Since there are no talks on the opening day (just an opening keynote and reception), I’m arbitrarily designating that as Day Zero. I’m giving several talks at the conference and I thought I’d comment here on my preparations. I also have a kind of “insider” status, being a member of the No Fluff, Just Stuff conference tour (one of the organizers of SpringOne2GX*) and, as the author of Making Java Groovy, I know a lot of people in the community. That will hopefully give me opportunities to share amusing anecdotes and other non-presentation-based tidbits of information here.

*What is the proper hashtag for the conference? In past years people have recommended #springone2gx, but that’s way too many characters. The value #s12gx seems reasonable, but didn’t seem to catch on. Most people I know used #s2gx, which is probably what I’ll adopt.

Speaking of embarrassing anecdotes, let me give you one right away. Two years ago, after one of my talks at that year’s s2gx conference, Guillaume Laforge and Cedric Champeau came up to me to say hi. Guillaume, who lives near Paris, has an outrageous French accent. Every time I talk to him I keep thinking of this character from the classic movie. So I finally got up the nerve to ask him, “Just once, would you say to me, ‘your mother was a hamster, and your father smelt of elderberries!'”.

He and Cedric both just stared at me like I’d lost my mind. They had no idea what I was talking about. It wasn’t until later I realized that even if they knew Monty Python and the Holy Grail (a minimum requirement for any decent developer), they knew it in French.

Oh well.

This week I’m still polishing (yeah, right, polishing — not writing from scratch, at least as far as you know) my slides. I’m scheduled to give the following talks:

This is an introduction to Grails, combining domain classes (of course, Quest, Task, Knight, and Castle), controllers, services (using the Google geocoder), and more. Experienced Grails developers can comfortably skip it, but newbies will no doubt appreciate the introduction. I plan to add in some architectural discussions, as well as some Hibernate and/or Spring stuff if time allows.

I gave a similar talk a couple years ago, but things have changed significantly since then. As a minimal example, now the default unit testing framework is Spock, rather than the JUnit subclasses we used to use. Everything is annotation based, too. I’ll definitely talk about testing controllers, services, and domain classes (constraints), and plan to do a couple of integration tests as well, and then talk about various plugins, like the Build Test Data plugin and some other functional ones.

As I travel from company to company*, I rarely see the new REST capabilities in Grails 2.3+ being used. Last year Graeme Rocher did a wonderful presentation on them, as well as a brief discussion of the asynchronous capabilities in Grails. I hope to cover much the same (REST) ground, but rather than get into async I’m going to talk about customizing responses, using HAL for hypermedia, and so on.

*My day job is teaching technical training courses in pretty much all areas related to Java, specializing in open source topics like Spring, Hibernate/JPA, Android, Groovy, and Grails. That means I visit somewhere between 30 to 50 companies a year, and while I’m mostly talking to people who don’t know much about Grails yet, I’m always trying to find out what they are using. Between that and the NFJS conferences, I get a decent sense of what is becoming popular in the industry and what isn’t catching on.

As a sample, both Groovy and Grails are still growing at their normal slow, steady pace. Spring Boot is generating a lot of excitement among the more advanced developers, but most Spring users in the field haven’t even heard of it. I imagine this year’s conference will start to change that.

It turns out that Jeff Brown (co-author of DGG2, the Definitive Guide to Grails 2) is giving a talk entitled RESTful Grails 2 at 12:45pm on Tuesday. This is extraordinarily fortunate for me, because that means I can steal (er, reuse) whatever he says. Sweet. 🙂

I gave a similar talk last year, and was just getting ready when Paul King walked into the room. Paul King is one of the Greatest Groovy Experts Ever, and I experienced a flood of Imposter Syndrome as soon as he entered. Fortunately, he didn’t violently disagree with anything I said and was kind enough to share some additional information after it was over. Is it any wonder he is one of my personal heroes?

Another interesting Paul King tidbit: last time I checked, he had more commits to the Groovy code base than anyone, ever. Heck, I just checked and he did six more today.

I’ve updated the talk with new information, which should be fun. The toughest problem I’ll have is not giving away spoilers for the Groovy Puzzlers talk coming later in the conference.

(Go to the puzzlers talk. It’s fun.)

This is a big one for me. The fact that Android applications are now built using Gradle is a big deal for every Android developer, and the Android plugin for Gradle is still evolving at a rapid rate. The new IDE, Android Studio, is also changing all the time. My hope is to give the most up-to-date information on it possible. I’ll show the multi-project build they use by default, add some dependencies, run some tests (using the Robotium plugin), talk about Spring Android, and show some flavors and variants.

Best of all, I expect to try to update Android Studio right before the talk, so I have the latest possible version in the so-called Canary channel. What could possibly go wrong?

This is a revised and extended version of the same talk I gave at the Gr8 conf in Minneapolis in July. Those talks were limited to an hour, and given that lots of speakers were talking about Ratpack*, I decided to focus on Grails for the REST part. Now I should have time for both.

*Dan “Tiger” Woods is giving his Ratpack Web Framework talk at 2:30pm on Tuesday.

Wait, let’s try to improve that:

[code language=”groovy”]
[‘Tiger’,’James’,’Ickey’,’Mirk’,’Sher’].each { nickname ->
println "Dan ‘${nickname}’ Woods"
}
[/code]

Let me know if you have some better suggestions. Also, Lari Hotari is giving a talk on Ratpack and Grails 3.

Since there are no images in this post, here’s a small spoiler from the Groovy Vampires talk. Note the nice subtitle.

Making Java Groovy: Still a better love story than Twilight

If you’re coming to the conference, please drop by and say hi. I hope to write a short blog post every day of the conference, commenting on what talks I attended and which people I spoke to, but that’ll depend on how much last minute “updating” I’ll need to do on my slides.

Categories
Groovy

Responses to “The Closure Of No Return”

I knew as soon as I wrote about implementing a simple prime number algorithm using Groovy that someone would find a more elegant way of solving the problem. In this post, I want to highlight some of the responses I received.

In my previous post, The Closure Of No Return, I discussed implementing an isPrime method that worked for relatively small integers. The algorithm is to try to divide the given number by all integers from two up to the square root of the number, rounded up.

My initial attempt, and the actual motivation for the blog post, was to demonstrate that if you use a return keyword inside a closure, you only return from the closure. So my initial implementation didn’t work:
[sourcecode language=”groovy”]
// THIS DOESN’T WORK
boolean isPrime1(int x) {
if (x == 2) return true
int limit = Math.sqrt(x) + 1
(2..limit).each { n ->
// nice try, but a return in a closure
// returns only from the closure
if (x % n == 0) return false
}
return true
}
[/sourcecode]
The each method takes a closure as an argument, which is like calling a completely separate method. The return statement inside the closure returns from that method, but not from the each loop itself.

In order to return the proper value, I introduced a local variable, called result, which I assigned inside the closure and then returned:
[sourcecode language=”groovy”]
boolean isPrime2(int x) {
if (x == 2) return true
boolean result = true
int limit = Math.sqrt(x) + 1
(2..limit).each { n ->
if (x % n == 0) {
result = false
// can’t break out of the loop
}
}
return result
}
[/sourcecode]
Since I couldn’t use the break keyword inside the loop, this implementation was forced to check all the integers up to limit. I therefore switched at that point to Groovy’s for-in loop, which does allow the break:
[sourcecode language=”groovy”]
boolean isPrime3(int x) {
if (x == 2) return true
boolean result = true
int limit = Math.sqrt(x) + 1
for (n in 2..limit) {
if (x % n == 0) {
result = false
break
}
}
return result
}
[/sourcecode]
That was my final implementation in the blog post. I posted that one the web and waited for the corrections to roll in.

One commenter, Eric Johansson, pointed out that once I switched to the for-in loop, I could go back to using return again and eliminate the local variable result. Of course that’s true, and I missed it because of the steps I went through to write the code. I wonder how often such hysteresis loops occur in practice.

Another person commenting on the post, identified at Tim but without an email address or a link, suggested using the any method:
[sourcecode language=”groovy”]
boolean isPrime3(int x) {
if (x == 2) return true
int limit = Math.sqrt(x) + 1
!(2..limit).any { n ->
x % n == 0
}
}
[/sourcecode]
The hope here is that the any method would stop at the first number that satisfied the closure. I wasn’t sure that was true, so I looked at the source code for Groovy, which can be found on GitHub. The any method is shown in the Groovy JDK as being part of the java.lang.Object class. One way methods are added to the Java standard library is through the metaprogramming methods in
org.codehaus.groovy.runtime.DefaultGroovyMethods. I looked in that class and found the any implementation, which adds the any method to the java.lang.Object class:
[sourcecode language=”groovy”]
// from DefaultGroovyMethods
public static boolean any(Object self, Closure closure) {
BooleanClosureWrapper bcw = new BooleanClosureWrapper(closure);
for (Iterator iter = InvokerHelper.asIterator(self); iter.hasNext();) {
if (bcw.call(iter.next())) return true;
}
return false;
}
[/sourcecode]
If I’m interpreting this correctly, the iterator walks through each element one by one and returns true the first time an element satisfies the closure. In other words, yes, this approach would work and leave the loop at the proper time.

Soren (sorry, I don’t know how to put the line through the “o”) Berg Glasius (http://twitter.com/sbglasius) suggested using the every method instead, which would also probably do the job.

Both great developer Jochen Theodorou and the indefatigable Tim Yates immediately identified the obvious alternative that I missed. Here’s Tim’s solution (which is a slight variation on Jochen’s):
[sourcecode language=”groovy”]
boolean isPrime5(int x) {
int limit = Math.sqrt(x) + 1
x == 2 || !(2..limit).find { n -> x % n == 0 }
}
[/sourcecode]
I remembered the findAll method, which I used in my tests, but I forgot all about the find method, which returns the first element that satisfies the closure. That’s pretty ironic, too, because (in Grails especially) I normally accidentally use find when I meant findAll.

(As an aside, as soon as I saw Tim’s name, I assumed his solution was going to be both elegant and have the take method in there somewhere. I was half right.)

The only problem I have with these solutions is that while they work, they invalidate the real reason for my blog post, which was to emphasize that a return inside a closure returns only from the closure. Still, that last one feels like a really good way to solve the actual problem, so I’m going to use that in the future.

The best part is that everyone who suggested an alternative was quite friendly about it. I may have felt a bit foolish for missing these alternatives, but that’s my own pressure on myself. One of the best features about the Groovy community is how helpful and easy to work with everyone is, which I really like. Hopefully by posting those solutions here, I’m paying some of that forward.

(Thanks to everyone who responded, whether I quoted them here or not. I really appreciate the feedback.)

Categories
Groovy

The Closure Of No Return

Even in a language like Groovy that is normally so clean and intuitive, there are traps for the unwary. I fell into one again today (in front of a room full of students), and I think it’s high time I documented it, at least so I’ll remember it for next time.

I’m teaching a Groovy / Grails class this week, and one of the problems I posed to the students was to write an isPrime method that worked for integers less than, say, 1000. The easiest brute force way to solve the problem is to divide the given number by every integer from 2 up to the square root of the number, rounded up.

Here’s a first try:
[sourcecode language=”groovy”]
// NOTE: THIS DOESN’T WORK
boolean isPrime1(int x) {
if (x == 2) return true
int limit = Math.sqrt(x) + 1
(2..limit).each { n ->
if (x % n == 0) return false // Danger, Will Robinson!
}
return true
}

assert (2..20).findAll { isPrime1(it) } == (2..20) // Wait, what??
[/sourcecode]
In other words, the method returns true for every number, whether it’s prime or not.

The problem is the return statement inside the each loop. The argument to the each method is a closure, and returning from a closure returns only from the closure, not the whole method.

I should emphasize that, so maybe next time I’ll remember it:

A return inside a closure returns only from the closure, not from the method that called it.

It’s actually not that hard to understand, when I think it through. Calling the closure is like calling another method. When I use the return keyword inside the closure, it’s like returning from that method, so it only returns from there and not from the each method itself.

So, how do I fix this? One way is to define a boolean variable outside the closure and then set it inside, but that leads to a minor problem as well.
[sourcecode language=”groovy”]
boolean isPrime2(int x) {
if (x == 2) return true
boolean result = true // local var to set in closure
int limit = Math.sqrt(x) + 1
(2..limit).each { n ->
if (x % n == 0) {
result = false
// don’t you wish you could break here?
}
}
return result
}

assert (2..20).findAll { isPrime2(it) } ==
[2, 3, 5, 7, 11, 13, 17, 19] // works, but no break
[/sourcecode]
I defined a boolean variable called result and initialized it to true. Then, inside the closure, if a number is not prime, I set the variable to false, and returned the variable at the end.

As the comment shows, however, I can’t break out of the loop. You can only use break inside loops, and some reason (I don’t know why), each loops don’t qualify. I’m forced to follow the loop to the end.

There is a way to solve that problem, too. I just need to replace the each loop with Groovy’s for-in loop.
[sourcecode language=”groovy”]
boolean isPrime3(int x) {
if (x == 2) return true
boolean result = true
int limit = Math.sqrt(x) + 1
for (n in 2..limit) {
if (x % n == 0) {
result = false
break // yay!
}
}
return result
}

assert (2..20).findAll { isPrime3(it)} ==
[2, 3, 5, 7, 11, 13, 17, 19] // works
[/sourcecode]
Now it works. This is also one reason to sometimes favor the for-in loop over the each iterator, but usually they’re interchangeable.

As usual, I couldn’t leave well enough alone. A common idiom in the Groovy JDK is to use metaprogramming to replace a static method in one class with an instance method in another. For example, java.lang.Math has the static abs method, but the Groovy JDK adds abs as an instance method to java.lang.Number. It’s not hard to do the same thing here:
[sourcecode language=”groovy”]
Number.metaClass.isPrime = { ->
Integer x = delegate as Integer
if (x == 2) return true
boolean result = true
int limit = Math.sqrt(x) + 1
for (n in 2..limit) {
if (x % n == 0) {
result = false
break
}
}
return result
}

assert (2..20).findAll { it.isPrime() } == [2, 3, 5, 7, 11, 13, 17, 19][/sourcecode]
The delegate of the closure is the number the isPrime method was called on, so if I assign it to x I can copy and paste my implementation from above.

The truly fun part was that I assigned this problem to the students, and then decided to live code the implementation in front of them. Of course I went for the each implementation, falling right into the trap. Since I’ve seen this problem many times, I recognized it pretty quickly and therefore wrote the other two implementations after that. I’d like to believe that the students got some value out of seeing me mess it up and then fix it. If nothing else, they learned the value of test cases. Without those assert statements, I probably wouldn’t have noticed the error in the first place.

Baruch Sadogursky (@jbaruch on Twitter) is doing a presentation on Groovy and Grails Puzzlers at Gr8conf in Minneapolis at the end of July, and he’s always interested in issues like this, so I made sure to send it along to him. If you know of any others, I’m sure he’d appreciate them as well.

Categories
Groovy

Groovy Groundhogs, revisited

For those people in the U.S. who are concerned that this morning Punxsutawney Phil, the Seer of Seers, Prognosticator of Prognosticators, emerged, reluctantly, but alertly, and stated in groundhog-ese, “I definitely see a shadow”, let me allay your fears using Groovy:

[sourcecode language=”groovy”]
Calendar cal = Calendar.instance

cal.set(year:2014, month:Calendar.FEBRUARY, date:2)
def groundhogDay = cal.time

cal.set(year:2014, month:Calendar.MARCH, date:20)
def firstDayOfSpring = cal.time

int days = firstDayOfSpring – groundhogDay
println """There are $days days between Groundhog Day and the first Day of Spring.
That’s ${(int) (days/7)} weeks and ${days % 7} days.
"""
[/sourcecode]

The result of that script is:

There are 46 days between Groundhog Day and the first Day of Spring.
That's 6 weeks and 4 days.

In other words, “six more weeks of winter” is a good thing, because otherwise we’d have to wait an extra four days.

A few notes are in order:

  • Here is the official Groundhog Day site.
  • According to the Wikipedia page, Phil has been predicting the weather since 1887. His accuracy rate is only about 39%, however.
  • Some kind of Groundhog Day celebration has been recorded since as far back as 1841. It bears similarities to the pagan festival of Imbolc, among others.
  • If you don’t like using the Calendar class (and who does?), the Groovy JDK also adds a parse method directly to java.util.Date:
    [sourcecode language=”groovy”]
    Date groundhogDay = Date.parse(‘MM/dd/yyyy’, ’02/02/2014′)
    Date firstDayOfSpring = Date.parse(‘MM/dd/yyyy’, ’03/20/2014′)
    [/sourcecode]
    and the rest is the same.
  • The Vernal Equinox this year occurs on March 20, 2014, at 1:57pm EDT.
  • I considered posting this blog entry over and over as some sort of weak tribute to the movie, but at least I spared you that. 🙂

There’s more, but I have to go get ready for our Super Bowl party, where the announcers have been talking about the weather all week and will no doubt be disappointed that the temperature will be in the 40s (Fahrenheit).

Categories
Groovy

Groovy Weather: A New Groovy Example at Java.net

One of the main goals of Making Java Groovy is to show Java developers how much Groovy can make their lives easier. To that end, I just published a blog post (through Manning’s account) over a Java.net entitled, Groovy Weather: POGOs, Gson, and Open Weather. The blog post comes with a coupon code for 45% off the book. 🙂

(Spoiler: it’s “kousenjn“, but if you’re going to use it at least drop by the blog link.)

Another spoiler: it’s freakin’ cold outside. That’s partly what my blog post is about — consuming JSON data from Open Weather Map and displaying it at the console. That’s not terribly difficult, but the real value added comes from using Google’s Gson parser to convert the JSON objects into Groovy.

If you’re new to Groovy, the blog post shows a lot of detail. Regular readers of my blog, however, probably are at least comfortable with the language, so I thought I’d summarize the good parts here.

First, I need to show the JSON data, so I know what to map to.

(Er, “to what to map”? Ugh. Winston Churchill was once criticized for ending a sentence with a preposition. His reply was, “Madam, that is nonsense up with which I will not put.” That’s one of those possibly apocryphal stories that I don’t want to try to verify because I like it too much.)

Here’s the trivial Groovy expression to download the data:
[code language=”groovy”]
import groovy.json.*

String url = ‘http://api.openweathermap.org/data/2.5/weather?q=marlborough,ct&#8217;
String jsonTxt = url.toURL().text
println JsonOutput.prettyPrint(jsonTxt)
[/code]

I’m using the static prettyPrint method of JsonOutput to make viewing the results easier. As a minor complaint, I have to mention that every time I use prettyPrint, I’m surprised it doesn’t actually print. It just formats the JSON data. I still need to print the result. That seems rather misleading to me.

Anyway, here’s the result:
[code language=”javascript”]
{
"coord": {
"lon": -72.46,
"lat": 41.63
},
"sys": {
"message": 0.193,
"country": "United States of America",
"sunrise": 1389096985,
"sunset": 1389130583
},
"weather": [
{
"id": 800,
"main": "Clear",
"description": "Sky is Clear",
"icon": "01d"
}
],
"base": "gdps stations",
"main": {
"temp": 260.41,
"humidity": 33,
"pressure": 1025,
"temp_min": 258.71,
"temp_max": 262.15
},
"wind": {
"speed": 1.54,
"deg": 0
},
"clouds": {
"all": 0
},
"dt": 1389130569,
"id": 4835003,
"name": "Hartford",
"cod": 200
}
[/code]
The current temperature is buried inside the object, in the “temp” property of the “main” subobject. I could just parse this using a JsonSlurper, but instead I decided to map the whole thing using Gson.

Gson wants a class structure that maps to the JSON hierarchy. Here’s mine, which I just stuffed into a single Groovy class called Model.groovy.
[code language=”groovy”]
class Model {
Long dt
Long id
String name
Integer cod

Coordinates coord
Main main
System sys
Wind wind
Clouds clouds
Weather[] weather
}

class Main {
BigDecimal temp
BigDecimal humidity
BigDecimal pressure
BigDecimal temp_min
BigDecimal temp_max
}

class Coordinates {
BigDecimal lat
BigDecimal lon

String toString() { "($lat, $lon)" }
}

class Weather {
Integer id
String main
String description
String icon
}

class System {
String message
String country
Long sunrise
Long sunset
}

class Wind {
BigDecimal speed
BigDecimal deg
}

class Clouds {
BigDecimal all
}
[/code]
I added the data types based on reading the docs, which are pretty thin, and following the nested structure of the JSON data. The names of the classes aren’t important. It’s the property names that have to match the keys in the JSON maps for deserialization to work.

Using Gson is almost trivial. All I need is the fromJson method in the Gson class:
[code language=”groovy”]
import groovy.transform.*
import com.google.gson.Gson

@ToString(includeNames=true)
class Model {

}

String url = ‘http://api.openweathermap.org/data/2.5/weather?q=marlborough,ct&#8217;
String jsonTxt = url.toURL().text
Gson gson = new Gson()
println gson.fromJson(jsonTxt, Model)
[/code]
Everything is converted to the Groovy class structure, just as expected.

Before printing the results, though, I need to do some data manipulation. If you looked at the current temperature value, you might have noticed it’s in Kelvin, of all things. As a US-based developer, I need to convert that to Fahrenheit.

[code language=”groovy”]
def convertTemp(temp) {
9 * (temp – 273.15) / 5 + 32
}
[/code]

The time fields are based on “Unix time”, which measures seconds in the current epoch (beginning January 1, 1970 GMT). Java’s Date class has a constructor that takes a long representing milliseconds from the beginning of the epoch.

[code language=”groovy”]
def convertTime(t) {
new Date(t*1000) // Unix time in sec, Java time in ms
}
[/code]

Finally, the wind speed is in “meters per second” and I want “miles per hour”. When I was in high school (and dinosaurs roamed the Earth), I learned about the Factor Label method, which meant I could memorize a single length conversion and calculate any other.

[code language=”groovy”]
def convertSpeed(mps) {
// 1 m/sec * 60 sec/min * 60 min/hr * 100 cm/m * 1 in/2.54 cm * 1 ft/12 in * 1 mi/5280 ft
mps * 60 * 60 * 100 / 2.54 / 12 / 5280
}
[/code]

I added all of these to the Model class, and some getters to use them.
[code langauge=”groovy”]
class Model {
// … as before …

def getTime() { convertTime dt }
def getTemperature() { convertTemp main.temp }
def getLow() { Math.floor(convertTemp(main.temp_min)) }
def getHigh() { Math.ceil(convertTemp(main.temp_max)) }
def getSunrise() { convertTime sys.sunrise }
def getSunset() { convertTime sys.sunset }
def getSpeed() { convertSpeed wind.speed }
}
[/code]

Finally, here’s my nice, formatted toString method to print the results (also a part the Model class):
[code language=”groovy”]
String toString() {
"""
Name : $name
Time : $time
Location : $coord
Weather : ${weather[0].main} (${weather[0].description})
Icon : http://openweathermap.org/img/w/${weather[0].icon}.png
Current Temp : $temperature F (high: $high F, low: $low F)
Humidity : ${main.humidity}%
Sunrise : $sunrise
Sunset : $sunset
Wind : $speed mph at ${wind.deg} deg
Cloudiness : ${clouds.all}%
"""
}
[/code]
I should mention that the Weather attribute of the Model class is a collection. Presumably that’s for when there are multiple weather stations associated with a given location. In the source code repository (linked below), I used Groovy’s each method to iterate over them all. Here I’m just using the first one.

The driver for the system is:
[code language=”groovy”]
import com.google.gson.Gson

class OpenWeather {
String base = ‘http://api.openweathermap.org/data/2.5/weather?q=&#8217;
Gson gson = new Gson()

String getWeather(city=’Marlborough’, state=’CT’) {
String jsonTxt = "$base$city,$state".toURL().text
gson.fromJson(jsonTxt, Model).toString()
}
}
[/code]
I like Groovy’s default arguments for methods. If I invoke the getWeather method without arguments (or as the weather property in the usual idiom), then the result is for “Marlborough, CT”. Otherwise I supply a city and a state and they’re used instead.

Clearly this needs to be tested, or at least the converters so. Here’s a Spock test for them:
[code language=”groovy”]
import spock.lang.Specification

class ModelSpec extends Specification {
Model model = new Model()

def ‘convertTemp converts from Kelvin to F'() {
expect:
32 == model.convertTemp(273.15)
212 == model.convertTemp(373.15)
}

def ‘convertSpeed converts from meters/sec to miles/hour'() {
expect:
(2.23694 – model.convertSpeed(1)).abs() < 0.00001
}

def ‘convertTime converts from Unix time to java.util.Date'() {
given:
Calendar cal = Calendar.instance
cal.set(1992, Calendar.MAY, 5)
Date d = cal.time
long time = d.time / 1000 // Java time in ms, Unix time in sec

when:
Date date = model.convertTime(time)

then:
d – date < 1
}
}
[/code]
The mps to mph value I got from putting “1 meter per second in mph” into Google, which gave me the proper result.

Just to make sure the calls are working properly, here are a couple of tests for the Model class.
[code language=”groovy”]
import spock.lang.Specification

class OpenWeatherSpec extends Specification {
OpenWeather ow = new OpenWeather()

def ‘default city and state return weather string'() {
when:
String result = ow.weather
println result

then:
result // not null is true in Groovy
result.contains(‘41.63’)
result.contains(‘-72.46’)
}

def "The weather is always great in Honolulu"() {
when:
String result = ow.getWeather(‘Honolulu’, ‘HI’)
println result

then:
result
result.contains(‘21.3’)
result.contains(‘-157.86’)
}
}
[/code]

Here’s a script to run the whole system:
[code language=”groovy”]
OpenWeather ow = new OpenWeather()
println ow.weather // called Marlborough, CT, but really Hartford

// Home of Paul King, co-author of _Groovy in Action_ and my personal hero
println ow.getWeather(‘Brisbane’,’Australia’)

// Home of Guillaume Laforge, head of the Groovy project
// (also one of my heroes, along with Dierk Koenig, Graeme Rocher, Tom Brady, David Ortiz, …)
println ow.getWeather(‘Paris’,’France’)

// Have to check the weather in Java, right?
println ow.getWeather(‘Java’,’Indonesia’)

// Any weather stations in Antarctica?
println ow.getWeather(”, ‘Antarctica’)
[/code]
Here are the results at the moment (Jan 7, 2014, at about 5:45pm EST):

Name         : Marlborough
Time         : Tue Jan 07 17:43:10 EST 2014
Location     : (41.63, -72.46)
Weather      : Clear (Sky is Clear)
Icon         : http://openweathermap.org/img/w/01n.png
Current Temp : 8.312 F (high: 11.0 F, low: 5.0 F)
Humidity     : 35%
Sunrise      : Tue Jan 07 07:16:25 EST 2014
Sunset       : Tue Jan 07 16:36:23 EST 2014
Wind         : 3.4448818898 mph at 258 deg
Cloudiness   : 0%

Name         : Brisbane
Time         : Tue Jan 07 17:36:03 EST 2014
Location     : (-27.47, 153.02)
Weather      : Clouds (broken clouds)
Icon         : http://openweathermap.org/img/w/04n.png
Current Temp : 78.566 F (high: 82.0 F, low: 77.0 F)
Humidity     : 46%
Sunrise      : Mon Jan 06 14:00:36 EST 2014
Sunset       : Tue Jan 07 03:47:48 EST 2014
Wind         : 10.51360057266 mph at 121 deg
Cloudiness   : 80%

Name         : Paris
Time         : Tue Jan 07 17:39:23 EST 2014
Location     : (48.85, 2.35)
Weather      : Clear (Sky is Clear)
Icon         : http://openweathermap.org/img/w/01n.png
Current Temp : 52.682 F (high: 54.0 F, low: 51.0 F)
Humidity     : 81%
Sunrise      : Tue Jan 07 02:42:36 EST 2014
Sunset       : Tue Jan 07 11:11:33 EST 2014
Wind         : 8.052970651396 mph at 220 deg
Cloudiness   : 0%

Name         : Batununggal
Time         : Tue Jan 07 17:43:35 EST 2014
Location     : (-6.96, 107.65)
Weather      : Clouds (scattered clouds)
Icon         : http://openweathermap.org/img/w/03n.png
Current Temp : 68.5904 F (high: 69.0 F, low: 68.0 F)
Humidity     : 91%
Sunrise      : Mon Jan 06 17:40:32 EST 2014
Sunset       : Tue Jan 07 06:10:58 EST 2014
Wind         : 2.9303865426 mph at 200 deg
Cloudiness   : 44%

Name         :
Time         : Tue Jan 07 17:43:35 EST 2014
Location     : (-78.33, 20.61)
Weather      : Clear (Sky is Clear)
Icon         : http://openweathermap.org/img/w/01d.png
Current Temp : -20.2936 F (high: -20.0 F, low: -21.0 F)
Humidity     : 38%
Sunrise      : Tue Jan 07 16:43:35 EST 2014
Sunset       : Wed Jan 08 04:43:35 EST 2014
Wind         : 15.770400858984 mph at 15.0058 deg
Cloudiness   : 0%

So, yeah, it’s cold outside. I also freely admit it’s a little weird seeing those non-US temperatures converted to Fahrenheit.

The Gradle build file for this system is almost trivial:
[code language=”groovy”]
apply plugin:’groovy’

repositories {
mavenCentral()
}

dependencies {
compile ‘org.codehaus.groovy:groovy-all:2.2.1’
compile ‘com.google.code.gson:gson:2.2.4’
testCompile ‘org.spockframework:spock-core:0.7-groovy-2.0’
}
[/code]

All of this code can be found in the book’s Github repo. I added this to Chapter 2: Groovy by Example. Chapter 2 now uses a multi-project Gradle build, so it doesn’t look exactly that the one shown here, but it works the same way.

This process is easy enough to replicate for any RESTful service that returns JSON data. The time consuming part, if any, is writing the POGO structure to capture the JSON tree, but at least with POGOs the result is pretty simple.

————-

Now for a few personal notes. First, the latest Amazon review is simply beautiful. It’s from a person who knew Java and didn’t expect much from Groovy, but found out how much it could help. That’s exactly what I’m trying to achieve. In fact, I’ve been amazed that every single Amazon reviewer, no matter how much he or she did or didn’t like specific aspects of the book, definitely understood the goal and appreciated it.

Second, I have a few new projects in the works, but I think I can mention one of them. I’m currently generating a series of screencasts for the book, which I’m calling “Making Java Groovy: The Director’s Cut”. The goal is to discuss why the book was written as it was — what was included, what was left out, what has changed since its publication in the Fall of 2013, and anything else I think might be interesting or helpful. Everyone at Manning has been very supportive of the effort so far. I hope to make at least the first set of screencasts available soon.

Third, I’ll be giving a talk at the Boston Grails Users’ Group on Thursday, January 9, at 7pm. I hope to bring some books to add to the raffle, along with an admission to the NFJS event in the Boston area in March. If you’re in the area, please drop by and say hello.

Fourth, if you’ve read this far, you deserve a reward! If you use the coupon code “kousen37” at Manning.com, you can get 37% off any book at Manning. 🙂

Oh, and in case you didn’t hear me celebrating, I’m now officially a 2013 JavaOne Rock Star. Thank you very much to everyone who recommended me.

Finally, those of you battling the so-called “polar vortex”, stay warm! It’s cold here, but at least we’re still above 0 (F, not C). Next week I’m planning to brave the winds of Caradhras, otherwise known as central Minnesota. Brr.

As the saying goes, follow the great advice found on the side of a mayonnaise jar: “Keep cool but don’t freeze”.

Categories
Groovy

Serving jokes locally with Ratpack and MongoDB

In two previous posts, I discussed applications I created that were simple client-side front ends for the Internet Chuck Norris Database (ICNDB), located at http://icndb.com. This post gives the details of the local server I created, using Groovy, MongoDB, and the cool Ratpack project (note new URL). The earlier posts contained parts of that app, but since then I’ve updated it to the latest version of Ratpack, revised the gradle build file accordingly, added a couple of integration tests, and checked the whole thing into GitHub.

I often use ICNDB in my Groovy presentations, because it’s easy to access, returns a simple JSON object, and is rather amusing.

(This, by the way, is in direct contrast to Mr. Norris himself, whose politics are somewhat to the right of Attila the Hun. Still, I only care about the jokes themselves, which are pretty funny.)

Accessing the site is trivial:
[sourcecode language=”groovy”]
import groovy.json.JsonSlurper

def url = ‘http://api.icndb.com/jokes/random&#8217;
def json = new JsonSlurper().parseText(url.toURL().text)
def joke = json?.value?.joke
println joke
[/sourcecode]
The Groovy JDK adds a toURL method to java.lang.String, which returns an instance of java.net.URL. It also adds a getText method to java.net.URL that returns the entire response as a string. I use the parseText method in JsonSlurper to parse it and just dig through the properties to get the contained joke.

Of course, my demo relies on that site being available, and that’s far from a sure thing, especially if Carlos Ray’s lawyers ever get to it. It also has a tendency to go down at inconvenient intervals, like when I’m trying to present the above script.

(Quick aside: this blog is hosted on WordPress, which has a much better uptime record than my actual home page. My site is hosted on a very old Windows laptop in my office. You’ve heard of “five nines” uptime, where a site guarantees it’ll be available 99.999% of the time? My site only promises “nine fives” uptime. It’s online a bit more than half the time.)

It behooves me, therefore, to keep a local copy if possible. That turns out to be pretty easy. First, there aren’t a whole lot of jokes. The ICNDB API offers the link http://api.icndb.com/jokes/count to return the total number of jokes. That request returns a JSON object:
[sourcecode language=”javascript”]
{
"type": "success",
"value": 546
}
[/sourcecode]
I can certainly handle a database of that size locally. In fact, in my app I load the whole thing into memory because why not?

Since the format of the jokes is JSON, I decided to use a MongoDB database to store them. The native format for MongoDB is BSON, or binary JSON, so all I have to do is grab the jokes and I can just append them to a local database. To make the code easier, I use the GMongo project, which is just a Groovy wrapper around Mongo’s Java client library.

The other useful method in the ICNDB API is http://api.icndb.com/jokes/random/num, where num represents the number of jokes you want returned. I want all of them, so I replace num with the total.

For example, if I access http://api.icndb.com/jokes/random/5, I get something like:
[sourcecode language=”javascript”]
{
"type": "success",
"value": [
{
"id": 204,
"joke": "Nagasaki never had a bomb dropped on it. Chuck Norris jumped out of a plane and punched the ground",
"categories": []
},
{
"id": 329,
"joke": "There are only two things that can cut diamonds: other diamonds, and Chuck Norris.",
"categories": []
},
{
"id": 348,
"joke": "There?s an order to the universe: space, time, Chuck Norris…. Just kidding, Chuck Norris is first.",
"categories": []
},
{
"id": 360,
"joke": "Two wrongs don’t make a right. Unless you’re Chuck Norris. Then two wrongs make a roundhouse kick to the face.",
"categories": []
},
{
"id": 406,
"joke": "Chuck Norris doesn’t say &quot;who’s your daddy&quot;, because he knows the answer.",
"categories": []
}
]
}
[/sourcecode]
The only difference from the original URL is that now the value property returns all of the contained jokes, but that’s not a problem. The overall script is therefore:
[sourcecode language=”groovy”]
import groovy.json.JsonSlurper
import com.gmongo.GMongo

// Drop the current icndb database, if it exists
GMongo mongo = new GMongo()
def db = mongo.getDB(‘icndb’)
db.cnjokes.drop()

// Get the total number of available jokes
JsonSlurper slurper = new JsonSlurper()
String jsonTxt = ‘http://api.icndb.com/jokes/count&#8217;.toURL().text
def json = slurper.parseText(jsonTxt)
int total = json.value.toInteger()

// Grab all of them at once
jsonTxt = "http://api.icndb.com/jokes/random/${total}".toURL().text
json = slurper.parseText(jsonTxt)

// Save them all locally
def jokes = json.value
jokes.each {
db.cnjokes << it
}
assert total == jokes*.id.size()
assert total == db.cnjokes.find().count()
[/sourcecode]
How cool is it that all I have to do is grab the jokes and append them to the collection to save them in the database? Truly, we live in magical times. 🙂

I can browse the database in Eclipse if I use the MonjaDB plugin. Here’s a screenshot showing it:
MonjaDB

Now that the database is populated, I can build the Ratpack app. I started off using the lazybones builder inside of gvm, the Groovy enVironment Manager, which I discussed in the earlier post. Ratpack keeps evolving, though, and lazybones hasn’t kept up, so the changes I’ve made to the resulting app are a bit more substantial than I originally intended.

Here’s the JokeServer class. In the constructor, I load all the jokes into a Groovy map, where the keys are the id’s and the values are the joke strings themselves.
[sourcecode language=”groovy”]
@Singleton
class JokeServer {
GMongo mongo = new GMongo()
Map jokes = [:]
List ids = []

JokeServer() {
DB db = mongo.getDB(‘icndb’)
def jokesInDB = db.cnjokes.find([categories: ‘nerdy’])
jokesInDB.each { j ->
jokes[j.id] = j.joke
}
ids = jokes.keySet() as List
}

[/sourcecode]
The other method in the class returns a random joke by shuffling the id’s and returning the associated joke. (The id’s themselves aren’t consecutive, partly because I’m only using the “nerdy” ones and partly because the original site skipped ID values.)
[sourcecode language=”groovy”]

String getJoke(String firstName = ‘Chuck’,
String lastName = ‘Norris’) {
Collections.shuffle(ids)
String joke = jokes[ids[0]]
if (!joke) println "Null joke at id=$id"
if (firstName != ‘Chuck’)
joke = joke.replaceAll(/Chuck/, firstName)
if (lastName != ‘Norris’)
joke = joke.replaceAll(/Norris/, lastName)
return joke
}
}
[/sourcecode]
I’m using Groovy’s nice optional arguments mechanism here, so if I invoke getJoke without arguments I get the original joke, but if I supply a first name or a last name they’re used in the joke itself.

Here’s my test case to make sure at least this much is working. It’s a regular JUnit test, implemented in Groovy.
[sourcecode language=”groovy”]
import static org.junit.Assert.*;

import org.junit.Before;
import org.junit.Test;

class JokeServerTest {
JokeServer server = JokeServer.instance // @Singleton on server

@Test
public void testGetJokeFirstNameLastName() {
String joke = server.getJoke(‘Patton’, ‘Boggs’)
assert !joke.contains(‘Chuck’)
assert !joke.contains(‘Norris’)
assert joke.contains(‘Patton’)
assert joke.contains(‘Boggs’)
}

@Test
public void testGetJoke() {
String joke = server.joke
assert joke
}

}
[/sourcecode]
Did you notice that I added @Singleton on the JokeServer, just for fun? That’s why the test grabs the server using the instance property. My first test then uses the strings “Patton” and “Boggs”, the name of the law firm that sent me the takedown notice. The second test accesses the joke property, which calls the getJoke method by the normal Groovy idiom.

Ratpack applications use a script called ratpack.groovy to set the various handlers. Since my script is so simple, I just added everything to that handler:
[sourcecode language=”groovy”]
import static ratpack.groovy.Groovy.*

import com.kousenit.JokeServer

JokeServer server = JokeServer.instance

ratpack {
handlers {
get {
String message
if(request.queryParams.firstName ||
request.queryParams.lastName) {
message = server.getJoke(
request.queryParams.firstName,
request.queryParams.lastName)
} else {
message = server.joke
}
response.headers.set ‘Content-Type’, ‘application/json’
response.send message
}

assets "public"
}
}
[/sourcecode]
The ratpack method takes a closure containing the various handlers. I only have a single handler, which is accessed using a get request. Then I get the relevant joke, set the Content-Type header to the MIME type for JSON, and return it. Actually, since my server returns the actual string, I probably shouldn’t set the header at all, but it hasn’t hurt anything so far.

The only difference between this script and the one I showed previously is the import statement at the top. Now the ratpack method is a static method in the ratpack.groovy.Groovy class, which Eclipse (actually, Groovy / Grails Tool Suite) can’t find even though it’s in the dependencies.

The next piece of the puzzle is the Gradle build script itself. Ratpack recently changed its package structure and moved its deployed versions to JFrog. Here’s the updated build script:
[sourcecode language=”groovy”]
apply plugin: "ratpack-groovy"

buildscript {
repositories {
maven { url "http://oss.jfrog.org/repo&quot; }
mavenCentral()
}
dependencies {
classpath ‘io.ratpack:ratpack-gradle:0.9.0-SNAPSHOT’
}
}

repositories {
maven { url "http://oss.jfrog.org/repo&quot; }
mavenCentral()
maven { url "http://repo.springsource.org/repo&quot; } // for springloaded
}

dependencies {
compile ‘com.gmongo:gmongo:1.0’
testCompile "org.spockframework:spock-core:0.7-groovy-2.0", {
exclude module: "groovy-all"
}

// SpringLoaded enables runtime hot reloading.
springloaded "org.springsource.springloaded:springloaded-core:1.1.4"
}

task wrapper(type: Wrapper) {
gradleVersion = "1.8"
}
[/sourcecode]
The buildscript block includes the information for downloading the ratpack-groovy plugin, which has changed the group id of the ratpack dependency to io.ratpack. I excluded the groovy-all module from the Spock dependency because it’s already part of the ratpack-groovy plugin, and I updated the Gradle version property in the wrapper to 1.8, but otherwise this is the same as the one generated by lazybones.

Before I run, though, I still want some sort of integration test. Most of the available examples online don’t have any tests (sigh), and I spent far too many hours figuring out how to get one to work, so I’m including it here.
[sourcecode language=”groovy”]
package com.kousenit

import ratpack.groovy.test.LocalScriptApplicationUnderTest
import ratpack.groovy.test.TestHttpClient
import spock.lang.Specification

class ServerIntegrationSpec extends Specification {

def aut = new LocalScriptApplicationUnderTest()
@Delegate TestHttpClient client = aut.httpClient()

def setup() {
resetRequest()
}

def "regular get request returns Chuck Norris string"() {
when:
String result = get(‘/’).asString()

then:
println result
result.contains(‘Chuck Norris’)
}

def "firstName and lastName parameters work"() {
when:
def response = get(‘?firstName=Carlos&lastName=Ray’)?.asString()

then:
println response
response.contains(‘Carlos Ray’)
}
}
[/sourcecode]
As with most Spock tests, the tests themselves are pretty self-explanatory. The hard part was figuring out the proper URLs to invoke and knowing to use the asString method, which wasn’t obvious at all. I’m also not clear on the mechanism used to get the TestHttpClient instance, but I’m sure Luke Daley will explain it to me when I see him next. 🙂

One last quirk should be noted for anyone trying to duplicate this. To run the server, I type:

> gradle run

which starts up the server on port 5050. Access the server using http://localhost:5050 or http://localhost:5050/firstName=Carlos&lastName=Ray and you’re all set.

For some reason, the script that runs the app requires the ratpack.groovy script to be located in the src/ratpack folder. If I want to run the tests, however,

> gradle test

then I have to have the ratpack.groovy file in the root of the project. I have no idea why, nor do I know how to configure them so I only need one and not the other, so I just copied the file into both locations.

(I know — that’s ugly and awkward. I promise to fix it when find out why it’s necessary in the first place.)

So, at long last, if you want the code, it’s all stored in my GitHub repository at https://github.com/kousen/cnjokeserver. Feel free to clone it and wreak whatever havoc upon it you desire.

——-

For those who might be interested, a few notes about my book, Making Java Groovy:

  • The book page at Amazon now has 24 reviews. All are four or five stars but one, which is extremely gratifying. More importantly, the text of each makes it clear that the book is finding its intended audience: Java developers who want to make their jobs easier by adding Groovy.
  • The lone three-star review doesn’t say anything bad about the book anyway, so at least I’ve got that going for me, which is nice.
  • If you get the book at Amazon rather than at Manning, you can still get the ebook versions (pdf, mobi, and epub). The mechanism to do so is included in an insert in the book.
  • The response to my silly marketing ideas in my last couple of posts has been silence punctuated by the occasional cricket, so I’m going to stop doing that unless something really good occurs to me. Oh well. They made me laugh during the writing process, and anything that keeps you writing is a Good Thing(TM).
Categories
Groovy

Making Java Groovy: A Celebrity (Non-)Endorsement

Several of my book author friends on the No Fluff, Just Stuff tour told me that writing a book would open doors for me. That doesn’t explain, though, why I seem to insist on climbing through windows.

I mean, writing Making Java Groovy put me on the NFJS tour, helped me become a speaker at Gr8 conf, DevNexus, and JavaOne*, gave me lots of new professional contacts, and means my author page at Amazon has some actual content. Sweet. But I’m always wondering what else I can do with it that most authors are too experienced, too normal, or maybe just too sane to consider.

*My evals so far from my presentation at JavaOne have been really good, so I’m still hoping that I’m awarded JavaOne Rock Star status. I totally want to party like a JavaOne rock star, party like a JavaOne rock star, etc.

For example, there are certain people that I only know through Twitter or other online media who I would live to meet. As one of my Silly Marketing Ideas (abbreviated SMI, as opposed to my Serious Marketing Ideas, abbreviated SMI), I thought if I could get one or more of them to endorse my book, that would be seriously cool, not to mention whatever it did for sales.

Of course, the silly part is that most of the people I want to approach aren’t even developers, to say nothing of Java people. If you place all this in a larger context, I call this entire effort an “experiment in accidental celebrity”, meaning I want to achieve D-List Twitter Celebrity status, but only if I can do the whole thing as a gag and blog about it here.

To that end, a couple weeks ago I chose four of the people I would love to meet somehow and sent them individualized emails.

That’s a long shot, since I’m sure the people I contacted get flooded with emails on a regular basis. Still, I had to start somewhere, and it’s not like I have a budget for this or anything.

What I do have is a set of author copies for my book. I showed the set in my last blog post when I arranged them on the coffee table in our living room:
coffeetablebook

After giving away a few to friends and family, I decided that I could part with a few more if they acted as my introduction to unsuspecting victims I wanted to meet. If they ultimately decided they loved the book, or even just the joke itself, and wanted to endorse it, so much the better.

One of the people I contacted was a person I truly enjoy and admire, Wil Wheaton. If you lost track of him after Stand By Me and his classic role as the much-loathed-but-not-his-fault-he-was-stuck-with-those-lines Wesley Crusher from Star Trek: The Next Generation, then you’ve missed a lot (here’s his IMDB page). His blog is excellent. I read his Just a Geek book, which I really enjoyed, and his Memories of the Future, Volume 1 book is among the funniest I’ve ever read. My wife and I have also enjoyed his guest appearances on Eureka, Criminal Minds, Leverage, and, of course, The Big Bang Theory.

He’s also great on Twitter, under the handle @wilw. If you follow him, be sure to also follow his wife, @AnneWheaton. I often say that following Wil is fun and following Anne is fun, but following both together is wonderful.

As I said, I ultimately mustered up my courage (which meant suppressing the nauseous feeling that this was not only particularly silly, but actively embarrassing), dug up his email address, and sent him a message. To summarize the message, I:

  • explained who I was and that I had just published a book
  • mentioned I was a fan and personalized the evidence enough to prove I wasn’t kidding
  • explained that this was a Silly Marketing Idea which he was free to ignore but gave me a hopefully non-creepy opportunity to contact him directly
  • asked him for a mailing address so I could send him a signed copy of my book

I didn’t get anything back right away, but I didn’t really expect to. I imagine he is inundated with email, and I’m sure I was one of millions. I expected that I would have to resend it roughly once a week to see what would happen**.

**I got that idea from The Shawshank Redemption. Andy sent a request for money to the town council once a week for two years until they finally realized he wouldn’t go away and sent some money for his prison library. I’ve always wondered about that, by the way. Did he send the same letter, or did he rewrite it each time? Did he vary the wording or the basic content? How did he keep from letting his annoyance or anger at being ignored seep into the letter? Neither the movie nor the original Stephen King story get into details.

Then, however, fate took hold. On 10/17, Anne Wheaton tweeted:

Anne Witchon ‏@AnneWheaton 17 Oct
Texas tweety buddies! 10/17 Austin: bit.ly/WilPSAustin
10/18 Houston: bit.ly/WilPSHouston
10/20 Dallas: bit.ly/WilPSDallas”

I knew I was traveling to Dallas this week, but it suddenly occurred to me his show was on Sunday and I was flying in on the same day. I checked my flight arrangements and realized I could actually make the show. I quickly bought a ticket online (not many were left, but I only needed one), donned my Star Trek polo shirt (the blue science officer one I use when I’m making Groovy presentations about the Spock testing framework) and drove over to the Granada Theater.

I brought a book with me, of course, but I didn’t sign it because I wasn’t sure I actually was going to meet Wil. I’m not the sort of person who goes to conventions, or even events like this, so I don’t really know how they work. In fact, I almost didn’t go at all***, because I was very tired after the flights and didn’t particularly want to leave my hotel room after I arrived. I went anyway, of course, or this would be a much shorter blog post.

***I know my wife Ginger will be shocked, SHOCKED! to hear that.

The show was called Wil Wheaton vs Paul and Storm. Here’s the poster:

wilwheatonpaulandstorm_400

I have to admit that I didn’t know Paul and Storm at all, except from Wil or Anne’s tweets about them. I knew they were a musical / comedy duo who wrote their own funny songs, but that’s about it.

Here’s the marquee from the theater:
granadatheater

The show was a blast. Before the show, the theater used a Twitter site that showed all tweets directed to the theater. I don’t remember many, but among the funniest were things like:

– What does the FOX say? Sorry we canceled Firefly

– Told my blind date I was the guy with the beard wearing a funny T-shirt. Crap.

– [Paul of Paul and Storm] Hanging out with this girl who was supposed to meet some guy with a beard and a funny T-shirt. Playing it cool…

Wil introduced the show, saying that any and all recordings were allowed as long as they were released under the Creative Commons license (“and if you don’t know what that is, ask a nerd and he’ll explain it to you in far more detail than you ever wanted”), but not to use flash photography because that distracted the performers and not to do anything to interfere with other audience members.

“In short,” he said, using one of his signature catch phrases, “Don’t Be A Dick, and you’ll be fine”.

Paul and Storm did their set first, and it was fantastic. Intelligent people tend to be quite clever but not comedian-level funny****. Both Paul and Storm were both. I highly recommend that you check out their website, listen to their music, buy their stuff, and go see them if at all possible. They are masters of the “X is my Y cover band” style of joke. I’d mention some here, but I don’t want to include any spoilers and I can’t remember them anyway. I guess I’ll just have to go see them again.

****I often put myself in that category.

After the intermission, Wil came out and told personal stories in the form of a comedy monologue. There were great (and no spoilers here), but the biggest impression I get from him is I never realized, even reading his Twitter feed, just how filthy he is. Even in his 40s he still looks like this pleasant guy next door, and you don’t expect him to be quite so foul. It works, though. 🙂

Wil and Paul and Storm then came out together and did a few songs filled with random riffs that the audience loved. Here is a link to some pictures from the show.

Here’s a Vine video Paul posted.

Finally, here’s a screen capture from that video showing the audience, with a circle showing me:

audience_at_wilvps

During the entire show, I was holding my book, hoping that I’d get a chance to meet Wil and explain why I was foisting it on him. I also had idle daydreams of him letting me take a picture of him holding it and tweeting it to his 2.4 million followers (!), thinking if only 1% of them bought it…

After the show, a line quickly formed in the lobby. It turned out that the rules were that Wil and Paul and Storm would sign autographs for everybody who wanted one, but that if you wanted a posed picture you’d have to get in the back of the line again.

I didn’t have anything to sign, but the couple in front of me in line gave me a few blank cards from a game called The World of Munchkin, which now gives me a perfect opportunity to show the difference between Paul and Storm and Wil Wheaton. Here are my autographs from Paul and Storm:
paulandstorm

They’re basically illegible, sure, but I’m not one to talk. My signature is appalling. Anyway, here’s what Wil drew:
bagof
Yup. That’s the Wil Wheaton Experience right there.

While he was signing, I gave him my book. I told him I had just published it (“Hey, congratulations!” “Thanks!”), showed him where I had already signed it for him and Anne (“Cool!”), told him that I had sent him email if he was curious about me, and told him what a fan I was (yeah, I talked fast).

The rest of the conversation went something like this:

Wil: Will this help me learn this stuff if I don’t know anything about Java?

Me: Uh, some. Maybe. I’ll be happy to answer questions about it online if you like. That’s what I do. I teach technical training classes. I’ll come back around for a picture, but I was wondering if maybe I could get a picture with the book in it…

Wil: No, I can’t do that. That would be like an endorsement.

Me: (sound of internal imaginary bubble popping) I completely understand.

And I do understand. As I say, this is for fun, and if something else comes of it, fine, but if not, maybe I made an impression on him that the average fan doesn’t.

I did come back around for a picture. As we were setting up, I said:

Me: I meant to tell you that the front matter is pretty funny.

Wil: Great!

Me: Also, do you mind if I blog about this?

Wil: Of course!

Here’s my picture with my new buddies Paul and Storm and Wil and Anne Wheaton:
wilandanneandme
From left to right, that’s Storm, Anne, Me, Wil, and Paul. Or maybe Paul, Anne, Me, Wil, and Storm. (Just kidding. It’s the former. I think. Hey, I bought the USB drive with all their music on it, so I can make one joke at their expense.)

I have to say, I’m still basking in the afterglow. They show was fun, meeting them was fun, and getting the picture was even better. I’m really glad I gave him the book, too, though I have to point out that this does not in any way constitute an endorsement of Making Java Groovy (which is getting really great reviews at Amazon).

Yet. Now if I can only get him to read it…

(Upon re-reading this, it’s starting to sound a bit too mercenary. Look, all I want is my book to last a while, and maybe to make enough money that I can keep doing what I’m doing. It took me 40 years to find my dream job, and now that I have it I don’t want to give it up. Also, it’s kind of fun coming up with silly ideas like this, just to see if I can bring myself to actually do some of them. My next post will get back to technical issues, I promise.)

Categories
Groovy

Making Java Groovy, the Listicle

[Note: I accidentally published this the first time before it was ready. It’s updated now.]

Unlike my previous posts about Making Java Groovy, this post concerns one of my Silly Marketing Ideas (SMI)*. The goal is to break out from the Groovy community and start selling to the larger Java community. Actually, I’m already doing that, so the real goal is to sell to developers in general. Of course, that’s not really enough. The real goal is to have my book become the first Java/Groovy integration book ever to make the New York Times Best Sellers list.

*Naturally, those are as opposed to my Serious Marketing Ideas (SMI).

That’s a somewhat ambitious goal, and to achieve it I’m going to have to appeal to the public at large, including people who have no interest whatsoever in a developer book. The goal of this particular post is to give people who never plan to write a line of code a reason to buy my book anyway.

That brings me to the listicle.

What is a listicle, you say? According to Google, which in this case means Wikipedia, a listicle is “a short form of writing using a list as its thematic structure, but is fleshed out with sufficient copy to be published as an article”. It also has some pretty serious negative connotations on the web, as they’re often displayed one item at a time in order to increase page views, which is basically evil.

This post won’t be like that. Or, rather, it does use a list as the thematic structure, but I’ll put the whole thing here and I’m not making any money from it no matter how it’s presented. In fact, this post was inspired by a tweet in my timeline:

Dan Woods (@danveloper)
“Groovy and Java are like Frodo and Samwise Gamgee, [headed into Mordor] … trying to defeat … clueless managers …” – @kenkousen lol
10/10/13 3:44 PM

(See https://twitter.com/danveloper/status/388389569189539840 for the full version.)

That’s an extract from the preface to my book. At some point I’ll post the whole preface here, but for the record, the full version of that quote is:

Groovy and Java are like Frodo and Samwise Gamgee, headed into the black depths of Mordor, battling privation and despair, desperately trying to defeat the horrible programming challenges that await them, as well as any orcs, Nazgul, or clueless managers they might encounter along the way.

That’s a little dark. Plus, I have no idea what the Ring of Power is in this analogy, or why you’d want to destroy it*.

*I do hope that if you’re holding a print copy of the book (that is, dead-treeware), no Ents were involved.

To segue into the actual purpose of this post, later in the front matter there is a section called “about this book”, and in it I say that, “I expect you are a developer and are at least comfortable with Java”. This is followed by an extensive footnote where I claim that you don’t really need to be a developer, since there are many reasons to buy my book that don’t involve actually reading it.

At long last, that brings me to the listicle that is the real subject of this post. In case you’re already thinking about what to buy your mom for the holidays, let me present:

The Top Ten Ways To Take Advantage Of Making Java Groovy
That Don’t Involve Actually Reading It

10. Prop open a door (a classic)

doorstop

That’s not a great picture of propping open a door, but hopefully it worked for you.

9. Level a table

propuptable

Note especially the use of a coaster to keep from damaging the book cover.

8. Shield against assorted non-lethal weaponry

shield

This is my son Xander’s first appearance in my blog, and note that he managed to stay hidden. The nerf weapon is visible, though.

7. Looks good on your bookshelf

bookshelf

I don’t collect print books like I used to. Most of my books are ebooks these days. Still, I was able to fill out the shelf with as many Groovy-related books as I could find, some of which are getting rather dated. I have the updated books, they’re not in print yet. If you’re in the Groovy community, how many can you identify?

6. Excellent coffee table book

coffeetablebook

This involved actually clearing off the coffee table in the living room, which made my wife Ginger happy.

5. Ugly bug / insect / big, hairy arachnid pulverizer

I’ve never taken a Vine video before. This is my first attempt, which I downloaded as an mp4 file. Hopefully it’s visible.

4. Make a book fort

bookfort

I got Xander to build the fort around a black cat we have on display for Halloween.

3. Learn balance by walking with it on your head

Remember when that used to be a thing? Neither do I, never having been to a “finishing” school, but it made for a decent video.

2. Fan yourself by riffling through the pages

To be honest, Ginger said it was better to just wave the book at herself than breeze through the pages, but so be it.

1. Impress your parents

This one requires some explanation. As the parent of a young adult (and as the child of high-achieving parents), I understand that parents are sometimes more concerned with your financial future than you are. You and I are often more interested in what we’re doing than whether it’s for a productive future.

The point is, sometimes we need a way to convince our parents that we’re making progress, thereby getting the time and space we need to do what we have to do. I’d like to believe my book can help you do that. My resume has always opened doors for me, and if somehow you can take advantage of it, so much the better. So use my book as a way to convince whoever needs convincing that you’re moving into a bold, new, financially lucrative area, whether you really are or not.

Besides, the footnotes are still pretty funny. 🙂