0

I am doing a practice course for Python that requests a script to calculate leap years.

Leap years have the following conditions:

  • Must be a multiple of 4
  • Must NOT be a multiple of 100, unless it is also a multiple of 400.

Attempt1

year = int(input("Check this year ")) leapFourYears = year % 4 leapCentury = year % 100 leapFourCenturies = year % 400 if (leapFourYears == 0 & leapCentury != 0) | leapFourCenturies == 0: print('leap year') else: print('not leap year') 

This works for, e.g., 2000, but it incorrectly prints 'not leap year' for, e.g., 2016.

I printed out each condition, and individually, they evaluate to true or false as expected. However, the moment I involve a & or | operator, the evaluation goes awry.

I started attaching parentheses and came upon this correct if-statement:

Attempt 2

if ((leapFourYears == 0) & (leapCentury != 0)) | (leapFourCenturies == 0): 

This works.

Can someone explain to me how Python python parses multiple conditions with & and | operators that do not have parentheses? How is Python evaluating it that makes it work for 2000 but not 2016?

Is there a way to do this without the parentheses around each condition?

Thanks!

Python 3.8.10

5
  • 2
    use and and or not logical bitwise operators Commented Feb 20, 2022 at 12:52
  • 1
    Regardless of parenthesis or not, you are using the wrong operators. You should be using and and or, not their bitwise equivalent. Either way, it's all about operator precedence. Commented Feb 20, 2022 at 12:52
  • if (leapFourYears == 0 & leapCentury != 0) | leapFourCenturies == 0: => if (not leapFourYears and leapCentury) or not leapFourCenturies: Commented Feb 20, 2022 at 12:53
  • docs.python.org/3/reference/… Commented Feb 20, 2022 at 13:00
  • @Julien thanks! Didn't know I had the wrong operators. Commented Feb 20, 2022 at 13:02

1 Answer 1

1

You are using the bitwise operators, not the logical operators. Instead of

if ((leapFourYears == 0) & (leapCentury != 0)) | (leapFourCenturies == 0): 

use

if leapFourYears == 0 and leapCentury != 0 or leapFourCenturies == 0: 

The and has priority over or(Operator Precedence in Python).

Sign up to request clarification or add additional context in comments.

4 Comments

Probably out of scope of this question/answer, but since all of these are essentially booleans I'd go with if not leapFourYears and not leapCentury or leapFourCenturies: for a more fluent reading/understanding, but again, this is just nitpicking.
Does and always have priority, so if I have if c1 and c2 or c3 and c4, it will evaluate as (c1 and c2) or (c3 and c4)?
@DeepSpace That's good to know, thanks!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.