The scene: a "typical" post-Thanksgiving day in New York City in 1953
Leonard: Give me an adjective...
...and with that simple interaction, Mad Libs® were born!
Many of us as children were taken on seemingly unendurable car rides and thought we'd die of boredom. Let's face it, you can play the ABC game for only so many miles. Then someone would pull out a Mad Libs® book and smiles would erupt on everyone's faces as hilarity ensued. These wonderful word games are part of the fabric of Americana, and have also spurred many imitations and comedic references.
(If this doesn't ring a bell, you should read more about them and play some online to get a feel what they are.)
We would like to create some fun, online Mad Libs®. There is real room for creativity here -- the lexical categories can be as standard as nouns, verbs and adjectives or be as creative as professor's name, canned meat, and favorite Monty Python actor. In general, however, the more general your blanks are, the more creative and hilarious your finished story will be.
We want you to randomly generate one of (at least) 5 different Mad Libs® sentences. That is, you'll generate a web page that asks the user for different blanks (you might ask for a noun, verb and adjective the first time, and a verb, adverb and pronoun the second time, etc.) and then sends a form to a python script which creates a Mad Lib® based on the response. Your randomization has to involve the types of lexical categories, and not just different output sentences with the same categories. E.g., you can't always ask for a noun and a verb and have template sentences that just use those two categories, like:
- Officer, I swear the NOUN said I needed to VERB in order to pass the DMV test!
- Momma always told me not to VERB the NOUN
- In order to VERB, one must pet the NOUN first!
square example from the CGI Programming supplementary notes, you saw how one Python program can generate the HTML form to send data to another Python program which parses the arguments (fields) and squares a number. The clever thing is that these can be the same Python program! This is commonly done to encapsulate all of the common code into one file. How does the program know whether it's called the first time (with no arguments) so it should print the "Welcome to my program! Please give me a verb and a noun..." HTML, and when it's called with the two arguments so it should print "Here is your Mad Lib®: Please don't eat the building. Want to play another? Click here!" HTML.
You already know the answer to this! How did
square.cgi get the value from the number? It used the dictionary-like object returned from
cgi.FieldStorage(), right? You already know how to query if a value is in a dictionary using
in, so just use that to see if there were any arguments passed in.
Here's a sample interaction of our program. We've taken screenshots of the web page it generates.
Here are some general tips that may help you in your journey:
- Remember, HTML parsers think anything within angled brackets is a special tag it needs to parse. So, if you are trying to print the type of a particular variable (as in
type(var)which might return <type 'dict'>), you might notice that nothing prints out. One quick fix is to use
repr(), which returns the string representation of an object (type
help(repr)for brief documentation) and then replace the angle brackets with square brackets in the string.
- There's also a handy function called
cgi.escape()that converts text to HTML (it replaces all occurrences of the four characters
- A more general way of displaying something in HTML is to use
pydoc.html.repr, as in:
import pydoc print pydoc.html.repr(whatever)
- There's also a handy function called
- The point above highlights some of the problems and frustrations you might have with debugging CGI programs. You may find it useful to write a log (a feature provided by by
cgitband described in the CGI Programming supplementary notes) instead of dumping errors to the page itself.
- You might notice that you need to pass information about which random Mad Lib® you're playing back to yourself so you can stuff the responses in the right template. If you use
type="hidden"in your input form field, you can pass secret messages to yourself that the user won't see (if they don't look at the URL you generate), like which template you're using. E.g., if you wanted to tell yourself you had just asked the user for the types of speech from template #3, you'd generate the following HTML :
<input type="hidden" name="Mad_Lib_Number" value="3">
- When asking for a VERB, it's usually pretty standard to assume you'll get the infinitive form. Thus, you should generate template sentences that have "to" in front of VERB" in your template.
- To differentiate cases where you may ask for multiple instances of the same part of speech (e.g., NOUN), you should probably internally label them NOUN1, NOUN2, NOUN3, etc. If you try the online Mad Libs®, you'll find yourself providing what seems like 15 nouns! Clearly they did something similar to keep track of all the nouns that were given so they could stuff them in the right place in their template...
- If you're working from home, you might have to read up on your Apache http server's documentation in order to turn on support for
cgi-binprograms. It's configured to be
offby default. If you're working with your instructional account, you should have no problems with this.
- Just to get a sense of the size of the solution, ours comes in under 50 lines.
Test each function in your program with enough different inputs to show that it works. When testing a function, print out the input, the expected result, and the actual result.
There are a couple of cool features you can add to make your program sing:
- Simulate paper. Some of the fun of the paper Mad Libs® are that you can see what the blanks were asking for and what the responses were written in pen. To simulate this, you'd have to use a handwriting-looking font in blue "pen" color written on blanks with the requested lexical categories below. Your result should look exactly like a filled-in paper Mad Libs® would.
- Auto-generated Mad Libs®. This would involve subdividing a dictionary of words into the various lexical categories and then running them through your templates.
- Go category mad! Take a look at some of the original Mad Libs®. They add categories like: EXCLAMATION, PLURAL NOUN, VERB (PAST TENSE), PLACE, STATE-OF-BEING, etc.
- Nerdify the problem. Use computer categories, like: "I just bought a COMPUTER_PART from COMPUTER_COMPANY, and the directions said to VERB the ANOTHER_PART into the AGAIN_ANOTHER_PART ADVERB until it PAST_TENSE_COMPUTER_VERB"
- Flip the problem on its head! Instead of asking them for the parts of speech, ask them for the Mad Libs® template (e.g., "I'm sorry I don't have my homework today. My NOUN ate my NOUN ADVERB") and have your program fill in the answer!
These are the requirements to meet for project completion.
- Use of functions — your program must be broken down into one or more functions — it cannot be one big long script.
- Each function has a docstring that summarizes its purpose and provides a description of its inputs and outputs.
- Tests and test output for each function in the program.
- All functions and variables have meaningful names.
- Tests showing the program generates at least five different Mad Libs® that have different lexical categories.