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.
if some_condition: code block``` Only execute the code if some condition is satisfied ```python x = 12 if x > 10: print("Hello")
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")
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")
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")
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)
There are many helper functions that make for loops even more powerful and easy to use. For example
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 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 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 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
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