# Tutorial 1 -- Control Statements

### while/else Statement

In a while statement, a sequence of instructions are executed as long as an expression is true. If the expression is false (which may be the first time it is tested) the suite of the else clause, if present, is executed and the loop terminates. Open your favorite Python IDE and copy and paste this code snippet. Recall that the text following a # is ignored by the interpreter. This is useful to insert comments. A code without comments is a bad code.

n = 0 # initialization of n
Nmax = 10
print("We print integers from 1 to Nmax")
while n <= Nmax: # start of loop
print(n) # note the indentation with a tab
n = n + 1

print("end of loop")


What would happen if you forget to initialize variable n as shown below?

# n = 0 # initialization of n
Nmax = 10
print("We print integers from 1 to Nmax =",Nmax)
while n <= Nmax: # start of loop: note the colon at the end of the statement
print(n) # note the indentation with a tab
n = n + 1

print("end of loop")


Spyder would likely give some warning in the margin of the lines requiring some attention. The output depends on your OS and interpreter. Here is what I get

In [2]: runfile('tuto1.py', wdir='Comp2020/python')
We print integers from 1 to Nmax = 10
end of loop


Python does not display an error, it completes the execution, but it clearly does not run properly since the integers are not printed.

Now remove the colon : in the while loop:

n = 0 # initialization of n
Nmax = 10
print("We print integers from 1 to Nmax =",Nmax)
while n <= Nmax # start of loop (we remove the colon)
print(n) # note the indentation with a tab
n = n + 1
# end of indentation = end of loop
print("end of loop")


You would likely get error messages which may or may not give you an idea how to fix the error(s).

### if/else Statement

A conditional instruction can be executed with the if statement. There is no switch statement: instead use elif.

First, we show how to use a simple if statement within a loop:

n = 0 # initialization of n
Nmax = 100
while n <= Nmax: # start of loop
n = n + 1
if n == Nmax:  # do not forget the ':'
print('end of loop: n= ',n)  # you must indent the lines within the 'if' statement
# end of indentation = end of if statement
print("We are done!")


As long as the identation level remains the same, the level of the execution is the same. Additional identations can be used to add levels of executions. In this example, we use the modulus operator % which divides two integers and returns the remainder:

x=12
if (x%2) == 0:            # is x modulo 2 equal to 0?
if (x%3) == 0:
if (x%7) == 0:
print ('x is a multiple de 2, 3 and 7 !')
else:
print ('x is a multiple de 2 et 3, but not of  7!')
else:
print ('x is a multiple of 2, but not of 3!')
else:
print ('x is not a multiple of 2!')


Here is an example of if\elif\else syntax: elif is short for else if.

x=1
print ('x=',x)
if x==2:
print ('x is equal to 2')
elif x==3:
print ('x is equal to 3')
else:
print ("is neither equal to 2")
print ('nor 3')


### for Loops

We can use for to enumerate through the members of a list. The syntax is for variable in list. To obtain a sequence of integers you can iterate over, use range(<number>).

In the following example, we compute the syracuse sequence ${ x_n }$ ($n \geq 0$) which satisfies $$x_{n+1} = \frac{1}{2} x_{n} \quad \text{if } n \text{ is even},\qquad x_{n+1} = \frac{1}{2} (3 x_{n}+1) \quad \text{if } n \text{ is odd}$$ starting with integer $x_0 \geq 1$. The initial value $x_0 =1$ yields the periodic sequence $1,2,1,2,1,\ldots$. The initial value $x_0= 7$ yields $7,11,17,26,13,20,10,5,8,4,2,1,2,1,2,1, \ldots$. It is conjectured (still unproven!) that any initial condition $x_0$ will lead eventually to the periodic sequence $1,2,1,2,\ldots$.

x = int(input("Enter x: "))
N=100
for n in range(N):
if (x%2) == 0:
x = x/2
print(x)
else:
x = (3*x+1)/2
print(x)


### An example of a simple algorithm & Python implementation

Euclid’s algorithm is an efficient method to compute the greatest common divisor (GCD) of two integers. The GCD of two integers is the largest integer that divides both of them without leaving a remainder. The algorithm can be represented by this flowchart (floor(x) returns floor of x, that is, the largest integer not greater than x).

Here is a simple implementation in python:

# Python program to demonstrate Basic Euclidean Algorithm

a = int(input("Enter a : "))
b = int(input("Enter b : "))
if a < b:
b, a = a, b # Exchange a & b

a_old = a
b_old = b

while True:
r = a % b
if r == 0:
break
a, b = b, r

print("The GCD of", a_old, "and", b_old, "is", b)


Here is an even simpler implementation:


a = int(input("Enter a : "))
b = int(input("Enter b : "))

while b: # this is equivalent to: while b != 0:
a, b = b, a%b

print("gcd(", a , "," , b, ") = ", a)


Example: Write a python script which computes the sum of the first N inverse of squared integers. Compute the relative error of the exact infinite sum $$\lim_{N\to \infty}\sum_{i=1}^N \frac{1}{i^2} = \frac{\pi^2}{6}$$

import math

N = int(input("Enter N : "))
sum = 0

for i in range(1,N):
sum += 1/i**2

inf_sum = math.pi**2/6
rel_error = abs((sum-inf_sum)/inf_sum)
print("Relative error with",N,"terms is",rel_error*100,"%")