2.5. Lecture 4: Python 2

Before this class you should:

  • Read Think Python:

    • Chapter 5: Conditionals and recursion;

    • Chapter 6: Fruitful functions; and

    • Chapter 7: Iteration

Before next class you should:

  • Read Think Python:

    • Chapter 8: Strings;

    • Chapter 10: Lists;

    • Chapter 11: Dictionaries; and

    • Chapter 12: Tuples

Note taker: Dylan Munro

2.5.1. Overview

This lecture covers the following topics:

  1. Modulus and floor division

  2. Conditionals
    • Boolean and logical operators

    • Conditional statements

    • Nested conditional statements

  3. Functions
    • Recursion

    • Return values

  4. Loops
    • While loops

  5. Cumulative Example - Newton’s method

2.5.2. Modulus and Floor Division

Modulus and floor division are two important mathematical operations in Python. They are similar to division, although have different use cases. While normal division is used to divide two numbers and return a floating point number, modulus and floor division are used to find the remainder and round down to the nearest integer, respectively.

Floor division: Used to divide two numbers and round down to the nearest integer.

For example, consider the following code which compares normal and floor division:

minutes = 105
hours = minutes / 60 # 1.75 (normal division)
hours = minutes // 60 # 1 (floor division - note that the 1.75 is rounded down to 1)

Modulus: Used to find the remainder of two numbers.

For example:

minutes = 105
print(minutes % 60) # 45 (because the remainder of 105 / 60 is 45)

2.5.3. Conditionals

2.5.3.1. Boolean operators

Boolean operators serve as the foundation for building logical expressions and making decisions based on conditions. They compare equality between two operands. Following this equality comparison, a boolean value is returned, which is often combined with conditional operators to control the flow of logic in a program. For example, if we have two possible outcomes, we can use a boolean operator to determine which outcome to execute.

There are two important keywords associated with boolean operators in Python:

  1. True: Indicates that a statement is true
    • Note that any nonzero number is also considered to be True

  2. False: Indicates that a statement is false
    • Note that zero is also considered to be False

There are also six boolean operators:

  1. == (Equals): Returns True if the two operands are equal

  2. != (Not equals): Returns True if the two operands are not equal

  3. > (Greater than): Returns True if the first operand is greater than the second

  4. < (Less than): Returns True if the first operand is less than the second

  5. >= (Greater than or equal to): Returns True if the first operand is greater than or equal to the second

  6. <= (Less than or equal to): Returns True if the first operand is less than or equal to the second

For example:

print(5 == 5) # True
print(5 != 5) # False
print(5 > 5) # False
print(5 < 5) # False
print(5 >= 5) # True
print(5 <= 5) # True

2.5.3.2. Logical Operators

Logical operators allow a Python program to make decisions based on multiple conditions by combining or modifying boolean expressions. For example, if we want a conditional branch to execute only if two conditions are both true, we can use the logical AND operator to combine them such that a conditional statement will only execute if they are both true.

There are three important keywords associated with conditional statements in Python:

  1. and: The logical AND operator - Returns True if both operands are True

  2. or: The logical OR operator - Returns True if either operand is True

  3. not: The logical NOT operator - Inverses the truth value of the operand. True becomes False and False becomes True.

For example:

x = 5
print(x > 0 and x < 10) # True
x = -1
print(x > 0 and x < 10) # False
print(not x == 0) # True

2.5.3.3. Conditional Statements

Conditional operators in Python are crucial tools for decision-making in a program, allowing the flow of execution to change based on certain conditions. Unlike Boolean operators, which primarily deal with logical operations and return Boolean values (True or False), conditional operators are used to compare values and determine the relative relationships between them. The result of these comparisons is a Boolean value, which can then be used to guide the program’s logic.

There are three important keywords relevant to conditional statements in Python:

  1. if (if): Indicates the start of a conditional statement which will be executed if the condition is True

  2. elif (else if): Indicates the start of a conditional statement which will be executed if the previous condition was False and this condition is True

  3. else (else): Indicates the start of a conditional statement which will be executed if all previous conditions were False

There is also a special keyword called pass which acts as a placeholder for branches which have not fully been implemented. For example:

x = 5
if x > 0:
    print("x is positive")
elif x < 0:
    print("x is negative")
else:
    pass # TODO: Implement this branch

2.5.4. Functions

2.5.4.1. Recursion

Recursion is a method where a function calls itself as part of its execution process. This technique is useful for solving problems that can be broken down into smaller, similar subproblems.

Key terms:

  1. Recursive function: A function which calls itself

  2. Base case: The condition for exiting the recursive function

    If the base case is not reached, the function will continue to call itself indefinitely - called infinite recursion

  3. Recursion: The process of executing a recursive function

For example, the following code will print the number 3, 2, 1 via recursion:

def countdown(n):
    if n <= 0: # Base case of n <= 0 - This means that after n is 0 or less, the function will terminate
        print("Blastoff!")
    else:
        print(n)
        countdown(n - 1)
countdown(3)

2.5.4.2. Return values

A return value is the value which a function returns to the caller. This value can be used in the caller’s code.

Key terms:

  1. Dead code: Code which is never executed. This includes code after a return statement

  2. Void function: A function which does not return a value

  3. Boolean function: A function which returns a value of True or False (boolean value)
    • Typically worded as a true/false question, ex: is_square(x, y)

  4. Fruitful function: A function which returns a value other than None

2.5.5. While Loops

While loops are used to execute a block of code repeatedly while a condition is true. They are similar to for loops, but with a different syntax and use case. For loops iterate over a sequence of elements, although while loops iterate based on a condition. As a result, while loops are advantageous when the number of iterations is not known in advance.

The flow of logic for a while loop is as follows:

  1. Determine if the condition is True or False

  2. If the condition is false, exit the while statement
    • Alternatively, the keyword break can be used to terminate the loop

  3. If the condition is true, execute the body of the while loop and subsequently return to step 1

For example, consider the following code which listens for a user to enter the word “done” and then exits the loop:

while True:
    line = input(">") # Read input from the user
    if line == "done":
        break
    print(line)

2.5.6. Cumulative Example - Newton’s Method

Newton’s method is an iterative method for finding successively better approximations to the roots of a real-valued function. It is used when the function is difficult to solve algebraically and is differentiable. In Newton’s method, we start with an initial guess and then use the tangent line to the function at that point to find a better guess.

The following code section applies conditionals, loops, and break statements to calculate a square root using Newton’s method:

while True:
    y = (x + a/x) / 2
    if y == x:
        break
    x = y

Note that the line of code if y == x is dangerous due to comparing floating point numbers. A safer way of implementing this is as follows:

epsilon = 0.0000001
while True:
    print(x)
    y = (x + a/x) / 2
    if abs(y - x) < epsilon:
        break
    x = y