Reputation: 4235
I'm writing a simple text-based game to enhance my knowledge of Python. In one stage of the game, the user needs to guess a number in the set [1, 5] in order to have his or her wish granted. They only get three attempts. I have two questions:
1) Lets assume that genie_number
is randomly selected to be 3. Does this value change after each guess by the user? I don't want the program to randomly choose another integer after each guess. It should remain the same so the user has a 3/5 chance of guessing it correctly.
2) I want to penalize users for not guessing only an integer, and I've done that under the except ValueError
section. But if the user makes three non-integer guesses in a row and exhausts all their attempts, I want the loop to re-direct to else: dead("The genie turns you into a frog.")
. Right now it gives me the error message below. How do I fix this?
'Before I grant your first wish,' says the genie, 'you must answer this
'I am thinking of a discrete integer contained in the set [1, 5]. You ha
(That isn't much of a riddle, but you'd better do what he says.)
What is your guess? > what
That is not an option. Tries remaining: 2
What is your guess? > what
That is not an option. Tries remaining: 1
What is your guess? > what
That is not an option. Tries remaining: 0
Traceback (most recent call last):
File "ex36.py", line 76, in <module>
start()
File "ex36.py", line 68, in start
lamp()
File "ex36.py", line 48, in lamp
rub()
File "ex36.py", line 38, in rub
wish_1_riddle()
File "ex36.py", line 30, in wish_1_riddle
if guess == genie_number:
UnboundLocalError: local variable 'guess' referenced before assignment
Here is my code so far:
def wish_1_riddle():
print "\n'Before I grant your first wish,' says the genie, 'you must answer this riddle!'"
print "'I am thinking of a discrete integer contained in the set [1, 5]. You have three tries.'"
print "(That isn't much of a riddle, but you'd better do what he says.)"
genie_number = randint(1, 5)
tries = 0
tries_remaining = 3
while tries < 3:
try:
guess = int(raw_input("What is your guess? > "))
tries += 1
tries_remaining -= 1
if guess == genie_number:
print "Correct!"
wish_1_grant()
else:
print "Incorrect! Tries remaining: %d" % tries_remaining
continue
except ValueError:
tries += 1
tries_remaining -= 1
print "That is not an option. The genie penalizes you a try. Be careful!"
print "Tries remaining: %d" % tries_remaining
if guess == genie_number:
wish_1_grant()
else:
dead("The genie turns you into a frog.")
Upvotes: 0
Views: 1932
Reputation: 19264
Answering your first question, no. If you keep calling randint(1, 5)
, yes it will change, but once you assign it, the value is fixed:
>>> import random
>>> x = random.randint(1, 10)
>>> x
8
>>> x
8
>>> x
8
>>> random.randint(1, 10)
4
>>> random.randint(1, 10)
8
>>> random.randint(1, 10)
10
As you can see, once we assign the random number to x
, x
always stays the same. However, if we keep calling the randint()
, it changes.
Answering your second question, you should not add 1 to tries
right after the int(raw_input())
, if the value is an integer, it will also addd 1 to tries. Instead, try to incorporate your code into something like below:
>>> tries = 0
>>> while tries < 3:
... try:
... x = raw_input('Hello: ')
... x = int(x)
... except ValueError:
... tries+=1
...
Hello: hello
Hello: 1
Hello: 4
Hello: bye
Hello: cool
>>>
You are getting the error, because you have incorrectly answered all 3 of the times. Therefore, nothing is assigned to guess
. After your while
loop, you try to see if guess
is something, which it isn't:
>>> tries = 0
>>> while tries < 3:
... try:
... guess = int(raw_input('Enter input: '))
... print guess
... except ValueError:
... tries+=1
...
Enter input: hello
Enter input: bye
Enter input: good morning
>>> guess
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'guess' is not defined
However, if you give correct input, guess
becomes something:
>>> tries = 0
>>> while tries < 3:
... try:
... guess = int(raw_input('Enter input: '))
... print guess
... except ValueError:
... tries+=1
...
Enter input: 4
4
Enter input: hello
Enter input: 9
9
Enter input: bye
Enter input: 6
6
Enter input: greetings
>>> guess
6
>>>
Contrary to what @LosFrijoles about the problem being with the scope, the error was actually due to the lack of correct input:
>>> x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
>>> for k in range(1):
... x = 1
... print x
...
1
>>> x
1
>>>
As you can see, the variable x
exists in both the for
loop and in the regular shell, so it is not a scope issue:
>>> x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
>>> for k in range(1, 3):
... try:
... x = int(raw_input('Hello: '))
... print x
... except ValueError:
... pass
...
Hello: hello
Hello: bye
>>> x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
>>>
As you can see, it is a error error... :) Because of the error, x
never gets assigned unless we actually give an integer input, because the code never reaches the print x
, because it breaks due to the error:
>>> x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
>>> for k in range(1, 3):
... try:
... x = int(raw_input('Hello: '))
... print x
... except ValueError:
... pass
...
Hello: hello
Hello: 8
8
>>> x
8
>>>
When we do give an integer input, x
becomes valid.
Upvotes: 1