$$\newcommand{\Oof}{\mathcal{O}(#1)} \newcommand{\F}{\boldsymbol{F}} \newcommand{\J}{\boldsymbol{J}} \newcommand{\x}{\boldsymbol{x}} \renewcommand{\c}{\boldsymbol{c}}$$

# While loops

Python also has another standard loop construction, the while loop, doing iterations with a loop index very much like the for loop. To illustrate what such a loop may look like, we consider another modification of ball_plot.py in the chapter A Python program with vectorization and plotting. We will now change it so that it finds the time of flight for the ball. Assume the ball is thrown with a slightly lower initial velocity, say $$4.5\hbox{ ms}^{-1}$$, while everything else is kept unchanged. Since we still look at the first second of the flight, the heights at the end of the flight become negative. However, this only means that the ball has fallen below its initial starting position, i.e., the height where it left the hand, so there is no problem with that. In our array y we will then have a series of heights which towards the end of y become negative. Let us, in a program named ball_time.py find the time when heights start to get negative, i.e., when the ball crosses $$y=0$$. The program could look like this

from numpy import linspace

v0 = 4.5                  # Initial velocity
g = 9.81                  # Acceleration of gravity
t = linspace(0, 1, 1000)  # 1000 points in time interval
y = v0*t - 0.5*g*t**2     # Generate all heights

# Find where the ball hits y=0
i = 0
while y[i] >= 0:
i += 1

# Now, y[i-1]>0 and y[i]<0 so let's take the middle point
# in time as the approximation for when the ball hits h=0
print "y=0 at", 0.5*(t[i-1] + t[i])

# We plot the path again just for comparison
import matplotlib.pyplot as plt
plt.plot(t, y)
plt.plot(t, 0*t, 'g--')
plt.xlabel('Time (s)')
plt.ylabel('Height (m)')
plt.show()


If you type and run this program you should get

y=0 at 0.917417417417


The new thing here is the while loop only. The loop (note colon and indentation) will run as long as the boolean expression y[i] > 0 evaluates to True. Note that the programmer introduced a variable (the loop index) by the name i, initialized it (i = 0) before the loop, and updated it (i += 1) in the loop. So for each iteration, i is explicitly increased by 1, allowing a check of successive elements in the array y.

Compared to a for loop, the programmer does not have to specify the number of iterations when coding a while loop. It simply runs until the boolean expression becomes False. Thus, a loop index (as we have in a for loop) is not required. Furthermore, if a loop index is used in a while loop, it is not increased automatically; it must be done explicitly by the programmer. Of course, just as in for loops and if blocks, there might be (arbitrarily) many code lines in a while loop. Any for loop may also be implemented as a while loop, but while loops are more general so not all of them can be expressed as a for loop.

A problem to be aware of, is what is usually referred to as an infinite loop. In those unintentional (erroneous) cases, the boolean expression of the while test never evaluates to False, and the program can not escape the loop. This is one of the most frequent errors you will experience as a beginning programmer. If you accidentally enter an infinite loop and the program just hangs forever, press Ctrl+c to stop the program.