Dr Jon Shiach, Department of Computing and Mathematics, Manchester Metropolitan University
On successful completion of this page readers will be able to:
The whole point of computer programming is to get the computer to do tasks that would take a human too long to complete. A lot of this is to do with repitition, performing the same calculations or commands over and over again. There are two constructs to help us do this: for loops and while loops.
If we want to repeat the execution of a set of commands a given number of times then we can use a for loop.
for variable in range:
commands
The for
declaration requires a loop variable and a range followed by a colon :
. The commands that we want to repeat are written underneath the for loop declaration and indented. The commands within the for loop are repeated for each value of the loop variable from the range. The for loop ends with the next non-indented command.
If the commands that are within a for loop do not require the loop variable then it is common to use _
as the loop variable.
The code below uses the for loop to print the integer numbers 0 to 4. Enter it into the code cell below and execute it to see the result.
for i in range(5):
print(i)
for i in range(5):
print(i)
0 1 2 3 4
Here the loop variable is i
and the range is defined by range(5)
which generates a list of the 5 numbers from 0 to 4. The print(i)
command was repeated 5 times, once for each value from the range. The use of end=", "
in the print()
command means that the values are printed on the same line separated by commas.
The $n$th Fibonnacci number is calculated using $F_{n} = F_{n-1} + F_{n-2}$ where the first two Fibonacci numbers are $F_1=0$ and $F_2=1$, e.g.,
$$0, 1, 1, 2, 3, 5, 8, 13, \ldots$$
The following code uses a for loop to print the first 20 Fibonacci numbers. Enter it into the code cell below and execute it.
a, b = 0, 1
for _ in range(20):
print(f"{a} ")
a, b = b, a + b
a, b = 0, 1
for _ in range(20):
print(f"{a} ")
a, b = b, a + b
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181
Note that the first two Fibonacci numbers are defined before using a for loop repeat the calculation 20 times.
The following program uses a for loop to sum the elements of the array X
. Enter this into the code cell below and execute it.
import numpy as np
X = np.array([ 1, 7, -4, 3, -5 ])
total = 0
for i in range(5):
total += X[i]
print(f"The sum of the five numbers is {total}")
import numpy as np
X = np.array([ 1, 7, -4, 3, -5 ])
total = 0
for i in range(5):
total += X[i]
print(f"The sum of the five numbers is {total}")
The sum of the five numbers is 2
for _ in range(10):
print("hello world")
hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world
for i in range(1, 21):
print(2 * i)
2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40
n, mysum = 100, 0
for i in range(1, n + 1):
mysum += i
print(f"The sum of the first {n} numbers is {mysum}")
The sum of the first 100 numbers is 5050
x = 1
for i in range(1, 53):
x *= i
print(x)
80658175170943878571660636856403766975289505440883277824000000000000
n, a, r, mysum = 10, 3, 4, 3
for _ in range(n - 1):
a *= r
mysum += a
print(f"The 10th term is {a} and the sum of the first 10 terms is {mysum}")
The 10th term is 786432 and the sum of the first 10 terms is 1048575
X = np.array([1.2, 4.3, 5.7, 1.4, 7.2, 3.5])
n, xbar, sigma = len(X), 0, 0
for x in X:
xbar += x
xbar /= n
for x in X:
sigma += (xbar - x) ** 2
sigma = np.sqrt(sigma / (n - 1))
print(f"The mean is {xbar:0.4f} and the standard deviation is {sigma}")
The mean is 3.8833 and the standard deviation is 2.3659388552256937
Hint: the command factorial(x)
from the math library computes the value of $x!$
import math
x, sinx = math.pi / 4, 0
for n in range(5):
sinx += (-1) ** n / math.factorial(2 * n + 1) * x ** (2 * n + 1)
print(f"sin(pi/4) = {sinx}")
sin(pi/4) = 0.7071067829368671
If we want to repeat the execution of a set of commands when we don't know how many repititions is required then we can use a while loop.
while logical condition:
commands
The indented commands will be exectuted as long as the logical condition
returns a True
result.
i = 0
while i < 5:
print(i)
i += 1
0 1 2 3 4
Note that we needed a variable i
which is incremented by 1 at each iteration to keep track of the number of iterations we have done. If we didn't increment i
then the logical condition i < 5
would always be true and the while loop would repeat the print(i)
command forever. This is a common programming error known as an infinite loop which can be exited by clicking on the ◾ button.
The program below uses a while
loop to print the first 20 Fibonacci numbers. Enter it into the code cell below and execute it.
a, b = 0, 1
n = 0
while n < 20:
print(a)
a, b = b, a + b
n += 1
a, b = 0, 1
n = 0
while n < 20:
print(a)
a, b = b, a + b
n += 1
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181
i = 0
while i < 10:
print("hello again")
i += 1
hello again hello again hello again hello again hello again hello again hello again hello again hello again hello again
while
loop to print the first 20 odd numbers.i, x = 0, 1
while i < 20:
print(x)
x += 2
i += 1
1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39
i, mysum = 0, 0
while i < 101:
mysum += i
i += 1
print(f"The sum of the first 100 natural numbers is {mysum}")
The sum of the first 100 natural numbers is 5050
Hint: The command x % y
returns the remainder of $x \div y$.
x, steps = 100, 0
print(x, end="")
while x > 1:
if x % 2 == 0:
x //= 2
else:
x = 3 * x + 1
steps += 1
print(f" -> {x}", end="")
print(f"\n{steps} steps were required to reach 1")
100 -> 50 -> 25 -> 76 -> 38 -> 19 -> 58 -> 29 -> 88 -> 44 -> 22 -> 11 -> 34 -> 17 -> 52 -> 26 -> 13 -> 40 -> 20 -> 10 -> 5 -> 16 -> 8 -> 4 -> 2 -> 1 25 steps were required to reach 1
Sometimes it is neccessary to interrupt the normal flow of a loop to either exit the loop before all iterations have completed or to move to the next iteration immediately without performing any further commands in the same iteration. To do this Python uses the break
and continue
commands.
The break
command is used to exit a loop.
The ratio of successive Fibonacci numbers converge to the golden ratio $\varphi = \dfrac{1+\sqrt{5}}{2} = 1.618\ldots$, i.e.,
$$\frac{1}{1} = 1, \qquad \frac{2}{1} = 2, \qquad \frac{3}{2} = 1.5, \qquad \frac{5}{3} = 1.6667, \qquad \frac{8}{5} = 1.6, \qquad \ldots$$
The program below uses a while
loop to calculate approximations of $\varphi$ ceasing iterations when the difference between two successive iterations is less than $10^{-6}$. Enter the following commands into the code cell below and execute it.
phi = (1 + math.sqrt(5)) / 2 # exact value of phi
a, b = 1, 1
while True:
phi_estimate = b / a
a, b = b, a + b
if abs(phi_estimate - b / a) < 1e-6:
break
print(f"The exact value of the golden ratio is {phi:1.8f}")
print(f"An approximation of the golden ratio using Fibonacci numbers is {phi_estimate:1.8f}")
phi = (1 + math.sqrt(5)) / 2 # exact value of phi
a, b = 1, 1
while True:
phi_estimate = b / a
a, b = b, a + b
if abs(phi_estimate - b / a) < 1e-6:
break
print(f"The exact value of the golden ratio is {phi:1.8f}")
print(f"An approximation of the golden ratio using Fibonacci numbers is {phi_estimate:1.8f}")
The exact value of the golden ratio is 1.61803399 An approximation of the golden ratio using Fibonacci numbers is 1.61803445
Here the logical condition used in the while loop is always True
so the indented commands will repeat undefinitely unless the break
command is executed. Note that we started the Fibonacci series at $F_2=1$ and $F_3=1$ since $\dfrac{F_2}{F_1}=\dfrac{1}{0}$ will cause a divide by zero error.
The continue
command moves to the next cycle of a loop.
The program below uses a for
loop to calculate the sum of five numbers. Negative numbers are removed from the calculation. Enter it into the code cell below and execute it.
X = np.array([ 1, 7, -4, 3, -5 ])
total = 0
for i in range(5):
if X[i] < 0:
continue
total += X[i]
print(f"The sum of the five numbers (excluding negatives) is {total}")
X = np.array([ 1, 7, -4, 3, -5 ])
total = 0
for i in range(5):
if X[i] < 0:
continue
total += X[i]
print(f"The sum of the five numbers (excluding negatives) is {total}")
The sum of the five numbers (excluding negatives) is 11
for
loops to loop through the numbers between 2 and 100 and print those numbers which are primes.
x % y
command will come in useful here).for n in range(2, 101):
isprime = True
for factor in range(2, n):
if n % factor == 0:
isprime = False
break
if isprime:
print(n)
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
Hints:
guess = int(input("Enter your guess > "))
can be used to prompt the user to enter a number.np.random.randint(a, b)
generates a randon integer in the range a
to b
.import numpy as np
n, guess, remaining = np.random.randint(0, 10), -1, 5
while remaining > 0:
guess = int(input("Enter your guess > "))
if guess == n:
print("You win!")
break
elif guess > n:
print("Your guess is too high", end="")
elif guess < n:
print("Your guess is too low", end="")
remaining -= 1
if remaining > 0:
print(f", you have {remaining} guesses remaining")
else:
print(f"\nNo guesses left, you lose. The number was {n}")
Enter your guess > 5 Your guess is too low, you have 4 guesses remaining Enter your guess > 7 You win!
The program below uses nested for loops to generate a multiplication square. Enter it into the code cell below and execute it to see the result.
M = np.zeros((10, 10))
rows, cols = M.shape
for i in range(rows):
for j in range(cols):
M[i,j] = (i + 1) * (j + 1)
print(M)
M = np.zeros((10, 10))
rows, cols = M.shape
for i in range(rows):
for j in range(cols):
M[i,j] = (i + 1) * (j + 1)
print(M)
[[ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.] [ 2. 4. 6. 8. 10. 12. 14. 16. 18. 20.] [ 3. 6. 9. 12. 15. 18. 21. 24. 27. 30.] [ 4. 8. 12. 16. 20. 24. 28. 32. 36. 40.] [ 5. 10. 15. 20. 25. 30. 35. 40. 45. 50.] [ 6. 12. 18. 24. 30. 36. 42. 48. 54. 60.] [ 7. 14. 21. 28. 35. 42. 49. 56. 63. 70.] [ 8. 16. 24. 32. 40. 48. 56. 64. 72. 80.] [ 9. 18. 27. 36. 45. 54. 63. 72. 81. 90.] [ 10. 20. 30. 40. 50. 60. 70. 80. 90. 100.]]
The first loop use used to loop through the rows of M
and for each value of i
we have another loop to loop through the columns of M
. Note that we had to add 1 to i
and j
when calculating the product of the row and column since Python uses zero indexing.
import numpy as np
A = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
B = np.array([[10, 11, 12], [13, 14, 15], [16, 17, 18]])
AB = np.zeros((A.shape[0], B.shape[1]))
for i in range(A.shape[0]):
for j in range(B.shape[1]):
for k in range(A.shape[1]):
AB[i,j] += A[i,k] * B[k,j]
print(AB)
[[ 84. 90. 96.] [201. 216. 231.] [318. 342. 366.]]