Reputation: 163
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
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
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
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