Input statement isn't evaluated during debugging - triggers a Try Except - python

I'm trying to write a basic tic-tac-toe in Python. One of my functions is meant to get the user's input as a number from 1 to 9. If the user enters a non-integer, or a number not between 1 and 9, it will return an error. It's nestled in a try-except to avoid worrying about type conversion.
def get_move():
print("Your move ...")
while True:
try:
move = input("Type a number from 1-9: ")
if move.isnumeric():
if (0 < int(move) < 10):
break
else:
print("The number is outside the range. Try again.")
else:
if (move.tolower == "quit") or (move.tolower == "exit"):
exit()
except:
print("Not a valid integer, try again.")
return move
This sort-of works when I run normally. But when I try to debug in VS Code, when the debugger reaches the line move = input("Type a number from 1-9: ") and I click "Step Into", it simply goes straight to the "except" clause. And the code proceeds in an infinite loop - it will never stop and wait for the user input, meaning that I have to manually stop the debugger.
Any idea why it might be doing this?
Edit:
Thanks for correcting my typo, but that hasn't solved the problem. I've changed the line from:
if (move.tolower == "quit") or (move.tolower == "exit"):
exit()
to:
if move.lower() == "quit" or move.lower() == "exit":
exit()
And also changed the except clause to except (ValueError, TypeError). Now I receive the following error:
Exception has occurred: EOFError
EOF when reading a line
File "[...]tictacpy.py", line 18, in get_move
move = input("Type a number from 1-9: ")
File "[...]tictacpy.py", line 46, in <module>
move = get_move()

Most likely this is happening because in the debugger you do not have a console for standard input, so calling input() will error (I don't know VS code specifically so I'm guessing here, but this is a reasonable cause).
In any case, I'd strongly suggest not using all-catching except clauses as this silences and wrongly handles errors that may happen that are not a part of your expected flow.
I'd start by changing your except to say except (ValueError, TypeError) so that it only catches errors resulting from bad input / type conversion issues. You'll then be able to see what the real error is.
Also, note that there is no such thing as move.tolower - you probably meant move.lower(). Maybe that's your bug?

Related

Press ENTER to exit program in Python not working

Trying to get my code to exit on the press of the enter button and I'm running into a ValueError: invalid literal for int() with base 10: '', but it's telling me that my error is on the line simulations_num = int(simulations). Anybody have an idea?
simulations = input("How many times would you like to run the simulation? ")
# Invalid answer, system exit
if (not simulations) or int(simulations) <=0:
print("That is not a valid number of simulations.")
print("Shutting down.")
SystemExit
simulations_num = int(simulations)
#the rest of my code comes here
I've also attempted if simulations == '' to no avail.
I have noticed that if simulations_num = int(simulations) isn't involved, the code works fine, but that part of the code (or something similar) is necessary for the rest of the code
You need to raise SystemExit(), or just use sys.exit() (which does the same thing).
you need to raise an error, or at least use sys.exit(0).
The working principle is this:
import sys
if not input(': ').lower() in ['yes','y','1']:
sys.exit(0)
applied to your example would be this
simulations = input("How many times would you like to run the simulation? ")
import sys
# Invalid answer, system exit
if (not simulations) or int(simulations) <=0:
print("That is not a valid number of simulations.")
print("Shutting down.")
sys.exit(0)
simulations_num = int(simulations)
#the rest of my code comes here
raise RuntimeError() would also be good
To address your code:
First of all, you need to add the "raise" keyword infront of SystemExit for it to work properly.
Second, to build a situation, in which you have to press Enter for the program to exit, you can use input().
Corrected Version:
simulations = input("How many times would you like to run the simulation? ")
# Invalid answer, system exit
if (not simulations) or int(simulations) <= 0:
print("That is not a valid number of simulations.")
print("Shutting down.")
input("Press Enter to exit...")
raise SystemExit("Exiting... Reason: invalid input!")
simulations_num = int(simulations)
# the rest of my code comes here

How to implement "if error occurs do not implement this code"?

I want to write a code in python that basically does something like this:
if error occurs while implementing int(a) print('valid character')
elif no error occurs while implementing int(a) print('invalid character')
a is an input.
I want to make a simple hangman game and if the input is not a letter I want a certain message to be displayed. I tried using if a==int(), but inputs are always a string.
Normally you would use a Try, Except clause to handle errors, but because you're not actually getting an error -- you just want to know if the input is an alphabetical character or not, you would use the string.isalpha function.
guess = input()
if not guess.isalpha():
print('You must supply an alphabetical character')
else:
#the rest of your code would go here
Now to have some fun. This is how you would implement exactly what you where asking, however, please note that this does not catch punctuation characters, emoji characters, and any other random characters that are none-numeric and non-alphabetical.
guess = input()
isOk = False
try:
int(guess)
except ValueError:
isOk = True
if not isOk:
print("you cannot enter a number")
I don't know if it's a good idea to mention this or not, because it's a pretty quirky feature of Python to add the else here, but you can technically condense the above code to
guess = input()
try:
int(guess)
except ValueError:
# All good
pass
else:
# we where able to cast to an integer = bad
print("you cannot enter a number")
but I probably wouldn't ever do that in production code. Also, an important note. As you learn about try except clauses. Even though it's possible to just do except: Make sure you always state whatever you are catching. In this case a ValueError except ValueError: . If you don't do this, you suppress all errors, and you risk getting into a situation down the road were an important error gets suppressed, and you have no idea why your program is behaving incorrectly.
explore try-except designs
try:
# do something here
except (ErrorName):
# error catching
print("invalid character")
Please try and include reproducible code, or a code block of pseudo-code so others can follow along easier!

While(!EOF()) equivalent in Python

I'm working on a school project and it specifically asks for a while not end-of-file loop which I don't know how to do in Python. I'm taking in user input (not from an external file) and computing some math in this infinite loop until they CTRL+C to break the loop. Any thoughts would really help me out. I've added part of the instruction if that helps clarify. Thanks.
Your loop is supposed to stop on two conditions:
An illegal value was entered, ie some value that couldn't be converted to a float. In this case, a ValueError will be raised.
You entered ctrl-Z, which means an EOF. (Sorry, having no Windows here, I just tested it on Linux, where I think that ctrl-D is the equivalent of the Windows ctrl-Z). An EOFError will be raised.
So, you should just create an infinite loop, and break out of it when one of these exceptions occur.
I separated the handling of the exceptions so that you can see what happens and print some meaningful error message:
while True:
try:
amount = float(input())
print(amount) # do your stuff here
except ValueError as err:
print('Terminating because', err)
break
except EOFError:
print('EOF!')
break
If you just want to quit without doing anything more, you can handle both exceptions the same way:
while True:
try:
amount = float(input())
print(amount) # do your stuff here
except (ValueError, EOFError):
break
Use the following:-
while True:
amount = raw_input("Dollar Amount: ")
try:
amount = float(amount)
# do your calculation with amount
# as per your needs here
except ValueError:
print 'Cannot parse'
break

python name not defined even though it is

I know this is basic but i actually don't even know what I've done wrong.
while True:
try:
end=int(input("If You Dont Want To Buy Anything Press 1 To Exit\nOr If You Would Like To Try Again Please Press 2"))
except ValueError:
print("\nPlease Enter Only 1 Or 2")
if end==1:
exit()
elif end==2:
continue
I have literally defined end at the start and yet the error is NameError: name 'end' is not defined I've even tried making end a global.
end is only assigned to if there was no ValueError. If int() raises an exception, then the assignment never takes place.
Either test for valid end values inside the try (so that you know no exception was raised), or assign a default value to end first.
For example, the following will not throw your exception and still prompt the user to re-enter the number if anything other than 1 or 2 was entered:
while True:
try:
end=int(input("If You Dont Want To Buy Anything Press 1 To Exit\nOr If You Would Like To Try Again Please Press 2"))
if end==1:
exit()
elif end==2:
break
except ValueError:
pass
print("\nPlease Enter Only 1 Or 2")
Note that I moved the print() to be outside the except block; it'll be printed if an exception was thrown or when no break or exit() was executed. Note that I used break here instead of continue to exit the while True loop; continue would just start the next iteration, prompting the user to enter a number again.
Others have explained the problem; here's a canonical solution. This matches the way many of us regard the process:
- grab a response
- until I get a legal response
- ... tell the user what's wrong
- ... get a new response
input_prompt = "If You Don't Want To Buy Anything Press 1 To Exit\nOr If You Would Like To Try Again Please Press 2"
response = input(input_prompt)
while response != '1' and response != '2':
print("\nPlease Enter Only 1 Or 2")
response = input(input_prompt)
end = int(reponse)
This has no unnatural loop exits (harder to follow and maintain), and no exception processing (slow).
It tries to assign a value to end, but catches a ValueError and after the except it tries to see what 'end' is however it was never assigned a value due to the Exception.
If int(input(...)) fails, a ValueError is raised. That happens before end is assigned. Add another control statement in the error handling, for instance
while True:
try:
end=int(input("If You Dont Want To Buy Anything Press 1 To Exit\nOr If You Would Like To Try Again Please Press 2"))
except ValueError:
print("\nPlease Enter Only 1 Or 2")
continue # ask again
if end==1:
exit()
elif end==2:
continue

Input strings and integers

Just a quick question because I really can't find a simple solution to my problem.
Is there a way to get a user input that is meant to be a integer, but when a string is entered
the program will not break and instead displays "Error"
I've been trying to work around it by converting strings to integers and vice-versa, but I constantly get "invalid literal for int() with base 10" error, or when it displays "Error" it does so in an infinite loop.
Here's my code just to help clear the question
choice = input("Enter your choice: ")
while choice != 3:
if choice == 1:
get_songs()
print
main()
elif choice == 2:
read_songs()
print
main()
else:
print "Invalid choice"
So essentially I want the else operation to work for strings as well as for an integer that is greater than 3 or less than 1.
but I constantly get "invalid literal for int() with base 10" error
You get an exception, specifically a ValueError. You can catch the exception using an except block. For more info, refer to whatever language tutorial you've been using thus far, or try Google for except block Python.
when it displays "Error" it does so in an infinite loop.
When you detect that the input isn't correct, you need to get new input before you try the loop again. Put the input-getting stuff inside your loop. Do not use recursion (calling main() from within main) in addition to the loop; you're only going to confuse yourself this way. Because you don't get a value for choice until you're inside the loop, it's easier to explicitly break out of the loop when you find the appropriate choice value, instead of trying to control the loop with it (i.e. testing for it in the while condition).
We can also use continue to simplify the loop structure: instead of doing all the work in the try block, we limit that to the part where we extract a number. We use continue in the except block to skip the rest of the loop when we don't have an actual number, and only do the rest of the loop when we do. (After all, maybe the code we call for choice == 1 or choice == 2 could raise ValueError for some totally different reason, and we'd want to do something different about that.)
while True:
try:
choice = int(raw_input("Give me a number"))
except ValueError:
print "Could you at least give me an actual number?"
continue
if choice == 1:
do_something()
elif choice == 2:
do_something_else()
elif choice == 3:
break
else:
print "Try a different number"
Since that choice always != 3, you will get an infinite loop.
You should get input again if it jumps into the "else" condition.
In your code, the while loop should encapsulate the input() line. The following is a clearer alternative, however:
Create a function which gets user input:
def getInteger(prompt):
while True:
userIn = input(prompt)
try:
return int(userIn)
except ValueError:
print "Error"
Here's something: I dislike making the user enter "" around the strings.
ch = raw_input("Enter choice: ")
#ch *is* a string at this point
if ch.isdigit():
choice = int(ch)
else:
print "Invalid choice"
Edit (from comments):
isdigit may not handle locale encoding correctly. In Python 3, you can use isdecimal instead.
— J.F. Sebastian

Categories