Welcome back! Hopefully now you should be comfortable with some basic Python syntax. Let's get into something a bit more interesting today: control structure! This allows you to actually build up your code.
Today we will go over if statements, for loops, and functions, and then we will do a debugging exercise.
As last time, let's start by importing numpy as np
import numpy as np
This is a conditional statement where the code will proceed only if the condition is met. Otherwise the code will stop or move on to the next condition.
The condition in an if
statement is a comparison that produces True
or False
(boolean). Here's a reminder of all the boolean operators you will probably be using:
== equal to
!= not equal to
< less than
<= less than or equal to
> greater than
>= greater than or equal to
The syntax for if
statements is the following:
if condition_is_met:
do something
Note the indentation of the second line! Python is very picky about this, though some other coding languages are not.
Now if you want to give the code a different option if the first fails, use else
.
if condition_is_met:
do something
else:
do a different thing
Thus, the code will only move to else
if the first condition is false. To include multiple options, use elif
, short for 'else if'.
if condition_is_met:
do something
elif different_condition_is_met:
do something else
else:
do another thing
Notice the way that things are indented. Each of the actions belonging to a conditional statement is indented below it. Also make sure you don't forget the colon (:
) at the end of each conditional line!
# solution here
if 1 == 1:
print("yes!")
if 1 != 1:
print("no!")
yes!
You probably noticed that the code stopped after printing "yes!", since the statement is false. If we don't want the code to stop, we would put in an else statement.
Try it again:
#solution here
if 1 != 1:
print("1 does not equal 1??!!")
else:
print("1 always equals 1, duh")
1 always equals 1, duh
b = 10
. Write an if
statement that checks if b is equal to 10 or 2 (all on one line), and if so, print the value of b.¶# solution here
b = 10
if b == 10 or b == 2:
print(b)
10
Like we mentioned yesterday, the syntax of arrays and indices can all be combined.
# solution here
linarray = np.linspace(0, 1, 10)
if linarray[-1] < 1:
print(linarray[-1])
else:
print(linarray[-1], "is not < 1")
#print("%i is not < 1" % linarray[-1])
1.0 is not < 1
For loops allow you to loop through all the values in an array and perform some operation or check a condition.
The basic syntax is "for x in arrayname."
for x in arrayname:
do something
"x" refers to each element within your array, so "x" could have been any random character, but "arrayname" has to be the actual array or list you're looping over.
For example:
shrek = ['Shrek', 'Donkey', 'Fiona', 'Lord Farquaad']
for name in shrek:
print(name)
Shrek Donkey Fiona Lord Farquaad
bikinibottom = np.array(['Gary', 'Spongebob','Patrick', 'Squidward', 'Sandy'])
# solution here
for friend in bikinibottom:
print("Barnacles,", friend + "!")
Barnacles, Gary! Barnacles, Spongebob! Barnacles, Patrick! Barnacles, Squidward! Barnacles, Sandy!
Another way to write a for loop is to loop over the indices of the array or list. This allows you, for instance, to index multiple arrays, or to keep track of both the index and the value of an array. You'll see what I mean in a minute. If you do it this way, the syntax goes like this:
for i in range(len(array)):
do something to array[i]
len(array)
gives you the length of the array. Feeding that number into range()
returns a list of indices of that length.
Now "i" is the index value rather than the value of the array. Here's an example:
array = np.linspace(0, 10, 21)
for i in array:
print("a =", i)
for i in range(len(array)):
print("the", i, "th value of array is", array[i])
a = 0.0 a = 0.5 a = 1.0 a = 1.5 a = 2.0 a = 2.5 a = 3.0 a = 3.5 a = 4.0 a = 4.5 a = 5.0 a = 5.5 a = 6.0 a = 6.5 a = 7.0 a = 7.5 a = 8.0 a = 8.5 a = 9.0 a = 9.5 a = 10.0 the 0 th value of array is 0.0 the 1 th value of array is 0.5 the 2 th value of array is 1.0 the 3 th value of array is 1.5 the 4 th value of array is 2.0 the 5 th value of array is 2.5 the 6 th value of array is 3.0 the 7 th value of array is 3.5 the 8 th value of array is 4.0 the 9 th value of array is 4.5 the 10 th value of array is 5.0 the 11 th value of array is 5.5 the 12 th value of array is 6.0 the 13 th value of array is 6.5 the 14 th value of array is 7.0 the 15 th value of array is 7.5 the 16 th value of array is 8.0 the 17 th value of array is 8.5 the 18 th value of array is 9.0 the 19 th value of array is 9.5 the 20 th value of array is 10.0
Combo time! You can also embed if statements into for loops, which checks the conditional statement for every value of the array.
np.array
to create an array containing the values [0.5, 2, 3, 7].¶for
loop that goes through each element of the array and adds two.¶if
and elif
inside the for
loop to check if the value is now less than 5, equal to 5, or greater than 5. If a condition is satisfied, have it print that (e.g. '4 < 5').¶#solution here
# A
array2 = np.array([0.5, 2., 3., 7.])
# B and C
for x in array2:
b = x+2.
if b < 5:
print(b, "< 5")
elif b == 5.:
print("%i = 5" % float(b))
elif b > 5.:
print("%i > 5." % float(b))
2.5 < 5 4.0 < 5 5 = 5 9 > 5.
This is where the true programming comes in. Basically any code you write will be a series of functions that accomplish some task. Functions include mathematical expressions, list/array sorting, statistical operations, and many more.
The syntax goes like this:
def function(a, b, c):
do something with a, b, and c
return something
First you define the function using "def". The definition of the function includes the name of the function and the arguments required for the function to work. You should leave the arguments as variables, and you will give the variables values when you call the function to use it.
Inside the function, some operation will be performed on the variables you've provided. However, the function won't actually give you any output unless you use return. Return tells the function what to give you back.
Here's an example:
def line(x, m, b):
y = m * x + b
return y
Now, to run the function, you call its name and then supply values for the arguments:
my_x = 1
my_m = 2
my_b = 3
one_value = line(my_x, my_m, my_b)
print(one_value)
#Confirm this is doing what we think
print(2*1+3)
5 5
You can feed the function an array as an argument as well. It will calculate an answer for each element of the array and make an array of outputs.
xarray = np.linspace(0, 5, 100)
array_of_values = line(xarray, 1, 2)
print(array_of_values)
[2. 2.05050505 2.1010101 2.15151515 2.2020202 2.25252525 2.3030303 2.35353535 2.4040404 2.45454545 2.50505051 2.55555556 2.60606061 2.65656566 2.70707071 2.75757576 2.80808081 2.85858586 2.90909091 2.95959596 3.01010101 3.06060606 3.11111111 3.16161616 3.21212121 3.26262626 3.31313131 3.36363636 3.41414141 3.46464646 3.51515152 3.56565657 3.61616162 3.66666667 3.71717172 3.76767677 3.81818182 3.86868687 3.91919192 3.96969697 4.02020202 4.07070707 4.12121212 4.17171717 4.22222222 4.27272727 4.32323232 4.37373737 4.42424242 4.47474747 4.52525253 4.57575758 4.62626263 4.67676768 4.72727273 4.77777778 4.82828283 4.87878788 4.92929293 4.97979798 5.03030303 5.08080808 5.13131313 5.18181818 5.23232323 5.28282828 5.33333333 5.38383838 5.43434343 5.48484848 5.53535354 5.58585859 5.63636364 5.68686869 5.73737374 5.78787879 5.83838384 5.88888889 5.93939394 5.98989899 6.04040404 6.09090909 6.14141414 6.19191919 6.24242424 6.29292929 6.34343434 6.39393939 6.44444444 6.49494949 6.54545455 6.5959596 6.64646465 6.6969697 6.74747475 6.7979798 6.84848485 6.8989899 6.94949495 7. ]
#solution here
def quad(x, m, b):
fx = m * x**2 + b
return fx
quad(3, 2, 4)
22
A surprisingly large part of research is making pretty plots, so let's explore that now!
To do some plotting, we will need to import the matplotlib package. Matplotlib is a mathematical plotting library containing most of the functions you will ever need to plot something. You will need to use matplotlib.pyplot, which most people import as plt.
import matplotlib.pyplot as plt
Making a basic plot with this is quite simple. The only required arguments are x-values and y-values, and anything else is #aesthetic.
So the syntax is like this:
plt.plot(x, y, other, optional, arguments)
Here is a very bare-bones example to start with: First we make a set of x values using linspace, and then we define a function that computes $x^2$ and compute the y values by feeding our x values into it.
#Define function for taking square
def squared(x):
return x**2
#Make x and y values
xvals = np.linspace(0,10,20) #ranges from 0 to 10 with 20 points total
yvals = squared(xvals)
#Plot
plt.plot(xvals, yvals, label="x^2")
plt.legend()
plt.show() #Marks the end of the commands for this plot
There are many details that you can add to the plots through what are called keywords. You just add these as additional arguments after your x and y values. For example, the label
option was used in the above example, which we used to assign the curve a label in the legend.
Some of the customizations include:
marker: o (circles), ^ (triangles), * (stars), . (small points), etc
linestyle: - (solid line), -- (dotted line), : (fine dotted line), etc
color: b (blue), r (red), c (cyan), m (magenta), y (yellow), k (black), g (green), etc
alpha: opacity, a float set between 0 and 1
label: name of that dataset to be used in the legend
Every keyword argument besides alpha should be given as a string. Note that the order of the arguments in plt.plot
matters for the required xvals and yvals, but order is flexible for all the optional arguments. You can always google a function to check what arguments it takes in what order. Here is the documentation for matplotlib.pyplot.plot()
.
After plt.plot(), you will want to add some other information.
plt.xlabel() - x axis label
plt.ylabel() - y axis label
plt.axis([]) - in the brackets list x_lowerlimit, x_upperlimit, y_lowerlimit, y_upperlimit for axis display
plt.title() - plot title
plt.legend() - adds a legend, but plt.plot() must contain a "label" argument
plt.show() - displays your plot
Here's a detailed example. By the way, you can use shorthand for the marker/line style and the color, so instead of typing out marker="o", color="blue"
, it will also understand simply "ob"
(blue circles).
a = np.array([0, 1, 2, 3])
b = np.array([7, 6, 5, 4])
plt.plot(a, b+2, 'ob',alpha=0.1, markersize=15, label='blue circles') #plot the b+2 as blue circles
plt.plot(a, b**2, '^m', label='pink triangles') #plot b^2 as magenta triangles
plt.xlabel("x label", fontsize=16)
plt.ylabel("y label", fontsize=16)
plt.title('scatter plot')
plt.legend(loc=1, frameon=True) #'loc' moves the legend around, frameon puts a box around the legend
plt.savefig("customfig.jpg")
plt.show()
#solution here
fig = plt.figure()
xarray = np.linspace(-5, 5, 200)
quadfx = quad(xarray, 5, 2)
plt.plot(xarray, quadfx, 'g--', label="quad function")
plt.legend(loc=9, frameon=True, fontsize=14)
#these are the symbols for solar and earth mass- might be helpful to you!
plt.xlabel("M$_{\odot}$", fontsize=16)
plt.ylabel("M$_{\oplus}$", fontsize=16)
plt.title("quad function")
fig.savefig('quadfx.jpg')
Finally, to save a figure, write fig = plt.figure() before your plot, and before you call plt.show(), write fig.savefig('filename.jpg').