CS 111 f21 – Scope; tuples; mutability and assignment

1 VS Code execute directory setting

If you're getting errors with files not being found when running your code, there is a VS Code setting you can change that will probably fix them.

Go to File->Preferences->Settings (Code->Preferences->Settings on Mac) and enter python.terminal.executeInFileDir in the search box at the top. A single setting should come up that looks like this:

vs-code-setting.png

Check that box, and you should be good to go.

2 Practice

Let's say we want to write a function all_positive that takes in a list of numbers and returns True if all the numbers in the list are positive (and returns False otherwise). For each version of this function given below, briefly describe what the function actually does (i.e., what it returns in terms of the parameter nums). You should assume that the parameter will be a non-empty list of ints. Note: zero is not considered a positive number.1

 def all_positive1(nums):
     acc = 0
     for num in nums:
         acc = acc + num
     if acc > 0:
         return True
     else:
         return False

def all_positive2(nums):
    for num in nums:
        if num > 0:
            return True
        else:
            return False

def all_positive3(nums):
    for num in nums:
        if num <= 0:
            return False
    return True

Write a function powers_of_2 that takes in a list of numbers (bases) and returns a new list where each element is 2 raised to the power of the corresponding element of bases. For example, powers_of_2([1, 3, 5]) should return [2, 8, 32]. The original list should not be modified.2

To create a new, empty list, use [], as in

result = []

To add an element to a list, use the append method, as in

result.append(5)

3 Tuples

  • list: sequence of arbitrary elements, elements can be added, removed, overwritten (mutable)
  • string: sequence of characters (single letters or symbols), elements are fixed (immutable)
  • tuple: sequence of arbitrary elements, elements are fixed (immutable)
    • a_list = ["a", "b", "c"]
    • a_str = "abc"
    • a_tuple = ("a", "b", "c")
  • tuples can do everything lists can do except item assignment
    • Why?
      • efficiency (technical reasons are beyond the scope of this course)
      • safety
        • for example, if you are representing locations in latitude and longitude, this data should always come in pairs

4 Scope

4.1 Mystery

x = 5
def square(x):
    x = x * x
    return x
y = 10
print(square(y))
print(y)
print(x)

what if we remove x = 5?

4.2 The scope of a variable refers to the part of a program where that variable exists

4.2.1 Practice

def cube(x):
    x2 = x * x
    x = x2 * x
    return x
for num in range(4):
    if x % 2 == 0:
        x = cube(num)
    print(x)
print(num)
print(x)
print(x2)

Need to add initial value for x

5 Aliasing

5.1 Mysteries

vec = [5,5,5]
q = vec
q[1] = 7
print(vec)
vec = [5, 5, 5]
q = vec
vec = [1, 2, 3]
print(q)
def zero(vec):
    for i in range(len(vec)):
    vec[i] = 0
vec = [1,2,3]
print(zero(vec))
  • looking at these examples with pythontutor.com, we can see that the immediate value of a list variable in memory is an arrow to the actual list
    • when we assign a new variable to a list or give a list as input to a function, it's this arrow that is used

5.2 Deep dive

name = "Aaron"
first_name = "Aaron"

print("name", id(name))
print("first_name", id(first_name))
print("Aaron", id("Aaron"))

print()
name = name + "!"
print(name, id(name))
print(first_name, id(first_name))

print()
print("mutable example:")
ys = [1, 2, 3]
xs = [1, 2, 3]
print("ys", id(ys))
print("xs", id(xs))
ys.append(5)
print("ys", ys, id(ys))
print("xs", xs)
zs = ys
print("zs", id(zs))

print()
def append10(nums):
    print("nums", id(nums))
    nums.append(10)

append10(ys)
print("ys", ys, id(ys))

print()
def addfun(s):
    print("s", s, id(s))
    s += "!"
    print("s", s, id(s))

course = "111"
print("course", course, id(course))
addfun(course)
print("course", course, id(course))

Footnotes:

1
  • all_positive1: computes the sum of integers in nums and returns True if this sum is positive, otherwise returns False
  • all_positive2: returns whether the first element of nums is positive
  • all_positive3: returns True if all elements of nums are positive (by returning False if any are non-positive)
2
def powers_of_2(bases):
  result = []
  for base in bases:
    result.append(2**base)
  return result