12.9. Project: Mad Dictionaries¶
Let’s use dictionaries to play Mad-Libs!
Note
If you are not familiar with Mad-Libs, you can learn about them here, and then play a few short samples with your friends.
If your teacher added you to a Trinket course, login to your account to access the starter code and complete the project.
Otherwise, use the links below to code in your own free account.
The code runs, but it does not really do anything. Your job is to build three functions that ask the player questions and complete a Mad-Lib.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | def create_madlib_dict(mlib_string):
words = mlib_string.split() # Split string into a list of words.
return {} # Return the new dictionary instead of {}.
def prompt_user_for_words(mad_lib_dict):
answers_dict = mad_lib_dict.copy() # Make an independent copy of the dictionary.
return answers_dict
def create_output(ml_dict, text):
new_text = text # Assign the starting value to new_text.
return new_text
def main():
mad_lib = ''
mlib_dict = create_madlib_dict(mad_lib)
user_responses = prompt_user_for_words(mlib_dict)
output = create_output(user_responses, mad_lib)
main()
|
12.9.1. Part 1: Mad-Lib Text¶
First, you need to create a string that looks something like a Mad-Lib statement.
Mad-Lib sentence with labeled blanks.¶
Instead of blanks, you will use symbols to indicate the words a player needs
to provide. For example, if they need to give a verb for the sentence, "The
turtle ____ home," your string might look like, "The turtle _verb1/ home."
Note the _ and / symbols on each side of the label verb1. We will
use this notation to indicate where the player needs to fill in a blank.
In the starter code, find the
main()function. Assign themad_libvariable a short Mad-Lib type sentence.Your
mad_libtext should contain two or three blanks where the player will need to suggest words. For example:"My _noun1/ colors are _color1/ and _color2/."Here, the player would be asked to give one noun and two colors to complete the sentence.
For now, keep the text simple. You can use more complicated Mad-Lib strings later.
Note
You do not have to use _ and / around a label, but you should use a
different symbol on each side. Just choose symbols that are NOT usually used
in normal text.
Examples:
{noun1}*noun1_^noun1|
12.9.2. Part 2: Build a Dictionary¶
Once you have your mad_lib string ready, the next statement in main()
calls the create_madlib_dict function. The mad_lib string gets passed
in as the argument.
The create_madlib_dict function takes the labels from the string and turns
them into keys for a new dictionary. The function then returns that dictionary.
Code the create_madlib_dict function:
Line 1 defines the function and takes a string as a parameter. Line 2 splits the
mlib_stringinto a list of words.On line 3, print
wordsto see what this list looks like (run the program). Note that the_and/symbols remain with the words we want the player to suggest.['My', '_noun1/', 'colors', 'are', '_color1/', 'and', '_color2/.']
Replace the
printstatement withnew_dict = {}, to create an empty dictionary.Now add a
forloop. It should:Iterate through the
wordslist.Check each word to see if it contains the underscore
_symbol.If
True, take a slice from the word and assign it to a variable. The slice should NOT include the symbols or any punctuation.key = word[1:word.find('/')] # Returns the characters between _ and /
If
True, add a new key/value pair tonew_dict. Usekeyfor the key, and use the empty string as the value.No
elsestatement is required for theif.
Print
new_dictafter the loop to check your progress. Properly done, it should look something like:{'noun1': '', 'color1': '', 'color2': ''}Remove the
printstatement and returnnew_dictfrom the function. This gets assigned to themlib_dictvariable inmain().
12.9.3. Part 3: Query the User¶
OK, now you’re ready to ask the player for the fill-in-the-blank words.
The next statement in main() calls the prompt_user_for_words function
and sends mlib_dict as the argument. We want the function to prompt the
player for each of the words needed in the Mad-Lib.
The function should work something like this:
Prompt the user to fill in the Mad-Lib blanks.¶
The first line in the prompt_user_for_words function creates a copy of the
dictionary you built in part 2. You need to add a loop to replace the values in
the collection with player-supplied words.
Set up a
forloop to iterate through the keys inanswers_dict.Each time the loop repeats, prompt the player to supply one of the missing words. Use the key name as part of the prompt. Note that any numbers in the key name should NOT be displayed in the prompt, so
noun1shows up as justnoun.When the player enters a word, update the dictionary to link the current key to that word. The word should be all lowercase.
Print
answers_dictafter the loop to check your progress. Properly done, the output should look something like:{'noun1': 'school', 'color1': 'salmon', 'color2': 'brown'}'school', 'salmon', and'brown'were the words entered in the console.Remove the
printstatement and returnanswers_dictfrom the function.
Back in the main() function, the returned dictionary gets assigned to the
user_responses variable.
12.9.4. Part 4: Print the Result¶
Almost done! Now you just need to complete the Mad-Lib and display it in the console.
The next statement in main() calls the create_output function and sends
it the user_responses dictionary and the original mad_lib string. These
get assigned to the ml_dict and text parameters in the function.
We want create_output to build and return the final message. The function
will NOT print the message.
Note
Yep. It’s time to use the accumulator pattern again!
Instead of the empty string, the accumulator variable
new_textis assigned the original text. This is important, and you will see why soon. For now, just roll with it.Code a
forstatement to loop throughml_dict.items(). If you need to review this idea, look back at the Loop by Key/Value Pairs section.Inside the loop, paste the following statements:
label = '_' + key + '/' new_text = new_text.replace(label, value)
keyandvalueare the names of the two loop variables.Next, return
new_text, which gets assigned to theoutputvariable inmain().Now check to see if your function produces the expected Mad-Lib. In
main(), add aprintstatement to display the value ofoutputon the screen.Choose a(n) noun: School Choose a(n) color: salmon Choose a(n) color: BROWN My school colors are salmon and brown.
Tip
Why new_text = text instead of new_text = ''? This has to do with
the replace statement in the loop.
Try running the program with
new_text = ''. What do you notice about the output?Try running the program with
new_text = text.replace(label, value)inside the loop. What do you notice about the output?
The replace method creates a new string that swaps one of the labels
(like _noun1/) with a different word. However, if new_text = '',
then the replace method finds nothing to trade. new_text never
becomes anything other than the empty string.
new_text = text.replace(label, value) always uses the unchanged
text string as a starting point, so only the last trade gets saved.
To preserve all of the replacements, new_text needs to start with the
same labels as text, then get reassigned after each change is made.
12.9.5. Part 5: Try Bigger Mad-Libs¶
Now that your program runs, it’s time to play!
Try giving your program a Mad-Lib with more than 2 or 3 blanks to fill.
What happens if you use a label with more than one word, like
_plural noun1/? Is this a code issue, or a label syntax issue?Ask your teacher to play your Mad-Lib game!
12.9.6. Part 6: Bonus Mission¶
What if a Mad-Lib requires a capitalized word?
"The _adjective1/ bus dropped us off in the middle of _city1/."
City names should be capitalized!
Refactor your code to .capitalize() the player’s word whenever the key
name begins with a capital letter.
"The _adjective1/ bus dropped us off in the middle of _City1/."
Choose a(n) adjective: golden
Choose a(n) City: phoenix
The golden bus dropped us off in the middle of Phoenix.
