Python Cookbook 2Nd Edition Jun 1002005 [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Python Cookbook 2Nd Edition Jun 1002005 [Electronic resources] - نسخه متنی

David Ascher, Alex Martelli, Anna Ravenscroft

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید







Recipe 3.2. Finding Last Friday


Credit: Kent Johnson, Danny Yoo, Jonathan Gennick, Michael
Wener


Problem



You want to find the date of last
Friday (or today, if today is Friday) and print it in a specified
format.


Solution


You can use the datetime module from
Python's standard library to easily achieve this:

import datetime, calendar
lastFriday = datetime.date.today( )
oneday = datetime.timedelta(days=1)
while lastFriday.weekday( ) != calendar.FRIDAY:
lastFriday -= oneday
print lastFriday.strftime('%A, %d-%b-%Y')
# emits, e.g.: Friday, 10-Dec-2004


Discussion


The handy little snippet of code in this recipe lets us find a
previous weekday and print the properly formatted date, regardless of
whether that weekday is in the same month, or even the same year. In
this example, we're looking for the last Friday (or
today, if today is Friday). Friday's integer
representation is 4, but to avoid depending on this
"magical number," we just import
the Python Standard Library calendar module and
rely instead on its calendar.FRIDAY attribute
(which, sure enough, is the number 4). We set a
variable called lastFriday to
today's date and work backward until we have reached
a date with the desired weekday value of 4.

Once we have the date we desire, formatting the date in any way we
like is easily achieved with the "string
formatting" method strftime of
the datetime.date class.

An alternative, slightly more terse solution uses the built-in
constant datetime.date.resolution instead of
explicitly building the datetime.timedelta
instance to represent one day's duration:

import datetime, calendar
lastFriday = datetime.date.today( )
while lastFriday.weekday( ) != calendar.FRIDAY:
lastFriday -= datetime.date.resolution
print lastFriday.strftime('%d-%b-%Y')

The datetime.date.resolution class attribute has
exactly the same value as the oneday variable in the
recipe's Solutionthe time interval of one
day. However, resolution can trip you up. The
value of the class attribute resolution varies
among various classes of the datetime
modulefor the date class
it's timedelta(days=1), but for
the time and datetime classes ,
it's timedelta(microseconds=1).
You could mix-and-match (e.g., add
datetime.date.resolution to a
datetime.datetime instance), but
it's easy to get confused doing so. The version in
this recipe's Solution, using the explicitly named
and defined oneday variable, is just as general,
more explicit, and less confusing. Thus, all in all, that version is
more Pythonic (which is why it's presented as the
"official" one!).

A more important enhancement is that we don't really
need to loop, decrementing a date by one at each step through the
loop: we can, in fact, get to the desired target in one fell swoop,
computing the number of days to subtract thanks to the wonders of
modular arithmetic:

import datetime, calendar
today = datetime.date.today( )
targetDay = calendar.FRIDAY
thisDay = today.weekday( )
deltaToTarget = (thisDay - targetDay) % 7
lastFriday = today - datetime.timedelta(days=deltaToTarget)
print lastFriday.strftime('%d-%b-%Y')

If you don't follow why this works, you may want to
brush up on modular arithmetic, for example at http://www.cut-the-knot.org/blue/Modulo.shtml.

Use the approach you find clearest, without worrying about
performance. Remember Hoare's dictum (often
misattributed to Knuth, who was in fact quoting Hoare):
"premature optimization is the root of all evil in
programming." Let's see why
thinking of optimization would be premature
here.

Net of the common parts (computing today's date, and
formatting and emitting the result) on a four-year-old PC, with Linux
and Python 2.4, the slowest approach (the one chosen for presentation
as the "Solution" because
it's probably the clearest and most obvious one)
takes 18.4 microseconds; the fastest approach (the one avoiding the
loop, with some further tweaks to really get pedal to the
metal
) takes 10.1 microseconds.

You're not going to compute last
Friday's date often enough, in your life, to be able
to tell the difference at 8 microseconds a pop (much less if you use
recent hardware rather than a box that's four years
old). If you consider the time needed to compute
today's date and to format the result, you need to
add 37 microseconds to each timing, even net of the I/O time for the
print statement; so, the range of performance is
roughly between 55 microseconds for the slowest and clearest form,
and 47 microseconds for the fastest and tersest oneclearly not
worth worrying about.


See Also


datetime module and strftime
documentation in the Library Reference
(currently at http://www.python.org/doc/lib/module-datetimel
and http://www.python.org/doc/current/lib/node208l).


    / 394