Getting safe user input in python - python

I'm writing a script that needs some very simple input from the user, and upon doing my research on this I am in a dilemma trying to work out the safest way to do it.
I only want an integer and stumbled across (what I thought was) a nice piece of code similar to (doing this from memory):
def getNumeric(prompt):
while True:
response = input(prompt)
try:
return int(response)
except ValueError:
print "please enter a number:",
This mostly worked, but if the user just pressed [enter] then it crashed. Turns out, I'm using python < 3, and the author wrote this for 3+. So now I have to rewrite for 2.7 to suit my needs. But how do I write it to cater for EITHER platform <3 and 3+?
I am writing something that could be used by others and want to make it the most portable I can. Should I bother?
As an aside, I am doing this for the Raspberry Pi, should I upgrade my python to 3, or leave it where it is (2.7.3)?

My suggestion is to upgrade the Pi to Python 3. There's no point developing Python code for two separate versions (unless it's a library, which you'd use much more precautions than just sharing functions). You can do:
# Python 3.x
def getNumeric(prompt):
while True:
try:
res = int(input(prompt))
break
except ValueError:
print("Numbers only please!")
return res
For Python 2.7.x, use raw_input() instead of input(). input() in Python 2 is not considered save since it evaluates the string given (and can be malicious).

Try:
def getNumeric(prompt):
while True:
response = input(prompt)
try:
if isinstance(response, int):
return int(response)
else:
print "please enter a number:"
except ValueError:
print "please enter a number:"

Related

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!

Check if input is a integer

I am writing a program that will ask the user to enter in an integer, and if it is not an integer, i will print "Error" and exit the program.
I tried this:
userNumber = input()
try:
val = int(userNumber)
except ValueError:
print("Error")
exit()
But this is not working and is giving me an error.
How can I fix this?
You're using Python 2 I think this is what you're looking for, and if you want a real print function (like Python 3 has), include this import at the top of your header:
from __future__ import print_function
userNumber = raw_input() # `input` in python 3,
# the `input` function in '2' is actually processed as Python.
# equivalent to eval(raw_input(prompt))
try:
val = int(userNumber)
except ValueError:
print("Error") # This is a print statement without the import in Python 2,
# In which case the parentheses are ignored.
exit()
In Python 2, input is equivalent to eval(raw_input(prompt)).
There are numerous problems with your program. The indentation is incorrect - the statements under try and except should be indented. Second, it's ValueError, not valueError. Third, you should be using print() instead of printf(). Finally, since you appear to be using Python 2, you should be using raw_input() instead of input().

except ValueError not tripping Python 3.4

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? "))

Raw input function inside Python def parameter

Please see the code below -
def add(a, b):
print "ADDING %d + %d" % (a, b)
return a + b
print "Let's do some math with just functions!"
age = add(float(raw_input("Add this:")), float(raw_input("To this:")))
Is there anyway, I can shorten the last line? Or, is there another way of getting user input?
Thanks
Applying "don't repeat yourself", we can take the repeated code and make a function out of it:
def add(a, b):
print "ADDING %d + %d" % (a, b)
return a + b
print "Let's do some math with just functions!"
def getf(prompt_mesg):
s = raw_input(prompt_mesg)
return float(s)
age = add(getf("Add this:"), getf("To this:"))
And then if you want you can make the input function handle errors better. Instead of raising an exception that takes down the whole program, you can handle errors gracefully:
def getf(prompt_mesg):
while True:
try:
s = raw_input(prompt_mesg)
return float(s)
except ValueError:
print("Could not convert that input. Please enter a number.")
This will loop forever until the user enters a valid input (or terminates the program).
I see you're using p2.x. First thing - I'd recommend switching to p3.x (it has many enhancements, but in this case you'll be happy to see that raw_input() became input() and input () with evaluation is gone).
Other way to shorten this stuff is using input() instead of raw_input(). If user gives you anything that is not a number, you'll get some sort of exception at addition, if he gives you a number (float, int, whatever) - your program will work.
==EDIT==
As glglgl pointed out - second part is dangerous and warning here is appriopriate. Using input() is basically the same as eval(raw_input()). Unfortunately, I forgot about the fact, that it doesnt take locals and globals parameters like eval - if it would, you could make it safe. For real-life applications it shouldnt be used, because some rogue user could evaluate anything he wants, causing program (or even computer) to crash. For simple apps like that, I stand my ground, and keep saying that it is useful.

input with input suggestion in Python

I do not know how to ask a user for input giving him a hint at the same time.
When I use raw_input("some description") a small window pops up and the user must enter something, as the input is completely empty. How to achieve the same, but with something already written to the input box (a hint for the user, which he/she could accept or simply change it)?
This has been answered before:
https://stackoverflow.com/a/2533142/1217949
The standard library functions input() and raw_input() don't have this functionality. If you're using Linux you can use the readline module to define an input function that uses a prefill value and advanced line editing:
def rlinput(prompt, prefill=''):
readline.set_startup_hook(lambda: readline.insert_text(prefill))
try:
return raw_input(prompt)
finally:
readline.set_startup_hook()

Categories