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 : Gabriel Bigas

2.5.1. Floor Division and Modulus

The floor division operator, //, divides and rounds down to the nearest integer. That integer is returned.

The modulus operator, %, divides two numbers and returns the remainder.

Example:

7 // 3 # floor division.
# answer: 2
7 % 3 # modulus.
# answer: 1

2.5.2. Boolean Expressions

A boolean expression is an expression that is either True or False.

The == operator is used to compare if two values are equal to each other. This should not be confused with the = operator, which is used to assign a value to a variable.

5 == 5 is a boolean expression. It is equal to True, since the value on each sides of the == operator are equal.

Example:

5 == 5
# True

5 != 5
# False

== is a relational operator. The others are:

  • != (not equal)

  • > (greater than)

  • < (less than)

  • >= (greater than or equal)

  • <= (less than or equal)

2.5.3. Conditional Execution

We almost always need to check conditions and make the program act accordingly.

The simplest form of this is an if statement.

The boolean expression that follows if is called the condition. If this boolean expression is true, the indented code will run. If not, the section of code is skipped.

Example:

if 5 > 3:
    print("This will run")

if 2 > 5:
    print("This will not run")

2.5.4. Alternative Execution

A second form of if statements is used when there are two possibilities.

If the if condition evaluates to True, the if block runs. If it evaluates to False, the else block runs instead.

Example:

if x > 0:
    print("x is positive")
else:
    print("x is zero or negative")

2.5.5. Chained Conditionals

Chained conditionals are used when there are more than two possibilities and multiple branches are needed. Branches are the different execution paths that a code can take. Sometimes, depending on the events that take place, certain areas of code will never run. Chained conditionals help control what branches run depending on multiple conditions. elif stands for “else if”.

The chain starts with an if statement, followed by one or more elif statements, and optionally ends with an else statement.

The difference between elif and else: - elif: can only test it’s condition if the prior condition(s) are False. It then checks if it’s own condition is True before running it’s branch. - else: Branch runs if the prior condition(s) are False. No condition.

In chained conditionals, only one branch will run.

Example:

if x > 0:
    print("x is positive")
elif x == 0:
    print("x is zero")
else:
    print("x is negative")

2.5.6. Nested Conditionals

A branch of a conditional can contain another conditional. This can be useful when multiple conditions need to be considered. Example:

if x == y:
    print('x and y are equal')
else:
    if x < y:
        print('x is less than y')
    else:
        print('x is greater than y')

The most important aspect of nested conditionals is indentation. Each nested condition requires an additional level of indentation.

2.5.7. Recursion

It is possible for a function to call another function, but it is also possible for a function to call itself. This practice is called recursion.

For example:

def countdown(n):
    if n <= 0:
        print('Blastoff!') # This is the base case to get out of the recursion.
    else:
        print(n)
        countdown(n - 1)

You can pass n as the argument to this function. Each time it runs, n is decreased and the function calls itself again with the new value of n as the parameter.

The function will run n times and eventually stop once n reaches 0.

When a function calls itself, it is recursive. Recursion can be very useful in certain applications, although sometimes a for loop is a better choice.

Example of running countdown():

countdown(3)
3
2
1
Blastoff!

2.5.8. Infinite Recursion

If a recursive function never reaches a base case, it will keep calling itself indefinitely. This is called infinite recursion and should be avoided. The base case is a condition that stops the recursion. It is written in the function so that, when met, the function does not call itself again, allowing the recursion to end. If infinite recursion occurs, you should review the code and ensure a proper base case is present.

2.5.9. Keyboard Input

Python has a built-in function called input.

Example:

text = input("Please enter your name: ")

When this function is executed, the program pauses until the user types input and presses Enter. The function then returns the string the user typed.

The argument passed to input is printed as a prompt to the user. It is good practice to include a prompt and optionally a newline using \n.

2.5.10. Debugging

When a syntax or runtime error occurs, Python provides an error message describing what went wrong.

It is important to read these error messages carefully and diagnose the correct problem.

Syntax errors are usually easy to find, but some—such as whitespace errors—can be tricky.

Example:

x = 5
 y = 6

In this case, the error message may point to y, but the actual problem is the extra space before it.

The true source of an error can appear earlier in the code where it points. The same is true for runtime errors.

2.5.11. Return Values

Calling a function generates a return value, which is often assigned to a variable or used as part of an expression.

If no return statement is used, the function returns None.

Functions that return values are called fruitful functions.

Example: a function can compute an integer a and return it for use elsewhere in the program.

It is sometimes useful to have multiple return statements, especially when handling multiple conditional branches.

Example:

def absolute_value(x):
    if x >= 0:
        return x
    else:
        return -x

result = absolute_value(-7)
print(result)  # Output: 7

2.5.12. Boolean Functions

Functions can return boolean values, which is useful for hiding complex tests inside functions.

For an if statement using a boolean value, there is no need to write:

if is_divisible == True:

Instead, you can write:

if is_divisible:

Python handles boolean expressions directly.

2.5.13. More Recursion

Example of a recursive factorial function:

def factorial(n):
    if n == 0:
        return 1
    else:
        recurse = factorial(n - 1)
        result = n * recurse
        return result

If n is not a positive integer (for example, a decimal), n may never reach 0 and the function will recurse infinitely.

Recursive functions must always cover all cases to prevent infinite recursion.

2.5.14. Checking Types

Sometimes, you need a specific type of argument for a function. For example, a function may only want an input of type int.

We can use the built-in function isinstance to verify the type of argument. It takes a variable and a type, and returns a bool result (True if they match, False if not).

Example:

x = 10
y = "hello"

print(isinstance(x, int))    # True
print(isinstance(y, int))    # False

2.5.15. Reassignment

It is legal to make more than one assignment to a variable. However, it is important to make sure it’s intentional. If a new assignment is made, the old value is forgotten. Python uses = for assignment. It is tempting to interpret a statement like a = b as equality, but it is simply assigning a the value of b. Reassigning variables is useful, but be cautious as they can make code difficult to read.

2.5.16. Updating Variables

A common kind of reassignment is an update, where the new value of a variable depends on the old. For example:

x = x + 1

It is important to note that you can only update a variable that has a value already. Therefore, it must be initialized.

2.5.17. The while Statement

In programming, repetition is also called iteration.

A while loop runs as long as its condition remains true.

The flow of a while loop is:

  1. Check the condition.

  2. If false, exit the loop.

  3. If true, run the loop body and repeat.

Example:

count = 1

while count <= 5: # The while loop breaks when count is greater than 5.
    print(count)
    count = count + 1

2.5.18. The break Statement

A break statement immediately exits a loop at the point where it is executed.

Example:

while True:
    line = input('> ')
    if line == 'done':
        break
    print(line)

Here, when break runs, the while loop ends and the code continues.

2.5.19. Square Roots

Loops are often used to compute numerical results by iteratively improving an approximation. For example:

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

However, testing floating-point values for equality is dangerous due to approximation errors. Instead, use a tolerance value (epsilon), alongside a safer, built-in function called abs:

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

This approach stops the loop once the values are “close enough.”