Jupyter Snippet P4M 05
Jupyter Snippet P4M 05
All of these python notebooks are available at https://gitlab.erc.monash.edu.au/andrease/Python4Maths.git
Control Flow Statements
The key thing to note about Python’s control flow statements and program structure is that it uses indentation to mark blocks. Hence the amount of white space (space or tab characters) at the start of a line is very important. This generally helps to make code more readable but can catch out new users of python.
Conditionals
If
if some_condition:
code block```
Only execute the code if some condition is satisfied
```python
x = 12
if x > 10:
print("Hello")
Hello
If-else
if some_condition:
algorithm 1
else:
algorithm 2```
As above but if the condition is False, then execute the second algorithm
```python
x = 12
if 10 < x < 11:
print("hello")
else:
print("world")
world
Else if
if some_condition:
algorithm
elif some_condition:
algorithm
else:
algorithm```
Any number of conditions can be chained to find which part we want to execute.
```python
x = 10
y = 12
if x > y:
print("x>y")
elif x < y:
print("x<y")
else:
print("x=y")
x<y
if statement inside a if statement or if-elif or if-else are called as nested if statements.
x = 10
y = 12
if x > y:
print( "x>y")
elif x < y:
print( "x<y")
if x==10:
print ("x=10")
else:
print ("invalid")
else:
print ("x=y")
x<y
x=10
Loops
For
for variable in something:
algorithm```
The "something" can be any of of the collections discussed previously (lists, sets, dictionaries). The variable is assigned each element from the collection in turn and the algorithm executed once with that value.
When looping over integers the `range()` function is useful which generates a range of integers:
* range(n) = 0, 1, ..., n-1
* range(m,n)= m, m+1, ..., n-1
* range(m,n,s)= m, m+s, m+2s, ..., m + ((n-m-1)//s) * s
In mathematical terms range `range(a,b)`$=[a,b)\subset\mathbb Z$
```python
for ch in 'abc':
print(ch)
total = 0
for i in range(5):
total += i
for i,j in [(1,2),(3,1)]:
total += i**j
print("total =",total)
a
b
c
total = 14
In the above example, i iterates over the 0,1,2,3,4. Every time it takes each value and executes the algorithm inside the loop. It is also possible to iterate over a nested list illustrated below.
list_of_lists = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
for list1 in list_of_lists:
print(list1)
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
A use case of a nested for loop in this case would be,
list_of_lists = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
total=0
for list1 in list_of_lists:
for x in list1:
total = total+x
print(total)
45
There are many helper functions that make for loops even more powerful and easy to use. For example enumerate()
, zip()
, sorted()
, reversed()
print("reversed: \t",end="")
for ch in reversed("abc"):
print(ch,end=";")
print("\nenuemerated:\t",end="")
for i,ch in enumerate("abc"):
print(i,"=",ch,end="; ")
print("\nzip'ed: ")
for a,x in zip("abc","xyz"):
print(a,":",x)
reversed: c;b;a;
enuemerated: 0 = a; 1 = b; 2 = c;
zip'ed:
a : x
b : y
c : z
While
while some_condition:
algorithm```
Repeately execute the algorithm until the condition fails (or exit via a break statement as shown below)
```python
i = 1
while i < 3:
print(i ** 2)
i = i+1
print('Bye')
1
4
Bye
Break
The break
keyword is used to abandon exection of a loop immediately. This statement can only be used in for and while loops.
for i in range(100):
print(i,end="...")
if i>=7:
break
print("completed.")
0...completed.
1...completed.
2...completed.
3...completed.
4...completed.
5...completed.
6...completed.
7...
Continue
The continue
statement skips the remainder of a loop and starts the next iteration. Again this can only be used in a while or for loop. It is typically only used within an if statement (otherwise the remainder of the loop would never be executed).
for i in range(10):
if i>4:
print("Ignored",i)
continue
# this statement is not reach if i > 4
print("Processed",i)
Processed 0
Processed 1
Processed 2
Processed 3
Processed 4
Ignored 5
Ignored 6
Ignored 7
Ignored 8
Ignored 9
Else statements on loops
Sometimes we want to know if a loop exited ‘normally’ or via a break statement. This can be achieved with an else:
statement in a loop which only executes if there was no break
count = 0
while count < 10:
count += 1
if count % 2 == 0: # even number
count += 2
continue
elif 5 < count < 9:
break # abnormal exit if we get here!
print("count =",count)
else: # while-else
print("Normal exit with",count)
count = 1
count = 5
count = 9
Normal exit with 12
Catching exceptions
Sometimes it is desirable to deal with errors without stopping the whole program. This can be achieved using a try statement. Appart from dealing with with system errors, it also alows aborting from somewhere deep down in nested execution. It is possible to attach multiple error handlers depending on the type of the exception
try:
code
except <Exception Type> as <variable name>:
# deal with error of this type
except:
# deal with any error
finally:
# execute irrespective of whether an exception occured or not```
```python
try:
count=0
while True:
while True:
while True:
print("Looping")
count = count + 1
if count > 3:
raise Exception("abort") # exit every loop or function
if count > 4:
raise StopIteration("I'm bored") # built in exception type
except StopIteration as e:
print("Stopped iteration:",e)
except Exception as e: # this is where we go when an exception is raised
print("Caught exception:",e)
finally:
print("All done")
Looping
Looping
Looping
Looping
Caught exception: abort
All done
This can also be useful to handle unexpected system errors more gracefully:
try:
for i in [2,1.5,0.0,3]:
inverse = 1.0/i
except Exception as e: # no matter what exception
print("Cannot calculate inverse because:", e)
Cannot calculate inverse because: float division by zero