Getting warning: Name 'guess' can be undefined - python-3.x

I am getting warning for the last guess in the last if statement. Can I just ignore that and be sure, there is no case for my program to work incorrectly?
import random
print('Try to guess hidden number from 1 to 50, U have 6 tries by the way')
hidden_num = random.randint(1, 50)
tries = 6
while tries>0:
guess = int(input(f'Guess the hidden number, tries left: {tries}\n'))
tries-=1
if guess == hidden_num:
print('Great Job, You got it!')
break
elif guess < hidden_num:
print('U were so close, take a bit higher')
else:
print('WowWo! Pick lower,Dude!')
if guess != hidden_num and tries == 0:
print('Don\'t be upset buddy, you have whole life ahead!')

Solved the warning issue, just by tabing last if condition, but still don't understand what is the code execution difference between this 2 cases:
if guess != hidden_num and tries == 0:
print('Don\'t be upset buddy, you have whole life ahead!')
and:
if guess != hidden_num and tries == 0:
print('Don\'t be upset buddy, you have whole life ahead!')

Related

Python Noob - Looking for anti-spaghetti suggestions and avoiding redundant code

First post here. I wanted to get this out to you folks because I'm looking for some insightful feedback and my approaches coming back into this world. My main experience is with Javascript on front-end work, and I hadn't written a single letter of python until yesterday afternoon, so excuse the mess.
I'm trying to see what you might see as some right-off-the-bat suggestions for abbreviating, or cleaning up this code. Maybe some glaring "please never do this again" items, or whatever insight you might have.
It's a console number guessing game, currently 1 - 10. It does run, with some bugs. The one main one that keeps tripping me up (and I'm sure it's simple) is if you guess the correct answer on the last try (3rd in this case) it does not run the 'Congrats' code. It runs the 'You failed' section.
Just looking for some suggestions or input of any kind to help assess MY thinking and approach to problem solving in this language. Also, if there's a better place on the web for this kind of nooby-ness, let me know. Thanks!
from random import randint
def guessing_game():
# Set the count and limits for the loop and game length.
guess_count = 0
guess_limit = 2
# Ask the user to take a guess.
guess = int(input("I'm thinking of a number between 1 and 10... "))
# Randomize the answer. Change the range according to preference.
the_answer = randint(1, 10)
# Start the loop
while guess_count < guess_limit:
if guess == the_answer: # The user wins and is prompted to play again. Init function would probably be useful.
print(f"Congrats, you won! The answer is {the_answer}!")
restart = input("Play again? ")
if restart.upper() == "Y":
guessing_game()
else: # The user declines to play and we break out of the loop.
print("Okay, thanks for playing! ")
break
break
elif guess != the_answer: # The user guessed the wrong answer. Ask again and add to the count.
print("Oops, try again.")
guess = int(input("I'm thinking of a number between 1 and 10... "))
guess_count += 1
if guess_count == guess_limit: # Shucks, the user failed. Inform them of their failure and offer redemption.
print('Sorry, you failed.')
restart = input("Play again? ")
if restart.upper() == "Y":
guess_count = 0
guessing_game()
else: # The user opted out of continuing this exciting adventure.
print("Okay, thanks for playing! ")
break
guessing_game()
1/23/2020 - 12:45pm EST Notice the updated code below per #An0n1m1ty. With this updated code I can make up to 4 incorrect guesses before it terminates. On the second wrong guess, there is no 'Oops' message printed, and on the fourth wrong guess, the program just ends. No 'You lost' message or prompt to play again.
Winning, however, seems to be functioning correctly. I will go over it and try to identify the logic behind the current behavior. You can see the changes I made with comments starting with 'CHANGE'.
Also, if there's a better place to display these code updates, please let me know. I didn't put it in an answer, because it's not an answer. Sorry, I'm a noob.
from random import randint
def guessing_game():
# Set the count and limits for the loop and game length.
guess_count = 0
guess_limit = 2
# CHANGE Moved guess input from here to beginning of loop
# Randomize the answer. Change the range according to preference.
the_answer = randint(1, 10)
# Start the loop
while guess_count < guess_limit:
# CHANGE Ask the user to take a guess.
guess = int(input("I'm thinking of a number between 1 and 10... "))
if guess == the_answer: # The user wins and is prompted to play again. Init function would probably be useful.
print(f"Congrats, you won! The answer is {the_answer}!")
restart = input("Play again? ")
if restart.upper() == "Y":
guessing_game()
else: # The user declines to play and we break out of the loop.
print("Okay, thanks for playing! ")
break
break
elif guess != the_answer and guess_count != guess_limit: # CHANGE The user guessed the wrong answer.
print("Oops, try again.")
guess = int(input("I'm thinking of a number between 1 and 10... "))
guess_count += 1
elif guess_count == guess_limit: # CHANGE Shucks, the user failed. Inform them of their failure and offer redemption.
print('Sorry, you failed.')
restart = input("Play again? ")
if restart.upper() == "Y":
guess_count = 0
guessing_game()
else: # The user opted out of continuing this exciting adventure.
print("Okay, thanks for playing! ")
break
guessing_game()
1/23/2020 - 7:45pm EST So with these changes we are a lot closer. The main issue is that if you get three wrong answers, the program just terminates. No failure message or prompt to play again. I believe this is because the loop condition is met after three tries, so the loop breaks and the
elif guess_count == guess_limit:
section never has a chance to run. I solved this issue by changing
while guess_count < guess_limit:
to
while guess_count <= guess_limit:
which allows the aforementioned section to run and prompt to play again. The only thing with this solution is that the loop runs one more time beyond the guess_limit because of the <= at the beginning of the loop. So you have to reduce the guess_limit by 1 of what you actually want.
The problem I'm having now is that if I go through a round and lose (only) and choose to play again, after losing or winning that next round and choosing NOT to continue, it will say "Okay, thanks for playing" and the game immediately starts over instead of terminating. So that's where I'm at now.
Thanks so much for all your help! Sounds weird, I'm sure, but it has me looking at it fresh again.
The following code is where the issue is:
elif guess != the_answer: # The user guessed the wrong answer. Ask again and add to the count.
print("Oops, try again.")
guess = int(input("I'm thinking of a number between 1 and 10... "))
guess_count += 1
When the user finally gets the answer right, the next bit of code will execute:
if guess_count == guess_limit: # Shucks, the user failed. Inform them of their failure and offer redemption.
print('Sorry, you failed.')
restart = input("Play again? ")
if restart.upper() == "Y":
guess_count = 0
guessing_game()
else: # The user opted out of continuing this exciting adventure.
print("Okay, thanks for playing! ")
break
Now, if the user is on the 3rd guess, guess_count == guess_limit will be true and the code will execute saying "Sorry, you failed"
To fix the issue, I did the following:
Move
guess = int(input("I'm thinking of a number between 1 and 10... "))
to the first line of the loop. i.e.:
while guess_count < guess_limit:
guess = int(input("I'm thinking of a number between 1 and 10... "))
Then, change:
elif guess != the_answer:
to
elif guess != the_answer and guess_count != guess_limit:
Then, change:
elif guess != the_answer and guess_count != guess_limit: # CHANGE The user guessed the wrong answer.
print("Oops, try again.")
guess = int(input("I'm thinking of a number between 1 and 10... "))
guess_count += 1
to
elif guess != the_answer and guess_count != guess_limit: # CHANGE The user guessed the wrong answer.
print("Oops, try again.")
guess_count += 1
Then, change:
guess_limit = 2
to
guess_limit = 3
Finally, change:
if guess_count == guess_limit:
to
elif guess_count == guess_limit:
Manual while loops are almost always the wrong answer in Python. It's much simpler to do a for loop over a range that runs up to the number of times specified. In addition, Python for loops can take an else block that executes when the loop runs to completion, but doesn't execute if you break (or return, or an exception bubble out), making them ideal for "needle in a haystack" scenarios where the needle wasn't found (while loops can have else blocks as well, but for loops are the better option here). It also lets you move common code (code that executes whether they guessed correctly or not, in this case, the "new game" check) outside both for and else, so you either output one set of data within the loop and break to the common code, or the loop runs to completion, and the else block outputs a different message before the common code.
So you could could be dramatically simplified by using a for/else to:
from random import randint
def guessing_game():
# Set the count and limits for the loop and game length.
guess_limit = 2 # Allows up to two guesses
# Randomize the answer. Change the range according to preference.
the_answer = randint(1, 10)
for guess_count in range(guess_limit):
guess = int(input("I'm thinking of a number between 1 and 10... "))
if guess == the_answer:
print(f"Congrats, you won! The answer is {the_answer}!")
break # Go to common code for retry
elif guess_count != guess_limit: # Don't need to retest guess != the_answer; this is an else that never executes unless they weren't equal
print("Oops, try again.")
# Don't need to prompt for input again, we'll prompt at top of loop
else:
# Only prints if loop ran to completion without breaking
print('Sorry, you failed.')
# Common code run for both success and failure:
restart = input("Play again? ")
if restart.upper() == "Y":
guessing_game()
else:
print("Okay, thanks for playing! ")
if __name__ == '__main__': # Get in the habit of using the import guard now; it's not necessary yet, but when it is, you want to be in the habit
guessing_game()
Note that the unbounded recursion here is potentially problematic. If the user plays close to a thousand times, you'll hit the Python recursion limit. If that's a concern, I'd refactor to separate "one game" from "all games", and have "all games" be implemented as a loop, so you don't need to recurse to play another game:
from random import randint
def play_one_game():
# Set the count and limits for the loop and game length.
guess_limit = 2 # Allows up to two guesses
# Randomize the answer. Change the range according to preference.
the_answer = randint(1, 10)
for guess_count in range(guess_limit):
guess = int(input("I'm thinking of a number between 1 and 10... "))
if guess == the_answer:
print(f"Congrats, you won! The answer is {the_answer}!")
break # Go to common code for retry
elif guess_count != guess_limit: # Don't need to retest guess != the_answer; this is an else that never executes unless they weren't equal
print("Oops, try again.")
# Don't need to prompt for input again, we'll prompt at top of loop
else:
# Only prints if loop ran to completion without breaking
print('Sorry, you failed.')
def guessing_game():
keep_playing = True
while keep_playing:
play_one_game()
# Common code run for both success and failure:
keep_playing = input("Play again? ").upper() == "Y"
print("Okay, thanks for playing! ")
if __name__ == '__main__': # Get in the habit of using the import guard now; it's not necessary yet, but when it is, you want to be in the habit
guessing_game()
This approach also helps minimize complexity; guessing_game used to do two barely related things:
Play a single instance of the game
Determine whether or not to play another game
Separating them out keeps the two behaviors separated, so understanding either feature is easier in isolation.
One last suggestion: There's no great way to handle the "don't give the Oops message on the last loop" case I can think of off-hand, but there are "not awful" ways to remove the need for a test that will fail on most loops. The simplest approach is to echo the extra message as part of the input, using an extra message that's initially empty, and unconditionally set to the "oops" message afterwards, so it's used for all subsequent loops. To do so, you'd just replace:
for guess_count in range(guess_limit):
guess = int(input("I'm thinking of a number between 1 and 10... "))
with:
extra = '' # No oops message the first time
for _ in range(guess_limit): # Don't even name guess_count, we never use it; by convention, _ means unused variable
guess = int(input(extra + "I'm thinking of a number between 1 and 10... "))
extra = "Oops, try again.\n" # From now on, oops incorporated into prompt
allowing you to completely remove:
elif guess_count != guess_limit:
print("Oops, try again.")
replacing a per loop conditional branch with unconditional execution paths (which also makes code easier to test, since there are fewer unused or lightly used paths).

Error message of 'ValueError: int() base must be >= 2 and <= 36, or 0' why?

I am making a little text based game where you have to guess the number that is between certain criteria which can either be preset by the user or by a random number generator but the problem is when I try to randomly generate the two parameters for the game I get an error 'ValueError: int() base must be >= 2 and <= 36, or 0'
I dont actually know what I should try as I have never encountered this problem before.
import random
Guess = 0
Run = ("Yes")
while Run == ("Yes"):
Number_1 = random.randint(1, 30)
Number_2 = random.randint(int(Number_1, 999999999999))
Answer = random.randint(int(Number_1), int(Number_2))
while int(Guess) != int(Answer):
Guess = (input("\nWhat is your guess? > "))
if int(Guess) < int(Answer):
print("The answer is Greater then that.")
if int(Guess) > int(Answer):
print("The answer is less then that.")
print("Congrates on guessing correctly!!")
Again = (input("\nDo you want to play again? ('y' or 'n') > "))
if Again == ("y"):
Run = ("Yes")
if Again == ("n"):
Run = ("No")
I expect it to generate 2 numbers a lowest possible number and a highest possible and then have the user try to guess that number but it cant seem to properly generate the number.
You've misplaced a closing paren in the statement Number_2 = random.randint(int(Number_1, 999999999999)), so instead of asking for a random int between Number_1 and 999999999999, you're telling the system to parse Number_1 as expressed in base-999999999999.

How to fix unexpected EOF while parsing in python 3.6?

Im getting the EOF at the end of the program when i try to run it. i dont really know how to fix it. at first i was getting "if" as an invalid syntax but i think i was able to fix that. thanks for the help
while True:
try:
print("Do you want to enter a number?")
print("y - yes")
print("n - no")
choice = int(input("Enter here: "))
if choice == y:
print("")
count = number
for indice in range(1,number + 1, 1):
print(number + indice)
print("")
print("All done")
You're missing a except to match try.
Note that there are other issues with your code that will break it, even once you've added except. For example,
if choice == y:
...
This should be 'y' instead of y. As it is, y is expected to be a variable, but you're looking to match on the user input 'y' or 'n'.
Also, if you want a string input, then:
choice = int(input("Enter here: "))
will throw an error if you enter, say, 'y':
invalid literal for int() with base 10: 'y'
Try taking things one line at a time and making sure you understand what's supposed to happen at each point, and test it. Then put them together.

My randomNumber generator play again acts weird

Now this is pretty beginner version of randomNumber guessing quiz code in Python. Many of you can look at it and make it 4 times shorter and I get it. However the point of this question is that I am unsure of the logic behind this problem.
If you execute this code, it will work just fine - till you get to Play again part.
When you type No - the program as intended quits. Yes starts again.
However if you type Yes first and the game goes one more time and you decide that it is for now I want to quit - this time you have to enter No twice.
And then it quits. I have no idea why. Ideas?
import random
def game(x,y):
con = True
count = 0
ranNum = random.randint(x,y)
while con:
userInput = int(input("Take a guess between these numbers {} and {}: ".format(x,y)))
count +=1
if userInput == ranNum:
print("You got it!")
print("Number of tries: {}.".format(count))
print("Play again?")
while True:
again = input("> ")
if again.lower() == "yes":
game(x,y)
elif again.lower() == "no":
con = False
break
elif userInput < ranNum:
print("Wrong! Try higher!")
elif userInput > ranNum:
print("Wrong! Try lower!")
game(5,10)
The simplest solution: You need a break or return after calling game() when the user answers 'yes'.
This has an unfortunate side effect where each successive game adds another call to the stack. A better design would move the 'play again?' question out of the game function.
The problem is you are running game(x, y) inside itself. Therefore, con is a local variable. Think of it this way: when you type no the first time, it exits out of the game(x, y) that is running inside game(x, y) Therefore, the number of times you have played is the number of times you need to type no. An easier way to do this would be, like #xulfir says, put the "Play again?" loop outside of the function, or you could put exit() instead of using break to just kill the program.

Do Not Display Message While in IF statement

I am going through "Python Programming for the absolute beginner - Third Edition" and inside of that there is a word jumble game. One of the exercises is to offer a hint to the user when they have guessed incorrectly. I have it working however when the hint statement is executed it also prints out the incorrect guess message, and I am stumped as to how to make it not print the incorrect guess message while in the hint.
Here is the code:
guess = input("\nYour guess: ")
wrong_guess_msg = "Sorry that was not correct. Try again."
while guess != correct and guess != "":
print(wrong_guess_msg)
guess = input("Your guess: ")
guess_count += 1
# Ask the user if they would like a hint after 4 wrong guesses
if guess_count == 4:
hint_response = input("Would you like a hint?: ")
if hint_response.lower() == "yes":
print("Here is your hint: {}".format(hint))
else:
guess = input("Your guess: ")
I have tried pulling the if guess_count statement out of the while loop, however it never executes. I tried change the while loop to include a condition where the guess_count != 4 and that sort of worked, meaning I didn't get the incorrect guess when I got the hint, however it exited the program.
Just not really sure what I am missing here.
You could structure the whole loop differently, thereby also eliminating the first prompt before the start of the loop:
wrong_guess_msg = '...'
while True:
guess = input('Your guess: ')
guess_count += 1
if guess == correct:
break
if guess_count == 4:
...
You may argue that this is leaving the while condition unused, but by that, you gain the chance to write your code straight and clean, exactly because you're not forced to put the correctness check right in front of each iteration. Always (if possible) let yourself be guided by how you would spell out an algorithm if explaining it to the next person, rather than by loop mechanics or other technical constraints.

Resources