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!
Related
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?
I can't seem to get my except statement to print when forcing an error.
PLANT_DATA = { 'daisy': 'diasy.csv',
'rose': 'rose.csv',
'cucumber': 'cucumber.csv' }
def filters():
print('Let\'s explore some plant data')
while True:
plant = input("Would you like to see data for Cucumber, Daisy or Rose plants?").lower()
if plant in PLANT_DATA.keys():
try:
print("Looks like you want to hear about {} plants!".format(plant))
break
except ValueError:
print("That is not a valid plant! Please try again.")
filters()
You're almost there. Yes:
print("Looks like you want to hear about {} plants!".format(city))
Is almost certainly going to throw an error, because city is not defined. But it's not guaranteed to throw an error because you have a logical blocker:
if plant in PLANT_DATA.keys():
If this is not True, you never get to your exception handler. It will just got back to another loop of the outer while loop. To get past this, you need to enter a valid key from PLANT_DATA. So, daisy, rose or cucumber as inputs will clear this check and make sure that you throw an error. However, it will be a NameError, not a ValueError.
It's very easy to throw an error; int('hi') would throw an error, for example, but it won't fit into the context of what you're trying to at all. So I think you're correct in keeping the example as it is, without changing the logic; you're wandering into python testing (and that's not a bad thing)
The following line;
if plant in PLANT_DATA.keys():
Checks if the provided key exists in the dictionary. You never reach your except clause as you're already performing the check earlier in code. This is why whenever you enter an incorrect value, it prompts you for the question again.
If you need to print an error, try this.
if plant not in PLANT_DATA.keys():
print("That is not a valid plant! Please try again.")
else:
print("Looks like you want to hear about {} plants!".format(city))
I am trying to make an input that would prevent a user entering an input like this "QWERTY" this "qwerty" or this "QW3RTY"
The input is for names so I want to make sure that it would need the user to have a capital letter at the start of their name "John" not "john"
I have tried to loop the question using while True: try and attempted to use .isalpha and .title but I couldnt seem to make it work
while True:
try:
name = input(str("What is your name? "))
if name is not name.isalpha:
print("Please Enter a Valid name")
continue
if name is not name.title:
print("Please have a capital letter at the start of your name!")
continue
else:
break
I expected for the if statements to work but it comes up with invalid syntax.
Your logic is faulty ... but you've replicated it, even though the first if failed. Correct your problems one at a time, rather than trying to write the whole program at once.
name is a string; name.isalpha is a function.
A string cannot ever be identical to a function.
I think what you want is
if name.isalpha():
Also, try requires an except clause to catch exceptions. Again, add program features individually. That way, when you hit an error, you'll be fixing only that one error.
See this lovely debug blog for help.
Implementing features one at a time is a much better place to start than to try to catch everything all at once. Also, make sure to call your functions, otherwise, they will be truthy:
if str:
print("True!")
else:
print("False!")
True!
# compared to
if str():
print("True!")
else:
print("False!")
False!
Functions are objects, and will not act Falsey.
while True:
name = input("What is your name? ") # no need for str function here
# you can wrap this whole thing in a
# try/except for ValueError
try:
if name.isupper() or name.islower() or not name == name.title():
raise ValueError("Please include proper capitalization")
elif not name.isalpha():
raise ValueError("Use only alphabetical characters, please")
else:
break
except ValueError as e:
print(e)
Alright so I'm trying to basically prevent someone from typing a string value into the field:
#User selection
print("Which program would you like to run?")
print("(Type '9' if you wish to exit the menu)")
selection = int(input())
print()
#Security statement followed by case statement
while selection <= 0 or selection >= 10:
try:
print("That is an invalid selection, please input a proper selection.")
print("Which program would you like to run?")
selection = int(input())
print()
except ValueError:
print("Cmon man")
Plain and simple, it's not running. I've tried reorganizing everything and I haven't found a proper solution. Been looking around for almost an hour now. No help to the issue. Any kind souls?
Ignore the case statement portion btw, that's not even written yet.
P.S. Just keep getting usual "String isn't a number durr" response
("ValueError: invalid literal for int() with base 10: 'why'")
P.P.S. Issue is already pointed out. I'm apparently stupidly oblivious lol... Thanks for the help.
Your try...except doesn't cover the initial user input and so the ValueError isn't actually caught.
If you enter an int outside the bounds defined (0 >= x >= 10) as the first input then you can see the try...except blocks working.
You'll need to refactor your code so that the first input request is inside your try block and the loop or wrap the existing input request in another try...except.
Also, as a side note, input() can take a string argument that will be displayed as a prompt to the user.
selection = int(input("Which program would you like to run? "))
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