Which is "more correct (logically)"? Specific to Leap Year, not in general.
With Parentheses
return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)
Without
return year % 4 == 0 and year % 100 != 0 or year % 400 == 0
Additional Info
Parentheses change the order in which the booleans are evaluated (and
goes before or
w/o parenthesis).
Given that all larger numbers are divisible by smaller numbers in this problem, it returns the correct result either way but I'm still curious.
Observe the effects of parentheses:
False and True or True
#True
False and (True or True)
#False
False and False or True
#True
False and (False or True)
#False
Without parentheses, there are scenarios where even though year is not divisible by 4 (first bool) it still returns True (I know that's impossible in this problem)! Isn't being divisible by 4 a MUST and therefore it's more correct to include parenthesis? Anything else I should be paying attention to here? Can someone explain the theoretical logic of not/including parentheses?
Include the parentheses. In English, the rule is:
The version with parentheses matches this two-pronged rule best.
return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)
^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
(1) (2)
As it happens, removing the parentheses does not break the code, but it leads to an unnatural version of the rules:
That's not the way I think of the leap year rule.
The parens affect what order your booleans take. and
s are grouped together and resolved before or
s are, so:
a and b or c
becomes:
(a and b) or c
if either BOTH a
and b
are truthy, OR if c
is truthy, we get True
.
With the parentheses you get:
a and (b or c)
Now you get True
if both a
is truthy and either b
OR c
is truthy.
As far as "correctness," as long as your code derives the correct result then "more correct" is only a matter of opinion. I would include parens where you feel like it makes the result more clear. For instance:
if (a and b) or c:
is more clear than
if a and b or c:
However it is NOT more clear (in my opinion) than:
if some_long_identifier and some_other_long_identifier or \
some_third_long_identifier_on_another_line:
Your guide when writing Python code should be PEP8. PEP8 is quiet on when you should include stylistic parentheses (read: parens that follow the natural order of operations), so use your best judgement.
For leap years specifically, the logic is:
In other words: all years divisible by 4 are leap years, unless they're divisible by 100 and NOT divisible by 400, which translates to:
return y % 4 == 0 and not (y % 100 == 0 and y % 400 != 0)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With