Bark Jr. Jr.
Bark Jr. Jr.

Reputation: 3

Python3 won't recognize a variable in code

All my code is below.

Just started learning to program this week. I'm attempting to make a Monty Hall simulator (text only) where the player chooses a door by selecting 1, 2 or 3. For some reason, though, Python doesn't seem to be recognizing the input!

Here are links to the game for the uninitiated:

Monty Hall wikipedia page

Monty Hall simulation

What my program attempts to do is as follows. First the player chooses a door, either 1, 2 or 3. Then the program checks to make sure that the player did indeed enter one of those three numbers. If not, then the person needs to choose again.

After this, the game randomly chooses a winning door. Then, per the rules of the game, the program needs to reveal a dummy prize (the goat). So the program randomly chooses one of the doors to be the "goat door." The program first makes sure that this door is not the winning door nor is it the chosen door.

Here's the error I get when running my code:

line 52, in <module>

     doors()

line 14, in doors

     while goatDoor == chosenDoor or goatDoor == winningDoor:

NameError: name 'chosenDoor' is not defined

My issue is that I can't tell why it keeps saying that chosenDoor is not defined!

Here's the code:

import random

def chooseDoor():   # choose a door
    chosenDoor = ''
    while chosenDoor != 1 and chosenDoor != 2 and chosenDoor != 3:
        print('Choose a door. (1, 2 or 3)')
        chosenDoor = input()
        return chosenDoor
    print('You chose door number ' + str(chosenDoor) + '.')

def doors():    # the winning door and the dummy door are randomly selected 
    winningDoor = random.randint(1,3)
    goatDoor = ''
    while goatDoor == chosenDoor or goatDoor == winningDoor:
        goatDoor = random.randint(1, 3)

def keepOrSwitch():
    switchDoor = 1
    if switchDoor == chosenDoor or switchDoor == winningDoor:
        switchDoor = 2
        if switchDoor == chosenDoor or switchDoor == winningDoor:
            switchDoor = 3
    print('Do you want to')
    print('KEEP your choice of door number ' + str(chosenDoor) + '?')
    print('...or...')
    print('Do you want to')
    print('SWITCH and choose door number ' + str(switchDoor) + '?')
    print()
    choice = ''
    while True:
        print('Type \'K\' for keep or type \'S\' for switch.')
        choice = input()
        if choice == 'K' or choice == 'k':
            break
        if choice == 'S' or choice == 's':
            chosenDoor = switchDoor
            break

def checkWin():
    if chosenDoor == winningDoor:
        print('You win!')
    if chosenDoor != winningDoor:
        print('You lose!')


# the rest of the code is the actual game
playAgain = 'yes'
while playAgain == 'yes' or playAgain == 'y':

    chooseDoor()

    doors()

    keepOrSwitch()

    checkWin()

    print('Do you want to play again? (yes or no)')
    playAgain = input()

Upvotes: 0

Views: 2671

Answers (4)

Tomos Williams
Tomos Williams

Reputation: 2088

Your variables are out of scope, you need to store the variables you're making down in the while loop and return the values from the methods you've made, then pass the values to checkWin

keepOrSwitch should return chosen

chooseDoor should return chosenDoor

doors should return winningdoor/goatdoor

checkwin should take chosenDoor + winnindoor + goatdoor

you'll then be able to reference your variables correctly

Upvotes: 3

cezar
cezar

Reputation: 12032

In your function:

def checkWin():
    if chosenDoor == winningDoor:
        print('You win!')
    if chosenDoor != winningDoor:
        print('You lose!')

you try to compare chosenDoor to winningDoor, but they are not yet defined. The function checkWin() has no access to localy defined variables in other functions.

You have to refactor your code. Eventually you could assign some parameters to the function checkWin and return some values from the other functions.

Also:

# the rest of the code is the actual game

can be replaced by:

if __name__ == "__main__":
    # your actual game

This is the standard way to run a Python program. If you import anything from this module in another file, the code won't run by accident.

EDIT: the error is actually caused by this line:

while goatDoor == chosenDoor or goatDoor == winningDoor:

In your function doors() you define goatDoor and winningDoor, but chosenDoor is not declared.

In the function keepOrSwitch() you have the same problem.

Nevertheless the function checkWin() will cause an error, too.

You have to refactor your function chooseDoor() too. It has a print statement after the return statement. It enters the while loop and will finish the function call never reaching the last line.

The simplest way to fix this would be to assign the return value of chooseDoor to a variable:

choosenDoorByTheUser = chooseDoor()

and later call the other functions with that variable as argument.

Upvotes: 3

Dorilds
Dorilds

Reputation: 448

In a python program you've only defined chosenDoor in the chooseDoor() function and you haven't passed chosenDoor into the next function doors(). You can pass chosenDoor to doors() by doing doors(chosenDoor).

Upvotes: 1

cardamom
cardamom

Reputation: 7441

You have posted a lot of code and it looks like a scope issue, the variables in your functions are not visible inside the other functions.

The quick and dirty way to fix this is to make that variable causing the error global like this:

def chooseDoor():   # choose a door
    global chosenDoor = ''
    while chosenDoor != 1 and chosenDoor != 2 and chosenDoor != 3:
        print('Choose a door. (1, 2 or 3)')
        chosenDoor = input()
        return chosenDoor
    print('You chose door number ' + str(chosenDoor) + '.')

I think that will probably fix it but it's not good coding practice.

Upvotes: 3

Related Questions