Blake Winton wrote:
def is_leap_year(year): is_leap = True try: datetime.date(year, 2, 29) except ValueError: is_leap = False return is_leap
I would write def is_leap_year(year): try: datetime.date(year, 2, 29) return True except ValueError: return False
If one insists on single-return style, then I'd prefer to do it this way:
def is_leap_year(year): try: datetime.date(year, 2, 29) is_leap = True except ValueError: is_leap = False return is_leap
You still have to type 'is_leap' multiple times, but at least it's a little bit more clear which conditions will result in it being True or False.
[...] Only having one
return point from a function is a long-standing convention that is supposed to make programs easier to read/debug/optimize/prove correct.
Indeed, it is supposed (by some) to be better, and is thought by others to sometimes make things more complicated. In the above code, a single return point gives you one place to set breakpoints during debugging, etc, but it also means that you introduce a new variable that you must type at least three times, introducing multiple opportunities for typos. As with most programming choices, single-return has both a benefit and a cost. In some situations the cost can be very large relative to the benefit; in others the cost is very small. I find it best not to be too dogmatic about most such stylistic questions -- I try to stay aware of the costs of a particular approach, but I'll happily use it when the net effect is to make the code simpler and more understandable.
Similar to the example that Kent later points out, in my work life I often find myself writing functions (to use as the body of a loop) where a number of unrelated tests must be done before proceeding with processing. (This is actually in an old, crufty dialect of Basic, but the same principle applies) I have a few choices in this case. I can simply write the loop body in-line and use gotos to skip segments if the tests fail (ew). I can write the loop body in-line and use multiply nested if/else statements, but it can get difficult to track what nesting level I'm at. I can use nested functions, each with just one test in it, something like this:
def func1(data): result = None if test1: result = func2(data) return result
def func2(data): result = None if test2: result = func3(data) return result
def func3(data): [...]
This gets pretty darn ugly to trace through, especially when I've got six or eight different tests. Or, I can simply use multiple returns:
def func(data) if not test1: return if not test2: return if not test3: return # do stuff with data...
It really does make it much simpler to track through the code, since I don't care, later in the function, about the specific results of each test, only about whether I should continue afterwards or not. In this case, I'm weighing the cost of multiple returns against the cost of multiple nestings or of using flag variables, and I find multiple returns to be the lowest-cost option.
Jeff Shannon Technician/Programmer Credit International
_______________________________________________ Tutor maillist - [EMAIL PROTECTED] http://mail.python.org/mailman/listinfo/tutor