I wanted to create a python program with user defined function which should read a year entered by user and return True/False by checking whether the entered year is a leap year or not.
The code should follow the Gregorian Calendar System also.
This is what I tried
def is_leap(year):
leap = False
if(year%4==0):
if(year0!=0):
if(year@0==0):
leap= True
else:
leap= False
else:
leap= False
else:
leap= False
return leap
year = int(input())
print(is_leap(year))
And I am not getting the desired output.
I tried this code with following two inputs
2024
Output was
False
And
2023
Output was
False
What am I missing here?
CodePudding user response:
Handling the exceptions first yields clearer code.
def is_leap(year):
if year % 400 == 0:
return True # an exception to the century rule
if year % 100 == 0:
return False # centuries aren't leap years
return year % 4 == 0
CodePudding user response:
Let's step through your code for 2024:
year%4==0
is True, so we enter the if blockyear0!=0
is also True, so we enter the if block again.
And now you check for year@0==0
. Um, why? 2024 isn't a century, so it can never be a multiple of 400. So your logic is broken here. 2024 is divisible by 4 and not divisible by 100. At this point we can simply return True!
Where we need to check for divisibility by 400 is in the next case (where year0!=0
is False).
If we take all of this, we get this code:
def is_leap(year):
if(year%4==0):
if(year0!=0):
return True
else:
if(year@0==0):
return True
else:
return False
else:
return False
(note how I got rid of the completely unnecessary variable.)
CodePudding user response:
By nesting the if/else, you act as an AND while you would need an OR.
Best is to refactor your code:
def is_leap(year):
if (year%4==0) and (year0!=0) or (year@0==0):
return True
return False
Which is equivalent to:
def is_leap(year):
return (year%4==0) and (year0!=0) or (year@0==0)
Tests:
assert not is_leap(1700)
assert not is_leap(1800)
assert not is_leap(1900)
assert not is_leap(2023)
assert is_leap(1600)
assert is_leap(2000)