Insights and exception mishandling : basic command-line game in Python - python

I am a beginner Python programmer (Python 3) and I just made my first real working program. I encounter an issue with the try: except: part (ln 63), I can't manage to trigger the range_error condition in the usr_input() function. I'm probably not using exceptions the right way.
from random import randint
def gen_num():
magic_num = randint(1,100)
return magic_num
def usr_input(range_error = False):
if range_error == True: # If number is out of range, displays additionnal warning message
print("Make sure you enter a number between 1 and 100 !")
usr_num_guess = input("Please enter an integer between 1 and 100 : ")
return int(usr_num_guess)
def play_again():
# We ask the user to choose if he wants to play again or not (yes / no)
yes = set(['yes','y','ye','yeah',''])
no = set(['no','n'])
usr_choice = input("Do you wish t play again ? (Y/n):").lower()
if usr_choice in yes:
return True
elif usr_choice in no:
return False
else:
sys.stdout.write("Please write 'yes' or 'no'")
def player_level_initialize():
# Setting up the user's desired level
easy_level = set(['easy',1])
med_level = set(['medium','med',2,''])
hard_level = set(['hard','difficult',3])
level_choice = input("Please select your level (easy,MED,hard) :").lower()
if (level_choice in easy_level):
return "easy"
elif (level_choice in med_level):
return "med"
elif (level_choice in hard_level):
return "hard"
else:
sys.stdout.write("Please write 'easy', 'med' or 'hard'")
print("Hello and Welcome to this awesome game !")
player_name = input("Please enter your name : ")
level = player_level_initialize()
keep_playing = True
usr_score = 0
while (keep_playing == True):
num_to_guess = gen_num()
num_of_attempts = 1
too_m_attempts = False
max_number_of_attempts = {
"easy":10,
"med":6,
"hard":3
}
usr_num_guess = usr_input()
while (too_m_attempts == False or usr_num_guess != num_to_guess):
if (num_of_attempts < max_number_of_attempts[level]):
try:
(usr_num_guess >= 1 and usr_num_guess < 100)
except:
usr_num_guess = usr_input(True) # If the input number is out of range, the player gets a warning message + new input
else:
if (usr_num_guess != num_to_guess):
if (usr_num_guess < num_to_guess):
print("It's more !")
else:
print("It's less !")
num_of_attempts += 1
usr_num_guess = usr_input()
elif (usr_num_guess == num_to_guess):
usr_score += 1
print("Good job", player_name, "you found the magic number in only", num_of_attempts, "attempts ! It was", num_to_guess, "You have a current score of", usr_score)
else:
print("Sorry, too many attempts ! The magic number was", num_to_guess)
too_m_attempts = True
keep_playing = play_again()
print("Thank you ! I hope you enjoyed the game !")

What you need is an if block instead of a try-except block:
if not (usr_num_guess >= 1 and usr_num_guess < 100):
usr_num_guess = usr_input(True) # If the input number is out of range, the player gets a warning message + new input
The code in the except part will only be executed if the line (usr_num_guess >= 1 and usr_num_guess < 100) raises an exception.
On the use of exception, when you write
try:
...
except:
...
the code will catch every possible exception and execute th code in the except block which is supposed to fix the situation. This is probably not what you want most of the time. For example, mis-spelling a variable (e.g. usr_num_guesss) will raise a NameError, and whatever user_input() do will not fix the error -- it is an entirely different problem already than an out-of-range input. You should only catch and handle the exceptions that can be handled by your code, such as:
except ValueError:
...

Related

Why isn't the int changing the str value to int in the try statement?

while True:
printing("Welcome to The Cheapest Dealer Ship\n", 0.025)
printing("What car would you like\n")
printing(
"""
(1) Standard $50
(2) SUV $60
(3) Minivan $80
""", 0.025)
ans = input(">>")
try:
int(ans)
except:
pass
if ans == 1:
Total += 50
Car = "Standard"
Car_cost = 50
break
elif ans == 2:
Total += 60
Car = "SUV"
Car_cost = 60
break
elif ans == 3:
Total += 80
Car = "Minivan"
Car_cost = 80
break
else:
printing("Please chose a valid option")
time.sleep(1)
replit.clear()
So basically this is a school code excersize but I can't quite figure why it will return with an else statement even if you answer 1,2 or 3. Not sure why int isn't working or what I'm doing wrong.
Either change your this line
int(ans)
To:-
ans = int(ans)
Or, you can directly take an integer as a input.
Change these lines of code
ans = input(">>")
try:
int(ans)
except:
pass
To this,
while True:
ans = (input(">>"))
if ans.isnumric():
while True:
if ans=="3" or ans=="2" or ans=="1"
break
else:
print("Please select any one (1\2\3)")
break
else:
print("Please enter only numbers.")
ans = int(ans)
After this you will have no need to use try and except statements and you will have less chances of getting errors.

how do i make my code start at the same point the user was already on once they go through a valueerror exception?

I complete all the steps that I am given by my code and finally it asks 'again (Y or N)'. (I have written an except argument that will prevent someone from ending the code by typing a wrong answer) When they input the wrong answer it starts the user back to the top of the code. I would like it to output what step the user was already on.
CODE:
while True:
try:
choice = int(input("ONLY CHOOSE 1 AS THERE IS NO OTHER CHOICE: "))
assert choice == 1
if choice == (1):
userInp = input("TYPE: ")
words = userInp.split()
start_count = 0
for word in words:
word = word.lower()
if word.startswith("u"):
start_count += 1
print(f"You wrote {len(words)} words.")
print(f"You wrote {start_count} words that start with u.")
again = str(input("Again? (Y or N) "))
again = again.upper()
if again == "Y":
continue
elif again == "N":
break
except AssertionError:
print("Please type a given option.")
except ValueError:
print("Please type a given option.")
EDIT:
So I have made some progress but I have one last problem
CODE:
while True:
try:
choice = int(input("ONLY CHOOSE 1 AS THERE IS NO OTHER CHOICE: "))
assert choice == 1
if choice == (1):
userInp = input("TYPE: ")
words = userInp.split()
start_count = 0
for word in words:
word = word.lower()
if word.startswith("u"):
start_count += 1
print(f"You wrote {len(words)} words.")
print(f"You wrote {start_count} words that start with u.")
while True:
again = input("again? (Y or N)")
if again not in "yYnN":
continue
break
if again == "Y":
continue
elif again == "N":
break
except AssertionError:
print("Please type a given option.")
except ValueError:
print("Please type a given option.")
The problem is that the variable 'again' is not defined when outside of the while loop (outside the while loop that is in the while loop). How do I fix this?
You could create another loop (inside this main loop) where you are asking for input, and have a try block there, so that it loops just the section where the user is giving input until they give correct input.

import random.randint guess game

problem1 = else not working when i type for example some character it crash
problem2 = when i win(guess number) it wont do anything (it should print (more in code))
import random
print("guess number 1,5")
player = int(input("type guess: "))
pc = random.randint(1, 5)
attemp = 1
while player != pc:
attemp = +1
if player != pc:
print("your guess", int(player), "pc", int(pc))
player = int(input("type guess: "))
pc = random.randint(1, 5)
elif player == pc:
print(
"you win with number",
int(player),
"you had",
int(attemp),
"attempts",
)
else:
print("please type int num only")
hráč = int(input("type type: "))
pc = random.randint(1, 5)
There are a few different places where the code doesn't work as intended.
int(input("type guess: ")) will crash if you type in something that is not an integer, because int(...) tries to convert it to an integer and fails. The easiest way to fix this is to catch the exception and ask again for a number in a loop:
while True:
try:
player = int(input("type guess: ")) # If this line fails, break won't be executed
break # If the conversion went well we exit the loop
except ValueError:
print('Invalid number')
while player != pc will exit the loop as soon as the user inputs the right number, and the code that prints the success message will not be executed. To fix this, change the loop in a while True and insert a break after you print the success message:
while True:
[...]
elif player == pc:
print("you win with number", [...])
break
You may also notice that the if...elif branches inside the loop cover every possible condition, so the final else part will never be executed. This is not a problem, since we are already handling the input error part when reading the number, so we can remove the else part completely. To simplify the code even more, the condition in the elif isn't necessary, since it's the opposite of the condition in the if, so the logic can be reduced to this:
<read number from user>
while True:
if player != pc:
<print failure message, get new number from the user and new random number>
else:
<print success message>
break
Finally, there is a small mistake in your code:
attemp = +1 probably doesn't do what you want it to do, in that it sets attemp to be equal to +1. I'm assuming you meant attemp += 1, which increments the value by 1
The final code becomes:
import random
print("guess number 1,5")
while True:
try:
player = int(input("type guess: "))
break
except ValueError:
print('Invalid number')
pc = random.randint(1, 5)
attemp = 1
while True:
attemp += 1
if player != pc:
print("your guess", int(player), "pc", int(pc))
while True:
try:
player = int(input("type guess: "))
break
except ValueError:
print('Invalid number')
pc = random.randint(1, 5)
else:
print(
"you win with number",
int(player),
"you had",
int(attemp),
"attempts",
)
break
This is not the cleanest possile way to do it (for example, reading a number from the user is a perfect candidate for a separate function, or you could restructure the logic so that in each iteration of the while True loop you first ask for a number, check it against the random number, print the right message and break if necessary), but I don't want to modify the code too much

Function in Python game not breaking and won't continue to next function

For a class we have to make a game where a person will enter an upper integer and a lower integer for a range. Then a random number is picked from in between those two numbers. The player would then guess a number and the game would end when you guessed the right number. In the function for my range I have a loop that will only end when you enter a correct range. It will then clear the console and continue to the guessing part of the game. The problem is once you enter a correct range it will clear the screen, then execute the wrong part of the loop and make it impossible to continue. What I have programmed so far is below, I started Python about 2 months ago.
**import time, os, random
#The beginning where you enter a range
def game_loop():
got_an_int = False
while got_an_int == False:
user_input1 = input("Enter the upper bound integer of the range: ")
user_input2 = input('Enter the lower bound integer of the range: ')
try:
user_input1 = int(user_input1)
user_input2 = int(user_input2)
print("Good job, that is a correct range.")
got_an_int = True
clear()
break
except:
print("That is not a correct range. Try again.")
#To continue after entering a correct range
def clear():
time.sleep(3)
os.system('clear')
time.sleep(1)
game_begin()
#Random Number Generator
def random_num(a,b):
random.randint(user_input1,user_input2)
#Where you begin the game
def game_begin():
guess_right = False
random_num = random_num(user_input1,user_input2)
while random_num != guess_right:
guess = input('Guess an integer in your range: ')
total_guess = [] + 1
try:
guess = int(guess)
if random_num > guess:
print("Too Low.")
guess_right = False
if random_num < guess:
print('Too High.')
guess_right = False
guess = int(guess)
if random_num == guess:
print("You got it! Good job.")
guess_right = True
the_end()
except:
print("That is not an int. Try again")**
You've got multiple problems, but the most glaring one is a combination of a few things:
random_num = random_num(user_input1, user_input2)
First, this line re-assigns the random_num symbol to be the result of calling random_num. After this line happens, any future calls to random_num won't work, because the function is "gone". Second, both user_input1 and user_input2 are not in scope in the game_begin function (they belong to the game_loop function).
Both of these problems are hidden because you're using "naked" excepts:
try:
...
except:
print(...)
You should only catch the Exceptions you're expecting and handle them appropriately, or make it so those exceptions won't happen.
In the end, I was able to get it to mostly work with the following. Additional problems I encountered are mentioned in the comments.
import time, os, random
def game_loop():
got_an_int = False
while got_an_int == False:
user_input1 = input("Enter the upper bound integer of the range: ")
user_input2 = input('Enter the lower bound integer of the range: ')
try:
user_input1 = int(user_input1)
user_input2 = int(user_input2)
print("Good job, that is a correct range.")
got_an_int = True
clear()
# Move game_begin call here and use parameters, so that randint call works
game_begin(user_input1, user_input2)
break
except:
print("That is not a correct range. Try again.")
def clear():
time.sleep(3)
os.system('clear')
time.sleep(1)
# Remove this - not needed
# def random_num(a,b):
# random.randint(user_input1,user_input2)
def game_begin(in1, in2):
guess_right = False
# No longer overwriting variable/func symbol
# Also, reverse order since range is taken Highest first then Lowest
random_num = random.randint(in2, in1)
# Initialize total_guess to 0
total_guess = 0
while random_num != guess_right:
guess = input('Guess an integer in your range: ')
# Can't add list and ints. I assume you wanted to keep a running total?
# Lists aren't how you would do that.
total_guess += 1
try:
guess = int(guess)
if random_num > guess:
print("Too Low.")
guess_right = False
if random_num < guess:
print('Too High.')
guess_right = False
guess = int(guess)
if random_num == guess:
print("You got it! Good job.")
guess_right = True
# This function doesn't exist, so the loop won't ever actually end
# NameError exception is raised
the_end()
except:
print("That is not an int. Try again")

My Guess The Number Game Will Not Loop Back to Beginning

import random
control = True
main = True
count = 0
user = input("Would you like to play Guess The Number?")
if (user == "yes"):
while (control == True):
randgen = random.randrange(0, 100)
print("Guess a random number")
while main == True:
number = int(input())
if (number == randgen):
print("Great Job you guessed the correct number")
print("You have tried ", count, "time(s)")
main = False
control = False
if (number < randgen):
count += 1
print("Your number is smaller than the random number")
print("You are at ", count, "trie(s)")
main = True
if (number > randgen):
count += 1
print("Your number is larger than the random number")
print("You are at ", count, "trie(s)")
main = True
again = int(input("Would you like to play again?1 for yes and 2 for no."))
if (again == 1):
control = True
user = ("yes")
if (again == 2):
control = False
print ("Ok bye bye")
##user ("no")
if (user == "no"):
print ("OK then Bye")
This Code works except for the part that when I want to play again it does not work. I have a coding background in java that's why I know some code but I made the guess the number game in java and I cannot figure out whats wrong with my python version(posted above).
Please make these changes:
if (again == 1):
control = True
main=True
user = ("yes")

Categories