## Week 6: Lists; More Functions

### Week 6 Goals

• Learn to represent data using lists

• Learn about list indexing other operations

• Learn how lists are used by functions

• Learn how characters are represented using ASCII encoding

### Get Week 6 In-class Code

To copy over the week 6 in-class example programs, do the following (If you have trouble with either of these steps, ask a Ninja or your professor for help):

1. Create a w06-lists subdirectory in your `cs21/inclass` directory, and cd into it:

``````\$ cd ~/cs21/inclass
\$ mkdir w06-lists
\$ cd w06-lists
\$ pwd
2. Copy over the week 6 files into your `w06-lists` subdirectory (check that they copied successfully copied by running `ls`:

``````\$ cp ~admin21/public/w06-lists/*.py ./
\$ ls
ascii.py biggest_circle.py largest.py lists.py list_functions.py``````

### Week 6 Code

• `largest.py`: more practice with functions

• `lists.py`: practice with lists and list operations

• `list_functions.py`: practice with functions that use lists

• `biggest_circle.py`: functions that use lists and graphics

• `ascii.py`: examples of using character encoding

### Week 6 Concepts

#### Lists

Until now, we have seen that a variable can hold a single value, e.g. if we set the variable `x` equal to 5, then `x` only holds the value 5.

A list is a variable that can hold multiple values, which are stored in an ordered manner.

In the following code, we use the bracket notation to create a list called `nums` that holds the values 5, 6, 4, and 2, in that order:

``````nums = [5, 6, 4, 2]
print(nums) # prints [5, 6, 4, 2]``````

We can access individual elements of a list using a 0-based index:

``````nums = [5, 6, 4, 2]

print(nums[1]) # prints 6

nums[0] = 11
print(nums) # prints [11, 6, 4, 2]``````

We can also get the number of elements in a list using the `len` function:

``````nums = [11, 6, 4, 2]
print(len(nums)) # prints 4``````

#### Working with Lists

We can iterate over the elements of a list in the same manner that we did with strings: either by iterating one element/character at a time, or by using the indices within the valid range to get each element/character by its index.

The following two for-loops produce the exact same output:

``````dogs = ['snoopy', 'bluey', 'pluto']

for dog in dogs:
print(dog + " is a good dog")

for i in range(len(dogs)):
print(dogs[i] + " is a good dog")``````

We can add elements to the end of a list using the `append` method:

``````dogs = ['snoopy', 'bluey', 'pluto']

dogs.append('underdog')

print(dogs) # prints ['snoopy', 'bluey', 'pluto', 'underdog']``````

When are also able to concatenate two lists in order to create a larger list. Note that this does not change either of the two lists, but rather creates a new one:

``````weekdays = ['mon', 'tue', 'wed', 'thu', 'fri']
weekend = ['sat', 'sun']

week = weekdays + weekend

print(week) # prints ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']``````

Often we may want to start with an empty list, i.e. one containing no elements, and then add some number of elements to it. The following code asks the user how many elements to add, then appends elements as they are provided:

``````songs = []
n = int(input("How many favorite songs do you have? "))
for i in range(n):
song = input("Tell me one of your favorite songs: ")
songs.append(song)
print(songs) # prints all songs in the list``````

#### Passing Lists to Functions

Lists can be passed as arguments to function. The parameter of the function will refer to the entire list.

The following function calculates the sum of the values in the list that is passed as an argument:

``````def sum(lst):
total = 0
for i in range(len(lst)):
total = total + lst[i]

An important difference between lists and other variables is that when a list is passed to a function, the function can modify the list, whereas it cannot modify arguments such as ints, floats, and strings.

For instance, consider the following function, which is attempting to change the value that is sent to it:

``````def change(x):
x = 0``````

Now let’s say we call this function as follows:

``````a = 5
change(a)
print(a) # prints 5``````

The code still prints 5, because the `change` function has only changed the value of the parameter `x`, not the value of the argument `a`.

However, lists behave differently when passed to functions:

``````def change_list(lst):
lst[0] = 0
lst.append(17)``````

Now when we call this function, the list is changed:

``````nums = [5, 7, 9]
change_list(nums)
print(nums) # prints [0, 7, 9, 17]``````

This happens because the parameter `lst` and the argument `nums` are aliases for the same list. This means that the list has two names: `lst` and `nums`.

Let’s take a look at the stack diagram to see why this happens!

First, here is what the stack diagram looks like for the code that calls `change_list`: the `nums` variable refers to the list containing [5, 7, 9]:

When `change_list` is called, we pass `nums` as the argument. This means that the value in the box labeled `nums` is copied to the box labeled `lst`, i.e. the parameter of the `change_list` function. What’s in the box labeled `nums` is the arrow pointing to the list, so now `lst` has an arrow pointing to that list, too.

Now when `change_list` runs the first line of code — `lst[0] = 0` — we change what is in the box for element #0 of the list. So the arrow now points to 0 instead of 5.

Next, when `change_list` runs the second line of code — `lst.append(17)` — a new box is added to the list, and it points to 17.

Finally, when `change_list` returns and we go back to `main`, the variable `nums` is still pointing to the same list, which has been updated by `change_list`. This is why `nums[0]` is now 0 instead of 5.

#### Character Encoding

Any piece of data that we use in our programs has two attributes: its value and its type.

For instance, if we have `x = 8`, then the variable `x` has the value 8 and the type "int".

Even the literal `1.7` has a value 1.7 and type "float".

The data’s value is always stored as a number, and the type determines which operations are legal and how they function.

But what about strings? For instance, how is "bingo" stored as a number?

Recall that a string is a sequence of individual characters, and though a string is not the same as a list, we can think of it as storing the individual characters "b", "i", "n", "g", and "o".

Then how are those characters' values stored as numbers?

To represent the individual characters, Python encodes them using an agreed-upon convention or standard that assigns numbers to individual characters, including letters of the alphabet but also punctuation, whitespace, and numerical characters such as `"7"`.

A popular standard for encoding characters is ASCII, which was developed in the 1960s and is still commonly used today.

In Python, we can find the encoding of an individual character by using the `ord(ch)` function, which returns the ASCII encoding of the character `ch`:

``````letter = "k"
print(ord(letter)) # prints 107, which is the ASCII encoding of "k"``````

We can also go the other direction using the function `chr(num)`, which returns the character that has `num` as its encoding:

``````n = 63
print(chr(n)) # prints "?", which has 63 as its ASCII encoding``````