= 0
x while x < 10:
= x + 1 # Accumulator x
While Loops (Iteration)
Introduction to Software Engineering (CSSE 1001)
There are (at least) two scenarios where repeating possibly indefinitely, is necessary:
- prompting the user for valid input, and
- playing a random game (i.e. guessing dice rolls).
While and Do Loops
A loop is a control structure that repeats code that belongs to it.
A while-loop is a control structure that repeats code while some condition is satisfied.
While-Loop
while <condition>:
<code>
x
10
Python Assignment Operators
Because accumulators like this or so common, there are some syntactic shortcuts we can use.
x += y
is equivalent tox = x + y
x *= y
is equivalent tox = x * y
x /= y
is equivalent tox = x / y
x %= y
is equivalent tox = x % y
= 0
x while x < 10:
+= 1 # Accumulator x
x
10
Infinite Loops
= 0
x while True:
print(x)
+= 1 x
0
1
2
3
.
.
. (infinite)
There is usually a key-stroke, typically Ctrl+C, that terminates a loop — it is a good idea to learn what it is in your IDE!
= 0
x while False:
print(x)
+= 1 x
Nothing prints.
The break keyword terminates a loop immediately and continues.
while True:
print("hello")
break
print("world")
hello
Do-While-Loop
A do-while
or repeat-until
are while-loop
variants available in other languages.
There is a popular variant to the while-loop
called a do-while
or repeat-until
that executes its body at least once.
do:<code>
while <condition> # this is not valid Python syntax
Although not natively supported in Python (they are in many other languages), we can simulate them.
= 0
x while 1: # Some programmers prefer 1 to True
+= 1
x if x > 0:
break
Big Example: Rebuilding Arithmetic
Suppose we have access to a succ
(successor) and pred
(predecessor) function that increments or decrements a value by one.
1) succ(
2
2) succ(
3
1) pred(
0
2) pred(
1
Can we implement addition, multiplication, and power using only these functions?
Our task will work as follows. We will assume there are values loaded in x
and y
and will have completed the task if ultimately the correct value to z
is assigned. We will also restrict our task to arithmetic on postive numbers only.
Suffice to say that we are disallowed from using any of the built-in arithmetic (e.g. +
, *
, …) to complete this task.
Task 1 (Addition)
The following code sequence increments x
by one y
-many times. This is equivalent to incrementing x
by y
. Which is further equivalent to adding x
and y
.
# Stores the sum of x and y in z.
= 2, 3
x, y
while y: # the "Pythonic" way of checking y != 0
= succ(x) # +1 to x
x = pred(y) # -1 to y
y
= x
z # z is now x + y
z
5
Task 2 (Multiplication)
This code sequence accumulates on t
by r
-increments s
-many times. This is equivalent to multiplying r
by s
.
# Stores the PRODUCT of r and s in t.
= 2, 3
r, s = 0
t
while s:
= t + r # we were not allowed to use this
t = pred(s)
s # t is now r * s
t
6
We “refactor” our code to use our definition of addition.
# stores the PRODUCT of r and s in t.
= 2, 7
r, s = 0
t while s:
# Stores the sum of x and y in z.
= t, r
x, y while y:
= succ(x)
x = pred(y)
y = x
z # z is now x + y
= z
t = pred(s)
s # t is now r * s
t
14
Task 3 (Power)
# stores the POWER of and a and b in c
= 2, 7
a, b = 1
c
while b:
= c * a # we weren't allowed to do this
c = pred(b)
b # c is now a**b
c
128
Refactoring to use our own multiplication code.
# stores the POWER of and a and b in c
= 2, 7
a, b = 1
c
while b:
# stores the PRODUCT of r and s in t.
= c, a
r, s = 0
t while s:
# Stores the sum of x and y in z.
= t, r
x, y while y:
= succ(x)
x = pred(y)
y = x
z # z is now x + y
= z
t = pred(s)
s # t is now r * s
= t
c = pred(b)
b # c is now a**b
c
128
Refactoring with Functions
As we can see our listings are getting somewhat cumbersome. This is precisely where functions should be utilized to abstract our code into more manageable pieces.
Our addition code, for example,
# Stores the sum of x and y in z.
= 2, 3
x, y
while y: # the "Pythonic" way of checking y != 0
= succ(x)
x = pred(y)
y
= x
z # z is now x + y
is better implemented by the add
function.
def add_positive(x: int, y: int) -> int:
"""Return the sum of x and y.
Precondition:
x > 0
y > 0
>>> add_positive(2, 3)
5
"""
while y: # the "Pythonic" way of checking y != 0
= succ(x)
x = pred(y)
y
return x
Assigning z = x
and returning z
is the same thing as just returning x
.
2, 3) add_positive(
5
We can contrast and compare the behaviour of code sequence against its implementation as a function. Note that because succ
and pred
do not actually exist in Python, we had to use arithmetic for this example.
This simplification cascades down into multiplication and power.
def multiply_positive(r: int, s: int) -> int:
"""Return the product of r and s.
Precondition:
r > 0
s > 0
>>> multiply_positive(2, 3)
6
"""
= 0
t
while s:
= add_positive(t, r)
t = pred(s)
s
return t
2, 3) add_positive(
5
def power_positive(a: int, b: int) -> int:
"""Return a to the power of b.
Precondition:
a > 0
b > 0
>>> power_positive(2, 3)
8
"""
= 1
c
while b:
= multiply_positive(c, a)
c = pred(b)
b
return c
2, 7) power_positive(
128
Exercise 1 Using only the new arithmetic functions we have developed. Implement
greater_than(x: int, y: int) -> int
which is true only when x > z
. Do not use >
.
User Input
The command x = input()
will wait for input from the keyboard and then assign it to x
with type(x) is str
.
Exercise 2 Write a function foo(target: int) -> int
that prompts the user to input a number until the user guesses some (secret) target.
For each guess the function should print Too high
, Too low
, or That's it!
depending on the guess.
Return the number of guesses required.
Random Numbers
Random number generation is handled by an external library. It is not built-in and therefore must be imported.
We can “import” a single command from the random library as follows.
from random import randint
1,6) # Chosen uniformly over the interval. randint(
4
Or we can import every command (which is almost certainly a bad idea because this pollutes our name space by defining a bunch of names “behind our backs”).
import random
1,6) random.randint(
1
Exercise 3 Write a function called bar() -> Nothing
that prompts the user to predict the result of a six-sided dice roll.
Repeat the prompt until the user predicts correctly.
Exercise 4 Write a function that prints the result of a six-sided dice roll until a six is rolled. Return the number of rolls required.
Exercise 5 Write a function that accumulates the result of dice rolls until some threshold is met/passed. Return the number of rolls required.
Summary
The while-loop is a control structure for repeating code a possibly infinite number of times.