1

        This block of code is used to display a random string from a list. The lists I've made are categories based on when the dialogue is appropriate to use. For example, there is a list for greetings, one for goodbyes, and as displayed below: one for when the input isn't understood. In these lists, some of the strings use the character's name (which is a variable) and some of them don't. In order to give the player's name to a string that uses it, use of string formatting is necessary, but when the randomly chosen string doesn't use string formatting I get this error: TypeError: not all arguments converted during string formatting

How could I avoid this error? Use of exception handling comes to mind, but as far as I know wouldn't work due to having to fit the print statment,

In the "functions" Module :

print(random.choice(strings.notUnderstand) % username)

In the "strings" Module :

notUnderstand = [
"""Pardon?
""",
"""I\'m sorry %s, can you repeat that?
""",
"""I don\'t understand what you mean by that.
"""
]

4 Answers 4

1

You could use format, imo it's cleaner:

not_understand = [
    """Pardon?
    """,
    """I\'m sorry {name}, can you repeat that?
    """,
    """I don\'t understand what you mean by that.
    """
]
print(random.choice(not_understand).format(name='abc'))
Sign up to request clarification or add additional context in comments.

Comments

0

Here is one way to do it:

notUnderstand = [
"""Pardon?
""",
"""I\'m sorry %(username)s, can you repeat that?
""",
"""I don\'t understand what you mean by that.
"""
]

print(random.choice(notUnderstand) % {'username': username})

Comments

0

You can use the format

import random

notUnderstand = [
"""Pardon?
""",
"""I\'m sorry {}, can you repeat that?
""",
"""I don\'t understand what you mean by that.
"""
]
username='sundar'
print random.choice(notUnderstand).format(username)

Comments

0

I don't think people actually understood your question; which is - how can I detect that a string has a variable replacement, to make sure I pass in the correct number of arguments.

Your problem basically boils down this. You have a list with two strings, one has a variable substitution:

s = ['Hello {}', 'Thank You']

At random, one of these strings needs to be printed. If it has a variable and you don't pass it in, it won't get printed correctly (it will raise TypeError)

>>> print('hello %s' % (1,))
hello 1
>>> print('hello' % (1,))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: not all arguments converted during string formatting

You can get rid of this problem partially by using .format(), because it will silently fail when there are no placeholders for it to substitute:

>>> print('hello'.format(name=1))
hello

But, if your string does have placeholders, you must pass enough variables to substitute all placeholders, otherwise you'll get a IndexError:

>>> print('hello {name} {}'.format(name=1))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: tuple index out of range

To solve this problem, you have to keep track of how many variables there are in each string, to make sure your pass in the correct number of arguments. Do this by storing a tuple in the list, which has the number (and optionally, the kind of variable) the string needs:

s = [('Hello {name}',('name',)), ('{name} is {foo}', ('name','foo',))]

Next, create a substitution dictionary:

subs = {'name': lambda: 'hello', 'foo': lambda: '42'}

I am using lambdas here because in reality you would want some function to be called to get the value of the variables.

Now, when you want to build your string:

random_string, vars = ('Hello {name}', ('name',))
print(random_string.format(**{k:subs.get(k)() for k in vars}))

1 Comment

Though you definitely understood my question, I did not understand your answer. I forgot to mention that I'm fairly new to programming and to Python, so I don't understand what a tuple is, what exactly a substitution dictionary is, or what lambadas are. Nonetheless, thank you for your time and for your answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.