CasperTheFriendlyCode CasperTheFriendlyCode - 3 months ago 12
Python Question

Replacing keywords in parentheses with user input

So, I'm making a little Python 3 applet for madlibs. So far, I have it so that it reads a text file, pulls a random story from it, and splits that story into a list for search through it. That all works great. I have the stories formatted so that, where words are needed, it uses (noun), (adverb), (name), et cetera. However, I have some issues with replacing those strings. Here is an example:

>>> for i in range(0,len(poss)):
... if '(' in poss[i]: poss[i] = input('{0}: '.format(poss[i].replace('(','').replace(')','')))
...
noun: monster
name.: Strange
name: Strange
adjective: yellow
noun!: eatery
place.
: Times Square
>>> poss = ' '.join(poss)
>>> print(poss)
Back to the Future

Marty was an innocent, young monster and made friends with the local scientist,
Doc Strange Doc Strange was a bit off, but he was one yellow genius. One day,
he told Marty that he had an invented a eatery Of course, Marty had to see it
in action. Late that night, they met at Times Square


It searches for the '(' character in each object, and then replaces the whole object with the word. It doesn't preserve the punctuation that might be involved. Also, you can see that the punctuation/newline characters are left over and shown when
input()
is called. How can I effectively replace just the substrings contained within the parenthesis?

For reference, here is the original text that was pulled from the file:

Back to the Future

Marty was an innocent, young (noun) and made friends with the local scientist,
Doc (name). Doc (name) was a bit off, but he was one (adjective) genius. One day,
he told Marty that he had an invented a (noun)! Of course, Marty had to see it
in action. Late that night, they met at (place).


and my intended result is:

Back to the Future

Marty was an innocent, young monster and made friends with the local scientist,
Doc Strange. Doc Strange was a bit off, but he was one yellow genius. One day,
he told Marty that he had an invented a eatery! Of course, Marty had to see it
in action. Late that night, they met at Times Square.

Answer

To address the problems with your approach I'd need to see the full code, but I have another suggestion.

You can actually use the regular expressions here, which allows making the substitution in a one-liner (almost).

In [1]: import re

In [2]: story = '''                               Back to the Future
   ...: 
   ...: Marty was an innocent, young (noun) and made friends with the local scientist,
   ...: Doc (name). Doc (name) was a bit off, but he was one (adjective) genius. One day,
   ...: he told Marty that he had an invented a (noun)! Of course, Marty had to see it
   ...: in action. Late that night, they met at (place).'''

In [3]: def replace(match):
   ...:     return input('{}: '.format(match.group()))
   ...: 

In [4]: print(re.sub('\((noun|name|adjective|place)\)', replace, story))
(noun): monster
(name): Strange
(name): Strange
(adjective): yellow
(noun): eatery
(place): Times Square
                               Back to the Future

Marty was an innocent, young monster and made friends with the local scientist,
Doc Strange. Doc Strange was a bit off, but he was one yellow genius. One day,
he told Marty that he had an invented a eatery! Of course, Marty had to see it
in action. Late that night, they met at Times Square.

re.sub() accepts a callable as replacement, which we use to call input() with the prompt extracted from the match.

Edit: to match any phrase in brackets, you can just change the pattern, e.g.:

print(re.sub('\(([^()]*)\)', replace, story))