While and for loops

A loop is a block of code used to carry out iterations. 

While Loop

A while loop instructs the computer to continuously execute our code based on the value of a condition.

The following is a sample of a number-guessing game.

# Import the random module to be able to create a (pseudo) random number.
import random

number = random.randint(1,25)                   # Generate random number
number_of_guesses = 0                           # Instantiate guess counter

while number_of_guesses < 5:
    print('Guess a number between 1 and 25: ')  # Tell user to guess number
    guess = input()                             # Produce the user input field
    guess = int(guess)                          # Convert guess to integer
    number_of_guesses += 1                      # Increment guess count by 1

    if guess == number:                         # Break while loop if guess is correct
        break
    elif number_of_guesses == 5:                # Break while loop if guess limit reached
        break
    else:                                       # Tell user to try again
        print('Nope! Try again.')

# Message to display if correct
if guess == number:
    print('Correct! You guessed the number in ' + str(number_of_guesses) + ' tries!')
# Message to display after 5 unsuccessful guesses
else:
    print('You did not guess the number. The number was ' + str(number) + '.')

Notes to future myself: This code still needs improvement for the following reasons:

  • If the user types a string, it crashes.
  • The code allows users to enter an input outside of the 1-25 range.
  • The code accepts the repeating inputs.

Let’s check some more samples.

Iterate with a while loop
# Assign `cat_adapted` to an initial value of 0 to act as a counter
cat_adapted = 0

# Create an iterative statement using `while` and `cat_adapted`
# Display how many cats have been adapted with each iteration

while cat_adapted <= 5:
    print('Cat adapted: ' + str(cat_adapted))
    # Increment the cat_adapted counter
    cat_adapted += 1
Cat adapted: 0
Cat adapted: 1
Cat adapted: 2
Cat adapted: 3
Cat adapted: 4
Cat adapted: 5
Iterate using while and if

Let’s do a similar code but this time we’ll count candies that are purchased and print them out, but only when a multiple of 10 purchases have been made.

candy_purchased = 0
while candy_purchased <= 100:
    if candy_purchased % 10 == 0:
        print('Candy purchased: ' + str(candy_purchased))
    candy_purchased += 1
Candy purchased: 0
Candy purchased: 10
Candy purchased: 20

Candy purchased: 90
Candy purchased: 100
Create a timer function
from time import sleep
n = 3
while n >= 0:
    print(n)
    sleep(1)    # Execution pauses for 1 second
    n = n - 1   # Decrement n by 1
3
2
1
0

Let’s make it more useful, by adding some warnings.

from time import sleep
mins = 10

while mins >= 0:
    if mins == 5:
        print('Place your reservation soon! 5 minutes remaining.')
    elif mins == 2:
        print('Don\'t lose your seats! 2 minutes remaining.')
    elif mins == 0:
        print('User timed out.')
    else:
        print(mins)
    mins -=1
    sleep(1)
10
9
8
7
6
Place your reservation soon! 5 minutes remaining.
4
3
Don't lose your seats! 2 minutes remaining.
1
User timed out.

Break & Continue

Break is a keyword that lets us escape a loop without triggering any ELSE statement that follows it in the loop. By using a break, we can end a loop even if the conditional statement is still true.

x = 1
i = 0
while x < 100:
   if i == 5:
       break
   print(i, x)
   x = x*2
   i += 1
0 1
1 2
2 4
3 8
4 16

By using a continue statement, we can skip an iteration of the loop without executing the rest of the code inside the loop for the current iteration. 

i = 0
while i < 10:
    if i % 3 != 0:
        print(i)
        i += 1
        continue      #to cycle back to the beginning
    i += 1
1
2
4
5
7
8

For Loop

For loop is a piece of code that iterates over a sequence of values.

# Example of for loop with range() function
for x in range(5):
    print(x)
0
1
2
3
4
Loops with multiple range() parameters
# Use a for loop to calculate 9!
product = 1
for n in range(1, 10):
    product = product * n

print(product)
362880
# Define a function that converts Fahrenheit to Celsius.
def to_celsius(x):
     return (x-32) * 5/9

# Create a table of Celsius-->Fahrenheit conversions every 10 degrees, 0-100
for x in range(0, 101, 10):
     print(x, round(to_celsius(x), 2))
0 -17.78
10 -12.22
20 -6.67
30 -1.11
40 4.44
50 10.0
60 15.56
70 21.11
80 26.67
90 32.22
100 37.78

Another sample through a list:

num = 5
y = [1, 2, 3]
for num in y:
   print(num)

print(num)
1
2
3
3

Notice that num exists as a variable before the for loop begins. The for loop’s first iteration reassigns its value with that of the first element in the sequence. This reassignment occurs with each iteration of the loop. When the loop terminates, the variable persists, and it contains the value it had after the final iteration of the loop.

Nested Loops

A nested loop is a loop inside of another loop. We can have an infinite number of nested loops, but it becomes more confusing to read and understand the more nested loops we add.

students = [['Igor', 'Sokolov'], ['Riko', 'Miyazaki'], ['Tuva', 'Johansen']]
for student in students:
   for name in student:
       print(name)
   print()
Igor
Sokolov

Riko
Miyazaki

Tuva
Johansen
Iterating with if, elif, and else
  • Define a function called score_counter that accepts the following argument:
    • score_list – a list of customer-submitted scores, where each score is an integer, 1-10
  • The function must iterate over the scores in score_list and bin them into three bins:
    • Negative (scores of 1-5)
    • Neutral (scores of 6-8)
    • Positive (scores of 9-10)
  • The output of the function must be three statements, each on its own line:
    1. ‘Negative: {number_of_negative_scores}’
    2. ‘Neutral: {number_of_neutral_scores}’
    3. ‘Positive: {number_of_positive_scores}’
def score_counter(score_list):
    negative_scores = 0
    neutral_scores = 0
    positive_scores = 0

    for score in score_list:
        if score >= 9:
            positive_scores += 1
        elif score >= 6:
            neutral_scores += 1
        else:
            negative_scores += 1

    print('Negative:', negative_scores)
    print('Neutral:', neutral_scores)
    print('Positive:', positive_scores)

To test the code above:

import random
random.seed(42)

possible_scores = list(range(1,11))
score_list1 = random.choices(possible_scores, weights=[8,8,8,8,8,3,3,4,20,30], k=10)
score_list2 = random.choices(possible_scores, weights=[1,2,3,4,5,10,15,15,7,9], k=450)
score_list3 = random.choices(possible_scores, weights=[1,2,3,4,4,5,5,10,15,25], k=10000)

print('Test 1:')            # SHOULD OUTPUT (neg, neut, pos):
score_counter(score_list1)  # 5, 1, 4
print('\nTest 2:')
score_counter(score_list2)  # 85, 253, 112
print('\nTest 3:')
score_counter(score_list3)  # 1935, 2652, 5413
Test 1:
Negative: 5
Neutral: 1
Positive: 4

Test 2:
Negative: 85
Neutral: 253
Positive: 112

Test 3:
Negative: 1935
Neutral: 2652
Positive: 5413
Create a for loop using if, not, and in
  • Define a function called id_validator that takes two lists as arguments:
    1. verified_ids – a list containing IDs of verified customers
    2. feedback_ids – a list containing unique IDs of all posters of feedback scores
  • The output of the function must be two statements, each on its own line:
    1. ‘{number_of_unverified_ids} of {number_of_feedback_ids} IDs unverified.’
    2. ‘{percent} unverified.’
def id_validator(verified_ids, feedback_ids):
   unverified_feedback = 0
    for id in feedback_ids:
        if id not in verified_ids:
            unverified_feedback += 1
    percent_unverified = unverified_feedback/len(feedback_ids)*100
    print(unverified_feedback, 'of', len(feedback_ids), 'IDs unverified.')
    print(str(round(percent_unverified, 2)) + '% unverified.')

To test the code above:

import ada_c2_labs as lab

# TEST SCENARIOS:                                   # SHOULD OUTPUT:
print('Test 1:')
ver1, fb1 = lab.lists_gen(8, 20, 15, 15)            # 4 of 15 IDs unverified.
id_validator(ver1, fb1)                             # 26.67% unverified.

print('\nTest 2:')
ver2, fb2 = lab.lists_gen(8, 1000, 900, 600)        # 357 of 900 IDs unverified.
id_validator(ver2, fb2)                             # 39.67% unverified.

print('\nTest 3:')
ver3, fb3 = lab.lists_gen(8, 15000, 14925, 13788)   # 1208 of 14925 IDs unverified.
id_validator(ver3, fb3)                             # 8.09% unverified.
Test 1:
4 of 15 IDs unverified.
26.67% unverified.

Test 2:
357 of 900 IDs unverified.
39.67% unverified.

Test 3:
1208 of 14925 IDs unverified.
8.09% unverified.
Create a nested loop
  • Write a function called purchases_100 that accepts the following argument:
    • sales – a list of lists where each inner list contains the prices of items purchased by a unique customer.
  • The function must return the number of customers whose purchases summed to $100 or more.
Example:
sales = [[2.75], [50.0, 50.0], [150.46, 200.12, 111.30]]

[IN] purchases_100(sales)
[OUT] 2
def purchases_100(sales):
    count = 0                           # Set a counter of totals > 100
    for customer in sales:              # Loop over each inner list
        customer_total = 0              # Set 0 value of purchases for the inner list
        for purchase in customer:       # For price in inner list:
            customer_total += purchase  # Add the price to value of purchases 
                                        # for inner list
        if customer_total >= 100:       # After looping over all prices in inner list, 
                                        # if total >= 100
            count+=1                    # Increment the counter
    return count

To test the function above:

import ada_c2_labs as lab
sales1 = lab.sales_data_generator(n_customers=10, seed=1)   # SHOULD OUTPUT:
print('Test 1:', purchases_100(sales1))                     # 5

sales2 = lab.sales_data_generator(n_customers=150, seed=18)
print('Test 2:', purchases_100(sales2))                     # 46

sales3 = lab.sales_data_generator(n_customers=1275, seed=42)
print('Test 3:', purchases_100(sales3))                     # 470
Test 1: 5
Test 2: 46
Test 3: 470

Which one to use: while or for loop?

Use while loops when we want to repeat an action until a Boolean condition changes, without having to write the same code repeatedly. 

Use for loops when there’s a sequence of elements that we want to iterate over. To loop over a variable, such as a record in a dataset, it’s always better to use for loops.


In