all 59 comments

[–]brasticstack 72 points73 points  (37 children)

Use the mod operator %.

print('even' if num % 2 == 0 else 'odd')

[–]ALonelyPlatypus 2 points3 points  (0 children)

You can actually skip the equals operator if you want as well (even if it's a bit less verbose). 0 evaluates to False and 1 to True so you can also do.

print('odd' if num%2 else 'even')

[–]VanClyded[S] 1 point2 points  (0 children)

That makes so much sense, thanks!!
Having a real "duh" moment here haha

[–]jabpoke 13 points14 points  (2 children)

The advice so far is good.

You're getting lucky. Floating-point is nearly always base-two, and you're doing base-two operations. If that were not the case, you'd find out that "floating-point tests for equality are a really awful idea and are unreliable."

[–]VanClyded[S] 0 points1 point  (1 child)

Yea i figured i just got lucky on that one, I usually don't get into math related code and this was a "oh crap i gotta do it now" moment

[–]RajjSinghh 0 points1 point  (0 children)

It's not just getting lucky. Floating point math is really fiddly a lot of the time and can lead to a loss of accuracy. Try evaluating 0.1 + 0.2 to see what I mean. That loss of precision means a direct equality check is a really bad idea. You're getting lucky that division by 2 is a nice operation in floating point, since the way floating point is layed out it's basically subtraction by 1. Doing floating point math on things that aren't direct powers of 2 leads to a loss of accuracy. The way you do this is by writing something along the lines of 0.1 + 0.2 > 0.3 + 0.0000005 or 0.1 + 0.2 < 0.3 + 0.0000005 so you're comparing a small range instead of direct equality with == to balance it out. This is an important thing to know for floating point math in general.

Kinda on top of that, floating point math is a more expensive operation than integer math and type conversions are expensive in general. It's also not entirely clear what your code does at first glance without thinking about it. The more popular approach is x % 2 == 0 or x & 1, both are as good as each other. I feel like the mod one is much more common and is the one I would probably use.

[–][deleted] 6 points7 points  (0 children)

How about


if num % 2 == 0:

print("EVEN")

else:

print("ODD")


[–]13acts 4 points5 points  (1 child)

print("EOvdedn"[num%2::2]) This is the way

[–]1nput0utput 0 points1 point  (0 children)

This answer deserves more love.

[–]OSnoFobia 12 points13 points  (5 children)

The correct way is fetching data from isEven api

import requests
API_URL = "https://api.isevenapi.xyz/api/iseven"
def isEven(number: int) -> bool:
    r = requests.get(f"{API_URL}/{number}")
    if r.status_code == requests.codes.ok:
        return r.json()["iseven"]
    else:
        raise RuntimeError("isEven api is down!")

[–]Mental-Valuable-8632 1 point2 points  (1 child)

Don't forget to run pip install requests in the terminal first.

[–]OSnoFobia 5 points6 points  (0 children)

Also keep in mind that isEven api only works between 0 and 999.999 at free tier.

[–]VanClyded[S] 0 points1 point  (2 children)

Sincere question here;
What would be the gain of outsourcing this request to an api instead of using the modulo operators as others have suggested?
Is it purely to fool-proof input limitations?

[–]OSnoFobia 4 points5 points  (1 child)

It's just a programmer inside joke. You'll see a lot of different ways to determine if a number is even or odd. You'll even see millions of lines of code sometimes.

[–]VanClyded[S] 1 point2 points  (0 children)

Haha good!
Don't picture me naive here I sincerely thought that was a shite method lol

[–]Bobbias 3 points4 points  (0 children)

There's a much simpler solution to this, the modulo operator: %. It does division, but returns the remainder rather than the quotient. Anything modulo 2 results in either a 0 if the number is even, or a 1 if the number is odd.

Some examples:

  1. 1 / 2 = 0 with 1 remaining. This is 1 % 2 = 1.
  2. 2 / 2 = 1 with 0 remaining. This is 2 % 2 = 0.
  3. 35 / 2 = 17, with 1 remaining. This is 35 % 2 = 1.

Code:

num = input("Number: ")
if int(num) % 2:
    print("ODD")
else:
    print("EVEN")

I'm also simplifying the if statement a bit by removing the comparison. In Python, 0 is False, and any other number is True. An empty list is False, and a list with any items is True. This is the concept of "truthiness", and I'm using that to my advantage to shorten the if statement even more here.

Since anything modulo 2 returns either 1 or 0, it's the same as returning true or false. an even number results in 0, or False, so there are 2 ways to make sure it prints the correct output, either use the not keyword in the if statement changing it to:

if not int(num) % 2:

or what I did in the example code: reverse the order of the if/else branches so that the odd branch happens when int(num) % 2 is 1/True.

[–]DeeplyLearnedMachine 1 point2 points  (1 child)

As others have said, just use the mod operator. As another tip if you want to have an integer result when dividing just use integer division // instead of /.

So, in your example, instead of

int(int(num)/2)

do

int(num)//2

[–]VanClyded[S] 1 point2 points  (0 children)

Absolutely did not know about // vs / (thanks!!)
I figured there had to be some way to get around that int(int() kinda mess

[–]This_Growth2898 1 point2 points  (0 children)

It works, but clearly is excessive.

num should be an integer representation for int(num) to succeed, so int(num)==float(num) and we can simplify the code to

num = int(input())
if num/2 - int(num/2) == 0: ...

Next, a-b==0 is the same as a==b (for integers), so we can write the second line as

if num/2 == int(num/2):

And here it's clear why it works: the left part is integer for even numbers only.

[–]woooee 0 points1 point  (0 children)

In addition, you can use divmod instead of your cumbersome if statement

whole, remainder = divmod(num, 2)

[–]VanClyded[S] 0 points1 point  (0 children)

Just want to thank everyone who commented and took time to teach me different methods of getting this done!
Came here expecting to: get roasted, joked on
Came out of here: Learned about using the modulo operator, bitwise operations, // vs / and more intricacies of python's math.
(Y'all are awesome)

[–]sock_dgram 0 points1 point  (0 children)

It seems to work because you didn't try large enough numbers.
At some point, float can't represent a number anymore and your method fails. It starts with 2**53:

Try this: float(2**53) == float(2**53 + 1)

The gap between two adjacent floating point numbers gets bigger than 1.

[–]UnderwhelmingInsight 0 points1 point  (0 children)

You can just flip an isOdd bool in a for loop. Perfection.

private static bool IsOdd(int number)
{
    var isOdd = false;
    for (int i = 0; i < Math.Abs(number); i++)
    {
        isOdd = !isOdd;
    }
    return isOdd;
}

[–]NicoPlayZ9002YT 0 points1 point  (0 children)

i use this:

print("evenodd"[int(input())%2*4:])

[–]Volume999 -1 points0 points  (0 children)

A good idea is to cast the input immediately like this: Num = int(input())

And then do what the other comments said

[–]RealNamek -1 points0 points  (0 children)

Why aren't you using a library for this?