Shorten it down a bit:
def is_ok(x):
is_int = False
is_pos = False
try:
x = float(x)
# Check if the number is integer or not
is_int = x.is_integer()
if x > 0:
is_pos = True
except ValueError:
print("not even a number!")
return is_int, is_pos
To explain how this works, you can pass a string to int()
to convert this to an integer. However, passing an invalid string (like foo
) will raise a ValueError
. We can catch that and display our "not even a number!"
message to the user. Much safer than using eval()
.
Try not to use eval()
unless you absolutely trust the input.
Removing all the variables you can also make it:
def is_ok(x):
try:
# Check if is an integer and greater than 0
return float(x).is_integer(), float(x) > 0
except ValueError:
print("not even a number!")
return False, False
Explanation of why your code didn't work
Your original problem was it was returning True, True
for even negative numbers. The problem here is that whilst you were using type(eval(x)) == int
you were then not making x
an integer object. This then has an unexpected effect when you try and compare a string to an integer later on (if x > 0
):
In [9]: "twenty" > 0
Out[9]: True
You can read more about this strange behaviour in this very detailed answer.
If you were to redefine x
as your variable:
try:
x = eval(x)
if type(x) == int:
Then when you made the comparison it would behave better and return True, False
for "-9"
.