Skip to content

Commit 4d55c36

Browse files
committed
Create is_leap.py
This is just a reminder about checking for leap years. It has two model functions.
1 parent d137d75 commit 4d55c36

1 file changed

Lines changed: 42 additions & 0 deletions

File tree

is_leap.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#!/usr/bin/python3
2+
3+
import sys
4+
5+
# Leap years occur every four years, with
6+
# exceptions for years divisible by 100 but not by 400.
7+
# The most recent leap years were 2020 and 2024, and
8+
# the next one will be in 2028
9+
#
10+
# Yes, maybe I could better emulate Falk Hüffner's work using
11+
# the Python ctypes module...but it seemed like there was a material
12+
# performance and simplicity hit. I'll leave that to someone else.
13+
# https://runebook.dev/en/articles/python/library/ctypes/ctypes.c_uint32
14+
15+
16+
def is_leap_year(year: int) -> bool:
17+
# This is the standard way...
18+
return (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)
19+
20+
21+
def is_leap_year_fast(y: int) -> bool:
22+
# This interesting function is based on a C function by Falk Hüffner. See:
23+
# https://hueffner.de/falk/blog/a-leap-year-check-in-three-instructions.html
24+
return ((y * 1073750999) & 3221352463) <= 126976
25+
26+
27+
def main(num_args: int, usage: str):
28+
if len(sys.argv) != num_args:
29+
this_script = sys.argv[0]
30+
usage_message = usage.replace("script_name", str(this_script))
31+
print(usage_message)
32+
sys.exit(1)
33+
else:
34+
# use abs() to deal convert negative numbers to positive
35+
if int(sys.argv[1]) < 0:
36+
print(f"You entered a negative number.\nWe will convert it and check for leap.")
37+
print(f"\t{is_leap_year(abs(int(sys.argv[1])))}")
38+
print(f"\t{is_leap_year_fast(abs(int(sys.argv[1])))}")
39+
40+
41+
if __name__ == '__main__':
42+
main(2, 'USAGE: python3 script_name <year_to_test, only use with positive numbers>')

0 commit comments

Comments
 (0)