闰年布尔逻辑:包含括号?

JBa*_*lin 4 python boolean-logic parentheses leap-year

哪个"更正确(逻辑上)"?特定于闰年,不是一般的.

  1. 括号

    return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)
    
    Run Code Online (Sandbox Code Playgroud)
  2. 没有

    return year % 4 == 0 and year % 100 != 0 or year % 400 == 0
    
    Run Code Online (Sandbox Code Playgroud)

附加信息

括号改变了布尔值的计算顺序(and在没有or括号之前).

鉴于在这个问题中所有较大的数字都可以被较小的数字整除,它会以任何方式返回正确的结果,但我仍然很好奇.

观察括号的影响:

  1. False and True or True
    #True
    
    False and (True or True)
    #False
    
    Run Code Online (Sandbox Code Playgroud)
  2. False and False or True
    #True
    
    False and (False or True)
    #False
    
    Run Code Online (Sandbox Code Playgroud)

如果没有括号,有些情况下即使年份不能被4整除(第一个bool),它仍然会返回True(我知道在这个问题上这是不可能的)!是不是可被4整除,因此包括括号更正确?还有什么我应该注意的吗?有人可以解释不包括括号的理论逻辑吗?

Ada*_*ith 5

parens影响你的布尔人的顺序.ands组合在一起并在ors 之前解析,因此:

a and b or c
Run Code Online (Sandbox Code Playgroud)

变为:

(a and b) or c
Run Code Online (Sandbox Code Playgroud)

如果两个都ab是truthy,或者如果c是truthy,我们得到的True.

用括号得到:

a and (b or c)
Run Code Online (Sandbox Code Playgroud)

True如果两者a都是真实的,或者bOR c是真的,那么你就得到了.


就"正确性"而言,只要您的代码得出正确的结果,那么"更正确"只是意见问题.我会在你认为结果更清晰的地方加入parens.例如:

if (a and b) or c:
Run Code Online (Sandbox Code Playgroud)

比...更清楚

if a and b or c:
Run Code Online (Sandbox Code Playgroud)

然而,(在我看来)并不比以下更清楚:

if some_long_identifier and some_other_long_identifier or \
   some_third_long_identifier_on_another_line:
Run Code Online (Sandbox Code Playgroud)

编写Python代码时的指南应该是PEP8.当你应该包括风格括号时,PEP8很安静(阅读:遵循自然操作顺序的parens),所以请使用你最好的判断.


特别是对于闰年,逻辑是:

  1. 如果年份可被4整除,请转到步骤2. ...
  2. 如果年份可以被100整除,请转到步骤3. ...
  3. 如果年份可以被400整除,请转到步骤4. ...
  4. 这一年是闰年(它有366天).
  5. 这一年不是闰年(它有365天).

换句话说:所有可被4整除的年份都是闰年,除非它们可以被100整除而不能被400整除,这意味着:

return y % 4 == 0 and not (y % 100 == 0 and y % 400 != 0)
Run Code Online (Sandbox Code Playgroud)