Advance Mad Libs Generator in Python
About the project:This program code Generates a Mad Libs story with some advanced additional features:
- Multiple Stories/Templates
- Random Word Suggestions
- Error Handling for Input
- Save/Load Stories
- User-Defined Stories
- Score/Rating System
- Clearer Instructions/Examples and
- Looping Play
Project Level: Beginner
You can directly copy the below snippet code with the help of green copy button, paste it and run it in any Python editor you have.
Steps: choose any code snippet and follow these stepsStep 1: Copy below code using green 'copy' button.
Step 2: Paste the code on your chosen editor.
Step 3: Save the code with filename and .py extention.
Step 4: Run (Press F5 if using python IDLE)
# mad_libs_generator.py
import random
import json
import os
# Global Data
# File to save/load user-defined stories and completed stories
STORIES_FILE = "mad_libs_stories.json"
COMPLETED_STORIES_FILE = "completed_mad_libs.json"
# Predefined lists of words for suggestions
WORD_SUGGESTIONS = {
"adjective": ["sparkling", "mysterious", "gigantic", "tiny", "brave", "silly", "ancient", "futuristic", "wobbly", "shiny"],
"noun": ["wizard", "dragon", "castle", "robot", "cat", "mountain", "flower", "spaceship", "shoe", "cloud"],
"verb": ["sing", "dance", "jump", "fly", "eat", "sleep", "run", "whisper", "shout", "explore"],
"adverb": ["quickly", "happily", "slowly", "loudly", "softly", "bravely", "eagerly", "silently", "clumsily", "gracefully"],
"animal": ["lion", "elephant", "penguin", "squirrel", "octopus", "giraffe", "dolphin", "owl", "zebra", "koala"],
"food": ["pizza", "sushi", "taco", "broccoli", "chocolate", "spaghetti", "sandwich", "curry", "pancake", "donut"],
"liquid": ["water", "juice", "soda", "coffee", "milk", "tea", "soup", "nectar", "slime", "potion"],
"emotion": ["happy", "sad", "angry", "excited", "confused", "surprised", "peaceful", "annoyed", "joyful", "nervous"],
"exclamation": ["Wow!", "Ouch!", "Hooray!", "Boo!", "Yippee!", "Aha!", "Oh no!", "Eureka!", "Gasp!", "Indeed!"],
"plural_noun": ["books", "trees", "cars", "friends", "stars", "shoes", "clouds", "monsters", "flowers", "buildings"],
"person_name": ["Alice", "Bob", "Charlie", "Diana", "Eve", "Frank", "Grace", "Harry", "Ivy", "Jack"],
"mythical_creature": ["unicorn", "griffin", "mermaid", "goblin", "fairy", "centaur", "phoenix", "werewolf", "vampire", "gnome"],
"verb_ing": ["running", "jumping", "sleeping", "eating", "flying", "swimming", "laughing", "crying", "thinking", "dreaming"]
}
# Story Management Functions
def get_default_stories():
"""
Returns a dictionary of default Mad Libs stories.
"""
return {
"1": {
"title": "A Day at the Park",
"template": """
Today, I went to the park with my {adjective_1} {noun_1}.
We saw a {adjective_2} {animal_1} {verb_ing_1} {adverb_1} near the {noun_2}.
Then, we decided to {verb_1} on the {adjective_3} {noun_3}.
It was a really {adjective_4} day, and we felt very {emotion_1}.
""",
"placeholders": [
"adjective_1", "noun_1", "adjective_2", "animal_1",
"verb_ing_1", "adverb_1", "noun_2", "verb_1",
"adjective_3", "noun_3", "adjective_4", "emotion_1"
]
},
"2": {
"title": "The Mysterious Journey",
"template": """
Once upon a time, a brave {hero_noun_1} set out on a {adjective_1} journey.
Their mission was to find the {adjective_2} {mythical_creature_1} that lived in the {noun_1} mountains.
Along the way, they had to {verb_1} over a {adjective_3} river and {verb_2} through a {adjective_4} forest.
Finally, they found the {mythical_creature_1} and it said, "{exclamation_1}!"
The {hero_noun_1} returned {adverb_1} and lived {adverb_2} ever after.
""",
"placeholders": [
"hero_noun_1", "adjective_1", "adjective_2", "mythical_creature_1",
"noun_1", "verb_1", "adjective_3", "verb_2",
"adjective_4", "exclamation_1", "adverb_1", "adverb_2"
]
},
"3": {
"title": "The Great Feast",
"template": """
For dinner last night, I ate a {adjective_1} {food_1}.
It was served with {adjective_2} {plural_noun_1} and a side of {liquid_1}.
The chef, a {adjective_3} {person_name_1}, said it was his {adjective_4} creation.
I felt very {emotion_1} after eating it, and decided to {verb_1} all night.
""",
"placeholders": [
"adjective_1", "food_1", "adjective_2", "plural_noun_1",
"liquid_1", "adjective_3", "person_name_1", "adjective_4",
"emotion_1", "verb_1"
]
}
}
def load_stories():
"""Loads user-defined stories from a JSON file."""
if os.path.exists(STORIES_FILE):
try:
with open(STORIES_FILE, 'r') as f:
return json.load(f)
except json.JSONDecodeError:
print(f"Warning: Could not decode {STORIES_FILE}. Starting with no user stories.")
return {}
return {}
def save_stories(stories):
"""Saves user-defined stories to a JSON file."""
with open(STORIES_FILE, 'w') as f:
json.dump(stories, f, indent=4)
print("User stories saved successfully!")
def load_completed_stories():
"""Loads previously completed Mad Libs stories from a JSON file."""
if os.path.exists(COMPLETED_STORIES_FILE):
try:
with open(COMPLETED_STORIES_FILE, 'r') as f:
return json.load(f)
except json.JSONDecodeError:
print(f"Warning: Could not decode {COMPLETED_STORIES_FILE}. Starting with no completed stories.")
return []
return []
def save_completed_story(story_text, title, rating, completed_stories):
"""Saves a completed Mad Libs story to a JSON file."""
completed_stories.append({
"title": title,
"story": story_text,
"rating": rating
})
with open(COMPLETED_STORIES_FILE, 'w') as f:
json.dump(completed_stories, f, indent=4)
print("Your completed story has been saved!")
def view_completed_stories(completed_stories):
"""Displays all previously completed Mad Libs stories."""
if not completed_stories:
print("\nNo completed stories saved yet.")
return
print("\n--- Your Saved Stories ---")
for i, story_data in enumerate(completed_stories):
print(f"\nStory {i+1}: {story_data['title']}")
print(f"Rating: {story_data['rating']} stars")
print(story_data['story'])
print("--------------------------")
def create_new_story():
"""Guides the user through creating a new Mad Libs story template."""
print("\n--- Create Your Own Mad Libs Story ---")
title = input("Enter a title for your new story: ").strip()
while not title:
print("Title cannot be empty.")
title = input("Enter a title for your new story: ").strip()
print("\nNow, type your story. Use curly braces {} for placeholders.")
print("Examples: {adjective_1}, {noun_2}, {verb_ing_3}, {person_name_1}")
print("Type 'END' on a new line when you are finished.")
template_lines = []
while True:
line = input()
if line.strip().upper() == 'END':
break
template_lines.append(line)
template = "\n".join(template_lines)
# Extract placeholders from the template
import re
placeholders = sorted(list(set(re.findall(r'\{(\w+)\}', template))))
if not placeholders:
print("No placeholders found in your story. Please try again.")
return None, None # Indicate failure
print("\nPlaceholders identified in your story:")
for p in placeholders:
print(f"- {p}")
confirm = input("Does this look correct? (yes/no): ").strip().lower()
if confirm != 'yes':
print("Story creation cancelled.")
return None, None
print("New story created successfully!")
return {"title": title, "template": template, "placeholders": placeholders}
# Helper Functions
def get_word_type_prompt(placeholder):
"""
Provides a user-friendly prompt and example based on the placeholder name.
"""
prompt_map = {
"adjective": "adjective (e.g., 'fluffy', 'brave')",
"noun": "noun (e.g., 'cat', 'computer')",
"verb": "verb (e.g., 'run', 'sing')",
"adverb": "adverb (e.g., 'quickly', 'loudly')",
"animal": "animal (e.g., 'dog', 'elephant')",
"food": "type of food (e.g., 'pizza', 'sushi')",
"liquid": "type of liquid (e.g., 'water', 'soda')",
"emotion": "emotion (e.g., 'happy', 'confused')",
"exclamation": "exclamation (e.g., 'Wow!', 'Oh no!')",
"plural_noun": "plural noun (e.g., 'shoes', 'trees')",
"person_name": "person's name (e.g., 'Alice', 'Bob')",
"mythical_creature": "mythical creature (e.g., 'dragon', 'unicorn')",
"verb_ing": "verb ending in -ing (e.g., 'running', 'sleeping')",
}
# Try to find the most specific match
for key, value in prompt_map.items():
if key in placeholder:
return value
return "word" # Fallback for unknown placeholders
def get_random_word(placeholder):
"""
Returns a random word based on the placeholder type.
"""
for word_type in WORD_SUGGESTIONS:
if word_type in placeholder:
return random.choice(WORD_SUGGESTIONS[word_type])
# Fallback if no specific type is matched, pick a random noun
return random.choice(WORD_SUGGESTIONS["noun"])
def get_user_input(prompt_text, placeholder_type):
"""
Gets user input, handles 'suggest' command, and validates for emptiness.
"""
while True:
user_input = input(prompt_text).strip()
if user_input.lower() == 'suggest':
suggested_word = get_random_word(placeholder_type)
print(f"Suggestion: '{suggested_word}'")
confirm_suggestion = input("Use this suggestion? (yes/no): ").strip().lower()
if confirm_suggestion == 'yes':
return suggested_word
else:
print("Please enter your own word.")
elif not user_input:
print("Input cannot be empty. Please try again.")
else:
return user_input
# Game Logic
def play_mad_libs(story_data, completed_stories):
"""
Plays a single round of Mad Libs with the given story data.
"""
print(f"\n--- Playing: {story_data['title']} ---")
print("Please provide the following words (type 'suggest' for a random word):\n")
mad_libs_words = {}
for placeholder in story_data['placeholders']:
prompt_text = f"Enter a {get_word_type_prompt(placeholder)} for '{placeholder}': "
user_input = get_user_input(prompt_text, placeholder)
mad_libs_words[placeholder] = user_input
completed_story = story_data['template'].format(**mad_libs_words)
print("\nHere is your completed Mad Libs story:\n")
print(completed_story)
# Rating system
while True:
try:
rating = int(input("\nHow would you rate this story? (1-5 stars, 5 being best): ").strip())
if 1 <= rating <= 5:
break
else:
print("Please enter a number between 1 and 5.")
except ValueError:
print("Invalid input. Please enter a number.")
# Save completed story
save_completed_story(completed_story, story_data['title'], rating, completed_stories)
def main():
"""
Main function to run the Mad Libs Generator, allowing multiple plays and features.
"""
print("Welcome to the Advanced Mad Libs Generator!")
# Load stories (default + user-defined)
all_stories = get_default_stories()
user_stories = load_stories()
# Merge user stories, ensuring keys don't clash (by appending to existing keys)
next_key = max([int(k) for k in all_stories.keys()] + [0]) + 1
for i, (key, story) in enumerate(user_stories.items()):
all_stories[str(next_key + i)] = story
completed_stories = load_completed_stories()
while True:
print("\n--- Main Menu ---")
print("1. Play a Mad Libs Story")
print("2. Create a New Story")
print("3. View Saved Stories")
print("4. Quit")
choice = input("Enter your choice (1-4): ").strip()
if choice == '1':
print("\nAvailable Stories:")
for key, story in all_stories.items():
print(f" {key}. {story['title']}")
story_choice = input("Enter the number of the story you want to play: ").strip()
if story_choice in all_stories:
play_mad_libs(all_stories[story_choice], completed_stories)
else:
print("Invalid story choice. Please enter a valid number.")
elif choice == '2':
new_story_data = create_new_story()
if new_story_data:
# Add new story to all_stories and save user_stories
next_key = max([int(k) for k in all_stories.keys()] + [0]) + 1
all_stories[str(next_key)] = new_story_data
user_stories[str(next_key)] = new_story_data # Add to user_stories for saving
save_stories(user_stories)
elif choice == '3':
view_completed_stories(completed_stories)
elif choice == '4':
print("Thanks for playing! Goodbye.")
break
else:
print("Invalid choice. Please enter a number between 1 and 4.")
# This ensures that main() is called only when the script is executed directly.
if __name__ == "__main__":
main()
If you like to see simpler version code view Simple Mad Lib Generator