Block B

Indefinite Looping with while

picture of Stephen Colbert

Truthiness and Falsiness A value is truthy if when it is cast to a boolean, it casts to True. A value is Falsy if when it is cast to a boolean, it casts to False.

Note that if statements will act on truthiness and falsiness. Here are examples of truthy and falsy expressions.


>>> bool(0)
False
>>> bool(314)
True
>>> bool("")
False
>>> bool("weqrijterwwer")
True
>>> bool(None)
False
>>> bool([])
False
>>> bool([1,2,3])
True

Question What's +=? It's a compound assignment operator. See these examples.


>>> x = 5
>>> x = x + 2
>>> x
7
>>> x += 2
>>> x
9
>>> x *= 2
>>> x
18
>>> #compound assignment operator
>>> x -= 1
>>> x
17

Afraid of commitment? So far, our looping has been walking through a collection such as a list, dictionary, or range object. Now we will look at a construct that can loop indefinitely.

Interchangeability The while loop is all you really need. However as you will see, the for loop is less error-prone.

A while statement is a boss statement. It looks like this.


while predicate:
    block

The predicate is something that is truthy or falsy. If the predicate is truthy, the block runs. If not, you are out of the loop. Think of this as a "sticky if."

Let's write a function to see if a numerical list is in order.


def is_in_order(x):
    """prec: x is a homogeneous list of sortable items
    postc: returns True if the list is in ascending order"""
    k = 0
    while k < len(x) - 1:
        if x[k] > x[k+1]:
            return False
        k += 1
    return True

def is_in_order_for(x):
    for k in range(0, len(x) - 1):
        if x[k] > x[k + 1]:
            return False
    return True

Let's write the Bozo Sort! Here is the algorithm

  1. Check to see if the list is sorted in order
  2. If it is, you are done.
  3. If not, shuffle and repeat.

def bozo(x):
    while not is_in_order(x):
        shuffle(x)

x = [5,2,8,9, 3, -2, -9, 6, 4]
bozo(x)
print(x)

Can you change each for to a while? Get your name in lights by pasting a solution into chat!


def print_list(x):
    for k in x:
        print(k)
x = ["a", 1, True]
print_list(x)

Drake


def print_list(x):
     a = 0
     while a < len(x):
          print(x[a])
          a += 1
x = [1,2,3,4,5]
print_list(x)

Morrison appealing to truthiness.


def print_list(x):
    while x:
        print(x[0])
        x = x[1:]
x = [1,2,3,4,5]
print_list(x)

def count_down(n):
    for k in reversed(range(n + 1)):
        print k
    print("Blastoff!")
count_down(10)

Mitchell


def count_down_while(n):
    k = n
    while k >= 0:
        print(k)
        k -= 1
    print("Blastoff!")

def harvest_caps(s):
    out = ""
    for k in s:
        if k.isupper():
            out += k
    return out
print(harvest_caps("AEioU"))

def harvest_caps_while(s):
    out = ""
    k = 0
    while k < len(s):
        if s[k].isupper():
            out += s[k]
        k += 1
    return out

Hanging and Spewing Uh oh, while gone wild. Hanging is when your program stops for "no good reason." It's frozen.

Spewing occurs when your program spews text to the screen withut surcease. In this case use control-c(Unix) or control-z(windoze).

Mini Case Study: A Number Guessing Game The computer picks a random integer 1-100 and it tells you if your guess is too high, too low, or if it is correct.


from random import randint
secret_number = randint(1,100)
guess = 0
while guess != secret_number:
    guess = input("Enter a guess:  ")
    guess = int(guess)
    if guess < secret_number:
        print(f"Your guess {guess} is too small.")
    elif guess > secret_number:
        print(f"Your guess {guess} is too big.")
##what is true here
print(f"Your guess {guess} is correct!")

Kersey


from random import randint
secret_number = randint(1,100)
guess = 0
while guess != secret_number:
    guess = input("Enter a guess:  ")
    guess = int(guess)
    if guess < secret_number:
        print(f"Your guess {guess} is too small.")
    elif guess > secret_number:
        print(f"Your guess {guess} is too big.")
##what is true here
print(f"Your guess {guess} is correct!")

Mitchell


from random import randint
secret_number = randint(1,100)
guess = 0
while guess != secret_number:
    guess = input("Enter a guess:  ")
    guess = int(guess)
    if guess < secret_number:
        print(f"Your guess {guess} is too small.")
    elif guess > secret_number:
        print(f"Your guess {guess} is too big.")
##what is true here
print(f"Your guess {guess} is correct!")

Here it is getting played.

unix> python guessing_game.py 
Enter a guess:  50
Your guess 50 is too small.
Enter a guess:  75
Your guess 75 is too big.
Enter a guess:  63
Your guess 63 is correct!

Can you tell the user how many guesses he made?

Mini Case Study: Nagging a Dolt This program asks a user to enter an integer. It nags the user until a parseable integer is entered.


def is_legit_integer(x):
    k = 0
    if x[k] == "+" or x[k] == "-":
        k += 1
    while k < len(x):
        if not x[k].isdigit():
            return False
        k += 1
    return True

number = "x"
while not is_legit_integer(number):
    number = input("Enter an integer")
print(f"{number} is an integer")

Here is a smart person.

unix> python nag.py
Enter an integer56

Here is the dolt

(base) MAC:Thu Mar 04:11:22:0304B> python nag.py
Enter an integercows
Enter an integerhorses
Enter an integercrowley
Enter an integerdunderhead
Enter an integer3432
3432 is an integer

Please sign on.

(base) MAC:Thu Mar 04:11:23:0304B> python nag.py
Enter an integer-5
-5 is an integer
(base) MAC:Thu Mar 04:11:23:0304B> python nag.py
Enter an integer+14
+14 is an integer

Mini Case Study: Roll a fair pair of dice until you get doubles Print out the rolls


from random import randint

def roll_dice():
    return (randint(1,6), randint(1,6))

x = (0, 100)
count = 0
while x[0] != x[1]:
    x = roll_dice()
    count += 1
print(f"You rolled doubles of {x[0]} after {count} rolls.")

from random import randint

def roll_dice():
    return (randint(1, 6), randint(1, 6))

roll_val = (0, 1)
k = 0
while roll_val[1] != roll_val[0]:
    k += 1
    roll_val = roll_dice()
    print(f"You rolled a {roll_val[0]} and a {roll_val[1]}")
print(f"Congratulations! You rolled double {roll_val[0]}s! It took you {k} rolls")
(base) MAC:Thu Mar 04:11:32:0304B> python moore.py
(1, 6)
(2, 4)
(1, 2)
(4, 4)
You rolled doubles of 4 after 4 rolls.
(base) MAC:Thu Mar 04:11:32:0304B> python moore.py
(2, 4)
(3, 4)
(2, 1)
(2, 4)
(3, 6)
(2, 3)
(2, 5)
(6, 3)
(2, 4)
(1, 3)
(5, 6)
(5, 3)
(5, 3)
(4, 2)
(6, 3)
(1, 3)
(1, 5)
(4, 1)
(3, 6)
(6, 5)
(5, 4)
(3, 2)
(3, 6)
(6, 5)
(4, 3)
(5, 5)
You rolled doubles of 5 after 26 rolls.
(base) MAC:Thu Mar 04:11:32:0304B> python moore.py
(2, 2)
You rolled doubles of 2 after 1 rolls.
(base) MAC:Thu Mar 04:11:32:0304B> python moore.py
(5, 2)
(6, 5)
(3, 1)
(5, 1)
(1, 3)
(2, 1)
(3, 4)
(3, 6)
(3, 6)
(6, 3)
(5, 5)
You rolled doubles of 5 after 11 rolls.
(base) MAC:Thu Mar 04:11:32:0304B> python moore.py
(5, 3)
(4, 2)
(1, 2)
(5, 2)
(4, 2)
(5, 2)
(1, 5)
(1, 4)
(6, 1)
(4, 1)
(6, 5)
(1, 3)
(3, 1)
(1, 3)
(3, 3)
You rolled doubles of 3 after 15 rolls.

Mini Case Study: Flip a fair coin until N heads occur N is a command line argument.