Where’s Wally?
A Python Brain Teaser
What do you think the following program will print?
This program will print Found Waldo
Why? Let’s start by reading str.find
documentation:
str.find(sub[, start[, end]])
Return the lowest index in the string where substring sub is found within the slice s[start:end]. Optional arguments start and end are interpreted as in slice notation. Return -1 if sub is not found.
So, haystack.find(needle)
will return -1
. Why is -1
considered true? The reason is … history.
The Python most of us use is called “CPython”, it’s written in C and started it’s life in 1991 (yes, Python is that old). At the time, C didn’t have boolean types — they were added in the C99 spec around 2000. Python adopted its truth rules from C. Even today, you can find the following in the official documentation:
Any object can be tested for truth value, for use in an if or while condition or as operand of the Boolean operations below.
By default, an object is considered true unless its class defines either a__bool__()
method that returnsFalse
or a__len()__
method that returns zero, when called with the object. Here are most of the built-in objects considered false:
- constants defined to be false: None and False.
- zero of any numeric type: 0, 0.0, 0j, Decimal(0), Fraction(0, 1)
- empty sequences and collections: ‘’, (), [], {}, set(), range(0)
Boolean values finally came to Python 2.3 after a long and bitter debate.
But, Python respects the old truth value semantics.
Back to our problem, we get -1
which is considered True
. And that’s why you see the Found Waldo
output.
Site note: I’ve seen this bug in the wild several times and even committed it myself a couple of times. 😏
What’s the solution? Use the in
operator.
Why does str.find
return –1
when not found? str.find
returns the index of the substring if it is found. Since the substring might be at the start (for example: str.find('Java', 'JavaScript')
, 0
can be a valid index. Even though -1
is a valid string index, it’s clear enough that it signals “not found.”
🎓 The lesson here? Read the docs, don’t assume you know what a function returns. The Python community invest a lot of effort to keep the documentation helpful and up to date.
If you like to solve programming problems, check out Miki Tebeka’s Brain Teaser books from The Pragmatic Bookshelf. You can save 35 percent on the ebook versions with promo code brain_teasers_35 through July 30, 2022: