A while
loop is similar to a for
loop in that it is a tool used to automate a repetive task. The core difference between while
and for
loops is as follows:
for
loop executes a predetermined number of times. A for
loop that begins with "for i in range(a,b)"
will execute exactly once for each value of the counter i
that falls within the given range. while
loop executes as long as some supplied condition is true. Depending on the nature of this condition, we do not necessarily know ahead of time how many times the loop will execute. The syntax for creating a while
loop is as follow:
while condition: code to be executed each iteration
The condition
in a while statement should be an expression that evaluates to a Boolean value. When Python encounters a while
loop, it will check to see if the condition evaluates to True
. If it does, then it will step into the loop and perform the first iteration. Each time the loop executes, Python returns to the start of the loop and checks the condition again. As long as the condition evaluates to True
, Python will continue executing iterations of the loop. If the condition ever evaluates to False
, then Python will stop executing the body of the loop, and will move on to the next lines of code.
The following cell illustrates a simple example of a while
loop. The cell prints out the squares of the first five positive integers.
n = 1
while n <= 5:
print(n**2)
n += 1
The task above could have been accomplished more succinctly using a for
loop:
for n in range(1,6):
print(n**2)
while
and for
Loops¶As it turns out, anything that can be accomplished with a for
loop can also be done with a while
loop. However, for
loops require fewer lines of code than a similar while
loop, and are typically easier to read. So why would we ever use a while
loop? As it turns out, while
loops are a more flexible tool than for
loops. There are some tasks that we cannot accomplish with a for
loop, but can with a while
loop.
When we create a for loop, we tell the loop (either explicitly, or programmatically) how many times it will run. As soon as Python encounters a statement starting with for
, it will know how many times that the loop will execute (assuming that no errors are encountered). On the other hand, while
loops will continue to execute for as long as some condition is true. Python does not know how many times it will execute a while
loop that it enounters, but it will keep doing so until the condition is no longer true. For this reason, while
loops are well-suited for situations in which we do not know how many times the loop will need to execute, either because it would be difficult to calculate, or because the condition depends on some external factors (such as user input) that Python has no way of knowing in advance.
As a somewhat superficial example, let's say that you wanted to know the smallest positive integer n
for which $n^5 > \left(7 n + 10 \right)^4$. If we could mathematically solve the inequality, we could get the answer, but that is certainly not easy to do. We can, however, simply start n
at 1, and then use a while
loop to increment n
for as long as $n^5 \leq \left(7 n + 10 \right)^4$
n = 1
while n**5 <= (7*n + 10)**4:
n += 1
print(n)
print(n**5)
print((7*n + 10)**4)
As a more practical use of while
loops, consider the following example.
Assume that a loan of \$225,000 is being repaid with monthly payments of \\$850, which occur at the end of the month. The loan is collecting interest at a monthly rate of 0.3%. So, at the end of each month, the remaining balance wil be multiplied by 1.003, and then \$850 is deducted from this balance. We can use a while
loop to determine the number of monthly payments required to fully repay the loan.
balance = 225000
rate = 0.003
pmt = 950
count = 0
while balance > 0:
balance = balance * (1 + rate) - pmt
count += 1
print(count)
It is very unlikely that amount owed during the last month was exactly \$850. As a result, after the loop finished executing, the balance
was likely negative. We can add the payment amount back to the balance to get the amount owed just before the final payment, and thus determine the true size of the last payment.
print(balance + pmt)
Programs often require input from the user. Python's input()
function provides a method of prompting the user for input. For example, consider the following code:
name = input("What is your name? ")
This code will print the string, "What is your name? " and will then wait for user input. The value entered by the user will then be stored in the variable name
.
name = input("What is your name? ")
print("Hello, " + name + "!")
User input can be combined with while
loops to create interactive programs. Here we implement a simple guessing game in which the user is prompted to try to guess a randomly generate number between 0 and 500.
import random
n = random.choice(range(0, 501))
print("I have selected a random number between 0 and 500, inclusive. Can you guess it?")
done = False
count = 1
while done == False:
guess = int(input("Please enter guess number " + str(count) + ": "))
if(guess < n):
print("Your guess was too small.")
elif(guess > n):
print("Your guess was too large.")
else:
print("That's it! It took you " + str(count) + " guesses to find the right answer.")
done = True
count += 1
It is often the case in Computer science and Data Science that some value of interest is calculated by performing a sequence of better and better approximations. In these situations, we might tell our program precisely how many approximations we want it to perform (likely with a for
loop). Alternately, we might ask our program to continue to calculate approximations until we have met some condition, such as two subsequent approximations being very near to each other.
In the example below, we will approximate the square root of K = 7,341,234,543,244,549
. Our approach will be fairly simple. We will make an initial guess for the square root, which we will call x
. We will divide K
by x
, naming the result y
. If our guess was good, then x
and y
will be very close to each other, and thus close to the actual solution. If our guess was bad, we will set x
to be equal to the average of x
and y
, since the true answer will have to be somewhere between these two approximations.
We will continue this process until x
and y
are within 1/10000 of each other. So that we know how many times the loop had to run, we will also create a counter n
.
K = 7341234543244549
x = 1
y = K/x
n = 0
while abs(x - y) > 0.0001:
x = (x + y) / 2
y = K / x
n += 1
print('Value of x: ', x)
print('Value of y: ', y)
print('Value of x*y:', x**2)
print('Iterations: ', n)
We will close with one more example drawn from the world of mathematics. It can be proven that the transcendental number $\pi$ can be written as a sum of infinitely many fractions as follows:
$$\pi = \frac{4}{1} - \frac{4}{3} + \frac{4}{5} - \frac{4}{7} + \frac{4}{9} - \frac{4}{11} + ...$$The more numbers we add in this never-ending series of fractions, the closer our approximation will be to the true value of $\pi$. It can be shown that the amount of error involved in our approximation will be less than the absolute value of the first term from the series that we DID NOT add into the total.
In the cell below, we will add together several terms of this series, stopping when we reach a term whose absolute value is less than 0.00001.
pi_approx = 0
keep_adding = True
n = 0
while keep_adding:
new_term = 4 / (2*n + 1)
pi_approx = pi_approx + new_term * (-1)**n
n += 1
next_term = 4 / (2*n + 1)
if next_term < 0.00001:
keep_adding = False
print(pi_approx)
print(n)
Note that the first 8 decimal digits of pi are: 3.14159265