Skip to content
Advertisement

When entering the wrong input, Gives ‘str’ is not callable error

The error occurs in the def ‘newround()’, and the given options are Yes/No, however when entering something like ‘test’ it says the else statement but then gives an error anyways. I looked up some info on the error, and the best thing i could find was if a variable was called ‘str’ but none of my variables are even close to that so I’m not sure why I get this error, also I’m new to coding so apologies if it’s something simple. Here is the code:

# Importing the random module
import random
import time

# The title of the game is printed
print("""         ***************************************
         Rock, Paper, Scissors! - By Max Pearson
         ***************************************""")


# All user defined functions apart from code() are defined here

# Defining the first Rock Paper Scissors
def rps1():
    # Take the users input of RPS
    user_choice = input("What is your choice? Rock, Paper, or Scissors?: ")
    # Strips and lowers user input
    user_choice = user_choice.lower()
    user_choice = user_choice.strip()
    RPS = ["Rock", "Paper", "Scissors"]
    computer_names = ["Computer", "Robot", "Android", "A.I", "PC",
                      "Algorithm", "Laptop", "Alexa", "Windows"]
    computer_name = random.choice(computer_names)
    # Selecting the computer's choice
    computer_choice = random.choice(RPS)
    computer_choice = computer_choice.lower()
    computer_choice = computer_choice.strip()
    # Sets the parameters for when the user inputs Rock
    if user_choice == "rock":
        print("You have chosen Rock")
        print("{} chose... {}".format(computer_name, computer_choice.title()))
        if user_choice == computer_choice:
            print("It's a tie!")
            newround()
        elif computer_choice == "paper":
            print("You lose...")
            newround()
        else:
            print("You win!")
            newround()
    # Sets the parameters for when the user inputs Paper
    elif user_choice == "paper":
        print("You have chosen Paper")
        print("{} chose... {}".format(computer_name, computer_choice.title()))
        if user_choice == computer_choice:
            print("It's a tie!")
            newround()
        elif computer_choice == "rock":
            print("You win!")
            newround()
        else:
            print("You lose...")
            newround()
    # Sets the parameters for when the user inputs Scissors
    elif user_choice == "scissors":
        print("You have chosen Scissors")
        print("{} chose... {}".format(computer_name, computer_choice.title()))
        if user_choice == computer_choice:
            print("It's a tie!")
            newround()
        elif computer_choice == "rock":
            print("You lose...")
            newround()
        else:
            print("You win!")
            newround()
    # Fallback for an invalid input
    else:
        print("Please enter a valid choice")
        rps1()


# Defining the option for a new round
def newround():
    # Take user input
    playagain = input("Would you like to play another game?(Yes/No): ")
    # Stripping and lowering the variable
    playagain = playagain.strip()
    playagain = playagain.lower()
    try:
        if playagain == "yes":
            rps1()
        elif playagain == "no":
            print("Okay!")
        else:
            print("Please enter a valid input(Yes/No)")
            playagain()
    except ValueError:
        print("Please enter a valid input(Yes/No)")
        newround()


# Defining the function to turn numbers into percentages
def percentage(x, num_sims):
    x = (x / num_sims) * 100
    return x


# Gives the user the option to view statistics
def percentified(wins, losses, ties, num_sims):
    # Take user input
    percentages = input("Would you like these results in a statistic?: ")
    percentages = percentages.lower()
    percentages = percentages.strip()
    if percentages == "yes":
        # Printing and formatting the results
        print(
            "Here are the percentages to one decimal "
            "point:nWins = {:.1f}%nLosses = {:.1f}%nTies = {:.1f}%".format(
                percentage(wins, num_sims), percentage(losses, num_sims),
                percentage(ties, num_sims)))
    elif percentages == "no":
        print("Okay, enjoy the results")
    else:
        print("Please enter a valid choice (Yes/No)")
        percentified(wins, losses, ties, num_sims)


# The second gamemode of Rock Paper Scissors
def rps2():
    # Defining a list for the random choice
    RPS = ["Rock", "Paper", "Scissors"]
    results = []
    try:
        # Takes an input from the user, to define the number of games
        num_sims = int(input("Please enter the number of "
                             "simulated games you would like: "))
        # Loops for the number the user entered
        if num_sims > 0:
            for i in range(0, num_sims):
                choice1 = random.choice(RPS)
                choice2 = random.choice(RPS)
                # Runs a check on every choice and adds it to a list
                if choice1 == choice2:
                    results.append("tie")
                elif choice1 == "Rock" and choice2 == "Paper":
                    results.append("loss")
                elif choice1 == "Rock" and choice2 == "Scissors":
                    results.append("win")
                elif choice1 == "Scissors" and choice2 == "Paper":
                    results.append("win")
                elif choice1 == "Scissors" and choice2 == "Rock":
                    results.append("loss")
                elif choice1 == "Paper" and choice2 == "Rock":
                    results.append("win")
                elif choice1 == "Paper" and choice2 == "Scissors":
                    results.append("loss")
                else:
                    print("Please enter a valid choice")
                    rps2()
            # Count the results and store them in a variable
            wins = results.count("win")
            losses = results.count("loss")
            ties = results.count("tie")
            # Print the user their results
            print("Here are the results:nWins = {}n"
                  "Losses = {}nTies = {}".format(wins, losses, ties))
            percentified(wins, losses, ties, num_sims)
        else:
            print("Please enter a valid number above 0")
            rps2()
    # Fallback incase user enters a string to the integer input
    except ValueError:
        print("Please enter a valid number")
        rps2()
    return wins, losses, ties, num_sims


def rps3():
    RPS = ["rock", "paper", "scissors"]
    user_choice = input("Please enter a choice (Rock, Paper, Scissors): ")
    user_choice.lower()
    user_choice.strip()
    computer_choice = random.choice(RPS)
    if user_choice == computer_choice:
        print("Congratulations! You got it correct!")
        newround2()
    elif user_choice == "rock" or 
            user_choice == "paper" or user_choice == "scissors":
        print("Oof, that was the wrong choice, better luck next time!")
        newround2()
    else:
        print("Please enter a valid choice (Rock, Paper, Scissors): ")
        rps3()


def newround2():
    playagain = input("Would you like to play again (Yes/No)?: ")
    playagain.lower()
    playagain.strip()
    if playagain == "yes":
        rps3()
    elif playagain == "no":
        print("Okay!")
    else:
        print("Please enter a valid choice (Yes/No: ")
        newround2()


try:
    # Defining the entirety of the body of the code
    def code():
        time.sleep(0.5)
        # Takes the users input
        try:
            playstyle = int(input("Would you like to play RPS, simulate "
                                  "a number of games, or guess "
                                  "the computer's choice? (1,2,3): "))
        except ValueError:
            print("Please enter a valid choice")
            code()
        if playstyle == 1:
            rps1()
        # Checks if the user wants to simulate games
        elif playstyle == 2:
            rps2()
        elif playstyle == 3:
            rps3()
        else:
            print("Please enter a valid choice (1/2/3)")
            code()
    code()
# Fallback incase user enters a string to the integer input
except ValueError:
    print("Please enter a valid choice (1/2/3)")
    code()

Here is the error message:

Traceback (most recent call last):
  File "/Users/maxp/PycharmProjects/pythonProject/RPS_maxpearson.py", line 222, in <module>
    code()
  File "/Users/maxp/PycharmProjects/pythonProject/RPS_maxpearson.py", line 213, in code
    rps1()
  File "/Users/maxp/PycharmProjects/pythonProject/RPS_maxpearson.py", line 40, in rps1
    newround()
  File "/Users/maxp/PycharmProjects/pythonProject/RPS_maxpearson.py", line 87, in newround
    playagain()
TypeError: 'str' object is not callable

Advertisement

Answer

In def newround, you have a variable called playagain, but inside the except part, you use it as a function. Maybe, rename your variables such that there would be no interference variables and function names.

User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement