Will the following print statement get executed?
if "a string?":
print("Do I get executed?")
Yes. Most values can be used in a boolean context. In Python, 0
, 0.0
,
None
, empty sequences (e.g. “”) and a few other values evaluate as False
and everything else is True
.
In general, I don’t recommend using this “implicit” type conversion as it just increases the chances for difficult-to-find bugs.
Now that we know about implicit booleans, though, we can resolve a common
bug. In a previous question, the solution was a == b or a == 5
. Can we
simplify that expression as a == b or 5
? No, that expression is evaluated as
a (a == b) or 5
, which is not the same (and will always evaluate to True
as 5
evaluates as True
).
Let’s think about a and b
. If a
evaluates to False
do I need to evaluate
b
? Similarly if in a or b
a
evaluates to True
do I need to evaluate
b
?
No. Python can “short-circuit” the evaluation. Doing so is a very powerful technique for managing potentially problematic situations.
is_valid(input) and dangerous_operation(input)
We can also apply relational operators, i.e. <
, ==
, etc., to other types;
most notably strings. For example:
>>> 'Aardvark' < 'Zebra'
True
>>> 'aardvark' < 'Zebra'
False
That doesn’t seem to make much sense… Just as +
has different meaning for
strings than integers, the <
for strings implements lexicographic ordering,
i.e. it compares the ordering of corresponding characters. The first characters
are compared, if equal, then the 2nd characters are compared and so on. If one
string is a substring of the other, it is lexicographically less than, e.g.
>>> "abc" < "abcdef"
True
This is not the same as a case-insensitive alphabetical ordering. In the character encoding used by Python (and lots of other software), all upper case letters are less than lower case letters. Hence “aardvark” is “greater than” “Zebra”.
Some more examples:
>>> "test" == "test"
True
>> "test" == "testing"[0:4]
True
>> "test" == "TEST"
False
If we wanted to ensure that a string comparison was case insensitive, how could
be we do so? Use the upper
or lower
methods to ensure consistent case.
while
loopsWe previously used for
loops to execute a block of code for a specific number
of repetitions. What if we don’t know how many iterations are needed? What
might be such a situation? Obtaining a valid input from a user. We don’t know
how many tries it will take someone to provide a valid input.
This is where we apply while
loops.
General structure:
while <bool expression>:
statement1
statement2
...
statementn
The statements in the loop body (i.e. statement1 … statementn) will be
executed repeatedly until the boolean expression, the loop conditional,
evaluates to False
.
Here is a concrete example. What will this code print?
>>> x = 5
>>> while x > 0:
... print(x)
... x = x-1
...
5
4
3
2
1
What is the implication of while
loops? That some statement(s) within the
body of the while
loop will change the loop conditional (or otherwise
terminate the loop). What happens if that is not the case, e.g.
while True:
print("How many times will this string get printed?")
Hit Ctrl-C (Ctrl and C simultaneously) or the Thonny “stop sign” button to stop execution.
This is called an infinite loop and is a common problem. You will likely need to use Ctrl-C or the stop sign button at some point.
What about the following loop? Will it terminate?
i = 0
while i < 10:
print("How many times will this string get printed?")
i = i - 1
No. Because i
starts at 0 and only gets smaller it will always be less than
i = randint(1, 20)
while i < 10:
print("How many times will this string get printed?")
i = i + 1
Yes. If the value is less than 10, the loop with terminate after some number of iterations. If the value is greater than or equal to 10, the loop won’t execute at all.
In addition to changing the loop conditional we can also explicitly terminate
the loop with the break
statement. As its name suggests, break
terminates
the loop and begins executing the first statement after the loop.
PI Questions (While loops)1
Let’s look at a more complex example: Let’s implement a guessing game in which Python picks a random integer from 1-20 (inclusive), and keeps asking the user to guess the number until they get it right. To help the user, the game should give hints “higher”, or “lower”.
What would be some key elements in such a program?
Check out guessing-game.py.
Here we see 3 strategies for implementing the loop:
correct
to track if the user answered correctlybreak
out of a “while True” loop on a correct answerNote the use of the input
function for reading user inputs:
>>> help(input)
Help on built-in function input in module builtins:
input(prompt=None, /)
Read a string from standard input. The trailing newline is stripped.
The prompt string, if given, is printed to standard output without a
trailing newline before reading input.
If the user hits EOF (*nix: Ctrl-D, Windows: Ctrl-Z+Return), raise EOFError.
On *nix systems, readline is used if available.
input
returns a string and so we need to convert the result to an int
for
use in our game.
Often we can implement the same functionality with both a for
loop and a
while
loop. In fact, in Python any for
loop can be readily implemented with
a while
loop. The reverse is trickier. There are hacks that would enable us
to make a for loop behave like a while loop in some situations, but they are
exactly that – hacks. So for our purposes we should think of while loops as a
superset of for
loops.
So when do we use a for
loop and when do we use a while
loop?
We use a for
loop when
As an example, iterating over all the elements in a sequence, e.g. a string, is an example of a situation where the number of iterations is known at the initiation of the loop (number of elements in sequence) and the increment is consistent (increment one element each iteration).
We would use a while
loop in other settings, such as
This an example where “style” matters but there are not necessarily clear “rules”. Often one approach or the other is more appropriate. The right choice will make the code more elegant, easier to reason about (and easier to debug).