Scope

Scope refers to the lines in a program in which a variable name is valid.

The variables in scope correspond to the variables in the function context/frame in our function stack diagrams.

Use Python Tutor to help you understand function stacks.

add1.py

Consider the following program and answer:

  • On what lines are there function definitions?

  • On what lines are there function calls?

  • What variable are in scope on line 7?

  • What variable are in scope on line 12?

  • Can main() access the variable

  • Can add() access the variable

  • What is the output of this program?

wk05 add1

Answers:

  • 5, 9

  • 11 (add), 12 (print), 15 (main)

  • offset, x, y

  • n, out

  • No

  • No

  • The result is 11

wk05 add1 stack

Immutability

  • Immutable means can not be changed.

  • Examples of immutable data types are int, float, bool, and string.

  • We can re-assign immutable types but we can’t change them. For example, we can assign a new string but can’t change the individual characters in one (see below).

  • When an immutable data type is passed to a function, changes to that variable do not persist after the function returns (see add2.py for an example).

>>> text = "apples"
>>> text[0] = "b"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment
>>> text = "bpples"
>>> text
'bpples'
>>> text = "bpples" + "text"
>>> text
'bpplestext'
>>> val = 10
>>> val = 12
>>> val = 12 + 5
>>> val
17
>>> text = "apples"
>>> text[0] = "B"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment

add2.py

wk05 add2

Function stack on line 14 image::wk05-add2-stack.png[]

Mutability

  • Mutable means can be changed.

  • An example of a mutable data type is list

  • We can change mutable types. For example, we can change the elements of a list (see below).

  • When a mutable data type is passed to a function, changes to that variable persist after the function returns (see addList.py for an example). Changes that persist after a function returns are call side effects

>>> text = list("apples")
>>> text
['a', 'p', 'p', 'l', 'e', 's']
>>> text[0] = "B"
>>> text
['B', 'p', 'p', 'l', 'e', 's']

addList.py

wk05 addList

Function stack on line 13

wk05 addList stack

Specifications

When we are working with variables, we must always keep track of what data type they are.

Similarly, when we work with functions, it is important to keep track of

  • the function inputs and their types (aka the parameters)

  • the function outputs and their type

  • any side effects

The best way to keep track of this information is with a function comment. Function comments ensure that users of our function are able to call the function correctly without bugs.

def add(x, y):
    """
    Purpose: return the sum of x and y and an offset
    Parameters: x (float/int) - left operand
                y (float/int) - right operand
    Return (float/int): sum of x + y + 5
    Side effects: none
    """
    offset = 5
    return x + y + offset

def offsetList(values):
    """
    Adds 5 to each element in a list
    Parameters: values (list) - list of values
    Return: none
    Side effects: each element of values is increased by 5
    """
    offset = 5
    for i in range(len(values)):
        values[i] = values[i] + offset

Practice: fancify.py

average.py

wk05 average

positive.py

wk05 positive

This is what the stack looks like on line 21. Notice that the values in the list change. Also notice that the variables i and total take on many values.

wk05 positive stack

The following code doesn’t work. Why?

wk05 positive broken

Answer: for val in numbers is a copy of the values in numbers. To change the values in numbers, we must use numbers[i] to change the value

mathquiz.py

Please see your inclass directory for a solution to math quiz.