jufg
jufg

Reputation: 163

Multiple occurrences of same word in Mad Libs game Python

I'm trying to make a Mad Libs game where the user enters in words that occurs multiple times in the sentence. At the moment I'm finding that the user is required to type in these same words multiple times.

sentence_a = """GENRE_OF_MUSIC was created by PERSON in Middle Earth.
                We only know because NUMBER years ago,
                MUSICIAN went on an epic quest with only a OBJECT for
                company. MUSICIAN had to steal GENRE_OF_MUSIC from PERSON
                and did this by playing a game of SPORT as a distraction."""

#Words to be replaced
parts_of_speech = ["MUSICIAN", "GENRE_OF_MUSIC", "NUMBER",
                    "OBJECT", "PAST_TENSE_VERB", "PERSON", "SPORT"]            

# Checks if a word in parts_of_speech is a substring of the word passed in.
def word_in_pos(word, parts_of_speech):
    for pos in parts_of_speech:
        if pos in word:
            return pos
    return None

def play_game(ml_string, parts_of_speech):    
    replaced = []
    ml_string = ml_string.split()
    for word in ml_string:
        replacement = word_in_pos(word, parts_of_speech)
        if replacement != None:
            user_input = raw_input("Type in a: " + replacement + " ")
            word = word.replace(replacement, user_input)
            replaced.append(word)
        else:
            replaced.append(word)
    replaced = " ".join(replaced)
    return replaced

print play_game(sentence_a, parts_of_speech)

When you run the code I want the user to only enter GENRE_OF_MUSIC once and for the Mad Libs sentence to use that entry only for each occurrence.

Upvotes: 2

Views: 388

Answers (3)

Laurent LAPORTE
Laurent LAPORTE

Reputation: 22992

Your code is unnecessary too complex.

First, you can ask the user the parts of speech to replace. You can do that with a loop over parts_of_speech and store each user input into a mapping:

parts = {}
for replacement in parts_of_speech:
    user_input = raw_input("Type in a " + replacement + ": ")
    parts[replacement] = user_input

Then you can split the sentence and replace each word by the user replacement, if it exist. If not, you keep the word:

words = [parts.get(word, word)
         for word in ml_string.split()]
return " ".join(words)

You get:

Type in a MUSICIAN: Bach
Type in a GENRE_OF_MUSIC: piano
Type in a NUMBER: 23
Type in a OBJECT: roller
Type in a PAST_TENSE_VERB: dig
Type in a PERSON: Mr president
Type in a SPORT: football
piano was created by Mr president in Middle Earth. We only know because 23 years ago, Bach went on an epic quest with only a roller for company. Bach had to steal piano from Mr president and did this by playing a game of football as a distraction.

Note: word_in_pos function is useless.

Upvotes: 0

Hugh Bothwell
Hugh Bothwell

Reputation: 56684

I would suggest using string formatting instead of search-and-replace.

Here's how it could work:

import string
from textwrap import dedent

FMT = string.Formatter()

def get_field_names(format_string):
    """
    Return a list of unique field names from the format string
    """
    return sorted(set(p[1] for p in FMT.parse(format_string) if p[1] is not None))

sentence_a = dedent("""
    {GENRE_OF_MUSIC} was created by {PERSON} in Middle Earth.
    We only know because {NUMBER} years ago, {MUSICIAN} went
    on an epic quest with only a {OBJECT} for company.
    {MUSICIAN} had to steal {GENRE_OF_MUSIC} from {PERSON}
    and did this by playing a game of {SPORT} as a distraction.
""")

parts_of_speech = get_field_names(sentence_a)
replace_dict = {pos:pos for pos in parts_of_speech}

# after getting input from player
replace_dict["MUSICIAN"] = "Chuck Berry"

# show result
print(sentence_a.format(**replace_dict))

Upvotes: 1

import random
import random

Reputation: 3245

You're not tracking the replacements to handle duplicate keywords.

You could change the code to loop through your keywords:

sentence_a = """GENRE_OF_MUSIC was created by PERSON in Middle Earth.
We only know because NUMBER years ago,
MUSICIAN went on an epic quest with only a OBJECT for
company. MUSICIAN had to steal GENRE_OF_MUSIC from PERSON
and did this by playing a game of SPORT as a distraction."""

#Words to be replaced
parts_of_speech = ["MUSICIAN", "GENRE_OF_MUSIC", "NUMBER",
                    "OBJECT", "PAST_TENSE_VERB", "PERSON", "SPORT"]            

def play_game(ml_string, parts_of_speech):    
    for word in parts_of_speech:
        if word in ml_string:
            user_input = raw_input("Type in a: " + word + " ")
            ml_string = ml_string.replace(word, user_input)
    return ml_string

print play_game(sentence_a, parts_of_speech)

Upvotes: 0

Related Questions