[Tutor] class method problem
Steven D'Aprano
steve at pearwood.info
Sun Sep 26 03:16:13 CEST 2010
On Sun, 26 Sep 2010 08:13:23 am David Hutto wrote:
> Since I had nothing else to do, but practice, this looks much better:
>
> def find(word, search):
> if search in word:
> print True
> else:
> print False
For some definition of "better".
If I called a function:
find("anti-disestablishmentarianism", "lish")
and got back an answer:
True
I'd feel ripped off and cheated. That would be like going to Google,
typing in something into the search box, and Google comes back with:
Yes, we found your terms on the Internet, but we won't tell you
where. If you would like to find something else, we won't tell
you where that is either.
Aside from the name of the function, which is deceptive because it
doesn't describe what the function does, the names of the arguments are
also poor. The first argument is not necessarily a word. Nor is there
any need for it to be -- it can be any text. The second argument is
poorly described as "search" -- search is a verb.
A better function signature might be:
def search(text, target):
# Search for target in text and print whether it is found or not.
Even this is slightly misleading, because "text" doesn't need to be an
actual string. It could be any sequence, such as a list. But this gives
the *intention* of the function, which is to do text searches. So this
is (in my opinion) an acceptable compromise between intention and
generality.
Now on to the code itself. The body of the function is needlessly
verbose. You say:
if search in word:
print True
else:
print False
This is so simple we can trace the entire function by hand. Say we call
search("I like spam and eggs", "spam"):
(1) target in text? => True
(2) take the if branch
(3) print True
Now say we call find("I like spam and eggs", "cheese"):
(1) target in text? => False
(2) take the else branch
(3) print False
Can you see the common factor? The object which is printed is always
precisely the same object generated by the `in` test. So we can
simplify the body of the function:
def search(text, target):
print target in text
But this is so simple, there's no point to wrapping it in a function!
Small functions that do one thing are good, up to a point, but when the
function is so small that it is just as easy to include the body in the
caller code, the function is pointless. It's not like "search(b, a)" is
easier to write or remember than "print a in b" -- if anything the
opposite is the case, because I would never remember which order to
pass the arguments.
--
Steven D'Aprano
More information about the Tutor
mailing list