A programmer was walking out the door for work when a flatmate said:
'While you're out, buy some milk.'
The programmer never came home.
4. Repetition Structures
Topics
Introduction to Repetition Structures
The while Loop: a Condition-Controlled Loop
The for Loop: a Count-Controlled Loop
Calculating a Running Total
Sentinels
Input Validation Loops
Nested Loops
Flow Control
Turtle Graphics: Using Loops to Draw Designs
Introduction to Repetition Structures
Often have to write code that performs the same task multiple times
Disadvantages to duplicating code
Makes program large
Time consuming
May need to be corrected in many places
# Double number multiple times
doubled_number = 1
print(doubled_number)
doubled_number = doubled_number * 2
print(doubled_number)
doubled_number = doubled_number * 2
print(doubled_number)
doubled_number = doubled_number * 2
print(doubled_number)
doubled_number = doubled_number * 2
print(doubled_number)
doubled_number = doubled_number * 2
print(doubled_number)
doubled_number = doubled_number * 2
print(doubled_number)
Repetition structure: makes computer repeat included code as necessary
Includes condition-controlled loops and count-controlled loops
condition-controlled: true/false conditions to control loop
count-controlled: repeats loop a specific number of times
Checkpoint
1. What is a repetition structure?
2. What is a condition-controlled loop?
3. What is a count-controlled loop?
The while Loop
# simple while-loop
square_number = 1
# double count until it's larger (or equal) than 1000
while square_number < 100:
print(square_number)
square_number = 2 * square_number
The while Loop: a Condition-Controlled Loop
while loop: while condition is true, do something repeatedly
Syntax
while condition:
statement
statement
etc.
condition: Boolean expression tested for true or false value
statement: Statements repeated as long as condition is true
Iteration: one execution of the body of a loop
In flow chart, line goes back to previous part
while loop is known as a pretest loop
Tests condition before performing an iteration
Will never execute if condition is false to start with
Requires performing some steps prior to the loop
# Create a variable to control the loop.
keep_going = 'y'
# Calculate a series of commissions.
while keep_going == 'y':
# Get a salesperson's sales and commission rate.
sales = float(input('Enter the amount of sales: '))
comm_rate = float(input('Enter the commission rate: '))
# Calculate the commission.
commission = sales * comm_rate
# Display the commission.
print(f'The commission is ${commission:.2f}')
# See if the user wants to do another one.
keep_going = input('Do you want to calculate another commission (Enter y for yes): ')
Infinite Loops
Loops must contain within themselves a way to terminate
Something inside a while loop must eventually make the condition false
Infinite loop: loop that does not have a way of stopping
Repeats until program is interrupted
Occurs when programmer forgets to include stopping code in the loop
# Create a variable to control the loop.
keep_going = 'y'
# Warning! Infinite loop!
while keep_going == 'y':
# Get a salesperson's sales and commission rate.
sales = float(input('Enter the amount of sales: '))
comm_rate = float(input('Enter the commission rate: '))
# Calculate the commission.
commission = sales * comm_rate
# Display the commission.
print(f'The commission is ${commission:.2f}')
Checkpoint
1. What is a loop iteration?
2. Does the while loop test its condition before or after it performs an iteration?
3. How many times will 'Hello World' be printed in the following program?
count = 10
while count < 1:
print('Hello World')
4. What is an infinite loop?
The for Loop
# simple for-loop
# double count until it's larger (or equal) than 1000
for number in [1, 2, 4, 8, 16, 32, 64]:
print(number)
The for Loop: a Count-Controlled Loop
Count-Controlled loop: iterates a specific number of times
Syntax
for variable in iterable
statement
statement
etc.
variable is the target variable
iterable is a sequence data type like list, tuple, range, str, ...
Target variable: the variable which is the target of the assignment at the beginning of each iteration
The usual variable naming rules apply
for num in [1, 2, 3, 4, 5]:
print(num)
Using the range Function with the for Loop
for num in [0, 1, 2, 3, 4]:
print(num)
for num in range(5):
print(num)
Using the range Function with the for Loop
The range function simplifies the process of writing a for loop
range returns an iterable object
Iterable: contains a sequence of values that can be iterated over
range characteristics:
One argument: used as upper limit
Two arguments: starting value and upper limit
Three arguments: third argument is step value
Upper limit is NOT included
for num in range(1, 5):
print(num)
for num in range(1, 10, 2):
print(num)
The range function can be used to generate a sequence with numbers in descending order
Make sure starting number is larger than end limit, and step value is negative
for num in range(10, 1, -1):
print(num)
Loop Example: Speed Conversion
Create a table that converts km/h to mi/h
Range: 60, 70, .., 130 km/h
Conversion formula: mph = kph * 0.6214
print('| km/h | mph |')
print('| ---- | ---- |')
LOWER_LIMIT = 60
UPPER_LIMIT = 130
STEP = 10
for speed_kmh in range(LOWER_LIMIT, UPPER_LIMIT+1, STEP):
speed_mph = speed_kmh * 0.6214
print(f'| {speed_kmh: 4} | {speed_mph:.1f} |')
Letting the User Control the Loop Iterations
Sometimes the programmer does not know exactly how many times the loop will execute
Can receive range inputs from the user, place them in variables, and call the range function in the for clause using these
variables
Be sure to consider the end cases: range does not include the ending limit
Example: Counting - Part 1
Ask the user to enter a number. Print the numbers 1, 2,... up to the number entered by user.
# Get the ending limit.
end = int(input('Enter upper limit '))
# Print the numbers
for number in range(1, end + 1):
print(number)
Example: Counting - Part 2
Ask the user to enter a lower and upper limit and print this sequence.
# Get the starting value.
start = int(input('Enter the starting number: '))
# Get the ending limit.
end = int(input('Enter upper limit: '))
for number in range(start, end + 1):
# Print the numbers
print(number)
Checkpoint
1. Rewrite the following code so it calls the range function instead of using the list [0, 1, 2, 3, 4, 5].
for x in [0, 1, 2, 3, 4, 5]:
print(‘I love to program!')
2. What will the following code display?
for number in range(6):
print(number)
3. What will the following code display?
for number in range(2, 6):
print(number)
4. What will the following code display?
for number in range(0, 501, 100):
print(number)
5. What will the following code display?
for number in range(10, 5, -1):
print(number)
Calculating a Running Total
Programs often need to calculate a total of a series of numbers
Typically include two elements:
A loop that reads each number in series
An accumulator variable
Known as program that keeps a running total: accumulates total and reads in series
At end of loop, accumulator will reference the total
# The number of iterations
MAX = 5
# Initialize an accumulator variable.
total = 0
# Get the numbers and accumulate them.
for counter in range(MAX):
number = int(input('Enter a number: '))
total = total + number
# Display the total of the numbers.
print('The total is', total)
keep_going = 'y'
# Initialize an accumulator variable.
total = 0
# Get the numbers and accumulate them.
while keep_going == 'y':
number = int(input('Enter a number: '))
total = total + number
keep_going = input('Enter another number? "y" for yes: ')
# Display the total of the numbers.
print('The total is', total)
The Augmented Assignment Operators
In many assignment statements, the variable on the left side of the = operator also appears on the right side of the =
operator
Example: x = x + 1
Augmented assignment operators:
special set of shorthand operators designed for this type of job
Example: x += 1
Checkpoint
1. What is an accumulator?
2. Should an accumulator be initialized to any specific value? Why or why not?
3. What will the following code display?
total = 0
for count in range(1, 6):
total = total + count
print(total)
4. What will the following code display?
number 1 = 10
number 2 = 5
number 1 = number 1 + number 2
print(number1)
print(number2)
5. Rewrite the following statements using augmented assignment operators:
1. quantity = quantity + 1
2. days_left = days_left - 5
3. price = price * 10
4. price = price / 2
Input Validation Loops
number = int(input('Enter an integer: '))
Computer cannot tell the difference between good data and bad data
If user provides bad input, program will produce bad output
GIGO: garbage in, garbage out
It is important to design program such that bad input is never accepted
Input validation: inspecting input before it is processed by the program
If input is invalid, prompt user to enter correct data
Commonly accomplished using a while loop which repeats as long as the input is bad
If input is bad, display error message and receive another set of data
If input is good, continue to process the input
Input Validation Examples
Test whether a given input is an integer:
# Get a test score.
number_string = input('Enter an integer: ')
# Make sure it is a integer
while not number_string.isdecimal():
print('Input must be an integer')
number_string = input('Enter an integer: ')
Example: Retail Price Calculations - Without Validation
Compute retail price as retail price = wholesale costs x 2.5
MARK_UP = 2.5 # The markup percentage
another = 'y' # Variable to control the loop.
# Process one or more items.
while another == 'y':
# Get the item's wholesale cost.
wholesale = float(input("Enter the item's wholesale cost: "))
# Calculate the retail price.
retail = wholesale * MARK_UP
# Display the retail price.
print(f'Retail price: ${retail:.2f}')
# Do this again?
another = input('Do you have another item? (Enter y for yes): ')
Example Retail Price Calculations - With Validation
MARK_UP = 2.5 # The markup percentage
another = 'y' # Variable to control the loop.
# Process one or more items.
while another == 'y':
# Get the item's wholesale cost.
wholesale = float(input("Enter the item's wholesale cost: "))
# Validate the wholesale cost.
while wholesale < 0:
print('ERROR: the cost cannot be negative.')
wholesale = float(input("Enter the item's wholesale cost: "))
# Calculate the retail price.
retail = wholesale * MARK_UP
# Display the retail price.
print(f'Retail price: ${retail:.2f}')
# Do this again?
another = input('Do you have another item? (Enter y for yes): ')
Checkpoint
1. What does the phrase "garbage in, garbage out" mean?
2. Give a general description of the input validation process.
3. Describe the steps that are generally taken when an input validation loop is used to validate data.
Nested Loops
Nested loop: loop that is contained inside another loop
Key points about nested loops:
Inner loop goes through all of its iterations for each iteration of outer loop
Inner loops complete their iterations faster than outer loops
Total number of iterations in nested loop:
number_iterations_inner x number_iterations_outer
Example: Clock
Analog clock works like a nested loop
Hours hand moves once for every 60 movements of the minutes hand: for each iteration of the “hours,” do 60
iterations of “minutes”
Seconds hand moves 60 times for each movement of the minutes hand: for each iteration of “minutes,” do 60
iterations of “seconds”
# We use time module to sleep for 1 second
import time
for minutes in range(60):
for seconds in range(60):
print(f'{minutes:02d}:{seconds:02d}')
# Wait 1 second
time.sleep(1)
# We use time module to sleep for 1 second
import time
for hours in range(24):
for minutes in range(60):
for seconds in range(60):
print(f'{hours:02d}:{minutes:02d}:{seconds:02d}', end='\r')
# Wait 1 second
time.sleep(1)
Example: Compute average score of several students.
# Get the number of students.
num_students = int(input('How many students do you have? '))
# Get the number of test scores per student.
num_test_scores = int(input('How many test scores per student? '))
# Determine each students average test score.
for student in range(1, num_students+1):
print(f'Student {student}')
# Initialize an accumulator for test scores.
total = 0.0
for test_num in range(1, num_test_scores+1):
score = float(input(f'Test number {test_num}: '))
# Add the score to the accumulator.
total += score
# Calculate the average test score for this student.
average = total / num_test_scores
# Display the average.
print(f'The average for student {student} is: {average:.1f}\n')
Printing Patterns
Write programs that produce patterns of the following kind:
****** * #
****** ** #
****** *** #
****** **** #
****** ***** #
****** ****** #
****** ******* #
****** ******** #
# Display a rectangular pattern of asterisks.
rows = int(input('How many rows? '))
cols = int(input('How many columns? '))
for r in range(rows):
for c in range(cols):
print('*', end='')
print()
# Display a triangle pattern.
BASE_SIZE = 8
for r in range(BASE_SIZE):
for c in range(r + 1):
print('*', end='')
print()
# Display a stair-step pattern.
num_steps = 6
for r in range(num_steps):
for c in range(r):
print(' ', end='')
print('#')
Flow Control: break
break statement:
breaks out of the innermost loop (while or for loop)
SECRET_NUMBER = 7
while True:
guess = int(input('Guess my number: '))
if guess == SECRET_NUMBER:
print('You\'re right! Can you read my mind?')
break
else:
print('Wrong! Have another try.')
The same without break
SECRET_NUMBER = 7
guess = int(input('Guess my number: '))
while guess != SECRET_NUMBER:
print('Wrong! Have another try.')
guess = int(input('Guess my number: '))
print('You\'re right! Can you read my mind?')
Flow Control: continue
continue statement:
continues with the next iteration of the loop
for num in range(2, 8):
if num % 3 == 0:
print('Found a multiple of 3:', num)
continue
print("Found a number: ", num)
num = 1
while num < 7:
num += 1
if num % 3 == 0:
print('Found a multiple of 3:', num)
continue
print("Found a number: ", num)
Flow Control: else
loops can have an else statement
else block is executed, if loop terminated normally, i.e. not with a break
for i in range(n):
do_something()
else:
do_another_thing()
# Find all prime numbers between 2 and 9
for n in range(2, 10):
for x in range(2, n):
if n % x == 0:
print(n, 'equals', x, '*', n//x)
break
else:
# loop fell through without finding a factor
print(n, 'is a prime number')
n = 1
while n < 9:
n += 1
for x in range(2, n):
if n % x == 0:
print(n, 'equals', x, '*', n//x)
break
else:
# loop fell through without finding a factor
print(n, 'is a prime number')
Turtle Graphics: Using Loops to Draw Designs
You can use loops with the turtle to draw both simple shapes and elaborate designs.
turtle_square.py
turtle_octagon.py
turtle_circles.py
turtle_starburst.py
# Draw a square sized 100px
import turtle
for x in range(4):
turtle.forward(100)
turtle.right(90)
turtle.hideturtle()
turtle.done()
# Draw an octogon sized 100px
import turtle
import math
for x in range(8):
turtle.forward(100)
turtle.right(45)
turtle.hideturtle()
turtle.done()
# Draw a nice figure with circles.
import turtle
# Number of circles to draw
NUM_CIRCLES = 36
# Radius of each circle
RADIUS = 100
# Angle to turn
ANGLE = 360 / NUM_CIRCLES
turtle.speed(0)
for x in range(NUM_CIRCLES):
turtle.circle(RADIUS)
turtle.left(ANGLE)
turtle.hideturtle()
turtle.done()
# Draw a nice figure with circles.
import turtle
START_X = -100 # Starting X coordinate
START_Y = 0 # Starting Y coordinate
NUM_LINES = 36 # Number of lines to draw
LINE_LENGTH = 200 # Length of each line
ANGLE = 170 # Angle to turn
turtle.hideturtle()
turtle.penup()
turtle.goto(START_X, START_Y)
turtle.pendown()
turtle.speed(0)
for x in range(NUM_LINES):
turtle.forward(LINE_LENGTH)
turtle.left(ANGLE)
turtle.hideturtle()
turtle.done()
Summary
This chapter covered:
Repetition structures, including:
Condition-controlled loops
Count-controlled loops
Nested loops
Infinite loops and how they can be avoided
range function as used in for loops
Calculating a running total and augmented assignment operators
Use of sentinels to terminate loops
Use break, continue and else to control flow of a loop
Using loops to draw turtle graphic designs