while loop

Documentation

Suppose the while loop has an else clause. When the expression next to the word while becomes false and we leave the loop, the else clause will be executed. If we leave the loop for any other reason (e.g., break, sys.exit), the else clause will not be executed.

  1. Python Tutorial
    1. First Steps Towards Programming has a while loop to compute the Fibonacci numbers.
    2. break and continue statements, and else clauses on loops
  2. Python Language Reference
    1. while loop
    2. break statement
    3. continue statement

Infinite loop and the time.sleep function

The indented statements will be repeated forever. Indent each indented statement with exactly four spaces.

infiniteloop.py

It was a dark and stormy night.
Some Indians were sitting by a campfire.
Then their chief rose and said,

It was a dark and stormy night.
Some Indians were sitting by a campfire.
Then their chief rose and said,

It was a dark and stormy night.
Some Indians were sitting by a campfire.
Then their chief rose and said,

To stop the script, click on IDLE’s “Python 3.8.0 Shell” window and pull down
Shell → Interrupt Execution

Traceback (most recent call last):
  File "/Users/myname/python/junk.py", line 15, in <module>
    time.sleep(3)   #Do nothing for 3 seconds.
KeyboardInterrupt
>>>

Each iteration of the loop needs only one call to the print function. The triple-quoted string contains three lines, each ending with one newline character. The print outputs one newline after it outputs the string.

while True:
    print("""\
It was a dark and stormy night.
Some Indians were sitting by a campfire.
Then their chief rose and said,
""")

    time.sleep(3)   #Do nothing for 3 seconds.
paragraph = """\
It was a dark and stormy night.
Some Indians were sitting by a campfire.
Then their chief rose and said,
"""

while True:
    print(paragraph)
    time.sleep(3)   #Do nothing for 3 seconds.

Two places to put the boolean expression: Russian roulette

You can put the boolean expression after the keyword while or after the keyword if.

"""
russianRoulette.py
"""

import sys
import random

instructions = """\
Welcome to Russian Roulette!
Press return to spin the cylinder and pull the trigger."""

print(instructions)
print()
_ = input("Go ahead: ")   #underscore is name for dummy variable
n = random.randrange(6)   #an integer in the range 0 to 5 inclusive

while n != 0:
    print("Click.")
    print()
    _ = input("Go ahead: ")
    n = random.randrange(6)

print("BANG!")
sys.exit(0)
Welcome to Russian Roulette!
Press return to spin the cylinder and pull the trigger.

Go ahead:
click

Go ahead:
click

Go ahead:
click

Go ahead:
click

Go ahead:
BANG!

No need to write the yellow section twice.

"""
russianRoulette.py
"""

import sys
import random

#a string containing 2 lines

instructions = """\
Welcome to Russian Roulette!
Press return to spin the cylinder and pull the trigger."""

print(instructions)

while True:
    print()
    _ = input("Go ahead: ")
    n = random.randrange(6)
    if n == 0:
        break   #Abandon the loop.
    print("Click.")

#The break statement sends us here.
print("BANG!")
sys.exit(0)

A break statement in a try statement:
loop until the user does it right.

tryagain.py

See else and break. The mantissa is a fraction that is always greater than or equal to .5 and less than 1.

Please type a number: 12e
Sorry, "12e" is not a number.  Try again.
Please type a number: q23
Sorry, "q23" is not a number.  Try again.
Please type a number: 123

Thank you for typing in the float number 123.0.
It is stored internally as the pair of integers 8,655,355,533,852,672 and 7.
123.0 = (8,655,355,533,852,672 / (2 ** 53)) * (2 ** 7) = 0.9609375 * 128
The fraction 8,655,355,533,852,672 / (2 ** 53) is the mantissa.
The integer 7 is the exponent.
Please type a number: 6

Thank you for typing in the float number 6.0.
It is stored internally as the pair of integers 6,755,399,441,055,744 and 3.
6.0 = (6,755,399,441,055,744 / (2 ** 53)) * (2 ** 3) = 0.75 * 8
The fraction 6,755,399,441,055,744 / (2 ** 53) is the mantissa.
The integer 3 is the exponent.
bc -l
6755399441055744 / 2^53
.75000000000000000000
control-d

A break statement in an if statement:
loop until we reach a goal.

Double the number each time around the loop.

powers.py

2 **  0 =      1
2 **  1 =      2
2 **  2 =      4
2 **  3 =      8
2 **  4 =     16
2 **  5 =     32
2 **  6 =     64
2 **  7 =    128
2 **  8 =    256
2 **  9 =    512
2 ** 10 =   1024
2 ** 11 =   2048
2 ** 12 =   4096
2 ** 13 =   8192
2 ** 14 =  16384
2 ** 15 =  32768
2 ** 16 =  65536
2 ** 17 = 131072
2 ** 18 = 262144
2 ** 19 = 524288

The log of 1,000,000 to the base 2 is 19.931568569324174

It would be satisfying to also print the number that goes over a million. For this, we need a break statement in an if statement.

import sys

i = 0
p = 1

while True:
    print(f"2 ** {i:2} = {p:9,}") #One million is a seven-digit number, plus 2 commas.
    if p >= 1_000_000:            #Test in the middle of the loop.
        break
    i += 1
    p *= 2

sys.exit(0)
2 **  0 =         1
2 **  1 =         2
2 **  2 =         4
2 **  3 =         8
2 **  4 =        16
2 **  5 =        32
2 **  6 =        64
2 **  7 =       128
2 **  8 =       256
2 **  9 =       512
2 ** 10 =     1,024
2 ** 11 =     2,048
2 ** 12 =     4,096
2 ** 13 =     8,192
2 ** 14 =    16,384
2 ** 15 =    32,768
2 ** 16 =    65,536
2 ** 17 =   131,072
2 ** 18 =   262,144
2 ** 19 =   524,288
2 ** 20 = 1,048,576

Loop until we reach a goal.

Halve the number each time around the loop.

smallest.py

6.103515625e-05 means
6.103515625 × 10–5 = 6.103515625 × .00001 = .00006103515625
The e stands for “exponent”.

                    1.0
                    0.5
                   0.25
                  0.125
                 0.0625
                0.03125
               0.015625
              0.0078125
             0.00390625
            0.001953125
           0.0009765625
          0.00048828125
         0.000244140625
        0.0001220703125
        6.103515625e-05
       3.0517578125e-05
      1.52587890625e-05
      7.62939453125e-06
     3.814697265625e-06
    1.9073486328125e-06
    9.5367431640625e-07
   4.76837158203125e-07
  2.384185791015625e-07
 1.1920928955078125e-07
etc.
2.2250738585072014e-308
1.1125369292536007e-308
 5.562684646268003e-309
    2.781342323134e-309
    1.390671161567e-309
    6.953355807835e-310
   3.4766779039175e-310
  1.73833895195875e-310
    8.691694759794e-311
    4.345847379897e-311
   2.1729236899484e-311
    1.086461844974e-311
     5.43230922487e-312
    2.716154612436e-312
     1.35807730622e-312
      6.7903865311e-313
     3.39519326554e-313
     1.69759663277e-313
       8.487983164e-314
       4.243991582e-314
       2.121995791e-314
      1.0609978955e-314
       5.304989477e-315
        2.65249474e-315
        1.32624737e-315
        6.63123685e-316
         3.3156184e-316
         1.6578092e-316
          8.289046e-317
          4.144523e-317
         2.0722615e-317
          1.036131e-317
          5.180654e-318
          2.590327e-318
          1.295163e-318
            6.4758e-319
            3.2379e-319
           1.61895e-319
             8.095e-320
            4.0474e-320
            2.0237e-320
             1.012e-320
              5.06e-321
              2.53e-321
             1.265e-321
               6.3e-322
              3.16e-322
               1.6e-322
                 8e-323
                 4e-323
                 2e-323
                 1e-323
                 5e-324
                    0.0

Number the lines of output.

Loop until we reach a goal.

Multiply the number by 1.04 each time around the loop.

#How many years would it take for my principal to double,
#at 4% compounded annually?

import sys
import math

year = 0
p = 100000.00   #principal

while True:
    print(f"{year:2} ${p:,.2f}")   #Print money with 2 digits to the right of the decimal point.
    if p >= 200000.00:
        break
    year += 1
    p *= 1.04

print()
print(f"The log to the base 1.04 of 2 is {math.log(2, 1.04)}")

sys.exit(0)
 0 $100,000.00
 1 $104,000.00
 2 $108,160.00
 3 $112,486.40
 4 $116,985.86
 5 $121,665.29
 6 $126,531.90
 7 $131,593.18
 8 $136,856.91
 9 $142,331.18
10 $148,024.43
11 $153,945.41
12 $160,103.22
13 $166,507.35
14 $173,167.64
15 $180,094.35
16 $187,298.12
17 $194,790.05
18 $202,581.65

The log to the base 1.04 of 2 is 17.672987685129698

Organ pipes

2 = 21/12 × 21/12 × 21/12 × 21/12 × 21/12 × 21/12 × 21/12 × 21/12 × 21/12 × 21/12 × 21/12 × 21/12

Exponentiation has higher precedence than division. We therefore need the parens to force the division to be executed before the exponentiation.

>>> 2 ** (1/12)
1.0594630943592953

A picture of two octaves:

octave.py

 0   100.00000 inches
 1   105.94631 inches
 2   112.24620 inches
 3   118.92071 inches
 4   125.99210 inches
 5   133.48399 inches
 6   141.42136 inches
 7   149.83071 inches
 8   158.74011 inches
 9   168.17928 inches
10   178.17974 inches
11   188.77486 inches
12   200.00000 inches

Loop until we reach a date.

See the while loop in the Teaser.

Nested while loops: factor an integer

factor.py

Please type an integer: 60
2
2
3
5

Better to write the loop in lines 13, 14, 20 as a for loop:

for factor in range(2, n + 1): #loop from 2 to n inclusive
    while n % factor == 0:     #while factor is a factor of n
        print(factor)
        n //= factor