Loop Clauses¶

author: Parin Chaipunya affil: KMUTT

for loops¶

The for loop is best used to iterate tasks in which the number of repeats is known.

The structure of a for loop is the following.

for i in <iterable>:
    <task 1>
    <task 2>
    ...
    <task n>

Notice that the tasks within the for loop is under indentations. To exit the loop, simply unindent the line.

The iterable is usually defined using range or a list, as one would see in the coming examples.

In [1]:
for i in range(4):
    print(f'i = {i}')
i = 0
i = 1
i = 2
i = 3

Example¶

Print values of i from 4 to 10.

In [2]:
for i in range(4,11):
    print(f'i equals to {i}')
i equals to 4
i equals to 5
i equals to 6
i equals to 7
i equals to 8
i equals to 9
i equals to 10

Example¶

Print values of i starting from 2, not exceeding 20, and increasing by 3 at a time. Also print your name after the loop is finished.

In [5]:
for i in range(2,20,3):
    print(f'I am {i}')
print('Parin Chaipunya')
I am 2
I am 5
I am 8
I am 11
I am 14
I am 17
Parin Chaipunya

Example¶

Let's find the value of $1 + 3 + 5 + \dots + 179$.

In [6]:
sum = 0
for i in range(1,180,2):
    sum += i
print(f'1+3+5+...+179 = {sum}')
1+3+5+...+179 = 8100

Example¶

We can also use for with a list.

In [7]:
Dogs = ["labrador", "chihuahua", "beagle", "poodle", "dachshund"]
for dog in Dogs:
    print(dog)
labrador
chihuahua
beagle
poodle
dachshund

Nested for loop¶

We now list all possible pairs from the two iterables.

In [8]:
Coin = ["Head", "Tail"]
Dice = range(1,7)
for x in Coin:
    for y in Dice:
        print(f'(x,y) = ({x},{y})')
(x,y) = (Head,1)
(x,y) = (Head,2)
(x,y) = (Head,3)
(x,y) = (Head,4)
(x,y) = (Head,5)
(x,y) = (Head,6)
(x,y) = (Tail,1)
(x,y) = (Tail,2)
(x,y) = (Tail,3)
(x,y) = (Tail,4)
(x,y) = (Tail,5)
(x,y) = (Tail,6)

while loop¶

The while loop is used to iterate tasks that we usually do not know the exact number of times to repeat, but rather the condition under which the tasks should be done. The while loop is usually used in conjunction with an update line.

The structure of a while loop is the following.

while <condition>:
    <task 1>
    <task 2>
    ...
    <task n>

Here, the <condition> refers to any assertion that returns either true or false. The tasks under the loop will be performed when true is returned or else the loop is terminated.

Example¶

Let's now do while loop. Let's print non-negative integers whose squares do not exceed 123.

In [9]:
i = 0;
while i**2 <= 123:
    print(f"i = {i}. i^2 = {i**2}.")
    i += 1
i = 0. i^2 = 0.
i = 1. i^2 = 1.
i = 2. i^2 = 4.
i = 3. i^2 = 9.
i = 4. i^2 = 16.
i = 5. i^2 = 25.
i = 6. i^2 = 36.
i = 7. i^2 = 49.
i = 8. i^2 = 64.
i = 9. i^2 = 81.
i = 10. i^2 = 100.
i = 11. i^2 = 121.

Example¶

Let's do another problem using while loop.

Consider the summation $S_{n} = \sum_{i=1}^{n} \frac{1}{n} = 1 + \frac{1}{2} + \frac{1}{3} + \dots + \frac{1}{n}$.

Find the smallest integer $m$ in which $S_{m} > 10$.

In [10]:
sum = 0
i = 0
while sum <= 10:
    i += 1
    sum += (1/i)
print(f'm = {i} and the sum S_m = {sum}')
m = 12367 and the sum S_m = 10.000043008275778

Example¶

By definition, $e = \lim_{n \to \infty} (1 + \frac{1}{n})^{n}$.

How far do we need to go (in term of $n$) to reach the accuracy of 15 decimal places of $e \approx 2.718281828459045$ ?

In [11]:
e_approx = 2.718281828459045
n = 1
lim = (1 + 1/n)**n
Err = abs(e_approx - lim)
while Err >= 1E-16:
    n += 1
    lim = (1 + 1/n)**n
    Err = abs(e_approx - lim)
    if n % 5E6 == 0:
        print(f'n = {n}; lim = {lim}')
print(f'** n = {n} with lim = {lim} **')
n = 5000000; lim = 2.718281555200129
n = 10000000; lim = 2.7182816941320818
n = 15000000; lim = 2.718281736418873
n = 20000000; lim = 2.7182817560533206
n = 25000000; lim = 2.7182817726626274
n = 30000000; lim = 2.718281790777263
n = 35000000; lim = 2.7182817881956653
n = 40000000; lim = 2.7182818021034367
n = 45000000; lim = 2.718281805878828
n = 50000000; lim = 2.718281814934939
n = 55000000; lim = 2.7182818174061043
n = 60000000; lim = 2.7182818134296105
n = 65000000; lim = 2.7182818031005027
n = 70000000; lim = 2.7182818287372563
n = 75000000; lim = 2.718281808906383
n = 80000000; lim = 2.7182817949495055
n = 85000000; lim = 2.7182818110383686
n = 90000000; lim = 2.718281820980393
n = 95000000; lim = 2.7182818217752125
n = 100000000; lim = 2.7182817983473577
n = 105000000; lim = 2.7182818140840626
n = 110000000; lim = 2.7182818297619304
n = 115000000; lim = 2.718281824263342
n = 120000000; lim = 2.7182818247557847
n = 125000000; lim = 2.7182818161551343
n = 130000000; lim = 2.7182818135554325
n = 135000000; lim = 2.718281798853157
n = 140000000; lim = 2.7182818384454057
n = 145000000; lim = 2.7182818387801695
n = 150000000; lim = 2.7182818632358083
n = 155000000; lim = 2.7182817760090243
n = 160000000; lim = 2.718281851730521
n = 165000000; lim = 2.7182818006836498
n = 170000000; lim = 2.7182818703375995
n = 175000000; lim = 2.718281819261742
n = 180000000; lim = 2.718281828531176
n = 185000000; lim = 2.7182818468426455
n = 190000000; lim = 2.7182818289285855
n = 195000000; lim = 2.718281856273097
n = 200000000; lim = 2.718281805143062
n = 205000000; lim = 2.718281862648893
n = 210000000; lim = 2.718281883932043
n = 215000000; lim = 2.718281820706676
n = 220000000; lim = 2.7182817695460653
** n = 220825296 with lim = 2.718281828459045 **

Conditioning¶

Conditioning clauses¶

We may find ourselves in need to perform some tasks under some specific circumstances, or to perform different tasks depending on particular conditions. These are the situations where we need to use an if clause, or if ... else, or if ... elif ... else.

if¶

The if clause is used when one wishes to perform a set of tasks only when a certain condition is satisfied. This follows the following structure

if <condition>:
    <tasks>

Here, the code block <tasks> is performed if <condition> returns true.

Example¶

In [12]:
a = 1

if a > 0:           # a > 0 returns `true`.
    print("a > 0")  # This is performed.

if a < 0:           # a < 0 returns `false`.
    print("a < 0")  # This is not performed.
a > 0

The logical conjunction and and or can be used in the condition.

Example¶

In [13]:
for a in [1, 3, 5, 7]:
    for b in [2, 4, 6, 7]:
        print(f"** a = {a}, b = {b} **")
        if a > 5 or b > 5:
            print("   Either a or b is larger than 5")
        if a > 5 and b > 5:
            print("   Both a and b are larger than 5")
** a = 1, b = 2 **
** a = 1, b = 4 **
** a = 1, b = 6 **
   Either a or b is larger than 5
** a = 1, b = 7 **
   Either a or b is larger than 5
** a = 3, b = 2 **
** a = 3, b = 4 **
** a = 3, b = 6 **
   Either a or b is larger than 5
** a = 3, b = 7 **
   Either a or b is larger than 5
** a = 5, b = 2 **
** a = 5, b = 4 **
** a = 5, b = 6 **
   Either a or b is larger than 5
** a = 5, b = 7 **
   Either a or b is larger than 5
** a = 7, b = 2 **
   Either a or b is larger than 5
** a = 7, b = 4 **
   Either a or b is larger than 5
** a = 7, b = 6 **
   Either a or b is larger than 5
   Both a and b are larger than 5
** a = 7, b = 7 **
   Either a or b is larger than 5
   Both a and b are larger than 5

if ... else¶

This if ... else clause is used when one wants a certain tasks to be performed under a condition, and another set of tasks to be performed otherwise. The structure is the following.

if <condition1>:
    <tasks1>
else:
    <tasks2>

Example¶

In [14]:
for a in [1, 3, 5, 7]:
    for b in [2, 4, 6, 8]:
        print(f"** a = {a}, b = {b}")
        if a > 5 or b > 5:
            print("   Either a or b is larger than 5")
        else:
            print("   Both a and b are not larger than 5")
** a = 1, b = 2
   Both a and b are not larger than 5
** a = 1, b = 4
   Both a and b are not larger than 5
** a = 1, b = 6
   Either a or b is larger than 5
** a = 1, b = 8
   Either a or b is larger than 5
** a = 3, b = 2
   Both a and b are not larger than 5
** a = 3, b = 4
   Both a and b are not larger than 5
** a = 3, b = 6
   Either a or b is larger than 5
** a = 3, b = 8
   Either a or b is larger than 5
** a = 5, b = 2
   Both a and b are not larger than 5
** a = 5, b = 4
   Both a and b are not larger than 5
** a = 5, b = 6
   Either a or b is larger than 5
** a = 5, b = 8
   Either a or b is larger than 5
** a = 7, b = 2
   Either a or b is larger than 5
** a = 7, b = 4
   Either a or b is larger than 5
** a = 7, b = 6
   Either a or b is larger than 5
** a = 7, b = 8
   Either a or b is larger than 5

if ... elif (... else)¶

When one wants to perform many different tasks depending on the different conditions, one could use the following structure.

if <condition1>:
    <tasks1>
elif <condition2>:
    <tasks2>
elif <condition3>:
    <tasks3>
...
elif <conditionN>:
    <tasksN>

One may also add the else clause at the end.

Example¶

In [15]:
for a in range(10):
    print(f"** a = {a}")
    r = a % 3
    if r == 0:
        print(f"   a is divisable by 3")
    elif r == 1:
        print(f"   a/3 has a remainder of 1")
    elif r ==2:
        print(f"   a/3 has a remainder of 2")
** a = 0
   a is divisable by 3
** a = 1
   a/3 has a remainder of 1
** a = 2
   a/3 has a remainder of 2
** a = 3
   a is divisable by 3
** a = 4
   a/3 has a remainder of 1
** a = 5
   a/3 has a remainder of 2
** a = 6
   a is divisable by 3
** a = 7
   a/3 has a remainder of 1
** a = 8
   a/3 has a remainder of 2
** a = 9
   a is divisable by 3
The history saving thread hit an unexpected error (OperationalError('attempt to write a readonly database')).History will not be written to the database.
In [ ]:
for a in range(1,21):
    print(f"** a = {a}")
    r2 = a%2
    r5 = a%5
    if r2 == 0:
        print("a is divisable by 2")