0

I am trying to make a simple magic eight ball program that asks a question, gives a random response, and then prompts the user if they want to try again. Everything works up until the "ask again" part where all hell breaks loose and this error appears:

TypeError: 'str' object is not callable

I am still very new to Python and quite honestly probably just making a rookie mistake, but there's no shame in asking for help I believe.

Here is the code:

def question():
    question = str(input("Ask a yes or no question: "))

    replies = ["It is certain",
     "It is decidedly so",
     "Without a doubt",
     "Yes definitely",
     "You may rely on it",
     "As I see it, yes",
     "Most likely",
     "Outlook good",
     "Yes",
     "Signs point to yes",
     "Reply hazy try again",
     "Ask again later",
     "Better not tell you now",
     "Cannot predict now",
     "Concentrate and ask again",
     "Don't count on it",
     "My reply is no",
     "My sources say no",
     "Outlook not so good",
     "Very doubtful",
               ]

    rand_num = random.randint(0, 20)

    print(replies[rand_num])

    def ask_again():
        again = input("Would you like to ask another question? (Y/N): ")
        if again == "Y" or "y":
            question()
        elif again == "N" or "n":
            print("Thank you and goodbye.")
        else:
            print("That is not an acceptable answer.")
            ask_again()
    ask_again()
question()
3

1 Answer 1

2
def question(): # <<<<< here you define `question` as the function
    question = str(input("Ask a yes or no question: ")) # <<< and here you "shadow" that with a string (see below the long explanation).

Then, later in the function definition:

def ask_again():
        again = input("Would you like to ask another question? (Y/N): ")
        if again == "Y" or "y":
            question() # <<< here, question is not a function anymore because you redefined the name `question` to a string on the second line of the function definition

What's going on?

When you def the function question(), you essentially define an object with name question that is associated with your function's code. In your function definition, however, the first thing you do is redefine the object question, assigning to it a string. This means that, inside the function definition scope, when you use question you're not referring to he function anymore, but to the string assigned to that object.

Thus the error when you do question() inside the definition in the line I marked above. At this point, you're not calling a function, but trying to "call" a string, which raises the error you're getting.

Note: Outside of the definition of the function question, calling question() will actually run the function, because you shadow the object only in the function definition's scope.

Sign up to request clarification or add additional context in comments.

7 Comments

They don't overwrite anything. The function is a global, the string a local. But the local is used when they expected it to be the function.
And thus, the name question gets redefined. I'm rewording the answer to use more proper definitions
It's still not the correct term. They are shadowing the global name (here as a closure).
I'm afraid I'm lacking lexicon to properly explain what is going on here with the necessary detail. I'm open for suggestions on how to improve the answer, though
It's already better; ask_again() finds the question name in the parent scope (the local namespace of the question function), rather than the question name in the global scope. Apart from using a different name, you could also fix it by telling Python to look for a global by adding the global question statement in the ask_again() function. But that'd be akin to binding your broken leg with a spalk to continue walking rather than have the bone set properly. :-)
|

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.