03-program-flow-and-control
September 2, 2023
[1]: # In this unit we look into the basic program flow and control structures.
# A Python program typically begins by 'importing' a set of packages.
# A package is essentially a library of pre-written functions, ready for our use
# They expand our capabilities multifold
# We begin by importing a very useful module named 'numpy'
# While importing, we can provide a shorter alias for referring to the module,␣
↪e.g. 'np'
# and use this alias to refer to functionality within the module in a compact␣
↪manner
# We will be covering numpy in detail later, but we will start using some of␣
↪it's functions
[2]: import numpy as np
# The numpy module is documented at https://numpy.org/doc/stable/index.html
[3]: # Just to start using numpy, let's create a list of random numbers (type :␣
↪real) using the numpy.random module
# To find out more about the numpy.random module visit: https://numpy.org/doc/
↪stable/reference/random/index.html
random_numbers = np.random.rand(10)
print(random_numbers)
[0.84270248 0.29449588 0.13701838 0.33827704 0.01733373 0.89229241
0.17518699 0.11655552 0.23609828 0.52067628]
[4]: # We want to write our own code to calculate the 'sum' of the numbers in the␣
↪list
# We can do that by using a Python control structure - the for loop
# Note that we take a couple of steps in the following statements
# 1. We create a variable to store the sum of the list
# 2. We iterate over the list and add each element to the sum
# Also note the syntax of the for statement. The 'for' statement line ends with␣
↪a ':'
1
# and the next line is indented. In Python this signals the beginning of a new␣
↪block
# So long as the subsequent statements are indented, they all belong to the␣
↪'forblock
'''To iterate in a range ''' # for i in range(50):
''' To iterate over a list ''' # for i in my_list
my_sum = 0
for i in random_numbers:
my_sum += i
print(f"There are {len(random_numbers)} numbers in the list")
print(f"Their sum: {my_sum}")
# The average of the list is simply the sum divided by the number of elements␣
↪in the list
average = my_sum / len(random_numbers)
print(f"Their average: {average}")
There are 10 numbers in the list
Their sum: 3.5706369890466965
Their average: 0.35706369890466966
[5]: # We can also use the 'while' control structure to do this
my_sum = 0
list_len = len(random_numbers)
i = 0
while(i < list_len):
my_sum += random_numbers[i]
i += 1
print(f"Sum of the numbers in the list: {my_sum}")
# Notice that we have created a block of two statements in the while loop
Sum of the numbers in the list: 3.5706369890466965
[6]: # Q: When will you use 'for' and when will you use 'while'?
[7]: # For some strange reason, if we want the sum of only those numbers greater␣
↪than 0.5 ...
# we can use the 'if' control structure
my_sum = 0
2
my_count = 0
for i in random_numbers:
if(i > 0.5):
my_sum += i
my_count += 1
print(f"There are {my_count} numbers greater than 0.5 in the list, and their␣
↪Sum is : {my_sum}")
# Notice that a new 'block' of two statements is created for the 'if' statement
There are 3 numbers greater than 0.5 in the list, and their Sum is :
2.255671171923966
[8]: # A couple of keywords are relevant in the context of for, while and if␣
↪statements
# These are 'break' and 'continue'
# The 'break' causes the program to immediately exit the block
# The 'continue' causes the program to skip the rest of the block and continue␣
↪with the next iteration
my_sum = 0
my_count = 0
for i in random_numbers:
if(i > 0.5):
my_sum += i
my_count += 1
if(my_sum > 1.0): # If the sum exceeds 1.0, stop the loop by breaking␣
↪out of it
break
print(f"{my_count} entries in the list had to be summed before their Sum␣
↪exceeded 1.\nThe sum at the point of exit is : {my_sum}")
2 entries in the list had to be summed before their Sum exceeded 1.
The sum at the point of exit is : 1.7349948930983583
[9]: # Example of 'continue'
my_sum = 0
my_count = 0
for i in random_numbers:
if(i >= 0.5):
continue
my_sum += i
my_count += 1
3
print(f"The list: {random_numbers}")
print(f"There are {my_count} entries in the list with value less than 0.5.␣
↪Their sum is : {my_sum}")
The list: [0.84270248 0.29449588 0.13701838 0.33827704 0.01733373 0.89229241
0.17518699 0.11655552 0.23609828 0.52067628]
There are 7 entries in the list with value less than 0.5. Their sum is :
1.3149658171227312
[10]: # Of course, we could have avoided the 'manual' summing by using the␣
↪appropriate function in the numpy module
print(np.sum(random_numbers))
print(np.average(random_numbers))
# That's the real advantage of importing packages like numpy
# We will be importing many such packages in the near future
# Packages have very useful functionality implemented in them and they help␣
↪make Python code very compact and powerful
# ... because most work is done inside the packages!
# ... learning Python also involves understanding the existence of the␣
↪packages and their capabilities
3.5706369890466965
0.35706369890466966
[16]: # We have started talking about 'function's, what are they? How to create them?
# Functions allow you to create reusable blocks of code that get executed when␣
↪the function is invoked (i.e. called)
def sum_of_numbers(a_list):
my_sum = 0
my_count = 0
for i in a_list:
my_sum += i
my_count += 1
return my_sum, my_count
# The above statements defined a function, and we can now call it with multiple␣
↪lists, one by one ...
# Notice that the list returns two values ... sum and count ... and we need two␣
↪variables to store them
list1 = [1, 2, 3, 4, 5]
list2 = [6, 7, 8, 9, 10]
4
print(sum_of_numbers(list1))
print(sum_of_numbers(list2))
# We use the same function multiple times
sum1, count1 = sum_of_numbers(list1)
sum2, count2 = sum_of_numbers(list2)
print(sum1, count1)
print(sum2, count2)
# The functions np.sum and np.average are functions defined in this manner and␣
↪packaged into 'numpy'
(15, 5)
(40, 5)
15 5
40 5
[12]: # The basic control strcutres covered above are documented at
# https://docs.python.org/3/tutorial/controlflow.html#more-control-flow-tools
[13]: # We now know the very basics of Python: types, variables, control structures,␣
↪functions, ...
# Good enough to start using it to solve some real world problems
# We will look into some more advanced topics later ...
# ... these topics will help us build more organized (class) and robust␣
↪programs (exceptions, etc.)
# ... but for now, we will use the basics to solve some real world problems
[14]: # To solve most problems we will 'import' the packages we need
# and use the modules and functions defined therein
# Some of the firsts packages will be numpy, scipy, matplotlib, pandas, ...