< CSSE 120 More about Mutators

CSSE 120 — Introduction to Software Development

More about Mutators — Description and Examples

Section 6.5.2 of your text (pages 183 - 193) explain the concept of a mutator: a function that mutates one or more of its parameters. This document elaborates with examples.

Background

In class we saw that functions can assign values to their formal parameters, e.g.:

    def nextSquare(x):
        x = x + 1
    return x * x

But we also saw that the calling code cannot see the effect of this assignment:

    y = 8
    next = nextSquare(y)
    print("y is {}, next is {}".format(y, next)

The above prints:

    y is 8, next is 81

This is because the assignment to x in the first line of the body of nextSquare() only changes the value referred to (or pointed to) by x. Informally, it just moves the post-it note for x onto the number 9, but the post-it note for y remains stuck to 8.

By the way, before we continue the discussion of mutators, note two detours:

Returning to our discussion of mutators, we've also seen that we can modify the CONTENTS of a list without using assignment:

    squares = []
    for n in range(10):
        squares.append(n ** 2)
    print(squares)
    # prints:
    # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Here the append() method tells the squares list to add the given square to its "tail". Informally, the squares post-it note remains stuck to the same list throughout the code, but the list is being mutated by the append() method.

We can also mutate a list by assigning to its individual elements:

    numbers = [2,3,5,7,11]
    for i in range(len(numbers)):
        numbers[i] = numbers[i] ** 2
    print(numbers)
    # prints:
    # [4, 9, 25, 49, 121]

In this example the numbers post-it note never moves once it is stuck to the original list. The assignment to numbers[i] in the body of the loop mutates the list by changing elements inside it. It might help to think of the list like an egg carton. We put the numbers 2, 3, 5, 7, and 11 into the first five pockets of the egg carton, then we affix the numbers post-it note to the carton. In the loop we take out each number and replace it with its square, one pocket at a time. The carton and the post-it note never change.

We can use this idea of mutating a list to create a function that changes its parameters. Here's a function that does just that:

    def factEach(nums):
        '''Replaces each element of nums with its factorial.'''
        for i in range(len(nums)):
            nums[i] = factorial(nums[i])  # factorial defined as in class

And some code demonstrating the function:

    numbers = [2, 3, 5, 7, 11]
    factEach(numbers)
    print(numbers)
    # prints:
    # [2, 6, 120, 5040, 39916800]