0

Can anyone explain what action does this

return  num.is_integer() 

return statement perform?

The code below is for checking that the given value is integer or not but it's also returning True for values like 7.0, 5.0, 9.0 which should have been float.

In the code below, for values like

num = 7 --------- it returns True which is understandable.

num = 7.5 ----------- it returns False which i didn't get why.

num = 7.0 ----------- it also returns True which I didn't get why.

def is_integer(num):
    if isinstance(num, float):
        return num.is_integer()
    elif isinstance(num, int):
        return True
    else:
        return False

PM 2Ring
  • 54,345
  • 6
  • 82
  • 182
  • `isinstance(7.0, int)` *doesn't* return `True`, nor does `is_integer(7.0)` even get that far. – chepner Oct 08 '22 at 13:09
  • @chepner `a = 7.0; a.is_integer()` → `True`. – Klaus D. Oct 08 '22 at 13:12
  • 1
    @KlausD. Yes, I know. That's the point: `(7.0).is_integer()` is what makes `is_integer` return `True`, not `isinstance(7.0, int)`. – chepner Oct 08 '22 at 13:15
  • @chepner Sorry, but that's not what I read from your first comment. Good you clarified. – Klaus D. Oct 08 '22 at 13:16
  • 1
    Welcome to Stack Overflow. "can anyone explain what action does this {return num.is_integer()} return statement is performing." [Did you try](https://meta.stackoverflow.com/questions/261592) to [read the documentation](https://docs.python.org/3/library/stdtypes.html#float.is_integer) in order to understand what `is_integer` does? – Karl Knechtel Oct 08 '22 at 13:19
  • "num = 7.5 -----------it returns False which i didn't get why?" Do you think it should return True instead? Why? Just to be clear: do you understand *what an integer is*? – Karl Knechtel Oct 08 '22 at 13:21

2 Answers2

1

num = 7.5 -----------it returns False which i didn't get why?

7.5 is a float value so is_integer method checks the value and it is a float. Then the method returns num.is_integer() which is False because 7.5 is not an integer.

num = 7.0 ----------- it also returns True which i didn't get why?

7.0 is a float value too. Then the method returns num.is_integer() which is True because it can cast to an integer.

Deniz Kaplan
  • 1,549
  • 1
  • 13
  • 18
  • 1
    Be careful with "cast": you can "cast" `7.5` to an integer as well; you just get back `7`. It's more accurate to say that `7.0 == int(7.0)`. – chepner Oct 08 '22 at 13:08
  • thanks @Deniz and chepner for the answer as i have recently started learning python and i didn't know that float.is_integer() is built-in types. your answer has helped me a lot thank you. – ANKESH KAPOOR Oct 09 '22 at 07:54
0

Assuming a function (with an if-elif chain) defined such as:

def is_integer(num):
    if isinstance(num, float):
        return num.is_integer()
    elif isinstance(num, int):
        return True
    else:
        return False

Which, is coincidentally equivalent to:

def is_integer(num):
    if isinstance(num, float):
        return num.is_integer()
    if isinstance(num, int):
        return True
    return False

How it works

Here is the pseudo-code for the above logic.

  • If num is (or is subclass of) a float:
    • return True if it represents an integer value, such as 7.0
    • else, return False
  • If num is (or is subclass of) an int, return True
  • If num is any other type, return False

Inputs

Thus, for the given inputs:

num = 7 --------- it returns True which is undestandable.

Correct, because 7 is an int type.

Now from the above pseudo-code, we can see:

num = 7.5 -----------it returns False which i didn't get why?

Since type(7.5) is float, and 7.5.is_integer() is False.

num = 7.0 ----------- it also returns True which i didn't get why?

Since type(7.0) is float, and 7.0.is_integer() is True.

num = False ---------- returns True

Since type(False) is bool, and bool is a subclass of int, so we then return True.

Testing

>>> is_integer(0)
True
>>> is_integer(1234567)
True
>>> issubclass(type(3), int)
True
>>> is_integer(1.2)
False
>>> is_integer(11.01)
False
>>> 3.21.is_integer()
False
>>> is_integer(7.00)
True
>>> 2.0.is_integer()
True
>>> is_integer(True)
True
>>> issubclass(type(False), int)
True

Resolution

can anyone explain what action does this return num.is_integer() return statement is performing.

It checks if num, which is a float value, represents an integer or decimal value such that the part after the decimal point . is nothing, or 0.

For example, float.isinteger() is true for 123.0 since it is a whole number which does not have a fractional part, but is false for 123.45 since the fractional part is .45, which means that the number represents a floating point value instead of an integer value.

Perhaps this could be better illustrated with the following example:

>>> 7.0 == int(7.0)
True
>>> 7.1 == int(7.1)
False

Note that 7.0.is_integer() returns True, since casting the float value to an int does not result in data being lost, whereas int(7.1) is 7, hence we have dropped the fractional part which is .1, and so 7.1 != 7.0.

the given below code is for checking the given value is integer or not but it also returning true for values like 7.0,5.0, 9.0 which should have been float.

This is correct, it is due to the float.isinteger() usage as mentioned above, which checks if the float values can be representable as an int without any data being lost.

To fix this, you can simply return whether isinstance(num, int) is true:

def is_integer(num):
    return isinstance(num, int)

However, the above does not account for bool values, since as mentioned issubclass(bool, int) is True. Thus, a check like isinstance(False, int) will actually return True.

To update it to return False for bool values, we can perform a stricter type check, only checking if the type of num is explicitly an int:

def is_integer(num):
    return type(num) is int

Finally, to check only for int and custom subclasses of int, but to exclude bool or any subclasses of bool, we can update to first check for a bool type or subtype, and then check for an int type or subtype, as shown below.

def is_integer(num):
    if isinstance(num, bool):
        return False
    # else, we *haven't* returned a value yet
    return isinstance(num, int)
rv.kvetch
  • 9,940
  • 3
  • 24
  • 53