A Mad Libs generator is one of the best first projects for any Python beginner. It combines four fundamental skills -- variables, the input() function, string concatenation, and f-strings -- into a single, satisfying program that produces a different silly story every time it runs. This tutorial walks through the entire build from an empty file to a working game.
Mad Libs is a fill-in-the-blank word game. One player asks another for random words -- a noun, a verb, an adjective, a place -- without revealing the story. The words are then inserted into a template, and the result is usually absurd and funny. A Python version of this game uses the input() function to ask for words, stores them in variables, and plugs them into a story string using f-strings or concatenation.
By the end of this tutorial, you will have a working Mad Libs program and a solid understanding of how Python handles user input and string formatting.
Gathering Words with input()
The input() function is Python's built-in tool for reading text from the keyboard. When Python reaches an input() call, it pauses the program, optionally displays a prompt message, and waits for the user to type something and press Enter. The text the user types is returned as a string, which you can store in a variable.
name = input("Enter your name: ")
print(name)
In this example, the string "Enter your name: " is the prompt. It appears on screen, and the program waits. Once the user types a name and presses Enter, that name is stored in the variable name. The print() function then displays it.
The input() function always returns a string, even if the user types a number. If you need a numeric value, you must convert it with int() or float(). For a Mad Libs game, strings are exactly what we want, so no conversion is necessary.
For a Mad Libs generator, you need several input() calls, one for each blank in the story. Give each variable a descriptive name that matches the word type you are requesting.
# Collect words for the Mad Libs story
adjective = input("Enter an adjective: ")
noun = input("Enter a noun: ")
verb = input("Enter a verb (past tense): ")
place = input("Enter a place: ")
number = input("Enter a number: ")
Notice the trailing space inside each prompt string (for example, "Enter an adjective: "). That space separates the prompt from whatever the user types, making the interaction look cleaner in the terminal.
Build a line that asks the user for a color and stores it in a variable called color:
Building the Story with f-Strings and Concatenation
Once you have gathered words from the user, you need a way to insert them into a story. Python gives you two main approaches: f-strings (formatted string literals) and string concatenation with the + operator.
String Concatenation with the + Operator
Concatenation joins strings together end to end. You use the + operator between each piece, and you must manually include spaces or punctuation.
adjective = "sparkly"
noun = "piano"
story = "The " + adjective + " " + noun + " flew across the sky."
print(story)
# Output: The sparkly piano flew across the sky.
Concatenation works, but it gets messy quickly. Every space needs its own string literal (" "), and the code becomes harder to read as the sentence grows.
f-Strings: The Modern Approach
An f-string is a string prefixed with the letter f before the opening quotation mark. Inside an f-string, any Python expression placed within curly braces {} is evaluated at runtime and inserted directly into the string. F-strings were introduced in Python 3.6 through PEP 498 and are now the preferred way to format strings.
adjective = "sparkly"
noun = "piano"
story = f"The {adjective} {noun} flew across the sky."
print(story)
# Output: The sparkly piano flew across the sky.
The f-string version reads like a natural sentence. The curly braces mark where each variable goes, and Python handles the rest. No manual spaces, no + signs, and far fewer opportunities for mistakes.
- Syntax
"Hello " + name + "!"- Pros
- Works in all Python versions; simple for two strings
- Cons
- Requires manual spaces; hard to read with many variables; slower for large joins
- Syntax
f"Hello {name}!"- Pros
- Highly readable; supports expressions inside braces; faster than .format() and %
- Cons
- Requires Python 3.6 or later
- Syntax
"Hello {}!".format(name)- Pros
- Works in Python 2.6+; supports named and positional placeholders
- Cons
- More verbose than f-strings; slightly slower
For multi-line stories, use a triple-quoted f-string. Start with f""" and end with """. This lets you write the story template across multiple lines without needing backslash-n (\n) escape characters.
This Mad Libs snippet should print a sentence using the user's word. One line has a bug that prevents the variable from being inserted. Find it.
f prefix before the opening quote: f"The {animal} ate {food} for lunch.". Without the f, Python treats {animal} and {food} as literal text, not as variable placeholders. The output would be the string The {animal} ate {food} for lunch. instead of the user's words.The Complete Mad Libs Program
Now it is time to put everything together. The program below asks for six words, inserts them into a story template using an f-string, and prints the result. You can copy this code, run it in any Python 3.6+ environment, and get a working Mad Libs game immediately.
# Mad Libs Generator
# Collect words from the user
adjective = input("Enter an adjective: ")
noun = input("Enter a noun: ")
verb_past = input("Enter a verb (past tense): ")
place = input("Enter a place: ")
food = input("Enter a food: ")
number = input("Enter a number: ")
# Build the story with an f-string
story = f"""Last summer, a {adjective} {noun} {verb_past} all the way
to {place}. When it arrived, it ordered {number} plates
of {food} and didn't share a single bite. The locals
still talk about the {adjective} visitor to this day."""
# Display the finished story
print("\n--- Your Mad Libs Story ---")
print(story)
When you run this program, it might look something like this in the terminal:
Enter an adjective: fuzzy
Enter a noun: cactus
Enter a verb (past tense): danced
Enter a place: Antarctica
Enter a food: spaghetti
Enter a number: 47
--- Your Mad Libs Story ---
Last summer, a fuzzy cactus danced all the way
to Antarctica. When it arrived, it ordered 47 plates
of spaghetti and didn't share a single bite. The locals
still talk about the fuzzy visitor to this day.
Every run produces a different story because the user supplies different words each time. That is the entire concept behind Mad Libs, and you have just built one from scratch.
How the Program Works, Line by Line
The first six lines each call input() with a descriptive prompt and store the returned string in a variable. The variable names (adjective, noun, verb_past, place, food, number) match the word types the prompts request. The story is a triple-quoted f-string, which means it can span multiple lines without escape characters. Each pair of curly braces contains a variable name, and Python replaces it with the corresponding value at runtime. Finally, print() displays the finished story. The \n before the heading line adds a blank line in the terminal for visual separation.
Forgetting the f prefix is the single most common error when working with f-strings. Without it, Python prints the literal text {adjective} instead of the variable's value. If your Mad Libs output shows curly braces, check that the string starts with f" or f""".
How to Build a Mad Libs Generator in Python
Follow these four steps to create a working Mad Libs game from scratch.
Collect words from the user with input()
Use the
input()function to prompt the user for each word type your story needs, such as a noun, verb, adjective, and place name. Store each response in a descriptive variable.Write a story template with placeholder variables
Create a multi-line string that tells a short story. Use f-string syntax with curly braces to mark where each user-supplied word should appear.
Print the completed story
Pass the f-string to the
print()function. Python substitutes each variable with the word the user entered and displays the finished Mad Libs story.Run and test the program
Execute the script in a terminal or IDE. Enter words at each prompt and read the generated story. Adjust the template or add more prompts to make the game more entertaining.
"The existing ways of formatting are either error prone, inflexible, or cumbersome." — PEP 498, Python Enhancement Proposals
Python Learning Summary Points
- The
input()function pauses the program, displays a prompt, and returns whatever the user types as a string. For a Mad Libs generator, you call it once for each blank in your story and store each result in a descriptively named variable. - F-strings (formatted string literals, prefixed with
f) let you embed variables and expressions directly inside a string using curly braces. Introduced in Python 3.6 through PEP 498, they are more readable and faster than both the+concatenation operator and the older.format()method. - String concatenation with
+joins strings end to end but requires manual spaces and becomes hard to read with many variables. Use it for simple two-string joins; prefer f-strings for anything longer. Together,input(), variables, and f-strings give you everything you need to build interactive text-based programs.
Try extending the generator: add more blanks, write a second story template, or wrap the whole program in a while loop so the user can play again without restarting the script.
Frequently Asked Questions
A Mad Libs generator is a simple Python program that asks the user for words like nouns, verbs, and adjectives using the input() function, then inserts those words into a pre-written story template. The result is a funny, nonsensical paragraph. It is a popular beginner project because it teaches variables, user input, and string formatting.
The input() function pauses the program, displays an optional prompt message, waits for the user to type something and press Enter, then returns whatever the user typed as a string. The returned string can be stored in a variable for later use.
An f-string (formatted string literal) is a string prefixed with the letter f before the opening quotation mark. Inside an f-string, you can place any Python expression inside curly braces {} and it will be evaluated and inserted into the string at runtime. F-strings were introduced in Python 3.6 and are the preferred way to format strings.
String concatenation is the process of joining two or more strings together using the + operator. For example, 'Hello' + ' ' + 'World' produces 'Hello World'. While it works for simple cases, f-strings are generally preferred for readability when combining strings with variables.
The input() function always returns a string because it captures raw text from the keyboard. Even if the user types a number like 42, input() returns the string '42', not the integer 42. To use the value as a number, you must convert it using int() or float().
Yes. String concatenation with the + operator and f-strings both produce the same result. However, f-strings are generally more readable and less error-prone, especially when a string contains many variables. Concatenation requires manually adding spaces and is harder to read as strings grow longer.
The print() function displays text to the screen and returns None. The input() function displays an optional prompt, pauses the program to wait for the user to type something, and returns the typed text as a string. print() is for output; input() is for input.
Use the escape character \n inside a string to create a new line. For example, print('Line one\nLine two') prints Line one on the first line and Line two on the second line. You can also use triple-quoted strings for multi-line text.
F-strings require Python 3.6 or later. If you are using an older version, you can use the .format() method or the % operator for string formatting instead. Python 3.12 further improved f-strings by removing earlier restrictions on nested quotes and backslashes inside expressions.
You can extend a Mad Libs generator by adding more word prompts, creating multiple story templates and letting the user choose one, reading templates from a text file, using lists and the random module to pick words automatically, or adding a loop so the user can play again without restarting the program.