Chapter 3: Control Flow#

Loops and Conditional Statements
and Some Coding Conventions#

Author: Dr. Suborna Ahmed

Learning Objectives:#

  • Controlling the Action:

    • Precursor to Conditional Statements

    • Conditional Statements

    • Complex Decisions

      • Conditional Expressions

      • Comparison and Logic Operators

    • Loops

      • while Loop

      • for Loop

      • Breaking Out of Loops

      • Keeping loops going

    • List Comprehensions

  • Functions in Python

    • Function: def

      • Single or Multiple Objects

      • Default Arguments

    • Function: lambda

  • A Few Coding Conventions

    • Variable Names

    • Consistency in Indentation

    • Whitespace

    • Comments on a Code

    • Special Characters

    • Keywords/Reserved Words

    • Multiple assignments

  • Modules

  • Objects

1. Controlling the Action:#

This chapter talks about how to controll the flow of your program’s execution. It covers various techniques that allow you to make decisions and control the actions performed in your program based on specific conditions you made.

Now, let’s make our own work flow and add conditions to make a decision.

1.1 Precursor to Conditional Statements#

This part provides an introduction to conditional statements. Basic questions about data can be answered using conditional statements, which is closely related to Booleans (have been discussed in week2 material).

We used logical operators and received output as a binary answer “TRUE” or “FALSE”. We can use equallity or inequality operators in the conditional statements.

  • Recall the comparison and logical operators we learned in week 2. The following codes are some examples which produce binary answers and can be used in conditional statements.

# Precursor to Conditional Statements

a, b = 2, 5
c = True
print("a =", a, ", b =", b, ", c =", c)

print("a > b is: ", a > b)
print("b > a is: ", b > a)

print(c == True)
print(c == False)

d = 'Active'
print(d == 'Non-active')
print(d == 'Active')
a = 2 , b = 5 , c = True
a > b is:  False
b > a is:  True
True
False
False
True

1.2 Conditional Statements#

Conditional statements help us decide the flow while making a decision based on values in a data set. It affects what the result we receive. We mostly use if statements but more statements are added using elif and else statements. These statements allow you to create branching paths in your code based on different conditions.

Basic Syntax for Conditional Statements:

- if statement:

  if (conditional expression):
   Statement blocks (statements to execute when the condition is True)

- else clause:

  if (conditional expression):
   Statement blocks (statements to execute when the condition is True)
  else:
   Statement blocks (statements to execute if the condition above is False)

- elif clause:

 if (conditional expression 1):
   Statement blocks 1 (statements to execute when the condition 1 is True)
  elif (conditional expression 2):
   Statement blocks 2 (statements to execute when the condition 2 is True)
  …
  else:
   Statement blocks n (statements to execute if all the conditions above are False)

Before talking about the conditional statement example below, we look at the input( ) function first.

  • The code below give an example to use the input( ) funciton to receive user’s input information and assign it to the variable “test1”. Then print “Hi ” plus the user’s input.

# Example for input function
test1 = input('Enter your first name:')
print('Hi ',  test1)
---------------------------------------------------------------------------
StdinNotImplementedError                  Traceback (most recent call last)
/var/folders/qt/qy37fy6s3c1553y2k74063pr0000gn/T/ipykernel_49163/232272545.py in <module>
      1 # Example for input function
----> 2 test1 = input('Enter your first name:')
      3 print('Hi ',  test1)

/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/ipykernel/kernelbase.py in raw_input(self, prompt)
   1001         """
   1002         if not self._allow_stdin:
-> 1003             raise StdinNotImplementedError(
   1004                 "raw_input was called, but this frontend does not support input requests."
   1005             )

StdinNotImplementedError: raw_input was called, but this frontend does not support input requests.

Examples:

  • The example below asks the user to enter a number using the input( ) function and assign it to the variable “number”.

  • Then, use the conditional statement to compare the number(user’s input) with 1.

# In Pythhon 3 we have to use eval(input()) to add a raw number but in Python 2 it's raw_input
# eval identfy the expression (your input) as a string but execute the expression as number here. 
# int function is optional here

print("Please enter a number")
number = int(eval(input()))
if (number > 1):
    print(number, 'is bigger than 1')
elif (number < 1):
    print(number, ' is less than 1')
else:
    print(number, 'is equal to 1')
  • The example below added more conditions to compare the number with different range boundaries to narrow the interval.

# Try to add more conditions

print("please enter a number")
number = int(eval(input()))

if (number<0):
    print(number, "is negative")
elif (0<=number<10):
    print(number, 'is with in the range 0 to 9')
elif (10<=number<20):
    print(number, ' is with in the range 10 to 19')
elif (20<=number<30):
    print(number, ' is with in the range 20 to 29')
else:
    print(number, 'is greater than 29')

1.3 Complex Decisions#

This part we will delves into more complex decision-making scenarios. We will discuss the conditional statements with if/elif/else combinations. Also, we will discuss the nested if statements, where conditions are nested within each other to create intricate decision structures.

# Example

p = 5

if p < 5:
    print('p<5')
elif p > 5:
    print('p>5')
else:
    print('p=5')
p=5

1.3.1 Conditional expressions#

Evaluates to False:#
  • Empty string (‘’ or “”)

  • Empty container (list, tuple, set, dictionary)

  • None

  • Anything that is false.

In Python, we can use single or double quotation marks to represent empty string, no space between the quotation marks. And an empty string always evaluates to False in a boolean context. Therefore, the statement under “else” will be executed.

# empty string example
if (''):
    print('print if')
else:
    print('print else')
print else

In Python, empty containers such as an empty list [], an empty tuple (), and an empty dictionary {} are considered to be False in a boolean context. Thus, the statement under “else” will be executed.

# empty container example
if []:
    print('print if')
else:
    print('print else')
print else

In Python, None value is also interpreted as False in boolean context. Thus, the statement under “else” will be executed

# "None" example
if None:
    print('print if')
else:
    print('print else')
print else
Evaluates to True:#
  • Everything else that is true.

The example below demonstrate that we can use True or False directly in the conditional statements. When we assign “val1” to be True, the statement under “if” will be executed; when we have a “not” before the True value, the statement under “else” will be executed.

# "True" and "False" example

val1 = True

if val1:
    print ('print if')
else:
    print('print else')
    
    
if(not val1):
    print ('print if')
else:
    print('print else')
print if
print else

1.3.2 Comparison and Logic Operators#

Comparison Operators#

Comparison operators compare values and return True or False.

>, >=, <, <=, ==, !=, is , is not, in, not in

Logic operators#

Logical operators can be used to provide multiple conditional expressions or perform negation of expressions:

and, or, not

We can also use logical operators to combine two or more than two boolean values together in the conditional statement. The example below shows that only when both x and y are greater than zero, the statement under “if” will be executed.

# example
x = 6
y = 5

if x > 0 and y > 0:
    print('x and y are positive values')
else:
    print('not both of them are positive')
x and y are positive values
Nested Conditions#

Conditional Statements can also be written in a nested condition, so that we are able to handle multiple conditions and create more sophisticated logic.

For example, if we want to check if a student is from this course (GEM 530 101) or not. We need to check: department information, course name, and section number.
The conditional statements first check if the student if from the same department, then check the course name, and last check the section number.

# condition 1: different department
# the information below are from the student
dep = "Economics"
course = "GEM530"
section = "101"

# nested if conditions
if dep == "Forestry":
    if course == "GEM530":
        if section == "101":
            print("Yes")
        else:
            print("The student is from a differenction section.")
    else: 
        print("The student is from a differenction course.")
else:
    print("The student is from a differenction department.")
The student is from a differenction department.
# condition 2: different course name
# the information below are from the student
dep = "Forestry"
course = "ECON101"
section = "101"

# nested if conditions
if dep == "Forestry":
    if course == "GEM530":
        if section == "101":
            print("Yes")
        else:
            print("The student is from a differenction section.")
    else: 
        print("The student is from a differenction course.")
else:
    print("The student is from a differenction department.")
The student is from a differenction course.
# condition 3: different section number
# the information below are from the student
dep = "Forestry"
course = "GEM530"
section = "102"

# nested if conditions
if dep == "Forestry":
    if course == "GEM530":
        if section == "101":
            print("Yes")
        else:
            print("The student is from a differenction section.")
    else: 
        print("The student is from a differenction course.")
else:
    print("The student is from a differenction department.")
The student is from a differenction section.

In condition4, we can see that although the student’s information are totally different, the conditional statements always check the department information first, and if it cannot match, then, the false message will be printed out.

# condition 4: different department, course and section number
# the information below are from the student
dep = "Economics"
course = "ECON101"
section = "100"

# nested if conditions
if dep == "Forestry":
    if course == "GEM530":
        if section == "101":
            print("Yes")
        else:
            print("The student is from a differenction section.")
    else: 
        print("The student is from a differenction course.")
else:
    print("The student is from a differenction department.")
The student is from a differenction department.

Activity 1

# example
x = 6
y = 5

if x > 0 and y > 0:
    print('x and y are positive values')
else:
    print('not both of them are positive')
  1. Try using ‘or’ instead of ‘and’ in the above example.

  2. Change the values of x & y.

  3. Change the statement to if-elif-else clauses (use at least one elif condition and you can change the values of x and y to check your statement).

  4. Change the statement to include nested if conditions.

# write your codes here

See solution for activity 1 at the end.

1.4 Loops#

loop_symbol.png

Loops are powerful constructs that allow you to repeat a block of code multiple times.

This section introduces loops and covers two common types in Python:

  1. while loop

  2. for loop

1.4.1 while loop#

  • While loop repeats a block of code as long as any specified condition is true.

CAN BACKFIRE IF YOUR CONDITION IS NEVER FALSE

We first assign i to be 2, and in the while loop, as long as i is less than 10, we will print out i and add 1 to i to update its value.

# Example 1
i = 2
while i < 10:
    print(i)
    i += 1 # add 1 to i every time after the print
2
3
4
5
6
7
8
9
# Example 2
a = 2
while a < 5:
    a = a + 1 # same as "a += 1"
    print(a)
3
4
5

Note

Range function

The range( ) function in Python is used to generate a sequence of numbers. It’s commonly used in loops to iterate over a specific range of values.

The range( ) function returns a range object that represents a sequence of numbers. This object can be converted to a list or iterated directly in a loop.

The general syntax for the range( ) function is as follows:   range(start, stop, step)

  • start (optional): The starting value of the sequence. If not provided, the sequence starts from 0.

  • stop (required): The ending value of the sequence. The sequence generated by range() will contain values up to, but not including, this value.

  • step (optional): The increment between consecutive values in the sequence. If not provided, the default step is 1.

  • range(stop): from 0 to stop-1

  • range(start, stop): from start to stop-1

  • range (start, stop, step): from start to stop-1, increments by step

See more examples on this site

range_func-2.png

  • On Jupyter, to get the result of range function you need to write list(range(add a value)) but on PyCharm we can direclty write range(add a value).

  • When you write range(x), you cannot see the complete sequence of elements, you need to write list(range(x)) to show the complete list.

range(3)
range(0, 3)
# Range Function
print(list(range(3))) # range(stop)

print(list(range(1,5))) # range(start, stop)

print(list(range(0,45,5))) # range(start, stop, step)
[0, 1, 2]
[1, 2, 3, 4]
[0, 5, 10, 15, 20, 25, 30, 35, 40]

Note

Append function

list.append( ) function adds element to the end of the list and the length of the list increases by one.

# append function examples
num = [2,4,6,8]
num.append(10)
print(num)

num.append(["x", "y"])
print(num)
[2, 4, 6, 8, 10]
[2, 4, 6, 8, 10, ['x', 'y']]

Note

  • list.append(x) adds x as a single element to the end of a list.

  • list.extend(x) iterates over x, which can be anything iterable, and adds each element of x to the list. The length of the list will increase by the number of elements in the iterable argument x.

# extend function example
num = [2,4,6,8]
letter = ["x", "y"]
num.extend(letter)
print(num)

num = [2,4,6,8]
letter = ["x", "y"]
print(num + letter)
[2, 4, 6, 8, 'x', 'y']
[2, 4, 6, 8, 'x', 'y']

1.4.2 for loop#

  • Perform a block of code for each element of a set of values.

  • It iterate over a set of sequence. It’s particularly useful for iterating over lists, strings, tuples, and other iterable objects.

CAN BACKFIRE IF YOU ADD TOO MANY NESTED LOOPS

We first create a variable named “word” and assign it the string “computer disk”. Then start a for loop that iterates over each character in word.
In this loop, “letter” is the loop variable and takes on the value of each successive character in “word” during each iteration of the loop.

The word "letter" doesn't have a special meaning in Python. It's a variable name, which means it's simply a name used to represent a value in the code that was chosen by the programmer for readability. In the script, "letter" represents each character (including spaces and punctuation) in the string "word" as the for loop iterates over it. You can give it another name you like, as in example 2, we use "character".

In the body of the loop, the print command is executed for each iteration. It calls the print function on “letter”, so the current character is outputted to the console.

# for loop: example 1
word = "computer disk"
for letter in word:
    print(letter)
c
o
m
p
u
t
e
r
 
d
i
s
k
# for loop: example 2
for character in 'hello':
    print(character) 
h
e
l
l
o

In example 3, we show the iteration for a list of numbers in range(10), which is a list of integer from 0 to 9. And we use “i” to represent the loop variable. You can use whatever you like, such as “x”, “j”… etc.

# for loop: example 3
for i in range(10):
    print(i)
0
1
2
3
4
5
6
7
8
9

Append in loops

append.png

In the example below, we first initialize an empty list named “new_list”, which is used to store the value append to the list after each iteration. The loop iterates over each value in range(10), which includes a sequence of numbers from 0 to 9 (10 is the stop argument and is exclusive). Inside the for loop, it appends the current value of “v” to “new_list” on each iteration and prints the current state of “new_list” after the append operation.

# for loop with append function: example 4 
new_list = []
for v in range(10):
    new_list.append(v)
    print(new_list)
[0]
[0, 1]
[0, 1, 2]
[0, 1, 2, 3]
[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4, 5]
[0, 1, 2, 3, 4, 5, 6]
[0, 1, 2, 3, 4, 5, 6, 7]
[0, 1, 2, 3, 4, 5, 6, 7, 8]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

In this example, we add a if statement before the append operation, which checks if the current value of “v” is less or equal to 3. If the condition meets, the append and print operation will be executed.

# for loop with append function and conditional statement: example 5
new_list = []
for v in range(10):
    if v <= 3:
        new_list.append(v)
        print(new_list)
[0]
[0, 1]
[0, 1, 2]
[0, 1, 2, 3]

1.4.3 Breaking Out of Loops#

breakout.png

Sometimes, you may need to prematurely exit a loop based on certain conditions. This subsection covers techniques for breaking out of loops, such as the break statement, which immediately terminates the loop and continues executing codes outside the loop.

The example below initiates a for loop where i is the loop variable. The range(100) function generates a sequence of numbers from 0 up to but not including 100. The if statement inside the loop checks if the current value of i equals 10. And the print function inside the loop prints the current value of i. When the if-condition meets, the break statement is executed: exits the for loop even if not all iterations have been completed.

# Breaking Out of Loops
for i in range(100):
    if i == 10:
        break # Exit the loop if the i equals to 10
    print(i)
0
1
2
3
4
5
6
7
8
9

1.4.4 Keeping loops going#

continue.png

In certain scenarios, you may want to skip the current iteration of a loop when it meets the condition, but continue the loop’s execution. This part discusses the continue function, which allows you to skip the remaining code inside a loop for the current iteration only, and move to the next iteration, without ending the entire loop.

The example below initiates a for loop for a sequence of numbers from 0 up to but not including 10. The if statement inside the loop checks if the current value of i is an even number. And the print function inside the loop prints the current value of i. When the if-condition meets, if i is an even number, the continue statement is executed: skips the rest of the current iteration and immediately starts the next iteration of the loop.

The % operator is the modulus operator, which returns the remainder of i divided by 2. If i is an even number, i%2 equals 0.
# Example 1
# continue function: skip
for i in range(10):
    if i%2 == 0:
        continue # Skip the current iteration if i is even
    print(i)
1
3
5
7
9

Here, when i is an even number, the pass statement is executed. The pass statement in Python does nothing.

# Example 2
# pass function: do nothing
for i in range(10):
    if i%2 == 0:
        pass # Do nothing if the i is even
    print(i)
0
1
2
3
4
5
6
7
8
9

Activity 2

  • Use a while loop or for loop to count numbers start from 1, and also meet the requirements below:

  1. if the number is divisible by 3, skip it;

  2. if the number is divisible by 5, do nothing;

  3. if the number is divisible by both 3 and 5, stop the loop

Hint: if (x % y == 0), x is divisible by y

See solution for activity 2 at the end.

1.5 List Comprehensions#

List comprehensions provide a concise way to create new lists based on existing iterables. It’s useful for one off loops, especially with lists. This subsection explores the syntax and usage of list comprehensions, which allow you to generate lists with a more compact and readable syntax.

It has four main parts:

  1. An Output Expression ⇒ how to change the input.

  2. A Variable representing members of the input sequence ⇒ related to input, preceded by for

  3. An Input Sequence ⇒ what iterable needs changing

  4. An Optional Predicate expression ⇒ if there needs a decisional if statement

list_comprehension.png

Consider the diagram above – these are the basic parts of a list comprehension. Note that list comprehensions are always surrounded with square brackets – just like lists! One of the most important things to remember for list comprehensions is that they will always result in a list! So if you want to adjust a list and return a list, then list comprehensions are the perfect tool.

The iterator part iterates through each member e of the input sequence a_list. The predicate checks if the member is an integer. If the member is an integer then it is passed to the output expression, squared, to become a member of the output list.

Compare the result of for loop and list comprehension to understand how can they work similarly.

  • If we have a list called x, which contains few numbers.

  • We want to create another list which contains the squared value of each element from list x

list_x = list(range(1,11))

# for loop
squared_list_x = []
for x in list_x:
    squared_list_x.append(x**2)
    
# list comprehension
list_comp = [x**2 for x in list_x]

print("for loop result:", squared_list_x)
print("list comprehension result:", list_comp)
for loop result: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
list comprehension result: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
# add predicate expression
# square the even numbers in the list only

list_x = list(range(1,11))

# for loop
squared_list_x = []
for x in list_x:
    if (x % 2 == 0): # check if x is even
        squared_list_x.append(x**2)
    
# list comprehension
list_comp = [x**2 for x in list_x if (x % 2 == 0)]

print("for loop result:", squared_list_x)
print("list comprehension result:", list_comp)
for loop result: [4, 16, 36, 64, 100]
list comprehension result: [4, 16, 36, 64, 100]
# List Comprehension examples
a = range(10)

# Set a basic structure
g1 = [x for x in a]  

# Multiply by 2
g2 = [x*2 for x in a]  # all values of a is squared

# Multiply by 2 only if x > 2
g3 = [x*2 for x in a if x > 2]

print("g1=", g1, "\ng2=", g2, "\ng3=", g3)
g1= [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
g2= [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] 
g3= [6, 8, 10, 12, 14, 16, 18]

Activity 3

Using comprehension to rewrite the loop below.

Hint: use sum( ) to calculate the total.

# calculate average score for scores >= 60
student_scores = [85, 95, 100, 20, 90, 60, 97, 68, 52, 42, 73, 78]

total = 0
for score in student_scores:
    if score >= 60:
        total += score
        
avg = total / len(student_scores)
print(avg)
62.166666666666664

See solution for activity 3 at the end.

2. Functions in Python#

There are lots of functions avaiable in Python that we can use anytime.

  • Some functions are provided by Python’s standard library and can be used directly without additional imports. Examples for built-in funcitons include print( ), len( ), type( ), and range( ), etc., and we have used a lot in previous examples and exercises.

  • Some functions can be used only after you import a library or module. Examples for these functions include datetime, which we introduced in week 1.

Built-in Functions#

The examples below show the use of abs(), min(), max() functions. All of them are built-in functions in Python.

- `abs(x)` function returns the absolute value of x
- `min(arg1, arg2, ..., argN)` function returns the smallest of its arguments.
- `max(arg1, arg2, ..., argN)` function returns the largest of its arguments.
# examples for built-in function
x1=-5.66
print(abs(x1)) # abs(): return the absolute value of the number

g3 = [x*2 for x in a if x > 2]
print("min(g3):", min(g3), "\nmax(g3):", max(g3)) # min(),max(): return the smallest/largest item in an iterable
5.66
min(g3): 6 
max(g3): 18

See more built-in functions and their usage.

2.1 Function: def#

Now we will talk about how to create our own functions and use them in Python.

We can create a function of our own using the def keyword, which allows you to encapsulate a block of code into a reusable entity. Then we can get the output after defining the parameters we added on the function.

def_function.png

Main component in the def function:

  • We set off with def name, parenthesis, and colon.

  • If it function needs parameters/arguments/inputs, and them in the parenthesis.

  • It should be concluded with a return.

The basic syntax of function definitions should be:

def function_name(input1, input2, ...):
    # function body 
    # ...
    # ...
    return output
# Example 1: create a function named addition to add two parameters and return the result
def addition(arg1, arg2):
    temp = arg1
    temp2 = temp + arg2
    return temp2
# get output for the funciton we defined above 
addition(2, 5)
7
  • We are not going to get any output for this function below since there’s nothing behind return.

# Example 2
def comboandprint(s1, s2):
    temp = s1+"_"+s2
    return
# we are not going to get any output for this function when we call it
comboandprint(s1="add", s2="text")
# To get a value or output, we add print() inside the function body
def comboandprint(s1, s2):
    temp = s1+"_"+s2
    print(temp)
    return

# now when we call the function, it has output
comboandprint(s1="add", s2="text")
add_text
# Example 3
def comboandprint(s1, s2):
    temp = str(s1)+","+str(s2)
    temp1= s1+s2
    print("add", temp, "=", temp1)
    return 

comboandprint(50, 100)
add 50,100 = 150
  • Summary:

    • Functions with print, print the output to console.

    • Without the return statement, they are called void functions which return None.

def function example:
Applying Pythagorean Equation to calculate the distance between two points

If we know the lengths of the two shortest sides (or coordinates of three points) we can find the length of the longest side using the Pythagorean equation.

Pythagorean.png

points_dist.png

Define a function named distance, given coordinates of two points, calculate the shortest distance between them.

# define the function
def distance(x1, y1, x2, y2):
    dx = x2 - x1
    dy = y2 - y1
    dist = (dx ** 2 + dy ** 2)**0.5
    return dist

# call the function with give coordinates
distance(781, 617, 978, 356)
327.00152904841286

2.1.1 Single or Multiple Objects#

Using def function we can return one or more objects. Previous examples returned one object.

Let’s try to return two objects:

def funcname1(arg1, arg2):
    temp = arg1
    temp2 = temp + arg2
    return temp2, temp

funcname1(arg1=0, arg2=2)
(2, 0)

2.1.2 Default Arguments#

In the def function we can add defult values for arguments to make them option. If users don’t override the value when they call the function, then the function will take the default value.

def_default.png

# Example 1: we give a default value for arg2
def funcname1(arg1, arg2=2):
    temp = arg1
    temp2 = temp + arg2
    return temp2, temp

print(funcname1(arg1=0)) # keep the default value: arg2=2

print(funcname1(arg1=0, arg2=100)) # change the default value
(2, 0)
(100, 0)
# Example 2: we give a default value for taxRate
def calCost(price, taxRate=0.05):
    return price + price * taxRate

print(calCost(100)) # keep the default value: taxRate=0.05
print(calCost(100,0.075)) # change the default value
105.0
107.5

Activity 4

Define a function called find_max_value, which take a list of number as the arguement and return the maximum number in the list. Suppose the list of number is not empty and includes at least two elements.

Hint: assume the first number in the list in the largest number at the beginning

After defined the function, use the function to find the max and min number for this list: [-8, 9, 0, 5, 2, 10]

See solution for activity 4 at the end.

2.2 Function lambda#

In lambda we declare one line version of a function. It’s a small anonymous function. A lambda function can take any number of arguments, but can only have one expression. Lambda function has concise syntax and are typically used for simple, one-line operations.

  • Note that lambda functions don’t have a name, which is why they are often referred to as “anonymous functions”.

lambda.png

The example below defines a lambda function that takes two arguments, x and y, and returns their sum. This function is assigned to the variable “a”. So “a” now refers to this lambda function.

# Example 1
a = lambda x, y: x + y #  define the function "a" with lambda syntax
print(a(3,4))
7

The example below defines a lambda function that takes a single argument, a, and returns a + 10. This function is assigned to the variable “x”. So “x” now refers to this lambda function.

# Example 2
x = lambda a : a + 10
print("x(5):", x(5))
x(5): 15

The example below defines a lambda function that takes two arguments, a and b, and returns their product. This function is assigned to the variable “x”. So “x” now refers to this lambda function.

# Example 3
x = lambda a, b : a * b
print("x(5, 6):", x(5, 6))
x(5, 6): 30

3. A Few Coding Conventions#

The section discusses some common coding conventions and best practices in Python. It covers guidelines for writing readable and maintainable code, using meaningful variable names, and organizing code with proper indentation and whitespace. This section emphasizes the importance of consistency and provides examples to illustrate the recommended coding conventions.

3.1 Variable Names#

Recall the week 1 material: rules and conventions for naming variables, including using descriptive names that convey the purpose or content of the variable, using lowercase letters, avoiding reserved words, and separating words with underscores or use camelCase for certain contexts. See the examples for bad and good variable names below:

Difficult to Understand

Meaningful name

killMe8=‘important info’

needToKnow=‘important info’

  1. Use meaningful names for Class, Object, Variables and Methods.

  2. Choose meaningful name instead of short name. UBC_id is better than ui.

  3. Maintain the length of a variable name. UBC_student_ID is too long? Be consistent; UBC_id or UBCid

  4. Begin a variable name with an underscore(_) character for a special case.

Refer Style Guide for Python Code

3.2 Consistency in Indentation#

Indentation is used to define blocks of code and maintain the structure and readability of the code. Consistent indentation need to be used to avoid syntax errors and improve code clarity.

Spaces are the preferred indentation method. Tabs should be used solely to remain consistent with code that is already indented with tabs. Four Spaces or One Tab: never mixed these two: tab and space.

Python 3 disallows mixing the use of tabs and spaces for indentation.

Python 2 code indented with a mixture of tabs and spaces should be converted to using spaces exclusively.

3.3 Whitespace#

Conventionally, we add a whitespace in expressions and statements. Appropriate use of spaces around operators, parentheses, commas, and colons on either side can enhance code readability.


Proper Method:
added = 5 + 6
r1 = [x * 10 for x in range(2)]
Avoid It:
added=5+6
r1=[x*10 for x in range(2)]

3.4 Comments on a Code#

Within a coded chunk we can add comments using a # symbol.

Comments can provide additional information, explanations, or context about the code to make it more understandable for both the developer and other readers. When adding comments along the code, we need to be aware of using clear and concise language, avoiding redundant comments, and documenting complex or non-obvious parts of the code.


Proper Method:
added = 5 + 6 # addition
r1 = [x * 10 for x in range(2)] # list comprehension
Avoid It:
added = 5 + 6 # 5+6
r1 = [x * 10 for x in range(2)] # r1

Use comments to explain your code using:

  • Three quotations: “”” Comments”””

  • A hashtag: # Comments

ALWAYS COMMENT! Commenting is a good practice to leave yourself some info or someone that you might share code with!

# examples
print("this is a cool print statement!")
# the above print statement writes out the important string to the console for your viewing 
this is a cool print statement!

3.5 Special Characters#

Symbol \n : used to create a new line#

# Example of "\n"
print("first line\nsecond line")
first line
second line

Symbol \t: tab#

# Example of "\t"
print("str1\ttstr2")
str1	tstr2

Symbol : : go to next level of statements#

# Example of ":"
class Testc:
    def testM():
        if True:
            pass

Symbol ; : multiple statements on a single line#

# Example of ";"
import math; x = math.pow(2, 3); print(x)
8.0

There are other characters that have special meanings or functions in the Python language, such as quotation marks for strings, parentheses for function calls, and square brackets for lists, which we used a lot in previous examples.

3.6 Keywords/Reserved Words#

Keywords are predefined words with special meanings and purposes in the Python language, such as if, for, while, and def. They can not be used as the names of variables, classes, and objects etc, or else a Syntax Error will occur. See the example below:

# Attempting to use a keyword as a variable name
if = 10
  File "<ipython-input-48-c09b58638d1d>", line 2
    if = 10
       ^
SyntaxError: invalid syntax

Here are some commonly used reserved words in Python:

and

or

if

else

elif

pass

break

continue

import

global

assert

except

print

class

exec

raise

in

is

finally

return

def

for

lambda

try

del

from

not

while

  • red ones are those we have used before

3.7 Multiple assignments#

We can assign values to multiple variables simultaneously in a single line statement.

# Multiple assignments
a = b = c = 0
a1, b1, c1 = 1, 1.0, "c1"
(a2, b2, c2) = (2,2.0, "c2")
print(" a, b, c: ", a, b, c,"\n", 
      "a1, b1, c1:", a1, b1, c1,"\n", 
      "a2, b2, c2:", a2, b2, c2)
 a, b, c:  0 0 0 
 a1, b1, c1: 1 1.0 c1 
 a2, b2, c2: 2 2.0 c2

We can also use multiple assignments for unpacking values from tuples, lists, or other iterable objects, or assigning multiple return values from a function.

# define a tuple
coordinates = (3, 4)
# unpack the values into separate variables
x,y = coordinates
print("x:", x)
print("y:", y)
x: 3
y: 4
# define a dictionary with multiple key-value pairs
person = {'name': 'Amy', 'age': 25, 'country': 'USA'}

# unpack the values from the dictionary into separate variables
name, age, country = person.values()

# Print the unpacked values
print("Name:", name)
print("Age:", age)
print("Country:", country)
Name: Amy
Age: 25
Country: USA

4. Modules#

Modules represent a logical way to organize and reuse our Python code.

To physically organize codes we can:

  • Save our code in files!

  • Organize files according to different classes, functions, etc. used in our programming.

  • Import files as standard modules, such as sys and math.

  • A file, ending with .py or .ipynb, is a module when they are saved on the disk for importing.

Built-in Modules#

  • Here are some examples of built-in modules in Python:

Module

Description

Examples

os

interacting with the operating system

os.system(command)

sys

system-specific parameters and functions

sys.path
sys.exit()

math

floating point math functions

math.pow()

shutil

high level file operations

shutil.copyfile()
shutil.move()

glob

get file lists from directory wildcard searches

glob.glob(‘*.shp’)

re

regular expression tools for advanced string processing

re.match(‘c’, ‘abcdef’)

  • Later in the course we will use built-in modules.

# example
# lambda.png file is copied to another folder
import shutil
from shutil import copytree
from IPython.paths import get_ipython_package_dir
shutil.copy("range.png", r"C:\Users\Suborna\OneDrive - The University Of British Columbia\Documents\GEM530_2021\Lecture\Week3\Lecture3_Exercise/range.png")

Note

Math Module

The math module in Python provides mathematical functions and constants that complement the basic math operations like addition, subtraction, multiplication, and division. These are particularly useful for more complex mathematical tasks.
Here are some examples for frequentlly used functions in math module:
- degrees
- radians
- asin
- sin
- cos
- acos
- exp
- fabs
- log10
- pi
- pow
- sqrt

# list of available math functions
dir(math)
['__doc__',
 '__file__',
 '__loader__',
 '__name__',
 '__package__',
 '__spec__',
 'acos',
 'acosh',
 'asin',
 'asinh',
 'atan',
 'atan2',
 'atanh',
 'ceil',
 'copysign',
 'cos',
 'cosh',
 'degrees',
 'e',
 'erf',
 'erfc',
 'exp',
 'expm1',
 'fabs',
 'factorial',
 'floor',
 'fmod',
 'frexp',
 'fsum',
 'gamma',
 'gcd',
 'hypot',
 'inf',
 'isclose',
 'isfinite',
 'isinf',
 'isnan',
 'ldexp',
 'lgamma',
 'log',
 'log10',
 'log1p',
 'log2',
 'modf',
 'nan',
 'pi',
 'pow',
 'radians',
 'sin',
 'sinh',
 'sqrt',
 'tan',
 'tanh',
 'tau',
 'trunc']

Examples of math module#

First, we need to import the math module, which contains a collection of mathematical functions.

import math

The math.degrees() function converts 1 radian to degrees.

print(math.degrees(1))
57.29577951308232

The math.radians() function converts 57.295 degrees to radians.

print(math.radians(57.295))
0.9999863949301512

The math.asin() function calculates the arc sine (inverse sine function) of 0.5.

print(math.asin(0.5))
0.5235987755982988

The math.exp() function calculates “e” raised to the power of 2, where “e” is the base of natural logarithms.

print(math.exp(2))
7.38905609893065

The math.log() function calculates the logarithm of 2 with base 10.

print(math.log(2, 10))
0.30102999566398114

The math.log10() function calculates the base-10 logarithm of 100.

print(math.log10(100))
2.0

This line blow prints the value of the mathematical constant \(\pi\).

print(math.pi)
3.141592653589793

5. Objects#

Everything in Python is an object. Almost everything has attributes and methods. Strings are objects. Lists are objects. Functions are objects. Even modules are objects.

object.png

Recall we have talked about some basic Python data types, including string, float, integer, etc.. They all are objects in Python and they belong to different classes.

  • Strings in Python are objects of the str class.

  • Floats in Python are objects of the float class.

  • Integers in Python are objects of the int class.

When you create a variable and assign it a value of a specific data type, you are creating an instance of the corresponding class. These objects can then be manipulated using class-specific methods and attributes.

# example

# Creating a string object
my_str = "Hello, World!"

# Using string-specific methods
print(my_str.upper())  
print(my_str.lower())  
HELLO, WORLD!
hello, world!

In this example, we create a variable my_str and assign it the value “Hello, World!”. By doing so, we are creating an instance of the str class, which represents a string object in Python.
Once the string object is created, we can manipulate it using class-specific methods. In this case, we use the upper(), lower() methods to transform and manipulate the string. These methods are specific to the str class and allow us to perform operations such as converting the string to uppercase, lowercase.

# example

# Creating an Integer object
x = 10 
# Creating a Float object
y = 2.5  


addition = x + y
print(addition)  

subtraction = x - y
print(subtraction)

multiplication = x * y
print(multiplication)  

division = x / y
print(division) 
12.5
7.5
25.0
4.0

In this example, we create two variables x and y, where x is assigned an integer value of 10 and y is assigned a float value of 2.5. These assignments create instances of the int and float classes, respectively.
We then perform various arithmetic operations on these int and float objects using the corresponding operators. The addition, subtraction, multiplication, division operations are demonstrated.

Note

Object-Oriented Programming (OOP)

Python supports object-oriented programming, which is a programming paradigm that emphasizes the use of objects and classes. OOP allows for modular and organized code by grouping related data and functions together.

OOP allows for code organization, reusability, modularity, and abstraction. It enables the creation of complex systems by breaking them down into manageable and understandable objects.

Solutions#

Activity 1#

  1. Try using ‘or’ instead of ‘and’ in the above code.

x = 6
y = 5

if x > 0 or y > 0:
    print('x or y is positive')
else:
    print('both x and y are not positive')
x or y is positive
  1. Change the values of x & y.

x = -8
y = 10

if x > 0 and y > 0:
    print('x and y are positive values')
else:
    print('at least one of them is not positive')
at least one of them is not positive
  1. Change the statements.

x = 0
y = 7

if x > y:
    print('x is greater than y')
elif x < y:
    print('x is smaller than y')
else:
    print('x is equal to y')
x is smaller than y
  1. Change the statement to nested if conditions.

x = -9
y = 7

if x > 0 and y > 0:
    if (x > y):
        print ('x is greater than y')
    elif (x < y):
        print ('x is smaller than y')
    else:
        print ('x is equal to y')
    print('x and y are both positive')
    
elif x < 0 and y < 0:
    if (x > y):
        print ('x is greater than y')
    elif (x < y):
        print ('x is smaller than y')
    else:
        print ('x is equal to y')
    print('x and y are both negative')
    
elif x > 0 and y < 0:
    print('x is positive and y is negative. \n x is greater than y')
    
elif x < 0 and y > 0:
    print('x is negative and y is positive. \n x is smaller than y')
    
else:
    print('at least one of x and y is equal to zero')
x is negative and y is positive. 
 x is smaller than y

Activity 2#

  • Use a while loop or for loop to count numbers start from 1, and also meet the requirements below:

  1. if the number is divisible by 3, skip it;

  2. if the number is divisible by 5, do nothing;

  3. if the number is divisible by both 3 and 5, stop the loop

  • while loop

number = 0

while True:
    number += 1
    if (number % 3 == 0) and (number % 5 == 0):
        break
    elif (number % 3 == 0):
        continue
    elif (number % 5):
        pass
    print(number)

print(number, "is divisible by both 3 and 5, loop ended")
1
2
4
5
7
8
10
11
13
14
15 is divisible by both 3 and 5, loop ended
  • for loop

for number in range(1, 50):
    if number % 3 == 0 and number % 5 == 0:
        break
    elif number % 3 == 0:
        continue
    elif number % 5 == 0:
        pass
    print(number)
    
print(number, "is divisible by both 3 and 5, loop ended")
1
2
4
5
7
8
10
11
13
14
15 is divisible by both 3 and 5, loop ended

Activity 3#

student_scores = [85, 95, 100, 20, 90, 60, 97, 68, 52, 42, 73, 78]

total = sum(score for score in student_scores if score >= 60) 

avg = total / len(student_scores)

print(avg)
62.166666666666664

Activity 4#

def find_max_value(list_of_numbers):
    max_value = list_of_numbers[0]  # assume the first number is the maximum at the start of the loop
    
    for number in list_of_numbers:
        if number > max_value:
            max_value = number

            
    return max_value


number_list = [-8, 9, 0, 5, 2, 10]
find_max_value(number_list)
10