How to test if something is not an integer? [duplicate] - python

This question already has answers here:
Asking the user for input until they give a valid response
(22 answers)
Closed 7 years ago.
I have to create a calculator for a small piece of schoolwork and I ask for inputs for the numbers and the symbol that will be used:
number1=int(input("\nWhat is your first number?"))
number2=int(input("\nWhat is your second number?"))
symbol=input("\nWhat is the symbol you will use?")
I want to know if there is any way I can make the int(input()) be asked again if they enter anything apart from an integer.
I'm not really good with Python atm so apologies if I missed something obvious.
Also sorry if this thread is a duplicate.

The canonical method in python would be something like:
def get_integer_or_retry(mesg)
while True:
val = input(mesg) # or raw_input for python 2
try:
val = int(val)
return val
except ValueError: #trying to cast string as int failed
pass # or you could let the user know their input was invalid
Note that if the user inputs 1.0 (or some other decimal that is also an integer), this will still throw ValueError (thanks Robᵩ ); if you need to handle floats that happen to be integers, you could do val = int(float(val)), but that will also accept (and silently round down) floating numbers ...

To know a variables type do type(var).
So, basically what you need to do:
if type(variable)==int:
do_something

Try isinstance method (https://docs.python.org/3/library/functions.html#isinstance)
>>> isinstance(5, int)
True
>>> isinstance("a", int)
False
in your case write a conditional, like,
if isinstance(number1, int):
#do something
The isinstance() built-in function is recommended for testing the type
of an object, because it takes subclasses into account.

I'm going to assume Python 2.7 for this answer.
I suggest first getting the input as a string, using raw_input, and
then trying to convert that to an integer. Python will raise an
exception if the conversion fails, which you can catch and prompt the
user to try again.
Here's an example:
while True:
try:
s1 = raw_input('Enter integer: ')
n1 = int(s1)
# if we get here, conversion succeeded
break
except ValueError:
print('"%s" is not an integer' % s1)
print('integer doubled is %d' % (2*n1))
and here's a sample execution, with inputs:
$ python 33107568.py
Enter integer: foo
"foo" is not an integer
Enter integer: 1.1
"1.1" is not an integer
Enter integer: 0x23123
"0x23123" is not an integer
Enter integer: 123
integer doubled is 246
On Python 3, you'd need to use input instead of raw_input; in
Python 2, input evaluates the user input as a Python expression,
which is rarely what is desired.

Related

How to change my string with dot to int in python [duplicate]

This question already has answers here:
ValueError: invalid literal for int() with base 10: ''
(15 answers)
Closed last month.
I'm new to the whole coding thing...so here goes.
Just trying to write a simple number guess game, but also do input validation. So that only integers are accepted as input. I've figured out how to weed out alphabetic characters, so I can convert the numbers into an integer. I'm having trouble when I put in a float number. I can't get it to convert the float number over to an integer. Any help is appreciated. As I said I'm on about day 3 of this coding thing so try to be understanding of my little knowledge. Thanks in advance.
Here's the function from my main program.
def validateInput():
while True:
global userGuess
userGuess = input("Please enter a number from 1 to 100. ")
if userGuess.isalpha() == False:
userGuess = int(userGuess)
print(type(userGuess), "at 'isalpha() == False'")
break
elif userGuess.isalpha() == True:
print("Please enter whole numbers only, no words.")
print(type(userGuess), "at 'isalpha() == True'")
return userGuess
Here's the error I'm getting if I use 4.3 (or any float) as input.
Traceback (most recent call last):
File "C:\\*******.py\line 58, in <module>
validateInput()
File "C:\\*******.py\line 28, in validateInput
userGuess = int(userGuess)
ValueError: invalid literal for int() with base 10: '4.3'
Actually int() function expects an integer string or a float, but not a float string. If a float string is given you need to convert it to float first then to int as:
int(float(userGuess))
Don't use isalpha to screen the output. EAFP -- convert it and handle that exception. Either the ValueError is exactly what you want, in that you can handle it and tell the user to correct their input. Or for some odd reason you want to silently correct their input from "4.3" to "4".
def validateInput():
while True:
global userGuess
userGuess = input("Please enter a number from 1 to 100. ")
try:
int(userGuess)
return userGuess # you shouldn't really keep this string...
except ValueError as e:
print("Please enter whole numbers only, no words.")
First, why do you want to convert the float string to an integer? Do you want to treat 4.7 as meaning the user has guessed 4? Or 5? Or a legal but automatically-invalid guess? Or as actually the value 4.7 (in which case you don't want integers at all)? Or…?
Second, the way you're approaching this is wrong. userGuess.isalpha() only tells you that the guess is made entirely of letters. That means you're still going to treat, say, "Hello!" as a number, because it has at least one non-letter.
If you want to know if a string is a valid integer, just call int on it, and use a try/except to handle the case where it isn't:
def validateInput():
while True:
global userGuess
userGuess = input("Please enter a number from 1 to 100. ")
try:
userGuess = int(userGuess)
print(type(userGuess), "after int succeeeded")
break
except ValueError:
print("Please enter whole numbers only, no words.")
print(type(userGuess), "after int failed")
return userGuess
If you want to handle actual words differently from other kinds of failure, e.g., so you can print a more specific error message, then you can check isalpha inside the except clause.
If you want to handle check whether it's a float so you can give a different error, do the same thing—try to call float(userGuess)—inside the except clause. Or, if you want to truncate floats, change that int(userGuess) to int(float(userGuess)).
You may also want some other checks even inside the try part. For example, what if they type -23 or 178? Those are integers, but they're not numbers between 1 and 100.
Obviously, the more validation you want, the more code it takes, because each test is another line of code. So, you may want to consider moving the validation out to a separate function from the looping over input, to make it more readable.
You could use string manipulation and typecasting.
int(userGuess.split('.')[0])

Is isinstance() function not enough to detect integers and floats?

I'm making a very basic calculator as my first project (I'm learning Python and want something to show what i've learned so far) and as it is right now, the program works fine.
As it is right now, I have a function to validate user inputs so that the code only accepts numbers and decimal points, and returns the input as a float value to be calculated.
However, I would like to make it so that the code can recognize if the user is entering an Integer or a Float value, so that a simple operation such as "2+2" doesn't return a float "4.0" result, and just a "4".
The function that I have working right now is the following:
def valid_num():
number = ''
valid = True
while valid:
try:
number = float(input('───→ '))
break
except ValueError:
print('')
print('Invalid input (numbers and decimal points only).')
return number
To be able to diferentiate between integers and float values, I looked up methods and found the isinstance() function, which I may not be applying correctly... This is the function that I'm trying to make work:
def valid_num():
number = ''
valid = True
while valid:
number = input('───→ ')
check_int = isinstance(number, int)
if check_int:
number = int(number)
break
check_float = isinstance(number, float)
if check_float:
number = float(number)
break
if not check_int and not check_float:
print('Invalid input (numbers and decimal points only).')
return number
Sorry if there's an obvious error I'm not seeing, I'm just starting to code... Thanks in advance for any help you can provide =D
As pointed out by #tim-roberts, isinstance(number, int) checks the type of number, which is a string.
To distinguish ints and floats, you have a couple of options:
Try to convert it to int, if that fails try to convert to float; this would use a pair of try/except clauses.
Validate the input as text, checking that it follows the rules you set for your calculator, probably using regular expressions; this would let you positively assert that it matches what you expect, rather than whatever the int and float functions accept.
You could also work throughout in float (or Decimal), then convert 4.0 to 4 on output; that would mean that you'd also get "4" for "0.5 * 8" (which may be better or worse than getting "4.0"; that's up to your UX design).

How do I prompt a user to choose an interval between 0-90 and store as a float? [duplicate]

This question already has answers here:
Asking the user for input until they give a valid response
(22 answers)
Closed 3 years ago.
I have a code thus far, but I'm trying to prompt the user to enter a number between [0-90], say 20 for example and store it as a float.
The code so far looks like this:
x=input("Choose a number Between [0, 90]")
x=float(20)
The goal is to get them to choose 20; If they choose a different number, it'll quit.
Python is a "duck typed" language. Since any variable can be any type, determined at the time of assignment, you need to explicitly check the value input to make sure it's between 0 and 99.
# First Set a standard error message here.
# Note the use of "{}" which will be filled in using the python method "format" later.
err = "The value must be a floating point number between 0 and 99. The value '{}' is invalid."
# Then get the value itself.
x=input("Choose a number Between [0, 90]")
# The value "x" will be a string, no matter what is typed. So you must convert it to a float.
# Because an invalid input (such as "a") will error out, I would use a try/except format.
try:
x=float(x)
except ValueError as e:
print(err.format(x))
# Then check the value itself
if ( (x < 0) or (x > 99) ):
raise ValueError(err.format(x))
#עומר דודסון's answer is also correct, in the sense that it will try to convert the input to a float, at the time of input. If an invalid input, such as "a" is entered, it will raise an error...so I would still put it in a try/except...
try:
x=float( input("Choose a number Between [0, 90]") )
except ValueError as e:
print(err.format(x))
# But you still need to check the value itself
if ( (x < 0) or (x > 99) ):
raise ValueError(err.format(x))
if you want to store the input as a float then use the function "float":
x=float(input("Choose a number Between [0, 90]"))

Even if the first command in if is true it doesn't print what i want , it only print the else command [duplicate]

This question already has answers here:
How do I check if a string represents a number (float or int)?
(39 answers)
How can I read inputs as numbers?
(10 answers)
Asking the user for input until they give a valid response
(22 answers)
Closed 6 months ago.
numberchk=(int(input("Enter a Roman numeral or a Decimal numeral:" )))
def int2roman(number):
numerals={1:"I", 4:"IV", 5:"V", 9: "IX", 10:"X", 40:"XL", 50:"L",
90:"XC", 100:"C", 400:"CD", 500:"D", 900:"CM", 1000:"M"}
result=""
for value, numeral in sorted(numerals.items(), reverse=True):
while number >= value:
result += numeral
number -= value
return result
if numberchk==int:
print(int2roman(int(numberchk)))
else:
print("error")
Use isinstance(numberchk, int) instead, because int is a type but numberchk is an instance of that type.
Since int(input(... always returns an integer as long as it can, you don't have to check it using if-else. To suppress error raising if input is not an integer, use try-except as #poke mentioned.
You can also use a while-loop and break to request the user input repeatedly until you get an legal input:
while True:
try:
numberchk=int(input("Enter a Roman numeral or a Decimal numeral:" ))
break
except ValueError:
print('error')
print(int2roman(numberchk))
if numberchk==int:
This will check if numberchk is equal to the int type. It will not check if numberchk is an integer (which you probably want to do). The correct way to check its type would be this:
if isinstance(numberchk, int):
However, this won’t make sense either. The way you get numberchk is by calling int() on a string:
numberchk=int(input(…))
So numberchk will always be an int. However, calling int() on a string that is not a number can fail, so you probably want to catch that error to find out whether or not the input was a number:
try:
numberchk = int(input("Enter a Roman numeral or a Decimal numeral:"))
except ValueError:
print('Entered value was not a number')
But this will again will be problematic, as—at least judging by the message you’re printing—you also want to accept Roman numerals, which can’t be converted to integers by int. So you should also write a function that takes a Roman numeral and converts it into an int.
Try using isdigit() function.
replace this part on your code
if numberchk==int:
with
if numberchk.isdigit():
Check the integer type instead of matching variable with int.
You can check type of variable with isinstance method.

Checking whether a variable is an integer or not [duplicate]

This question already has answers here:
What's the canonical way to check for type in Python?
(15 answers)
Closed 3 years ago.
The community reviewed whether to reopen this question last year and left it closed:
Original close reason(s) were not resolved
How do I check whether a variable is an integer?
If you need to do this, do
isinstance(<var>, int)
unless you are in Python 2.x in which case you want
isinstance(<var>, (int, long))
Do not use type. It is almost never the right answer in Python, since it blocks all the flexibility of polymorphism. For instance, if you subclass int, your new class should register as an int, which type will not do:
class Spam(int): pass
x = Spam(0)
type(x) == int # False
isinstance(x, int) # True
This adheres to Python's strong polymorphism: you should allow any object that behaves like an int, instead of mandating that it be one.
BUT
The classical Python mentality, though, is that it's easier to ask forgiveness than permission. In other words, don't check whether x is an integer; assume that it is and catch the exception results if it isn't:
try:
x += 1
except TypeError:
...
This mentality is slowly being overtaken by the use of abstract base classes, which let you register exactly what properties your object should have (adding? multiplying? doubling?) by making it inherit from a specially-constructed class. That would be the best solution, since it will permit exactly those objects with the necessary and sufficient attributes, but you will have to read the docs on how to use it.
All proposed answers so far seem to miss the fact that a double (floats in python are actually doubles) can also be an integer (if it has nothing after the decimal point). I use the built-in is_integer() method on doubles to check this.
Example (to do something every xth time in a for loop):
for index in range(y):
# do something
if (index/x.).is_integer():
# do something special
Edit:
You can always convert to a float before calling this method. The three possibilities:
>>> float(5).is_integer()
True
>>> float(5.1).is_integer()
False
>>> float(5.0).is_integer()
True
Otherwise, you could check if it is an int first like Agostino said:
def is_int(val):
if type(val) == int:
return True
else:
if val.is_integer():
return True
else:
return False
Here's a summary of the different methods mentioned here:
int(x) == x
try x = operator.index(x)
isinstance(x, int)
isinstance(x, numbers.Integral)
and here's how they apply to a variety of numerical types that have integer value:
You can see they aren't 100% consistent. Fraction and Rational are conceptually the same, but one supplies a .index() method and the other doesn't. Complex types don't like to convert to int even if the real part is integral and imaginary part is 0.
(np.int8|16|32|64(5) means that np.int8(5), np.int32(5), etc. all behave identically)
If you really need to check then it's better to use abstract base classes rather than concrete classes. For an integer that would mean:
>>> import numbers
>>> isinstance(3, numbers.Integral)
True
This doesn't restrict the check to just int, or just int and long, but also allows other user-defined types that behave as integers to work.
>>> isinstance(3, int)
True
See here for more.
Note that this does not help if you're looking for int-like attributes. In this case you may also want to check for long:
>>> isinstance(3L, (long, int))
True
I've seen checks of this kind against an array/index type in the Python source, but I don't think that's visible outside of C.
Token SO reply: Are you sure you should be checking its type? Either don't pass a type you can't handle, or don't try to outsmart your potential code reusers, they may have a good reason not to pass an int to your function.
Why not try something like:
if x%1 == 0:
Rather than over complicate things, why not just a simple
if type(var) is int:
A simple method I use in all my software is this. It checks whether the variable is made up of numbers.
test = input("Enter some text here: ")
if test.isdigit() == True:
print("This is a number.")
else:
print("This is not a number.")
You can also use str.isdigit. Try looking up help(str.isdigit)
def is_digit(str):
return str.isdigit()
Found a related question here on SO itself.
Python developers prefer to not check types but do a type specific operation and catch a TypeError exception. But if you don't know the type then you have the following.
>>> i = 12345
>>> type(i)
<type 'int'>
>>> type(i) is int
True
it's really astounding to see such a heated discussion coming up when such a basic, valid and, i believe, mundane question is being asked.
some people have pointed out that type-checking against int (and long) might loose cases where a big decimal number is encountered. quite right.
some people have pointed out that you should 'just do x + 1 and see whether that fails. well, for one thing, this works on floats too, and, on the other hand, it's easy to construct a class that is definitely not very numeric, yet defines the + operator in some way.
i am at odds with many posts vigorously declaring that you should not check for types. well, GvR once said something to the effect that in pure theory, that may be right, but in practice, isinstance often serves a useful purpose (that's a while ago, don't have the link; you can read what GvR says about related issues in posts like this one).
what is funny is how many people seem to assume that the OP's intent was to check whether the type of a given x is a numerical integer type—what i understood is what i normally mean when using the OP's words: whether x represents an integer number. and this can be very important: like ask someone how many items they'd want to pick, you may want to check you get a non-negative integer number back. use cases like this abound.
it's also, in my opinion, important to see that (1) type checking is but ONE—and often quite coarse—measure of program correctness, because (2) it is often bounded values that make sense, and out-of-bounds values that make nonsense. sometimes just some intermittent values make sense—like considering all numbers, only those real (non-complex), integer numbers might be possible in a given case.
funny non-one seems to mention checking for x == math.floor( x ). if that should give an error with some big decimal class, well, then maybe it's time to re-think OOP paradigms. there is also PEP 357 that considers how to use not-so-obviously-int-but-certainly-integer-like values to be used as list indices. not sure whether i like the solution.
If you want to check that a string consists of only digits, but converting to an int won't help, you can always just use regex.
import re
x = "01234"
match = re.search("^\d+$", x)
try: x = match.group(0)
except AttributeError: print("not a valid number")
Result: x == "01234"
In this case, if x were "hello", converting it to a numeric type would throw a ValueError, but data would also be lost in the process. Using a regex and catching an AttributeError would allow you to confirm numeric characters in a string with, for instance, leading 0's.
If you didn't want it to throw an AttributeError, but instead just wanted to look for more specific problems, you could vary the regex and just check the match:
import re
x = "h01234"
match = re.search("\D", x)
if not match:
print("x is a number")
else:
print("encountered a problem at character:", match.group(0))
Result: "encountered a problem at character: h"
That actually shows you where the problem occurred without the use of exceptions. Again, this is not for testing the type, but rather the characters themselves. This gives you much more flexibility than simply checking for types, especially when converting between types can lose important string data, like leading 0's.
why not just check if the value you want to check is equal to itself cast as an integer as shown below?
def isInt(val):
return val == int(val)
It is very simple to check in python. You can do like this:
Suppose you want to check a variable is integer or not!
## For checking a variable is integer or not in python
if type(variable) is int:
print("This line will be executed")
else:
print("Not an integer")
If you are reading from a file and you have an array or dictionary with values of multiple datatypes, the following will be useful.
Just check whether the variable can be type casted to int(or any other datatype you want to enforce) or not.
try :
int(a);
#Variable a is int
except ValueError :
# Variable a is not an int
In the presence of numpy check like ..
isinstance(var, numbers.Integral)
.. (slow) or ..
isinstance(var, (int, long, np.integer))
.. in order to match all type variants like np.int8, np.uint16, ...
(Drop long in PY3)
Recognizing ANY integer-like object from anywhere is a tricky guessing game. Checking
var & 0 == 0
for truth and non-exception may be a good bet. Similarly, checking for signed integer type exclusively:
var ^ -1 == -var - 1
If the variable is entered like a string (e.g. '2010'):
if variable and variable.isdigit():
return variable #or whatever you want to do with it.
else:
return "Error" #or whatever you want to do with it.
Before using this I worked it out with try/except and checking for (int(variable)), but it was longer code. I wonder if there's any difference in use of resources or speed.
A simple way to do this is to directly check if the remainder on division by 1 is 0 or not.
if this_variable % 1 == 0:
list.append(this_variable)
else:
print 'Not an Integer!'
Here is a simple example how you can determine an integer
def is_int(x):
print round(x),
if x == round(x):
print 'True',
else:
print 'False'
is_int(7.0) # True
is_int(7.5) # False
is_int(-1) # True
If you just need the value, operator.index (__index__ special method) is the way to go in my opinion. Since it should work for all types that can be safely cast to an integer. I.e. floats fail, integers, even fancy integer classes that do not implement the Integral abstract class work by duck typing.
operator.index is what is used for list indexing, etc. And in my opinion it should be used for much more/promoted.
In fact I would argue it is the only correct way to get integer values if you want to be certain that floating points, due to truncating problems, etc. are rejected and it works with all integral types (i.e. numpy, etc.) even if they may not (yet) support the abstract class.
This is what __index__ was introduced for!
If you want to check with no regard for Python version (2.x vs 3.x), use six (PyPI) and it's integer_types attribute:
import six
if isinstance(obj, six.integer_types):
print('obj is an integer!')
Within six (a very light-weight single-file module), it's simply doing this:
import sys
PY3 = sys.version_info[0] == 3
if PY3:
integer_types = int,
else:
integer_types = (int, long)
use the int function to help
intchecker = float(input('Please enter a integer: '))
intcheck = 0
while intcheck != 1:
if intchecker - int(intchecker) > 0:
intchecker = float(input("You didn't enter a integer. "
"Please enter a integer: "))
else:
intcheck = 1
print('you have entered a integer')
I was writing a program to check if a number was square and I encountered this issue, the
code I used was:
import math
print ("this program will tell you if a number is square")
print ("enter an integer")
num = float(input())
if num > 0:
print ("ok!")
num = (math.sqrt(num))
inter = int(num)
if num == inter:
print ("It's a square number, and its root is")
print (num)
else:
print ("It's not a square number, but its root is")
print (num)
else:
print ("That's not a positive number!")
To tell if the number was an integer I converted the float number you get from square rooting the user input to a rounded integer (stored as the value ), if those two numbers were equal then the first number must have been an integer, allowing the program to respond. This may not be the shortest way of doing this but it worked for me.
You can do this.
if type(x) is int:
#!/usr/bin/env python
import re
def is_int(x):
if(isinstance(x,(int,long))):
return True
matchObj = re.match(r'^-?\d+\.(\d+)',str(x))
if matchObj:
x = matchObj.group(1)
if int(x)-0==0:
return True
return False
print is_int(6)
print is_int(1.0)
print is_int(1.1)
print is_int(0.1)
print is_int(-956.0)
If you have not int you can do just this:
var = 15.4
if(var - int(var) != 0):
print "Value is not integer"
If you want to write a Python 2-3 compatible code
To test whether a value is an integer (of any kind), you can to do this :
# Python 2 and 3:
import sys
if sys.version_info < (3,):
integer_types = (int, long,)
else:
integer_types = (int,)
>>> isinstance(1, integer_types)
True
# Python 2 only:
if isinstance(x, (int, long)):
...
# Python 3 only:
if isinstance(x, int):
...
source : http://python3porting.com/differences.html
A more general approach that will attempt to check for both integers and integers given as strings will be
def isInt(anyNumberOrString):
try:
int(anyNumberOrString) #to check float and int use "float(anyNumberOrString)"
return True
except ValueError :
return False
isInt("A") #False
isInt("5") #True
isInt(8) #True
isInt("5.88") #False *see comment above on how to make this True
you can do this by:
name = 'Bob'
if type(name) == str:
print 'this works'
else:
print 'this does not work'
and it will return 'this works'... but if you change name to int(1) then it will return 'this does not work' because it is now a string...
you can also try:
name = int(5)
if type(name) == int:
print 'this works'
else:
print 'this does not work'
and the same thing will happen
There is another option to do the type check.
For example:
n = 14
if type(n)==int:
return "this is an int"

Categories