Do Not Display Message While in IF statement - python-3.x

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.

Related

Getting warning: Name 'guess' can be undefined

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!')

Issue with checking ranges in if statement

I'm new to python and doing a cyber sec. course, one of the modules is Python.
I am playing around trying to code a number guesser game without a tutorial. Can someone look at this code and tell me why the code doesn't seem to be following the if statements.
Thanks.
EDIT: ERROR: I am trying to create code that will judge which "difficulty" the player has selected by checking which of the ranges it fits into. The issue is, it is printing each of the "difficulty" options, not just the one it fits in to.
EDIT 2: Changed title to be more specific so it may help others.
print("Welcome to the number guesser game!")
tutorial = input("Would you like a tutorial? (Y/N): ")
while tutorial != "Y" or "y" or "N" or "n":
input("Input not recognised, would you like a tutorial? Y (for yes) or N (for no)")
if tutorial == "N" or "n":
print("Let's get right into it!")
if tutorial == "Y" or "y":
print("In this game you will pick a number, the number you pick will be added to a random number between 1 and 20 /nYou will then attempt to guess the number generated, with a hint given every guess")
break
difficulty = input("Please choose a random number \nGuide:\nEasy 1-10\nMedium 1-100\nHard 1-1,000\nExtreme Numbers above 1,000-10,000")
if difficulty >="1" <="10":
print("You have chosen easy! You must be a noob!")
if difficulty >"10" <="100":
print("You have chosen medium! Good choice!")
if difficulty >"100" <="1000":
print("You have chosen hard! Pfft, good luck")
if difficulty >"1000" <="10000":
print("You have chosen extreme! You must be nuts")
if difficulty <="0" >"10000":
difficulty = input("Nice try, pick again: ")
else:
difficulty = input("Input not recognised, please input a number greater than 0: ")```
Explanation
That's because first, if the input is not y, then it will say not recognized.
And it's because, if it's y, it checks the no statement, then it breaks.
That means, It will say both.
Then, it goes strange because you are doing >= with str and str. It will react strange. so you should compare int with int.
Solution
First, use and in the first statement. then, use elif. and use break in the if statement too. and do int(input()) to convert to int. then, you can use elif again. and remove the quotes.
Try this:
print("Welcome to the number guesser game!")
tutorial = input("Would you like a tutorial? (Y/N): ")
while True:
if tutorial != "Y" and tutorial !="y" and tutorial !="N" and tutorial !="n":
tutorial = input("Input not recognised, would you like a tutorial? Y (for yes) or N (for no)")
if tutorial == "N" or tutorial =="n":
print("Let's get right into it!")
break
elif tutorial == "Y" or tutorial == "y":
print("In this game you will pick a number, the number you pick will be added to a random number between 1 and 20 /nYou will then attempt to guess the number generated, with a hint given every guess")
break
difficulty = int(input("Please choose a random number \nGuide:\nEasy 1-10\nMedium 1-100\nHard 1-1,000\nExtreme Numbers above 1,000-10,000"))
if difficulty >=1 and difficulty <=10:
print("You have chosen easy! You must be a noob!")
elif difficulty >10 and difficulty<=100:
print("You have chosen medium! Good choice!")
elif difficulty >100 and difficulty<=1000:
print("You have chosen hard! Pfft, good luck")
elif difficulty >1000 and difficulty<=10000:
print("You have chosen extreme! You must be nuts")
elif difficulty <=0 and difficulty >10000:
difficulty = input("Nice try, pick again: ")
else:
difficulty = input("Input not recognised, please input a number greater than 0: ")
And for the while loop, turn it to while True: then check it with a if statement. then you can check y or n.
First off in the while loop to check if the variable tutorial is "Y" or "y" or "n" or "N" you're doing tutorial != "Y" or "y" or "N" or "n", which is incorrect because it's saying if (tutorial != "Y") or ("y") or ("n") or ("N") and the latter 3 conditions return true because it is a non empty string.
with the if conditions there are 3 problems, first one is the one I just described, second is you're not converting the input to integer before checking, third is that you're nesting the conditions unnecessarily.
Simplify your checking, and do it in a loop so they cannot progress if they enter invalid input:
difficulty = -1
while difficulty < 1 or difficulty > 10000
try
difficulty = int(input("Please choose a difficulty.\nGuide:\nEasy 1-10\nMedium 1-100\nHard 1-1000\nExtreme 1000-10000\n: "))
except ValueError:
print("not a number")
if difficulty > 0 and difficulty <=10:
print("You have chosen easy! You must be a noob!")
elif difficulty<=100:
print("You have chosen medium! Good choice!")
elif difficulty<=1000:
print("You have chosen hard! Pfft, good luck")
elif difficulty<=10000:
print("You have chosen extreme! You must be nuts")
You don't need each elif to make sure the number is greater than the end of the range of the check before; if it wasnt then that elif would have been true, not this one. In other words, if youre playing a guessing game with another human and you say "is the number less than or equal to 10" and they say no, you don't need to say "is it greater than 10 and less than.. " because the "greater than" is implied - it has to be greater than because it isn't less than or equal to

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).

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.

Loop contining not working?

This is my code I am a new to Python, it repeats even if you Type "Y" and it doesn't exit the program when typing "N". Thanks in Advance, forgive my indentation errors
if I type in Y it just repeats the code/ question when using Break and when typing in N the code ends but the program doesn't exit:
while True:
answer = input("Would You Like To Play?")
if answer == "Y":
print("good luck")
elif answer == "N":
exit()
You have to escape the loop, with while True: it will always indefinitely execute unless you exit the loop with a break or an exit().
A better practice however, is using a Boolean value as a loop control variable and changing it when you need to. That will break the loop.
This will work :
flag = True
while flag:
answer = input("Would You Like To Play?")
if answer == "Y" or answer == "y":
print("good luck")
#do whatever you want to here
flag = False
elif answer == "N" or answer =="n":
flag = False
Also in your code the indentation was wrong, I edited it so it's alright now, check your indentation because indentation matters a lot in terms of control flow. That might fix it.

Resources