2

I am trying to write a game of rock, paper, scissors, and I am getting an error about a file I imported not having an attribute of "quitGame", even though I should have that variable imported along with the others.

Here is the function that has the quitGame variable (uneeded parts filtered out):

def playRps():
    game = "".join([playerAction, computerAction])
    global quitGame

    outcomes = {
        "rr": tied,
        "pp": tied,
        "ss": tied,
        "rp": playerLoss,
        "ps": playerLoss,
        "sr": playerLoss,
        "rs": playerWin,
        "pr": playerWin,
        "sp": playerWin,
    }

    if playerAction == "q":
        quitGame = True  # TODO: Figure out why this isn't working in the main.py file
    else:
        action = outcomes.get(game)
        if action:
            action()
        else:
            print("Invalid input!")

You can also find the entire functions.py file here.

Here is the main.py file that should runs the program (uneeded parts filtered out):

import functions  # Imports the functions.py file
while True:
    playGame = str(input('Would you like to play "Rock, Paper, Scissors"? (Y/n): '))

    if playGame == "y":
        while True:
            functions.playerChoice()
            functions.computerChoice()
            functions.playRps()
            if functions.quitGame == True:
                break

    elif playGame == "n":
        print("Terminating program...")
        quit()

    else:
        print("Unknown input. Please enter a valid answer.")
        continue

You can also find the entire main.py file here.

Here is the interaction that gave me the error I am trying to fix:

(.venv) johnny@lj-laptop:rock_paper_scissors$ /home/johnny/Projects/rock_paper_scissors/.venv/bin/python /home/johnny/Projects/rock_paper_scissors/main.py
Would you like to play "Rock, Paper, Scissors"? (Y/n): y

    Rock, paper, or scissors?
    Acceptable responses are...
    "r": Chooses rock.
    "p": Chooses paper.
    "s": Chooses scissors.

    "q": Quits the game.
    r
Tied! No points awarded.
Traceback (most recent call last):
  File "/home/johnny/Projects/rock_paper_scissors/main.py", line 18, in <module>
    if functions.quitGame == True:
AttributeError: module 'functions' has no attribute 'quitGame'

I find this very odd, because other variables such as playerScore and computerScore work as expected. I have functions. added before each variable and function, so it makes no sense as to why it's telling me I don't have it.

I even added global quitGame in the function that creates the variable. I don't see why this isn't working.

My question to you guys is:

  • Why am I getting an error when I call that variable? What am I doing wrong?
11
  • 4
    As a programmer you should try very, very, very hard not to use globals. Commented Feb 1, 2021 at 16:43
  • 1
    Perhaps you could do without the global and return True or False from playRps(). Commented Feb 1, 2021 at 16:44
  • 1
    @LiterallyJohnny You can use a class. You can return variables from functions. You cna use Google to help find answers too. Here are some: stackoverflow.com/questions/59330578/… stackoverflow.com/questions/11462314/… Commented Feb 1, 2021 at 16:46
  • 1
    @LiterallyJohnny if playRps() == False is indeed correct syntax. That's pretty basic Python, I'd recommend taking a basic tutorial on how to use functions. Commented Feb 1, 2021 at 16:47
  • 1
    I'd suggest making sure you understand the benefits and pitfalls of globals before just taking internet strangers at their word. Globals do have a serious cost, but if you don't know why you should avoid them, you won't know when you should not avoid them. Commented Feb 1, 2021 at 16:50

2 Answers 2

1

You have to use global before the variables is "requested" not "declared".

So if you want quitGame to be global you have to declare it were do you prefer (for example in main.py) and then were do you want to use it (as the example in a function) use "global quitGame".

You can tell to your function to access to a global var called quiteGame, instead of declaring quiteGame as global.

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

4 Comments

Oh, that makes sense. Thanks for this answer!
No problem, I also tried to declare the var global but doesn't work like that in python ;) p.s. The suggestion of avoiding global var is a good suggest
Yeah, I'll keep that in mind. I don't understand why globals aren't meant to be used, but I'll check into it and see why. I don't mind doing research.
I developed many functions that act on global var to modify or read from them data (on little "one-file" scripts). But a best practice is to build your function to be indipendent from the enviroment, so the global var dipendency is a costrain. The best solution is to develop a function that can be used even outside of his enviroment. How? Simply passing as argument in the function those vars .
0

Cloned your repository and realised that I can play the game if I first chose "q" first, followed by answering "Y" then playing the game.

Would you like to play "Rock, Paper, Scissors"? (Y/n): y

    Rock, paper, or scissors?
    Acceptable responses are...
    "r": Chooses rock.
    "p": Chooses paper.
    "s": Chooses scissors.

    "q": Quits the game.
    q
Would you like to play "Rock, Paper, Scissors"? (Y/n): y

    Rock, paper, or scissors?
    Acceptable responses are...
    "r": Chooses rock.
    "p": Chooses paper.
    "s": Chooses scissors.

    "q": Quits the game.
    r
Tied! No points awarded.
Would you like to play "Rock, Paper, Scissors"? (Y/n): 

This is because your functions.quitGame global is only initialised when functions.playRps() is run. Before this, it does not exist and thus if you answered "r" right after choosing "y" to start the game, the functions.quitGame global does not exist yet. You can fix this by initialising the variable in your functions.py file beneath the declaration of computerScore:

playerScore = 0
computerScore = 0
quitGame = False

After this, you will then be able to play the game without any issue.

Comments

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.