How to ask for only the variables necessary to the story in MadLib in Python

174 views Asked by At

I'm sorry if this has been answered elsewhere. I am a 100% beginner. I am working my way through codeacademy and one of the projects was a Madlib. I have since transferred it over to visual studio and done a few myself from scratch. I had the idea to just create a massive baseline MadLib so that all I would have to do is write out the story with the proper necessary variables. When I run this program it works, but it asks for every single input. How do I get the program to only ask for the specific variables that I need for the story? Thanks in advance and here is the code.

""" Newscast MadLib by Salem
"""

print ("Here comes a MadLib yall!!!")

noun1 = input("Enter a Noun: " )
noun2 = input("Enter a Noun: " )
noun3 = input("Enter a Noun: " )
noun4 = input("Enter a Noun: " )
noun5 = input("Enter a Noun: " )
adj1 = input("Enter an Adjective: ")
adj2 = input("Enter an Adjective: ")
adj3 = input("Enter an Adjective: ")
adj4 = input("Enter an Adjective: ") 
adj5 = input("Enter an Adjective: ")
verb1 = input("Enter a Verb: ")
verb2 = input("Enter a Verb: ")
verb3 = input("Enter a Verb: ")
verb4 = input("Enter a Verb: ")
verb5 = input("Enter a Verb: ")
adv1 = input("Enter a Adverb: ")
adv2 = input("Enter a Adverb: ")
adv3 = input("Enter a Adverb: ")
adv4 = input("Enter a Adverb: ")
adv5 = input("Enter a Adverb: ")
verbing1 = input("Enter a Verb ending in ing: ")
verbing2 = input("Enter a verb ending in ing: ")
verbing3 = input("Enter a verb ending in ing: ")
verbs1 = input("Enter a verb ending in S: ")
verbs2 = input("Enter a verb ending in S: ")
verbs3 = input("Enter a verb ending in S: ")
pnoun1 = input("Enter a Proper Noun: ")
pnoun2 = input("Enter a Proper Noun: ")
pnoun3 = input("Enter a Proper Noun: ")
pnoun4 = input("Enter a Proper Noun: ")
pnoun5 = input("Enter a Proper Noun: ")
plnoun1 = input("Enter a Plural Noun: ")
plnoun2 = input("Enter a Plural Noun: ") 
plnoun3 = input("Enter a Plural Noun: ")
plnoun4 = input("Enter a Plural Noun: ")
plnoun5 = input("Enter a Plural Noun: ")
body1 = input("Enter a Body Part: ")
body2 = input("Enter a Body Part: ")
body3 = input("Enter a Body Part: ")
body4 = input("Enter a Body Part: ")
body5 = input("Enter a Body Part: ")
bodypl1 = input("Enter a part of the body Plural: ")
bodypl2 = input("Enter a part of the body Plural: ")
bodypl3 = input("Enter a part of the body Plural: ")
emotion1 = input("Enter an Emotion: ")
emotion2 = input("Enter an Emotion: ")
emotion3 = input("Enter an Emotion: ")
historicm1 = input("Enter a Historic Monument: ")
historicm2 = input("Enter a Historic Monument: ")
mansname1 = input("Enter a Mans Name: ")
mansname2 = input("Enter a Mans Name: ")
womname1 = input("Enter a Womans Name: ")
womname2 = input("Enter a Womans Name: ")
occup1 = input("Enter an Occupation: ")
occup2 = input("Enter an Occupation: ")
occup3 = input("Enter an Occupation: ")
shape1 = input("Enter a Shape: ")
shape2 = input("Enter a Shape: ")
shape3 = input("Enter a Shape: ")
rest1 = input("Enter a Restaurant Name: ")
rest2 = input("Enter a Restaurant Name: ")
rest4 = input("Enter a Restaurant Name: ")
liquid1 = input("Enter a type of Liquid: ")
liquid2 = input("Enter a type of Liquid: ")
personir1 = input("Enter the name of someone in the room: ")
personir2 = input("Enter the name of someone in the room: ")
personir4 = input("Enter the name of someone in the room: ")
food1 = input("Enter a type of Food: ")
food2 = input("Enter a type of Food: ")
food3 = input("Enter a type of Food: ")
fperson1 = input("Enter the name of a famous person: ")
fperson2 = input("Enter the name of a famous person: ")
fperson3 = input("Enter the name of a famous person: ")
sword1 = input("Enter a Silly Word: ")
sword2 = input("Enter a Silly Word: ")
sword3 = input("Enter a Silly Word: ")
num1 = input("Enter a Number: ")
num2 = input("Enter a Number: ")
num3 = input("Enter a Number: ")
num4 = input("Enter a Number: ")
num5 = input("Enter a Number: ")
place1 = input("Enter a Place: ")
place2 = input("Enter a Place: ")
place3 = input("Enter a Place: ")
place4 = input("Enter a Place: ")
place5 = input("Enter a Place: ")


story = ("Putting on a newscast might look easy, but it takes a lot of %s work. Go behind the scenes, and you will see dozens of %s workers %s in every direction! Reporters run back and forth between the studio and locations all around %s to cover %s stories and interview %s . They are joined by videographers who operate handheld %s to capture all the action. The anchors are the people who %s behind the news desk and read the stories during the newsccast. They have to look %s on air, so they can often be found getting makeup applied to their %s . The director tells everyone where and when to %s . Its easy to spot a director because he wears a headset on his %s and yells things like CAMERA TWO and %s ! A newscast is live television so if you make aor an %s mistake, everyone watching at home on their %s will know!")

    story = story % (adj1, adj2, verbing1, place1, adj3, plnoun1, plnoun2, verb1, adj4, bodypl1, verb2, 
    body1, sword1, adj5, plnoun3)

    print (story)

I am struggling with this lol, I appreciate all the help. This is the revision

    """ Newscast MadLib by Salem
"""

print ("Here comes a MadLib yall!!!")


noun1 = input("Enter a Noun: " )
noun2 = input("Enter a Noun: " )
noun3 = input("Enter a Noun: " )
noun4 = input("Enter a Noun: " )
noun5 = input("Enter a Noun: " )
adj1 = input("Enter an Adjective: ")
adj2 = input("Enter an Adjective: ")
adj3 = input("Enter an Adjective: ")
adj4 = input("Enter an Adjective: ") 
adj5 = input("Enter an Adjective: ")
verb1 = input("Enter a Verb: ")
verb2 = input("Enter a Verb: ")
verb3 = input("Enter a Verb: ")
verb4 = input("Enter a Verb: ")
verb5 = input("Enter a Verb: ")
adv1 = input("Enter a Adverb: ")
adv2 = input("Enter a Adverb: ")
adv3 = input("Enter a Adverb: ")
adv4 = input("Enter a Adverb: ")
adv5 = input("Enter a Adverb: ")
verbing1 = input("Enter a Verb ending in ing: ")
verbing2 = input("Enter a verb ending in ing: ")
verbing3 = input("Enter a verb ending in ing: ")
verbs1 = input("Enter a verb ending in S: ")
verbs2 = input("Enter a verb ending in S: ")
verbs3 = input("Enter a verb ending in S: ")
pnoun1 = input("Enter a Proper Noun: ")
pnoun2 = input("Enter a Proper Noun: ")
pnoun3 = input("Enter a Proper Noun: ")
pnoun4 = input("Enter a Proper Noun: ")
pnoun5 = input("Enter a Proper Noun: ")
plnoun1 = input("Enter a Plural Noun: ")
plnoun2 = input("Enter a Plural Noun: ") 
plnoun3 = input("Enter a Plural Noun: ")
plnoun4 = input("Enter a Plural Noun: ")
plnoun5 = input("Enter a Plural Noun: ")
body1 = input("Enter a Body Part: ")
body2 = input("Enter a Body Part: ")
body3 = input("Enter a Body Part: ")
body4 = input("Enter a Body Part: ")
body5 = input("Enter a Body Part: ")
bodypl1 = input("Enter a part of the body Plural: ")
bodypl2 = input("Enter a part of the body Plural: ")
bodypl3 = input("Enter a part of the body Plural: ")
emotion1 = input("Enter an Emotion: ")
emotion2 = input("Enter an Emotion: ")
emotion3 = input("Enter an Emotion: ")
historicm1 = input("Enter a Historic Monument: ")
historicm2 = input("Enter a Historic Monument: ")
mansname1 = input("Enter a Mans Name: ")
mansname2 = input("Enter a Mans Name: ")
womname1 = input("Enter a Womans Name: ")
womname2 = input("Enter a Womans Name: ")
occup1 = input("Enter an Occupation: ")
occup2 = input("Enter an Occupation: ")
occup3 = input("Enter an Occupation: ")
shape1 = input("Enter a Shape: ")
shape2 = input("Enter a Shape: ")
shape3 = input("Enter a Shape: ")
rest1 = input("Enter a Restaurant Name: ")
rest2 = input("Enter a Restaurant Name: ")
rest4 = input("Enter a Restaurant Name: ")
liquid1 = input("Enter a type of Liquid: ")
liquid2 = input("Enter a type of Liquid: ")
personir1 = input("Enter the name of someone in the room: ")
personir2 = input("Enter the name of someone in the room: ")
personir4 = input("Enter the name of someone in the room: ")
food1 = input("Enter a type of Food: ")
food2 = input("Enter a type of Food: ")
food3 = input("Enter a type of Food: ")
fperson1 = input("Enter the name of a famous person: ")
fperson2 = input("Enter the name of a famous person: ")
fperson3 = input("Enter the name of a famous person: ")
sword1 = input("Enter a Silly Word: ")
sword2 = input("Enter a Silly Word: ")
sword3 = input("Enter a Silly Word: ")
num1 = input("Enter a Number: ")
num2 = input("Enter a Number: ")
num3 = input("Enter a Number: ")
num4 = input("Enter a Number: ")
num5 = input("Enter a Number: ")
place1 = input("Enter a Place: ")
place2 = input("Enter a Place: ")
place3 = input("Enter a Place: ")
place4 = input("Enter a Place: ")
place5 = input("Enter a Place: ")


def entera(adj1, adj2, verbing1, place1, adj3, plnoun1, plnoun2, verb1, adj4, bodypl1, verb2, body1, sword1, adj5, plnoun3):
    input("Enter a {}: ".format(adj1))
    input("Enter a {}: ".format(adj2))
    input("Enter a {}: ".format(verbing1))
    input("Enter a {}: ".format(place1))
    input("Enter a {}: ".format(adj3))
    input("Enter a {}: ".format(plnoun1))
    input("Enter a {}: ".format(plnoun2))
    input("Enter a {}: ".format(verb1))
    input("Enter a {}: ".format(adj4))
    input("Enter a {}: ".format(bodypl1))
    input("Enter a {}: ".format(verb2))
    input("Enter a {}: ".format(body1))
    input("Enter a {}: ".format(sword1))
    input("Enter a {}: ".format(adj5))
    input("Enter a {}: ".format(plnoun3))
    return (adj1, adj2, verbing1, place1, adj3, plnoun1, plnoun2, verb1, adj4, bodypl1, verb2, body1, sword1, adj5, plnoun3)



story = ("Putting on a newscast might look easy, but it takes a lot of {} work. Go behind the scenes, and you will see dozens of {} workers {} in every direction! Reporters run back and forth between the studio and locations all around {} to cover {} stories and interview {} . They are joined by videographers who operate handheld {} to capture all the action. The anchors are the people who {} behind the news desk and read the stories during the newsccast. They have to look {} on air, so they can often be found getting makeup applied to their {} . The director tells everyone where and when to {} . Its easy to spot a director because he wears a headset on his {} and yells things like CAMERA TWO and {} ! A newscast is live television so if you make aor an {} mistake, everyone watching at home on their {} will know!")

story = story.format(entera("adj1", "adj2", "verbing1", "place1", "adj3", "plnoun1", "plnoun2", "verb1", "adj4", "bodypl1", "verb2", "body1", "sword1", "adj5", "plnoun3"))

print (story)

and this is the error its throwing

Exception has occurred: IndexError
Replacement index 1 out of range for positional args tuple
  File "C:\Users\hgsal\Documents\python\ML Newscast", line 117, in <module>
    story = story.format(entera("adj1", "adj2", "verbing1", "place1", "adj3", "plnoun1", "plnoun2", "verb1", "adj4", "bodypl1", "verb2", "body1", "sword1", "adj5", "plnoun3"))
3

There are 3 answers

0
quizdog On

To ask for only the variables needed by the story we need someway to indicate the name of each variable the story uses and what question to ask to fill in the value for that variable. One way to do that is encode the variable and and the question to ask are part of the story string and use that to drive the user questions. Here is an approach that does this:

"""
MadLibs
the madlib story will have fixed text and fill-in-the-blank text that we     
will encoded as placeholders in the form:  {variable_name:question_to_ask}

we use a regular expression of scan the story for all the placeholders and 
- prompt the user for input with the question_to_ask string
- store their response in a dict with the key being the variable_name
  and the value being the user response for that variable

the resulting dictionary will have all the information we need to fill in the blanks

next we modify the original story with another regular expression to remove the
:question_to_ask portion of each placeholder.  

that leaves the story string in the perfect form to call story.format(**values)

the **values notation passes the values dict as a set of keyword arguments 
that .format() uses to fill in the placeholders with the user responses


"""


import re    # bring in regular expression module

story = """
Hi my name is {name1:Name of person in room} and I live in {location:A Location}
where I like to eat {food1:Type Of Food} and watch {tvshow1:A Television Show}
when I am feeling {emotion1:An Emotion}"""

placeholder_pattern = re.compile(r"(?s)\{(.+?):(.+?)\}")
question_pattern = re.compile(r"(?s):[^}]+?}")

values = {}    # start with empty dictionary

placeholders = placeholder_pattern.findall(story)  # find all placeholders
for variable, question in placeholders:            # iterate over each placeholder
    value = input(question + "? ")
    values[variable] = value                       # add variable:value to dict

print("\nThe values dictionary is:", value, "\n")  # debug
story = question_pattern.sub("}", story)           # remove the question from each placeholder
print(story.format(**values))                      # use .format() to fill in placeholders

Running the program:


runfile('C:/demo1.py', wdir='C:')

Name of person in room? Fred

A Location? the library

Type Of Food? hotdogs

A Television Show? Mad Men

An Emotion? sad

The values dictionary is: {'name1': 'Fred', 'location': 'the library', 'food1': 'hotdogs', 'tvshow1': 'Mad Men', 'emotion1': 'sad'} 


Hi my name is Fred and I live in the library
where I like to eat hotdogs and watch Mad Men
when I am feeling sad
0
SayLem3737 On

With the help of your comments and my friend Josh I have setup a script that works wonderfully. Here is the final result. I do apologize, there is profanity.

""" Newscast MadLib by Salem
"""

print ("Here comes a fucking MadLib yall!!!")


def entera(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o):
    p = input("Enter a fucking {}: ".format(a))
    q = input("Enter a fucking {}: ".format(b))
    r = input("Enter a fucking {}: ".format(c))
    s = input("Enter a fucking {}: ".format(d))
    t = input("Enter a fucking {}: ".format(e))
    u = input("Enter a fucking {}: ".format(f))
    v = input("Enter a fucking {}: ".format(g))
    w = input("Enter a fucking {}: ".format(h))
    x = input("Enter a fucking {}: ".format(i))
    y = input("Enter a fucking {}: ".format(j))
    z = input("Enter a fucking {}: ".format(k))
    ab = input("Enter a fucking {}: ".format(l))
    ac = input("Enter a fucking {}: ".format(m))
    ad = input("Enter a fucking {}: ".format(n))
    ae = input("Enter a fucking {}: ".format(o))
    return (p, q, r, s, t, u, v, w, x, y, z, ab, ac, ad, ae)



story = ("Putting on a newscast might look easy, but it takes a lot of {} work. Go behind the scenes, and you will see dozens of {} workers {} in every direction! Reporters run back and forth between the studio and locations all around {} to cover {} stories and interview {} . They are joined by videographers who operate handheld {} to capture all the action. The anchors are the people who {} behind the news desk and read the stories during the newsccast. They have to look {} on air, so they can often be found getting makeup applied to their {} . The director tells everyone where and when to {} . Its easy to spot a director because he wears a headset on his {} and yells things like CAMERA TWO and {} ! A newscast is live television so if you make a/an {} mistake, everyone watching at home on their {} will know!")

story = story.format(*entera("Adjective", "Adjective", "Verb ending in ING", "Place", "Adjective", "Plural Noun", "Plural Noun", "Verb", "Adjective", "Body Part Plural", "Verb", "Body part", "Silly Word", "Adjective", "Plural Noun"))

print (story)
4
OneCricketeer On

You would need to defer the input to the string format rather than collect all variables ahead of time

def entera(desc):
    return input("Enter a {}: ".format(desc))

story = "Putting on a newscast might look easy, but it takes a lot of {} work"

story = story.format(entera("Adjective"))