Day 2 - Lists & User defined functions

Date: 01/07/2020
Time: 12:00 PM - 3:00 PM
Location: Hostos Community College - A-534


Introduction to Lists

Lists are a type of data structure that allows you to store any type of data sequentially. A data structure is a way or organizing data for effective/efficient use and/or storage. Lists are the first data structure we will be going over in this boot camp. Later on, we will touch on sets and dictionaries. There are many data structures in computer science, some are not built into Python so you'd have to implement them yourself. This is beyond the scope of this boot camp given the amount of time we have left. So let's start with lists.

If you come from a C++ background, you may have used vectors or dynamic arrays. Lists work in a very similar fashion to those two. You store the data sequentially and you access the data with an index. Here's a little diagram showing you how the indices work.

The value of the indices are on top, whereas the value stored inside the list is inside the box. The bottom numbers are the negative indices. They're another way of accessing the data inside a list. Let's see how we can declare a list in Python.
To make an empty list, you just have to use square brackets like this:

my_list = []

This is an empty list with nothing inside. We can fill the data when we create the list by seperating each value inside the square bracket with commas like such:

my_list = [1, 10, 20, 25, 38, 45.27, 57]

Now that we've created the list, Python has a nice built in function called len() to tell us the length of the list. Let's see it in action:

my_list = [1, 10, 20, 25, 38, 45.27, 57]
print(len(my_list)) # this will print 7

Be warely of the index values! The length of the list may be 7, but the last index in the array is 6. Let's talk a little more about indices and how we can use them.

Indices

As stated earlier, Python will store the value sequentially and we can access each element by their index. These indices can go backwards or forwards, but let's see the traditional index values first.

Note that traditionally, the first index of a list is always 0. It is the same as most other programming languages, except for in MATLAB. In computer science, we often start with the first index being 0. In Mathematics, traditionally matrices start with index 1. we will use the list we created above and perform some operations with their indices.

my_list = [1, 10, 20, 25, 38, 45.27, 57]
answer = my_list[0] + my_list[2]
print(answer) # this will print 21

When we access my_list[0] we care acccessing the first element of the list. When we access my_list[2], we are accessing the third element of the array. The first element is 1 and the third is 20. That makes their sum 21.

Python allows us to also use the indices in a list. Let's try to traverse or iterate through and print a list by the list's index.

for index in range(0,len(my_list)):
    print(my_list[index])

The range function will stop at len(my_list) - 1, which is perfect because our last index is also len(my_list) - 1. I know that in C++, many of you have used a similar for loop to print an array, however, Python makes things super easy for you by allowing the print() function to also work with lists. In other words, we can do the same thing in one line of code by typing:

print(my_list)

Lists in Python has a few more interesting and useful functions that we can take advantage of that we will talk about in a later section.

We can also slice a list by it's index. Let's say we wanted the first three elements of our original list to be put into a smaller sublist. We can do that with the following code

mini_list = my_list[:3]

You can read that as mini_list = my_list up to index 3. Say we wanted to make another mini_list, and this time, we wanted our second mini-list to be everything after the third element in our original list. We can do it in a similar fashion like this:

second_mini_list = my_list[3:]

This is just saying we want the contents of second_mini_list to be everything after the third element in my_list. It's similar to MATLAB if you've ever used MATLAB.

Python lists have many useful built-in methods, so let's talk about some of the basic ones.

Basic List Methods

Here is a list of some of the basic built-in methods of lists.

We most likely won't be using sort() and reverse() all too much during this boot camp, since it's good practice to learn how to reverse a list manually and to know a few different sorting algorithms. We'll be covering some sorting algorithms towards the end of the course (merge sort and maybe quick sort).

Again, this isn't the full list of built-in methods, but these are the basic ones that we'll use at least once throughout this boot camp. Now that we've done the introduction to lists, we can do some programming challenges and practice with them.

Defining Functions in Python

To general way to define a function is as such:

def my_function(arguments):
    do something     return result # optional

Functions in programming are a way of abstracting pieces of code so that it can be repeated again, and again with only the argument changing. This allows us to write programs more efficiently, as we won't have to write repeated code over and over again.
as a simple example let's implement the function f(x) = x2+1. This can easily be done in Python.

def f(x):
    return x**2 + 1

The return of a function, as the name implies, is what the function returns? I'm not sure if that makes sense, but it is the final output of the function after it finishes running. In Python, you can have more than one return. For example, if we wanted to modify the above function to return both x2+1 and x2-1 (in that order), we can do the following:

def f(x):
    first_ans = x**2 + 1     second_ans = x**2 - 1     return first_ans, second_ans

And then there are times where you manipulate the input argument rather than having a return
As an example, let's implement a function that takes in a list of integers as the input argument. The function replaces the first element of the list with the number 10 (if the first element exists).

def my_function(my_list):
    my_list[0] = 10

As you can see, there is no return to this function, all it does is takes the input list and changes the first element to 10.
HOWEVER
When we test any kind of code, we have to consider the edge cases. That is, we have to see the behavior of the function when an input is unexpected. In the case of our code above, if we put an empty list into this function, the function will throw an error. The error will tell you something along the lines of: IndexError: list index is out of range. This means that index 0 does not exist in the list (it's empty). To fix this, we have to add an if statement. We should only attempt to change the first element to 10, when there is a first element to even change.

def my_function(my_list):
    if len(my_list) > 0:         my_list[0] = 10

And that's it! Let's try doing some programming challenges that involves functions.