I don't understand this integer test function

I am following this tutorial video from freeCodeCamp called Object Oriented Programming with Python. That tutorial, or object oriented programming isn’t necessarily important to this topic. But in that tutorial there is a function that I still don’t understand why it works. Hopefully someone here can explain it in a way I understand.

def is_integer(num):
    # check if num is an integer.
    # Floats ending with point-zero are considered integers.
    if isinstance(num, float):
        return num.is_integer()
    elif isinstance(num, int):
        return True
    else:
        return False

If you run the code yourself, you will see that it works as expected. Inputs of 5 and 5.0 return True while an input of 5.25 returns False. But I don’t understand how this works. Even after stepping-through with the debugger, I don’t understand how this can possibly work. I am confused by the line return num.is_integer().

  1. How is it that num.is_integer() does not result in an error when is_integer() is not a method of the float class?
  2. How does this return True for input of 5.2 but not 5.0?

From what I understand that return statement should cause an infinite loop. to me it says “is num a float? Yes, then return the output of this function with this number. Is num a float? Yes…”

I understand how numbers like 5.0 and 5.6 cause isinstance(num, float) to return True. I have no idea how then return num.is_integer() somehow differentiates between 5.0 and 5.6.

But it is a method on floats:

https://docs.python.org/3/library/stdtypes.html?highlight=is_integer#float.is_integer

1 Like

Because Python doesn’t use strict typing - meaning the interpreter will change the datatype of a variable when needed.
In order to achieve this, Python is turning most things into actual objects (hence it’s techncially all OOP).
So what is the significant difference inbetween a float and an integer? Anything behind the decimal point. So Python is basically saying, a float without a fraction COULD be an integer - because to a user, it would behave the same within Python.

Sure, if you hardcode 5.0 it seems weird, but you usually don’t hardcode numbers you check. You got some calculations and in the end, you want to know if it’s an integer or a float. And as Python doesn’t use strong typing, it’s reasonable to assume that a number without fraction is an integer.

1 Like

Oh! I see. Thanks! Maybe the creator of the tutorial should have used a different name for the function to avoid this confusion. I was thinking that the return statement had a recursive call to the function. Now if you don’t mind I have another question: how is it that Python does not get confused by having these two things with the same name?

My guess would be that because .is_integer() is operating on num, which is a float, Python looks for a float method with that name before it goes looking for a function with that name. Is that correct?

It never looks for a function :wink:
Either it finds a method or it doesn’t. Because of inheritance it might go up the object-chain to look for methods, but that’s it.

Note: you can use help(float) and Python will list the documentation-string of the object.

I understand now. Thanks @Jagaya and @JeremyLT for clearing this up for me. I appreciate it!