I hope you celebrated the new year well, and now you have a great festive mood. At least I have it that way - we didn’t drink any alcohol and clinked glasses with water from a five-liter canister at midnight, so we woke up, took a walk, and then I remembered one of yesterday’s congratulations on the New Year:
I wish that at the end of each year you remember the past 366 if (((year% 4 == 0 and year% 100! = 0) or (year% 400 == 0)) else 365 days, thinking about yourself:
- Oh, nifiga myself, what was the action. I will definitely tell my grandchildren or write a book about it later.
So, the above is a rather simple inline-way to determine the number of days per year (year variable), which, in fact, fully reveals their essence: in the
Gregorian calendar those years are considered as leap years, but their 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 divisible by 4 without a remainder, but divisible by 100, only with a remainder, then it is a leap year, otherwise it is non-leap, except if it is divisible 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 are in leap years (366 days) and non-leap years (365 days), or just want to write the definition of the number of days per year as quickly as possible? Is it possible to do this in Python? Of course you can.
So, in Python there is a
calendar module. It is just perfect for finding out if 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 number of the day 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 just 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 of the week on the first day of a given month and the number of days in a 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 obtain 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 exactly how this line is executed, it becomes obvious that this solution is very inefficient if you need to count the number of days for a large number of years.
We check with the
timeit module.
It takes
13.69 seconds to execute it 1 million times, if the import calendar is done once at the beginning. If the import calendar is done every time, then
14.49 seconds.
Now try another option. It requires knowledge of how many days are in leap years and non-leap years, but it is very short:
>>> import calendar >>> year = 2013 >>> 365+calendar.isleap(year) 365
And, as it is easy to guess, it is already much faster:
0.83 seconds, including the import calendar, and
0.26 seconds if the import calendar is done once at the beginning.
Let's also see how much time is required for the very first variant, with a “manual” approach:
0.07 seconds for 2012 and 2013 and
0.12 seconds for 2000 (I think everyone understands where this difference in speed comes from for these years).
It turns out that this is the fastest version 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 — after all, when determining the number of days in one, two, ten, or a hundred years, you are unlikely to feel any difference.
Write, optimize, improve, test and read performance - 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.