Check if the input is a string in python - python

I am trying to check if my input is a string with try-except block. The function runs without an error. However it checks if the input is an integer, not string. How can I inverse this?
def lexicon(word):
while True:
try:
a=str(input(word))
print("Input is a string. string = ", a)
except ValueError:
print("Oops..Input is not supposed to be a number. Try again!")
return a
b=lexicon("Enter the word you'd like: ")

As discussed with user pavel in the comments to his answer, there are two different styles to code for a problem like this: EAFP ("Easier to Ask for Forgiveness than Permission"), meaning that you make your code work on an assumption and take action if it fails; and LBYL ("Look Before You Leap"), in which you first check whether your assumption is true, and then choose the appropriate action to take.
The try/except route is EAFP, since it just executes the code in the try block without bothering to first check whether it would work. If you want to do it in LYBL style, you would explicitly need to ascertain whether the user input is a string representation of a numeric value, and then act accordingly. I'll provide skeletal code for both approaches below. However, note that Python is a little weird compared to other languages in that it seems to have a certain cultural favour for EAFP.
Also, since you are only asking about checking for integers, I will focus on that here. This means that the code will accept floats as valid inputs.
EAFP: try/except
The problem that presumably trips you up is that input always returns a string, so testing if it is a string is nonsensical and will always yield True. However, note that try/except is only an abrigded version of error handling that you can do in Python; the full version is try/except/else/finally. The else block takes effect if no except blocks are executed, and finally is always run at the end. So you could check whether your input is an integer, and make the program raise a failure if that check succeeds. I admit however that this does seem a bit backwards.
try:
a = int(input())
except ValueError:
# do whatever
else:
raise ValueError("Input must not be an integer")
LBYL: if/else
str objects have several methods to test their contents without having to run into errors. For example, .isalpha() checks if all characters are in the alphabet (which returns False however if you include spaces and special characters); isnumeric() checks whether the string is a representation of a number; etc. See a full list here. So depending on what kind of inputs you want to allow, you would need to use one of these methods, or a combination of them, in an if block. The code below essentially does the same thing as the try/except/else version above, using .isdigit() which returns True if all characters in the string are digits (i.e., the same kind of input for which int(a) would succeed).
Note also that I am making use of the new assignment operator := in this code, which is new to Python 3.8. This way, you don't need to explicitly assign the variable a first, however it's a bit harder to catch where the code actually executes an input() function. If you code for backwards compatibility, or don't like the look of this, you'd have to go with the classical a = input() first.
if (a := input()).isdigit():
raise ValueError("Input must not be an integer")
# do whatever

If you want specifically to check the value type of the string, you're better off using if/else and isinstance:
if not isinstance(word, str):
raise TypeError(f"Expecting a string as a value, not {type(word)}.")
else:
#do something

Related

Conditional isn't working while checking input type int

Well I'm very very new to python programming and still learning.So I tried to create a function where I used len to count the number of letters in a string.But since, len doesn't work for integers I set up conditionals so that it would return a message saying "integers don't have length".
But I'm not getting the message even when I type an integer. please help me to solve this.
here is my code:
def Length_String(L):
if type(L) == int:
return "sorry,integers don't have length"
else:
return len(L)
x = input()
y = Length_String(x)
print(y)
It's not that important but still I want to know what is causing the conditional not to work. please help me.
Note you can always type help(whatever) in a Python prompt to read some useful stuff about it:
input(...)
input([prompt]) -> string
Read a string from standard input. The trailing newline is stripped.
If the user hits EOF (Unix: Ctl-D, Windows: Ctl-Z+Return), raise EOFError.
On Unix, GNU readline is used if enabled. The prompt string, if given,
is printed without a trailing newline before reading.
So you always get a string. One way to see if this string could be converted to an integer is:
try:
int(L)
return "Error, this is an integer!"
except ValueError:
return len(L)
Of course, this won't work for floats, so there maybe more checks you want to do (or just use float(L)). Another way
if L.isnumeric(): # or isdigit or isdecimal
return "Error, this is a number!"
return L
Here it's worth mention that in addition to the help which can show methods you can always type dir(something) in a Python prompt so see some useful methods in a list.
They input function in Python returns a value of type str even if what you type in is an integer value.
In Python input() returns string no matter what you enter. So you don't need to check if the entered value is an int. If you still want to check it, you could do it with isinstance function:
if isinstance(L, int):
return "sorry,integers don't have length"

Creating one for loop for 3 strings

So I have a String called 'Number' with 'abf573'. The task is, to find out if the String 'Number' just has characters and numbers from the Hexadecimal System.
My plan was to make a for loop, where we go through each position of the String 'Numbers', to check with an if statement if it is something out of the Hexadecimal System. To check that, I thought about writing down the A-F, a-f and 0-9 into Lists or separat Strings.
My Problem now is, that I have never done something like this in Python. I know how to make for loops and if-/else-/elif-Statements, but I dunno how to implement this in to this Problem.
Would be nice, if someone can give me a hint, how to do it, or if my way of thinking is even right or not.
I find it quite smart and fast to try to convert this string into an integer using int(), and to handle the exception ValueError which occurs if it is not possible.
Here is the beautiful short code:
my_string = 'abf573'
try:
result = int(my_string, 16)
print("OK")
except ValueError:
print("NOK")
Strings are iterables. So, you can write
Number = '12ab'
for character in Number:
if character in 'abcdef':
print('it is HEX')
Also, there is an isdigit method on strings, so your number is hex is not Number.isdigit()

setting "if" to make sure variable is a number and not a letter/symbol

How do I create an "if" statement to make sure the input variable is a number and not a letter?
radius = input ('What is the radius of the circle? ')
#need if statement here following the input above in case user
#presses a wrong key
Thanks for your help.
Assuming you're using python2.x: I think a better way to do this is to get the input as raw_input. Then you know it's a string:
r = raw_input("enter radius:") #raw_input always returns a string
The python3.x equivalent of the above statement is:
r = input("enter radius:") #input on python3.x always returns a string
Now, construct a float from that (or try to):
try:
radius = float(r)
except ValueError:
print "bad input"
Some further notes on python version compatibility
In python2.x, input(...) is equivalent to eval(raw_input(...)) which means that you never know what you're going to get returned from it -- You could even get a SyntaxError raised inside input!
Warning about using input on python2.x
As a side note, My proposed procedure makes your program safe from all sorts of attacks. Consider how bad a day it would be if a user put in:
__import__('os').remove('some/important/file')
instead of a number when prompted! If you're evaling that previous statement by using input on python2.x, or by using eval explicitly, you've just had some/important/file deleted. Oops.
Try this:
if isinstance(radius, (int, float)):
#do stuff
else:
raise TypeError #or whatever you wanna do

Specify input() type in Python?

Is it possible to define input times, like time, date, currency or that should be verified manually? Like for example:
morning = input('Enter morning Time:')
evening = input('Enter evening Time:')
.. I need (only) time here, how do I make sure that user enters input in xx:xx format where xx are integers only.
input (in Python 2.any) will return the type of whatever expression the user types in. Better (in Python 2.any) is to use raw_input, which returns a string, and do the conversion yourself, catching the TypeError if the conversion fails.
Python 3.any's input works like 2.any's raw_input, i.e., it returns a string.
You can't really force the input function to return a certain type. It's best you write some kind of a wrapper that reads some input from the user and then converts it to an appropriate type for your application (or throw an exception in case of an error).
Also, as Alex said, it's better to use raw_input for user input since it will always return the entered value as a string. Much more manageable.

What's the most pythonic way of testing that inputs are well-formed numbers

I have a function that expects real numbers (either integers or floats) as its input, and I'm trying to validate this input before doing mathematical operations on it.
My first instinct is to cast inputs as floats from within a try-except block.
try:
myinput = float(input)
except:
raise ValueError("input is not a well-formed number")
I could also call isinstance(mydata, (float, int, long) ) but the list of "all these could be numbers" seems a bit inelegant to me.
What's the most pythonic way of going about it? Is there another option I overlooked?
To quote myself from How much input validation should I be doing on my python functions/methods?:
For calculations like sum, factorial etc, pythons built-in type checks will do fine. The calculations will end upp calling add, mul etc for the types, and if they break, they will throw the correct exception anyway. By enforcing your own checks, you may invalidate otherwise working input.
Thus, the best option is to leave the type checking up to Python. If the calculation fails, Python's type checking will give an exception, so if you do it yourself, you just duplicate code which means more work on your behalf.
In Python 2.6 and 3.0, a type hierarchy of numeric abstract data types has been added, so you could perform your check as:
>>> import numbers
>>> isValid = isinstance(myinput , numbers.Real)
numbers.Real will match integral or float type, but not non-numeric types, or complex numbers (use numbers.Complex for that). It'll also match rational numbers , but presumably you'd want to include those as well. ie:
>>> [isinstance(x, numbers.Real) for x in [4, 4.5, "some string", 3+2j]]
[True, True, False, False]
Unfortunately, this is all in Python >=2.6, so won't be useful if you're developing for 2.5 or earlier.
Maybe you can use a combination of assert and isinstance statements.
Something like the following is I think a more pythonic way, as you throw an exception whenever your inputs don't follow your requirements. Unfortunately I don't see any better definition of what is a valid number than yours. Maybe someone will come with a better idea.
number = (float, int, long)
assert isinstance(mydata, (float, int, long))
I don't get the question.
There are two things with wildly different semantics tossed around as "alternatives".
A type conversion is one thing. It works with any object that supports __float__, which can be quite a variety of objects, few of which are actually numeric.
try:
myinput = float(input)
except:
raise ValueError("input is not a well-formed number")
# at this point, input may not be numeric at all
# it may, however, have produced a numeric value
A type test is another thing. This works only with objects that are proper instances of a specific set of classes.
isinstance(input, (float, int, long) )
# at this point, input is one of a known list of numeric types
Here's the example class that responds to float, but is still not numeric.
class MyStrangeThing( object ):
def __init__( self, aString ):
# Some fancy parsing
def __float__( self ):
# extract some numeric value from my thing
The question "real numbers (either integers or floats)" is generally irrelevant. Many things are "numeric" and can be used in a numeric operation but aren't ints or floats. For example, you may have downloaded or created a rational numbers package.
There's no point in overvalidating inputs, unless you have an algorithm that will not work with some types. These are rare, but some calculations require integers, specifically so they can do integer division and remainder operations. For those, you might want to assert that your values are ints.

Categories

Resources