Week 3 notebook

In [2]:
def isprime2(n):
    if n < 2:
        return False
    for d in range(2, round(n**0.5) + 1):
        if n%d == 0:
            return False
    return True
In [4]:
isprime2(7)
Out[4]:
True
In [5]:
isprime2(12)
Out[5]:
False

Code comments

Code comments start with #:

In [9]:
def mprimes2(n):
    
    #plist is the list for storing prime numbers
    plist = []
    for k in range(n+1):
        
        #iprime2 tests if a number is a prime or not
        if isprime2(k):
            plist.append(k) #adding a prime to the list
    return plist

Docstring is string that can be used to explain what a function does and how to use it. Docstring must be placed immediately after the def statement:

In [14]:
def myprimes2(n):
    '''
    Returns the list of all primes smaller or equal to n
    '''
    
    #plist is the list for storing prime numbers
    plist = []
    for k in range(n+1):
        
        #iprime2 tests if a number is a prime or not
        if isprime2(k):
            plist.append(k) #adding a prime to the list
    return plist
In [11]:
from math import sin
In [12]:
help(sin)
Help on built-in function sin in module math:

sin(...)
    sin(x)
    
    Return the sine of x (measured in radians).

In [15]:
help(myprimes2)
Help on function myprimes2 in module __main__:

myprimes2(n)
    Returns the list of all primes smaller or equal to n

More about lists

List indexing

In [16]:
states = ['AK', 'NY', 'MI', 'IL', 'TX']
In [17]:
print(states[0])
AK
In [18]:
print(states[2])
MI

Note: Indexing starts with 0!

Negative indexes count from the end of the list:

In [19]:
states[-1]
Out[19]:
'TX'
In [20]:
states[-3]
Out[20]:
'MI'

Changing a value on a list:

In [21]:
states[1] = 'CA'
In [22]:
print(states)
['AK', 'CA', 'MI', 'IL', 'TX']

Inserting an element into a list:

In [23]:
states.insert(1, 'OH')
In [24]:
print(states)
['AK', 'OH', 'CA', 'MI', 'IL', 'TX']
In [25]:
states.pop(2)
Out[25]:
'CA'
In [26]:
print(states)
['AK', 'OH', 'MI', 'IL', 'TX']

Indexing nested lists:

In [27]:
nested = [[1, 2], [4, 5, 6]]
In [28]:
print(nested[0])
[1, 2]
In [29]:
print(nested[0][0])
1
In [30]:
print(nested[1][2])
6
In [31]:
nested[1][2] = 'hello'
In [32]:
print(nested)
[[1, 2], [4, 5, 'hello']]

List slicing

List slicing produces a sublist of a list:

In [33]:
letter = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
In [35]:
slice1 = letter[1:6]
In [36]:
print(slice1)
['b', 'c', 'd', 'e', 'f']
In [37]:
slice2 = letter[1:-1]
In [38]:
print(slice2)
['b', 'c', 'd', 'e', 'f', 'g']

Slice from 1st element to the end:

In [39]:
slice3 = letter[1:]
In [40]:
print(slice3)
['b', 'c', 'd', 'e', 'f', 'g', 'h']

From the beginning to the 5th element:

In [41]:
slice4 = letter[:6]
print(slice4)
['a', 'b', 'c', 'd', 'e', 'f']

Slicing can be used with the argument specifying step:

In [43]:
slice5 = letter[1:6:2]
In [44]:
print(slice5)
['b', 'd', 'f']
In [47]:
print(letter[-1::-1])
['h', 'g', 'f', 'e', 'd', 'c', 'b', 'a']

Slicing can be used to change several elements on a list at once:

In [48]:
a = [1, 2, 3, 4, 5, 6, 7, 8]
In [49]:
a[:3] = [100, 100, 100]
In [50]:
print(a)
[100, 100, 100, 4, 5, 6, 7, 8]

Testing if an element is on a list:

In [51]:
vowels = ['a', 'e', 'i', 'o', 'u']
In [52]:
'u' in vowels
Out[52]:
True
In [53]:
'n' in vowels
Out[53]:
False
In [54]:
for letter in 'buffalo':
    if letter in vowels:
        print(letter)
u
a
o
In [55]:
for letter in 'buffalo':
    if not (letter in vowels):
        print(letter)
b
f
f
l

This also works:

In [56]:
for letter in 'buffalo':
    if letter not in vowels:
        print(letter)
b
f
f
l

Mutable vs immutable objects

In [58]:
a = [1, 2, 3]
print(a)
[1, 2, 3]
In [59]:
b = a
In [60]:
print(b)
[1, 2, 3]
In [61]:
b[0] = 1000
In [62]:
print(b)
[1000, 2, 3]
In [63]:
print(a)
[1000, 2, 3]

Compare this with the following:

In [64]:
a = 1
b = a
In [65]:
print(a)
1
In [66]:
print(b)
1
In [67]:
b += 1
In [68]:
print(b)
2
In [69]:
print(a)
1
In [70]:
a = [1, 2, 3]
In [71]:
id(a)
Out[71]:
4477207880
In [72]:
b = a
In [73]:
id(b)
Out[73]:
4477207880
In [74]:
a is b
Out[74]:
True
In [75]:
c = [1, 2, 3]
In [76]:
id(c)
Out[76]:
4477062152
In [77]:
a is c
Out[77]:
False
In [78]:
a == c
Out[78]:
True
In [17]:
a = [1, 2, 3]
b = a.copy()
In [18]:
b[0] = 100
In [19]:
b
Out[19]:
[100, 2, 3]
In [20]:
a
Out[20]:
[1, 2, 3]

Idexing and slicing for strings

In [21]:
s = 'Minneapolis'
In [22]:
print(s[0])
M
In [23]:
print(s[-2])
i
In [24]:
print(s[1:-1])
inneapoli
In [25]:
print(s[::2])
Mnepls
In [26]:
'f' in 'Buffalo'
Out[26]:
True
In [27]:
'c' in 'Buffalo'
Out[27]:
False
In [28]:
s = 'cat'
In [29]:
s[0] = 'b'
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-29-b157954a8563> in <module>()
----> 1 s[0] = 'b'

TypeError: 'str' object does not support item assignment
In [32]:
def b_sub(s):
    return 'b' + s[1:]
In [33]:
b_sub('cat')
Out[33]:
'bat'
In [34]:
b_sub('river')
Out[34]:
'biver'

More about functions: positional, keyword, default arguments

In [35]:
from math import pi

def cyl_vol(r, h):
    return pi*r**2*h
In [36]:
cyl_vol(1, 2)
Out[36]:
6.283185307179586
In [37]:
cyl_vol(2, 1)
Out[37]:
12.566370614359172

Passing arguments by keyword:

In [39]:
cyl_vol(r = 1, h=2)
Out[39]:
6.283185307179586
In [40]:
cyl_vol(h=2, r=1)
Out[40]:
6.283185307179586

You can specify some arguments by keyword and some by position, but position arguments must come first:

In [41]:
def timer(n, delay, msg):
    from time import sleep
    
    for i in range(n, 0, -1):
        print(i)
        sleep(delay)
    print(msg)
In [45]:
timer(10, delay=0.5, msg='wake up!')
10
9
8
7
6
5
4
3
2
1
wake up!

Default arguments:

In [46]:
def timer(n, delay = 1, msg = 'time up!'):
    from time import sleep
    
    for i in range(n, 0, -1):
        print(i)
        sleep(delay)
    print(msg)
In [47]:
timer(5)
5
4
3
2
1
time up!
In [48]:
timer(5, msg = 'boom!!!')
5
4
3
2
1
boom!!!

Plotting with matplotlib

In [2]:
import matplotlib.pyplot as plt

Basing plotting is done using plt.plot() function.

Syntax: `plt.plot([list of x-ccords], [list of y-ccords])

In [3]:
plt.plot([1, 2, 3, 4], [2, 1, 1.5, 2])
plt.show() # use plt.show() to display the plot

You can use this to make plots look sharper:

In [4]:
%config InlineBackend.figure_format = 'retina'
In [5]:
plt.plot([1, 2, 3, 4], [2, 1, 1.5, 2])
plt.show()
In [6]:
plt.plot([1, 2, 3, 4], [2, 1, 1.5, 2])
plt.plot([0, 1, 2], [1, 2, 0])

plt.show()
In [7]:
xlist = range(-5, 6)
ylist = []
for x in xlist:
    ylist.append(x**2)
In [8]:
list(xlist)
Out[8]:
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]
In [9]:
print(ylist)
[25, 16, 9, 4, 1, 0, 1, 4, 9, 16, 25]
In [10]:
plt.plot(xlist, ylist)
plt.show()
In [11]:
plt.plot(xlist, ylist, 'ro') # marker options: r = red, o = circle
plt.show()
In [12]:
plt.plot(xlist, ylist, 'gs') # marker options: g = green, s = square
plt.show()
In [13]:
plt.plot(xlist, ylist, 'gs-') # marker options: g = green, s = square, - = connect by lines
plt.show()
In [14]:
plt.plot(xlist, ylist, 'gs-', ms=20) # marker options: g = green, s = square, - = connect by lines
# ms specifies the marker size
plt.show()
In [15]:
plt.figure(figsize=(8, 4))

plt.title('My plot $f(x) = x^2$ ', fontsize = 20)
plt.plot(xlist, ylist, 'ro') # marker options: r = red, o = circle
plt.xlim(-10, 10)
plt.ylim(-2, 30)
plt.xlabel('This is x-axis')
plt.ylabel('This is y-axis')

plt.show()
In [16]:
xlist = []
for i in range(101):
    xlist.append(i/100)
In [17]:
print(xlist)
[0.0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.1, 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.2, 0.21, 0.22, 0.23, 0.24, 0.25, 0.26, 0.27, 0.28, 0.29, 0.3, 0.31, 0.32, 0.33, 0.34, 0.35, 0.36, 0.37, 0.38, 0.39, 0.4, 0.41, 0.42, 0.43, 0.44, 0.45, 0.46, 0.47, 0.48, 0.49, 0.5, 0.51, 0.52, 0.53, 0.54, 0.55, 0.56, 0.57, 0.58, 0.59, 0.6, 0.61, 0.62, 0.63, 0.64, 0.65, 0.66, 0.67, 0.68, 0.69, 0.7, 0.71, 0.72, 0.73, 0.74, 0.75, 0.76, 0.77, 0.78, 0.79, 0.8, 0.81, 0.82, 0.83, 0.84, 0.85, 0.86, 0.87, 0.88, 0.89, 0.9, 0.91, 0.92, 0.93, 0.94, 0.95, 0.96, 0.97, 0.98, 0.99, 1.0]
In [18]:
from math import sin

ylist = []
for x in xlist:
    ylist.append(sin(20*x))
In [19]:
print(ylist)
[0.0, 0.19866933079506122, 0.3894183423086505, 0.5646424733950354, 0.7173560908995228, 0.8414709848078965, 0.9320390859672263, 0.9854497299884603, 0.9995736030415051, 0.9738476308781953, 0.9092974268256817, 0.8084964038195901, 0.675463180551151, 0.5155013718214642, 0.33498815015590466, 0.1411200080598672, -0.058374143427580086, -0.25554110202683167, -0.4425204432948521, -0.6118578909427189, -0.7568024953079282, -0.8715757724135881, -0.9516020738895161, -0.9936910036334645, -0.9961646088358407, -0.9589242746631385, -0.8834546557201531, -0.7727644875559871, -0.6312666378723208, -0.46460217941375737, -0.27941549819892586, -0.08308940281749641, 0.11654920485049364, 0.3115413635133787, 0.49411335113860894, 0.6569865987187891, 0.7936678638491526, 0.8987080958116269, 0.9679196720314863, 0.998543345374605, 0.9893582466233818, 0.9407305566797731, 0.8545989080882805, 0.7343970978741134, 0.5849171928917617, 0.4121184852417566, 0.22288991410024592, 0.02477542545335954, -0.17432678122297965, -0.3664791292519284, -0.5440211108893699, -0.6998746875935424, -0.8278264690856536, -0.9227754216128073, -0.9809362300664916, -0.9999902065507035, -0.979177729151317, -0.9193285256646764, -0.8228285949687089, -0.6935250847771236, -0.5365729180004349, -0.3582292822368287, -0.1656041754483094, 0.03362304722113669, 0.23150982510153895, 0.4201670368266409, 0.5920735147072245, 0.7403758899524486, 0.8591618148564968, 0.9436956694441042, 0.9906073556948704, 0.9980266527163617, 0.965657776549278, 0.8947911721405042, 0.7882520673753163, 0.6502878401571169, 0.4863986888537997, 0.30311835674570226, 0.1077536522994423, -0.09190685022768165, -0.2879033166650653, -0.4724219863984693, -0.6381066823479474, -0.7783520785342962, -0.8875670335815046, -0.9613974918795568, -0.9969000660415961, -0.9926593804706332, -0.948844497918124, -0.8672021794855813, -0.750987246771676, -0.6048328224062841, -0.43456562207189353, -0.2469736617366209, -0.049535640878370965, 0.14987720966295234, 0.3433149288198954, 0.5230657651576964, 0.6819636200681355, 0.8136737375071054, 0.9129452507276277]
In [20]:
plt.plot(xlist, ylist)
plt.show()

List comprehensions

In [21]:
squares = []
for i in range(11):
    squares.append(i**2)
In [22]:
squares
Out[22]:
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

The same code using list comprehensions:

In [23]:
squares2 = [i**2 for i in range(11)]
In [24]:
squares2
Out[24]:
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
In [25]:
greetings = ['hello', 'hi', 'howdy']
mylist = [ x + '!' for x in greetings]
In [26]:
mylist
Out[26]:
['hello!', 'hi!', 'howdy!']

List comprehensions with if statement:

In [27]:
# list of squares of even integers

evensq = []
for i in range(11):
    if i%2 == 0:
        evensq.append(i**2)
In [28]:
evensq
Out[28]:
[0, 4, 16, 36, 64, 100]

with list comprehensions:

In [29]:
evensq2 = [i**2 for i in range(11) if i%2 == 0]
In [30]:
evensq2
Out[30]:
[0, 4, 16, 36, 64, 100]
In [31]:
xlist = [x/100 for x in range(101)]
ylist = [sin(20*x) for x in xlist]
plt.plot(xlist, ylist)
plt.show()
In [32]:
from math import pi, cos

thetalist = [2*pi*i/1000 for i in range(1001)]
xlist = [sin(t) for t in thetalist]
ylist = [cos(t) for t in thetalist]

plt.axis('equal') # makes units on x and y axes equal
plt.plot(xlist, ylist)
plt.show()