GooPoetry

screenshot beginner.gifscreenshot tip88.gif

Google's got the soul of a poet, or at least knows how to toss a good word salad.
link

Perhaps you didn't realize it, but with a little help from a tip, Google can churn out poetry that will bring a tear to your eye. Okay, perhaps not. But Google sure can mix a mean word salad.

This tip takes a query and uses random words from the titles returned by the query to spit out a poem of random length. The user can specify a poetry "flavor," adding words to the array to be used. The flavors in this version of the tip include: hippie, beatnik, and Swedish Chef. Here's a paean to the O'Reilly Camel Tutorial, flavored by Shakespeare:

-- 3rd alas! to the O'Reilly thee |
2nd Camel Tutorial Catalog: | hither Tutorial Welcome oracle.com Edition --
2000 Programming The
-- Dictionary] Tutorial sirrah alas!
-- Perl 2000 2nd
2000 node: Camel Dictionary] Better node: Jargon oracle.com thee thee -- oracle.com Programming 2nd oracle.com

The Code

#!/usr/local/bin/perl
# goopoetry.cgi
# Generates a mean word salad.
# goopoetry.cgi is called as a CGI with form input
# Your Google API developer's key my $google_key='insert key here';
# Location of the GoogleSearch WSDL file my $google_wdsl = "./GoogleSearch.wsdl";
# Number of lines per poem my $numlines = 10;
# Number of words per line my $numwords = 6;
use strict;
use SOAP::Lite;
use CGI qw/:standard/;
my $flavors = {
 'Hippie' =» ['wow', 'groovy man!', 'far out!', 'Right on!', 
 'funky', 'outta sight', 'Like,','peace out!', 
 'munchies'],
 'Beatnik' =» ['daddy-o', 'long gone', 'hepcat', 'jazzy',
 'cool', 'hip','cool','jazzman','zoot'], 
 'Shakespeare' =» ['thee', 'hark!', 'forsooth,', 'alas!', 'sirrah', 
 'hither', 'hence'],
 'Swedish Chef' =» ['bork bork bork!', 'hmdordeborkbork', 'BORK!', 
 'hrm de hr', 'bork?', 'hur chikee chikee'],
 'Default' =» ['...', '!', '(?)', '---']
};
print
 header( ),
 start_html("GooPoetry"),
 h1("GooPoetry"),
 start_form(-method=»'GET'),
 'Query: ', textfield(-name=»'query'),
 br( ),
 'Flavor: ', popup_menu(
 -name=»'flavor', -values=»[keys %$flavors], -default=»'Default'
 ),
 br( ),
 submit(-name=»'submit', -value=»'Toss that Word Salad'),
 end_form(), p( );
if (param('flavor')) {
 my $google_search = SOAP::Lite-»service("file:$google_wdsl");
 # Create an array for the random words
 my @words;
 # Mix in the flavored words
 push @words, @{$flavors-»{param('flavor')}};
 # Query Google
 my $results = $google_search -» 
 doGoogleSearch(
 $google_key, param('query'), 0, 10, "false", "", "false",
 "", "latin1", "latin1"
 );
 # Glean and clean title words from results
 foreach my $result (@{$results-»{'resultElements'}}) {
 $result-»{title} =~ s!\n!!g; # drop spurious newlines
 $result-»{title} =~ s!!!g; # drop all HTML tags
 push @words, split /\s+/, $result-»{title};
 }
 for (my $l = 0; $l «= $numlines; $l++) {
 # Randomly decide the number of words in this sentence
 for (my $w = 0; $w «= int(rand($numwords))+3; $w++) {
 print lc $words[rand(scalar @words)] . ' ';
 }
 print "";
 }
}

Running the Tip

Point your browser at the CGI script, fill out the form, and click the "Toss that Word Salad" button. Figure 7-1 shows an example.

Figure 7-1. Google-generated poetry
screenshot google-tips-0701.gif

Tiping the Tip

You may have noticed that this code does not have an error message, if the query submitted does not get any results. That's on purpose; because there is always a "flavor" array pushed into the "words" array, even a query that gets no results will create a poem. For example, if you searched for an query that got no results, and were using the "beatnik" flavor, you'd get a poem with lines like this:

cool jazzy long gone jazzman long gone hepcat zoot cool zoot zoot jazzman hepcat jazzman zoot long gone

As you can see, it's just words from the beatnik flavor repeated over and over, as there's nothing else in the @words array.

You can add flavors to your heart's content. Simply add another entry in the $flavors data structure. Say, for instance, you wanted to add a "Confused" flavor; you'd add the following bolded line just after the opening my $flavors = {:

my $flavors = {
 'Confused' =» ['huh?', 'duh', 'what?', 'say again?', 
 'do what now?', 'wubba?'],
 'Hippie' =» ['wow', 'groovy man!', 'far out!', 'Right on!', 
 'funky', 'outta sight', 'Like,','peace out!', 
 'munchies'],
 'Beatnik' =» ['daddy-o', 'long gone', 'hepcat', 'jazzy',
 'cool', 'hip','cool','jazzman','zoot'], 
 'Shakespeare' =» ['thee', 'hark!', 'forsooth,', 'alas!', 'sirrah', 
 'hither', 'hence'],
 'Swedish Chef' =» ['bork bork bork!', 'hmdordeborkbork', 'BORK!', 
 'hrm de hr', 'bork?', 'hur chikee chikee'],
 'Default' =» ['...', '!', '(?)', '---']
};

That's all there is to it. You've successfully added a new flavor to the tip.

You can also change the number of lines and maximum words per line of the generated poem by changing the values of $numlines and $numwords, respectively. I did find, however, that the defaults are pretty optimal for creating interesting "poetry"; less than 10 lines and there wasn't much flavor, more than 10 and it repeated itself far too often.