Lab 1: Introduction to Python, Part I¶
This lab is adapted from Math 215 Lab 1.
Setting up Google Colab¶
In these labs we will be using Python, which is a powerful, general-purpose programming language that is widely used in science and engineering. It has many libraries and packages available to add on that make it a powerful tool for scientific computing and applied mathematics. Even better, it is a great first language to learn for beginners to computer programming! There are several ways to write programs in Python. In these labs we will be using Google’s Colaboratory notebooks to write our code and create the files we will submit for grading. This allows us to write and run Python programs in an internet browser without the hassle of downloading and installing any software on our computers. This will be described in more detail below.
The first step is to make sure you have a Google account (if you have a Gmail account, you’re done with this step). You can set one up at
https://accounts.google.com/signup
Once your Google account is setup, navigate to the page
https://colab.research.google.com
This will take you to a page with some introductory material about Google Colab. Click the button in the top right corner to sign into your Google account if you are not already signed in.
From the Google Colab welcome page you can navigate through a variety of introductory material to learn about Google Colab, or you can create a new notebook of your own to play around with. We will do the latter and create a new practice notebook in which to work and test our code.
Create a new notebook by selecting
File > New notebook
from the top menu in Google Colab.
Name your notebook Sandbox
.
Your sandbox notebook can be used to test code snippets while you’re learning.
Use Sandbox
in the same way you’d use paper to take notes in a lecture course.
You won’t turn this notebook in; it’s just for your benefit.
Now select
Tools > Settings > AI Assistance
and make sure both options are unchecked. (Generative AI is a very useful tool – and it’s really cool – but it’s more of a hindrance when your goal is to learn a new programming language.)
Running Code in Cells¶
Once you’ve created a new notebook you’ll notice a little box to enter your code underneath the various menus.
This is called a cell
, and it is the basic building block of a Colab notebook.
Any code that you want to execute in a notebook must be placed in a cell.
In your notebook type the following into the cell:
>>> print("Hello World!")
(These three arrows >>>
indicate that the code that follows is something you type into a cell.)
As you might expect, this is a command which tells the notebook to display the phrase Hello world!
below the cell.
In order to tell Python to actually perform this command, we must execute the cell, by holding down the Shift button and pressing Return or Enter.
Execute this cell. You should see the following:
>>> print("Hello World!")
Hello World!
(Code written here without the three arrows is the expected output.)
Congratulations, you’ve just run your first Python program. After running your “Hello World!” command, you should notice that a new cell appears beneath the output of your last cell. You can enter new commands into this cell, and execute them the same way you did in the above cell. You can enter as many commands in a cell as you want, by putting each of them on a separate line. When you execute a cell with more than one command, the commands will be executed one at a time, from top to bottom.
In the cell that was just created write and execute the following two commands:
>>> print("Hello World!")
>>> print("I'm hungry.")
Hello World!
I'm hungry.
Each time you execute a cell, a new cell should be created at the bottom of the notebook.
If at any time you want to create an additional new cell, you can push the +Code
button at the top of the notebook.
You can also move any cell up or down in the notebook, by selecting that cell and pushing the ↑ and ↓ buttons that appear in the top right corner of the cell.
Likewise, you can delete any cell by selecting it first, and then clicking on the 🗑 [trash can] icon that appears in the top right corner of the cell.
At any time you can go back to a previous cell and edit it, and re-execute it as many times as you’d like.
It is this ability to execute your code in small bite-sized chunks, and to go back and forth editing different parts, that makes Colab notebooks an easy way to quickly test out different ideas and pieces of code.
Python Basics¶
Arithmetic¶
Perhaps the most basic use of our notebook is as a fancy calculator, with all of the standard arithmetic operations defined: +
, -
, *
, and /
.
Python follows the usual order of mathematical operations, including the use of parentheses.
For example, to compute \(15 × 3 − 81 ÷ 9\), we would enter
>>> 15 * 3 - 81 / 9
36.0
Note
The output is 36.0
, not 36
, because we used division.
Python now treats the output like a decimal number instead of an integer.
In Python, the decimal number data type is called float
, which stands for floating point number.
The integer data type is called int
.
If we want to force the output to be an int
instead, we can use integer division: //
:
>>> 15 * 3 - 81 // 9
36
This works as expected. Be careful, though: if you use integer division and the result is not an integer, Python will round down:
>>> 7 // 2
3
>>> 7 / 2
3.5
We can compute exponentiation using the **
operator.
For example, we can compute \(2^5\) by typing the following.
>>> 2**5
32
Practice: Compute the values of \((13 − 17) × 6\) and \(2^3 + 21\) in your practice notebook. You should get
-24
and29
respectively as your answers.
Output and print statements¶
As mentioned above, we can include as many statements as we want in a single cell by putting each of them on a separate line. Notice, however, that only the result of the final command is included in the output displayed underneath the cell:
>>> 11+1
>>> 12-11
>>> 3*7
>>> 15 // 3
5
If we’d like to see the output of multiple commands we can use the print
command to make
sure that those commands are included in the output display.
Practice: Enter the following commands in a cell, and execute them. What output do you see?
>>> print(11 + 1) >>> print(12 - 11) >>> print(3 * 7) >>> print(15 // 3)
Variables¶
Just like in mathematics, a variable in Python is a placeholder for some value. For
example, we can define a variable called a
and assign the value 2
to it simply by executing the
following code:
>>> a = 2
After executing this cell, the variable a
can be used in other cells within this notebook, and
when executing these statements Python will replace the variable a
with the value currently
stored there.
>>> a + 15
17
We can also redefine the value of a
at any time in our notebook, and we can even use the
current value of a
when we redefine it.
>>> a = a + 1
>>> print(a)
3
>>> a = a**a
>>> print(a)
27
>>> a = -17
>>> print(a)
-17
Sometimes it is useful to swap the values of given variables. The following does not work. (Try it out!)
>>> x = 2
>>> y = 5
>>> x = y
>>> y = x
>>> print(x,y)
To swap variables, we can introduce a “placeholder” variable as follows:
>>> x = 2
>>> y = 5
>>> print(x, y)
2 5
>>> z = x
>>> x = y
>>> y = z
>>> print(x, y)
5 2
Pratice: Enter the following commands into a cell. What do you expect the output will be? Now, execute the cell and check your answers.
>>> b=5 >>> print(b) >>> b=b+7 >>> print(b) >>> b=3*(5-b) >>> print(b)
We can also use symbols such as <
and >
to compare various quantities and variables. We
can use a double equal sign ==
to test whether two quantities are equal, and <=
and >=
to test
quantities that are less than or equal to, or greater than or equal to each other.
>>> a = 5
>>> print (7 <= a)
False
>>> print(a == 5)
>>> print(a < 10)
True
True
Notice that the commands a=5
and a==5
have different meanings in the above code. In the
first case we are assigning the value of 5
to the variable a
, while in the second case we are
checking the value of a
and testing if it equals the number 5
.
Practice: What will the output of the following cell be?
>>> c=-5 >>> c=c+3 >>> print(c==-5) >>> print(c>=1) >>> print(c==-2)
Finally, notice that variables in Python can represent a variety of objects, not just numbers.
For example, variables can represent strings (str
), which are sequences of characters, or Booleans (bool
)
which are variables that are either True
or False
.
>>> c = "my string"
>>> b = 7 > -2
>>> print(b, c)
True my string
Lab Instructions
Until this point, all of the code you’ve written should be in your Sandbox
notebook.
Create a new notebook called Lab01
.
In these labs, the code you’ll turn in for credit will be labeled Task
.
Write the code for each Lab 1 task in your Lab01
notebook.
For future labs, create a new notebook each time.
Task 1¶
Enter the expression
and store it as a variable called my_first_var
.
Remember to use parentheses to ensure that the order of operations is correct.
Don’t just save the numerical value of this expression,
which is 20
. Save the actual expression with the addition, multiplication, division, subtraction, and parentheses as the variable.
Functions, Part 1¶
In computer programming, like in mathematics, a function is an object which accepts as input values from some set, and produces output which depends both on the input values and some given rules. In Python we illustrate how to define simple functions with the following example.
Type the following into a cell, and execute it.
def reciprocal(n):
# A function that takes the reciprocal of the input n.
return 1/n
Here we have defined a function called reciprocal
, which has a single input parameter n
. The
first line of the function definition begins with def
, followed by the name of the function, the
parameters it accepts in parentheses, and ends with a colon. Each line in the remainder of
the function must be indented (which Colab will do for you automatically), and the function
definition ends with a return
statement that defines what the output of the function will be. It
is customary to put a docstring directly below the def statement, which is a comment designed
to describe the purpose of the function to the user.
(A comment is anything written after a #
; Python will ignore it.)
In the case of our function reciprocal
, it
accepts a single value n
as its input, and it returns the value 1/n
as its output. To evaluate our
function on a given input, we write it much as one might expect:
>>> reciprocal(13)
0.07692307692307693
>>> a = 2
>>> reciprocal(a)
0.5
Warning
What do you think will happen if we try:
>>> reciprocal(0)
You should have received an ugly error message when you tried to evaluate reciprocal(0)
,
as a result of trying to divide by zero. Python will produce an error message anytime you try to
execute code that violates one of its rules. Learning to interpret error messages is an important
part of becoming a good programmer. Be warned though, just because you don’t
get an error message when you execute your code doesn’t mean that your code is doing what
you want it to be doing. This is why we will always test our code with various input values.
Our functions can also include more lines of code inside of them, which dictate which steps to perform before returning the output of the function. We can also define new variables inside of a function. In this case, each step in the function should be on its own line, indented from the first line of the function.
Practice: Define the following function in your practice notebook. Remember to indent all of the lines in the function definition from the second line on! Proper use of indentation and whitespace is very important in Python.
def arithmetic(i): j=i+2 k=3*j w=k-5 return wWhat output do the following commands produce? (Try to figure it out before you run the code.)
>>> print(arithmetic(3)) >>> print(arithmetic(-10))
Task 2¶
Define a function called arithmetic2(i)
which does exactly the same thing
as the function arithmetic(i)
defined above, but which only has a def
line and
a return
statement. In other words, write a function that does the exact same thing as
arithmetic(i)
, but which fits in only two lines of code.
Test your Code
Whenever you are instructed to write a function in these labs, we will include some test code that you can run to make sure your code is working properly. This is a very important step in programming – don’t skip it!
>>> arithmetic2(3)
10
>>> arithmetic2(-10)
-29
Functions, Part 2¶
One item to note in the arithmetic
example is how variables are treated by Python when they
are defined inside of a function (like the variables j
, k
, and w
above). They are examples of
local variables, which are defined and can only be accessed from within the function itself. For
example, when calling the function arithmetic(3)
, the intermediate variable k
is assigned the
value of 15
as part of the evaluation. However, as soon as the function finishes evaluating, the
variable k
and its value are immediately discarded, and can no longer be accessed. Trying to
access it will result in an error message, indicating that we did something wrong:
>>> arithmetic(3)
10
>>> k
NameError: name 'k' is not defined
We can define functions that accept multiple values as inputs, functions that output multiple return values, and functions that call other functions when they are being evaluated.
def multiply(x,y):
return x*y
>>> multiply(3,7)
21
def sum_diff(x,y):
return x+y, x-y
>>> sum_diff(3,7)
(10, -4)
def mult_add(x,y):
w = multiply(x,y)+x # Here we call the function multiply that we defined earlier.
return w # Make sure that the cell containing the definition of multiply has already been executed.
>>> mult_add(3,7)
24
Task 3¶
Define a function called
triple(y)
which takes a valuey
as input, and outputs3y
.Define a function called
avg(x,y)
which takes two valuesx
andy
as input, and outputs the mean ofx
andy
. Recall that the mean of two numbers \(a\) and \(b\) is defined to be \((a+b)/2\).Define a function called
combine(x,y)
which takes a pair of input valuesx
andy
, and finds the mean ofx
and3y
. The functioncombine(x,y)
should call both of your functionstriple(y)
andavg(x,y)
in its definition.
>>> triple(10)
30
>>> avg(5, 25)
15.0
>>> combine(6,5)
10.5
Lists¶
So far, we have seen the int
, float
, str
, and bool
data types.
Another very important data type in Python is the list
data type. A list is an ordered
collection of objects (which can be numbers, strings, or even other lists), which we specify by
enclosing them in square brackets []
.
>>> my_list=["Hello",91.7,"world",15,100,-10.2]
Here the list my_list
contains two strings, two floats (decimal values), and two integers. We
can access any of the elements in a given list, or any subset of the elements by indexing and
slicing. The elements in a list are all labeled from left to right with an integer index, starting
at zero. For example, the first element in my_list
is "Hello"
which has index 0
, the second
element is 91.7
and has index 1
, and so on. To access any of the individual objects in the list,
we use a pair of square brackets []
as in the following example.
>>> my_list[0]
Hello
>>> my_list[4]
100
Warning
An important thing to remember is that Python begins indexing elements of a list starting
at 0
. This may seem unusual at first, since humans typically start counting objects with the
number 1
.
We can also access elements from the end of a list by using negative numbers.
>>> my_list[-1]
-10.2
>>> my_list[-3]
15
If we would like to access a range of characters in a list, we can slice the list L
using the
notation L[start:stop]
, where start
and stop
are both integer index values. Using
this command will return all of the objects in L
that are between the positions start
and stop
.
It will include start
and exclude stop
.
>>> L = [0,1,2,3,4,5,6]
>>> L[3:6]
[3,4,5]
>>> L[-3:-1]
[4,5]
By not specifying a starting or stopping index, Python returns the elements starting at the beginning of the list, or stopping at the end.
>>> L[:4]
[0,1,2,3]
>>> L[3:]
[3,4,5,6]
>>> L[-2:]
[5,6]
Warning
There is something you will need to be careful about when using lists in Python, and in
particular when you are trying to copy a list. Suppose I create a list, called list_a
with the
values [1,2,3]
. Suppose I then create a second list list_b
, and assign it the value of list_a
.
As expected, when we print the values of list_b
Python returns the list [1,2,3]
.
>>> list_a=[1,2,3]
>>> list_b=list_a
>>> print(list_a)
>>> print(list_b)
You might expect that what we’ve done above is to create two separate lists, list_a
and list_b
,
both of which happen to have the same values. However, we have actually only created a single
list, but given it two different names list_a
and list_b
to reference it by! For example, if we
change one of the entries in list_b
, we will also be changing the list list_a
.
>>> list_b[0]=100
>>> print(list_b)
[100,2,3]
>>> print(list_a)
[100,2,3]
There are several ways to create a new copy of a list, which will avoid this behavior. One is
by using the command list_a.copy()
, which we illustrate below.
>>> list_a=[1,2,3]
>>> list_b=list_a.copy() # Here we create a separate copy of list_a, and assign it to list_b.
>>> print(list_a)
[1,2,3]
>>> print(list_b)
[1,2,3]
>>> list_b[0]=100 # Now this only changes list_b.
>>> print(list_a)
[1,2,3]
>>> print(list_b)
[100,2,3]
Finally, we can change lists in a number of ways. One way is to use the index of a list element to access that element and to redefine it directly.
>>> my_list=[1,2,3,4]
>>> my_list[2] = -15
>>> print(my_list)
[1,2,-15,4]
Task 4¶
Write a function
first(c)
which accepts as input any listc
, and outputs the first element in the listc
.Write a function
first_last(c)
which accepts as input a listc
, and outputs two values, the first element and the last element ofc
(in that order).Write a function
middle(c)
which accepts as input a listc
, and outputs a list which is the same asc
except that the first element and the last element have been removed.
>>> w=[1,2,3,4,5]
>>> first(w)
1
>>> first_last(w)
(1, 5)
>>> middle(w)
[2,3,4]
Task 5¶
Define a function swap(c)
which accepts a list c
with two or more elements,
and returns another list which is the same as c
except that the first and last elements are
switched.
The first line of code in your swap
function should be
copied_list=c.copy()
The rest of your function should only reference copied_list
so that the original list c
remains unchanged.
>>> A = [0,1,2,3,4,5]
>>> swap(A)
[5,1,2,3,4,0]
>>> A
[0,1,2,3,4,5]
Conditionals¶
So far we have enough tools to create functions which perform arithmetic operations and
rearrange lists, but not much else. To define more complicated functions we will need a few
more building blocks. We will end this lab by talking about if
statements, and will learn about
for
loops in the next lab. We introduce if
statements with the following example.
if 1<7:
print("1 is less than 7")
else:
print("1 is not less than 7")
All if
statements start with a condition, or question, whose answer may be either True
or
False
. In our case, this question is asking whether the number 1
is less than 7
. When Python
executes the if
statement it first checks to determine whether the condition is True
or False
.
If the condition is True
then Python will continue and execute the code which is contained
immediately below the if
statement line (this code needs to be indented). If, on the other
hand, the condition is False
, then Python will jump immediately to the else
line and execute
the indented block of code below it, skipping over any commands in between.
In our case, because 1 is indeed less than 7, Python will execute the line after the if
statement, and will print the following output.
1 is less than 7
Note that if
statements do not need to be followed by else
statements. If an if
statement
is not followed by an else
statement, and the condition contained in the if
statement is False
,
then the code won’t do anything:
if 1>7:
print("1 is greater than 7") #This won't execute since 1>7 is False.
Notice that we can also write if
statements that contain more than one step. Every step that
we want to be evaluated should be indented beneath the if
line or the else
line (depending on
if we want it to be evaluated when the condition is True
or False
respectively).
What will the following code output? And what will the value of a
be when the code is finished executing?
a=-5
if a==7:
print("a was equal to 7") # Both of these indented lines will be
a=4 # evaluated if a is equal to 7.
else:
print("a was not equal to 7") # Both of these indented lines will
a=7 # be evaluated if a is not equal to 7.
The most important use of conditional statements is in function definitions. Consider the following functions.
def f(x):
if x < 0:
return 0
else
return x
Every time we call the function f(x)
only one of the two return
statements is
being executed, while the other is simply skipped over depending on whether the if
evaluates
the condition to be True
or False
.
>>> f(7)
7
>>> f(-100)
0
Task 6¶
Write a function called absolute_value(x)
which accepts as input a single
number x
, and returns the absolute value of x
.
>>> absolute_value(10)
10
>>> absolute_value(-10)
10
Compound Conditions¶
To test more complicated conditions it is useful to use the and
and or
operators. The statement P and Q
will return True
only if both P
and Q
are True
. If either one of, or both of, P
and
Q
are False
, then the statement P
and Q
will return False
.
(10<11) and (-3>=-12) # This will return True because both (10<11) and (-3>=-12) are True.
(10<11) and (-3==-12) # This will return False because one of the statements is False.
(10==11) and (-3==-12) # This will also return False because both of the statements are False.
The statement P or Q
, on the other hand, will return True
if at least one of, or both of, P
and Q
are true. The only situation in which P or Q
will return False is if both P
and Q
are
False.
(10<11) or (-3>=-12) # This will return True because at least one of the statements is True.
(10<11) or (-3==-12) # This will return True because at least one of the statements is True.
(10==11) or (-3==-12) # This will return False because both of the statements are False.
Task 7¶
Define a function, called indicator(lower,upper,n)
which accepts as input
three numbers lower
, upper
, and n
, with lower <= upper
, and returns 1
if the number n
satisfies lower <= n <= upper
, and returns 0
otherwise.
>>> indicator(3,7,2)
0
>>> indicator(-3,9,8)
1
Task 8¶
Define a function, called trunc_max(x,y)
which accepts as input two numbers
x
, y
, and returns the larger of the two numbers if at least one of them is positive, and
returns 0
otherwise.
>>> trunc_max(3,-5)
3
>>> trunc_max(2,7)
7
>>> trunc_max(-173,-21)
0
Hint
You may need to use multiple if
statements, possibly nested inside each other. Remember that every time you call an if
statement, you need to indent the code inside the
if
statement.
Here is some “pseudocode” to get you started:
if both numbers are negative:
return 0
else:
if the first number is larger than the second:
return the first number
else:
return the second number