[ Python's type() function and its 'if' related problems ]
So I have the following code:
user_input = raw_input("Enter an integer, string or float:")
input_type = type(user_input)
if input_type == "str":
print "Your string was %s." % user_input
elif input_type == "int":
input_type = int(input_type)
print "Your integer was %d." % user_input
elif input_type == "float":
input_type = int(input_value)
print "Your float was %d." % user_input
else:
print "You did not enter an acceptable input."
This does not work — I believe because of the if
— so I changed it to be:
if "str" in input_type
and "int"
for the float and integer, but get an error:
Traceback (most recent call last):
File "types.py", line 4, in <module>
if "str" in input_type:
TypeError: argument of type 'type' is not iterable
Why do I get this and how can I fix it?
Answer 1
There are a number of problems here.
user_input = raw_input("Enter an integer, string or float:")
input_type = type(user_input)
Since raw_input
always returns a string, input_type
will always be str
here.
if input_type == "str":
print "Your string was %s." % user_input
input_type
will be str
—that is, the actual object representing the string type—not "str"
, which is just a string. So, this will never be true, and neither will any of your other tests.
Changing this to:
if "str" in input_type:
… can't possibly help anything, unless you're expecting input_type
to be either a collection of strings, or a longer string with "str"
in the middle of it somewhere. And I can't imagine why you'd expect either.
These lines:
input_type = int(input_type)
… are trying to convert the input_type
—which, remember, is a type, like str
or int
, not the value—to an integer. That can't be what you want.
These lines:
print "Your integer was %d." % user_input
Are printing the original string you received from the user, not the thing you converted to an int
. This would work if you used %s
rather than %d
, but it's probably not what you were trying to do.
print "Your float was %d." % user_input
Even if you fix the previous problem, you can't use %d
to print floats.
Next, it's almost always a bad idea to test things by comparing types.
If you really need to do it, it's almost always better to use isinstance(user_input, str)
not type(user_input) == str
.
But you don't need to do it.
In fact, it's generally better to "ask forgiveness than permission". The right way to find out if something can be converted to an integer is to just try to convert it to an integer, and handle the exception if it can't:
try:
int_value = int(user_input)
print "Your integer was %d." % int_value
except ValueError:
# it's not an int
Answer 2
First of all, "does not work" is not useful. Please in the future explain exactly how it's not working, what you expect and what you get that is unsatisfactory.
Now to your problem: raw_input
will always return a string. It is up to you to see if contents of that string conform to something that looks like an integer or a float, and convert accordingly. You know how to convert; the conformity testing would normally be done through a regular expression.
Answer 3
You would need to use isinstance
and input
to get your code to do what you expect as follows:
user_input = input("Enter an integer, string or float:")
if isinstance(user_input, str):
print "Your string was %s." % user_input
elif isinstance(user_input, int):
print "Your integer was %d." % user_input
elif isinstance(user_input, float):
print "Your float was %f." % user_input
else:
print "You did not enter an acceptable input."
raw_input
always returns a string.
When using input
, you must include ' or " around a string input. Also, never use input
like this because it can be very dangerous. Use the try except
method suggested by abarnert.
Answer 4
While I don't think this is a true duplicate, Differences between isinstance() and type() in python contains a very relevant answer and is good to read.
You would ultimately want to write a try/except
that treats the data appropriately.
if isinstance(user_input, str): #or basestring, if you prefer, but Python 3 apparently doesn't use it
useThisLikeAString(user_input)
try:
intInput = int(user_input)
useThisLikeAnInt(user_input)
except TypeError:
useThisLikeSomethingElse(user_input)
The accepted answer is totally right, in other words, but the link to that discussion is worthwhile.