Leap Years
I hope you had a great New Year, and now you have a great holiday mood. At least for me it’s just that - we didn’t drink any alcohol, and clinked glasses at midnight with glasses of water from a five-liter canister, so we woke up, took a walk, and then I remembered one of yesterday’s New Year greetings:
So, the above is a fairly simple inline-way to determine the number of days in a year (variable year), which, in fact, fully reveals their essence: in the Gregorian calendar, leap years are those years whose serial number is either a multiple of 4, but not a multiple of 100 , or a multiple of 400. In other words, if a year is divided by 4 without a remainder, but divided by 100 only with a remainder, then it is a leap year, otherwise it is a leap year, except if it is divided without a remainder by 400, then it is still a leap year.
For example, 2013 is a non-leap year, 1700, 1800 and 1900 are again non-leap years, but 2000, 2004, 2008 and 2012 are leap years.
But what if we don’t remember how many days in leap (366 days) and non-leap (365 days) years, or just want to write the definition of the number of days in a year as quickly as possible? Is it possible to do so in Python? Of course you can.
So in Python there is a calendar module . It is just great for finding out whether a particular year is a leap year (or, for example, how many leap years in a certain interval), determine the number of days in a month, get the day number of the week for a certain date, and so on.
In particular, we can get the number of days in each month of the year, and simply add up.
The calendar.monthrange function takes the year number as the first argument and the month number as the second argument. Returns the day number of the week of the first day of the given month and the number of days in the given month:
Accordingly, we can calculate the total number of days for all 12 months, and thus get the number of days for a given year:
But if you think about how this line is executed, it becomes obvious that this solution is very inefficient if you need to calculate the number of days for a large number of years.
We check using the timeit module .
It takes 13.69 seconds to execute it 1 million times if import calendar is done once at the beginning. If import calendar is done every time, then 14.49 seconds.
Now try another option. It requires knowledge of how many days are in leap and non-leap years, but it is very short:
And, as you might guess, it is already much faster: 0.83 seconds, including import calendar, and 0.26 seconds if import calendar is done once at the beginning.
Let's also see how much time the very first option takes, with a “manual” approach: 0.07 seconds for 2012 and 2013 and 0.12 seconds for 2000 (I think everyone understands where this speed difference comes from for these years).
It turns out that this is the fastest option of these three:
Of course, in most cases, you can use any of these options - in the end, when determining the number of days in one, two, ten, or one hundred years, you are unlikely to feel any difference.
Write, optimize, improve, test and consider productivity - but do not forget about the readability of the source code of your programs.
Happy New Year! Good luck, happiness, joy and self-improvement in the new year.
I wish that at the end of each year, remembering what happened in the past 366, if ((year% 4 == 0 and year% 100! = 0) or (year% 400 == 0)) else 365 days, I thought about yourself:
- Oh, nifiga yourself, what was the action. I will definitely tell my grandchildren, or I will write a book about this later.
So, the above is a fairly simple inline-way to determine the number of days in a year (variable year), which, in fact, fully reveals their essence: in the Gregorian calendar, leap years are those years whose serial number is either a multiple of 4, but not a multiple of 100 , or a multiple of 400. In other words, if a year is divided by 4 without a remainder, but divided by 100 only with a remainder, then it is a leap year, otherwise it is a leap year, except if it is divided without a remainder by 400, then it is still a leap year.
For example, 2013 is a non-leap year, 1700, 1800 and 1900 are again non-leap years, but 2000, 2004, 2008 and 2012 are leap years.
But what if we don’t remember how many days in leap (366 days) and non-leap (365 days) years, or just want to write the definition of the number of days in a year as quickly as possible? Is it possible to do so in Python? Of course you can.
So in Python there is a calendar module . It is just great for finding out whether a particular year is a leap year (or, for example, how many leap years in a certain interval), determine the number of days in a month, get the day number of the week for a certain date, and so on.
In particular, we can get the number of days in each month of the year, and simply add up.
The calendar.monthrange function takes the year number as the first argument and the month number as the second argument. Returns the day number of the week of the first day of the given month and the number of days in the given month:
>>> import calendar
>>> calendar.monthrange(2013, 1)
(1, 31)
Accordingly, we can calculate the total number of days for all 12 months, and thus get the number of days for a given year:
>>> import calendar
>>> year = 2013
>>> sum(map(lambda x: calendar.monthrange(year, x)[1], range(1, 13)))
365
But if you think about how this line is executed, it becomes obvious that this solution is very inefficient if you need to calculate the number of days for a large number of years.
We check using the timeit module .
It takes 13.69 seconds to execute it 1 million times if import calendar is done once at the beginning. If import calendar is done every time, then 14.49 seconds.
Now try another option. It requires knowledge of how many days are in leap and non-leap years, but it is very short:
>>> import calendar
>>> year = 2013
>>> 365+calendar.isleap(year)
365
And, as you might guess, it is already much faster: 0.83 seconds, including import calendar, and 0.26 seconds if import calendar is done once at the beginning.
Let's also see how much time the very first option takes, with a “manual” approach: 0.07 seconds for 2012 and 2013 and 0.12 seconds for 2000 (I think everyone understands where this speed difference comes from for these years).
It turns out that this is the fastest option of these three:
>>> import calendar
>>> year = 2013
>>> 366 if ((year%4 == 0 and year%100 != 0) or (year%400 == 0)) else 365
365
Of course, in most cases, you can use any of these options - in the end, when determining the number of days in one, two, ten, or one hundred years, you are unlikely to feel any difference.
Write, optimize, improve, test and consider productivity - but do not forget about the readability of the source code of your programs.
Happy New Year! Good luck, happiness, joy and self-improvement in the new year.