Intro to Python Homework

  • Write a line of code that stores the value of the $atan(5)$ in the variable y.

In [1]:
import numpy as np
y = np.arctan(5)
  • In words, what the math.ceil and math.floor functions do?

They return round down to the nearest integer (ceil) or up to the nearest integer (floor).

  • Store the result of $5x^{4} - 3x^{2} + 0.5x - 20$ in the variable y, where $x$ is 2.

In [2]:
x = 2
y = 5*(x**4) - 3*x**2 + 0.5*x - 20
  • Construct a conditional that prints $x$ if it is smaller than 20 but greater than -5

In [3]:
if x > -5 and x < 20:
    print(x)


2
  • Construct a conditional that prints $x$ if it not between 5 and 12.

In [4]:
if x <= 5 and x >= 12:
    print(x)
  • What will the following code print? (Don't just copy and paste -- reason through it!)

It will print c. x does not meet the first two conditionals (x > 2 or x < 0 and not x == 2, so it will reach x == 2. Since it equals 2, this will print c and skip the last line printing d.

  • Write a loop that prints every 5th number between 1 and 2000. (HINT: try help(range))

In [5]:
for i in range(1,2001,5):
    print(i)


1
6
11
16
21
26
31
36
41
46
51
56
61
66
71
76
81
86
91
96
101
106
111
116
121
126
131
136
141
146
151
156
161
166
171
176
181
186
191
196
201
206
211
216
221
226
231
236
241
246
251
256
261
266
271
276
281
286
291
296
301
306
311
316
321
326
331
336
341
346
351
356
361
366
371
376
381
386
391
396
401
406
411
416
421
426
431
436
441
446
451
456
461
466
471
476
481
486
491
496
501
506
511
516
521
526
531
536
541
546
551
556
561
566
571
576
581
586
591
596
601
606
611
616
621
626
631
636
641
646
651
656
661
666
671
676
681
686
691
696
701
706
711
716
721
726
731
736
741
746
751
756
761
766
771
776
781
786
791
796
801
806
811
816
821
826
831
836
841
846
851
856
861
866
871
876
881
886
891
896
901
906
911
916
921
926
931
936
941
946
951
956
961
966
971
976
981
986
991
996
1001
1006
1011
1016
1021
1026
1031
1036
1041
1046
1051
1056
1061
1066
1071
1076
1081
1086
1091
1096
1101
1106
1111
1116
1121
1126
1131
1136
1141
1146
1151
1156
1161
1166
1171
1176
1181
1186
1191
1196
1201
1206
1211
1216
1221
1226
1231
1236
1241
1246
1251
1256
1261
1266
1271
1276
1281
1286
1291
1296
1301
1306
1311
1316
1321
1326
1331
1336
1341
1346
1351
1356
1361
1366
1371
1376
1381
1386
1391
1396
1401
1406
1411
1416
1421
1426
1431
1436
1441
1446
1451
1456
1461
1466
1471
1476
1481
1486
1491
1496
1501
1506
1511
1516
1521
1526
1531
1536
1541
1546
1551
1556
1561
1566
1571
1576
1581
1586
1591
1596
1601
1606
1611
1616
1621
1626
1631
1636
1641
1646
1651
1656
1661
1666
1671
1676
1681
1686
1691
1696
1701
1706
1711
1716
1721
1726
1731
1736
1741
1746
1751
1756
1761
1766
1771
1776
1781
1786
1791
1796
1801
1806
1811
1816
1821
1826
1831
1836
1841
1846
1851
1856
1861
1866
1871
1876
1881
1886
1891
1896
1901
1906
1911
1916
1921
1926
1931
1936
1941
1946
1951
1956
1961
1966
1971
1976
1981
1986
1991
1996
  • What will the following program print out?

It will print 0 to 9 and then -10 to -99.

  • Write a loop that calculates a Riemann sum for $x^2$ for $x \in [-5,5]$.

In [6]:
# left hand integral
dx = 1
integral = 0
for x in range(-5,5):
    integral = integral + dx*x**2
print(integral)

## A better, higher accuracy way
dx = 0.001
midpoints = np.arange(-5,5,dx) + dx/2
print(np.sum(midpoints**2)*dx)


85
83.33333250005565
  • Create a list of all integers between 2 and 30.

In [7]:
some_list = []
for i in range(2,31):
    some_list.append(i)
    
## another (better!) way is to cast it; faster
some_list = list(range(2,31))
  • Create a list called some_list that has all sin(x) for x $\in$ [$0$, $\pi/4$, $\pi /2$, $3 \pi /4$... $2 \pi$].

In [8]:
import numpy as np
some_list = []
for i in range(0,9):
    some_list.append(np.sin(np.pi*i/4))
print(some_list)

[100,-99,98,-97,96,...,0]

In [9]:
some_list = []
for i in range(-100,1):
    if i % 2:
        some_list.append(i)
    else:
        some_list.append(-i)
  • Write a loop that creates a dictionary that uses the letters A-E as keys to the values 0-4.

In [10]:
letters = "ABCDE"
some_dict = {}
for i in range(5):
    some_dict[letters[i]] = i

## A different way using a cool function called enumerate
some_dict = {}
for number, letter in enumerate("ABCDE"):
    some_dict[letter] = number
    
## Or even MORE compact using list comprehension
some_dict = dict([(letter,number) for number, letter in enumerate("ABCDE")])
  • Create a $3 \times 3$ numpy array with the integers 0-8:

    [[0,1,2],
       [3,4,5],
       [6,7,8]]
    

    Multiply the whole array by 5 and then take the natural log of all values (elementwise). What is the sum of the right-most column?


In [11]:
some_list = [[0,1,2],[3,4,5],[6,7,8]]
for i in range(3):
    for j in range(3):
        some_list[i][j] = some_list[i][j]*5
        some_list[i][j] = np.log(some_list[i][j])

total = 0
for j in range(3):
    total = total + some_list[j][2]
    
print(total)


9.210340371976182
/Users/harmsm/miniconda3/lib/python3.7/site-packages/ipykernel_launcher.py:5: RuntimeWarning: divide by zero encountered in log
  """
  • Repeat the exercise above using a numpy array. Use a numpy array to calcualte all sin(x) for x $\in$ [$0$, $\pi/4$, $\pi /2$, $3 \pi /4$... $2 \pi$].

In [12]:
some_array = np.array([[0,1,2],[3,4,5],[6,7,8]],dtype=np.int)

## OR
some_array = np.zeros((3,3),dtype=np.int)
total = 0
for i in range(3):
    for j in range(3):
        some_array[i,j] = total
        total += 1

## OR (probably most efficient of the set)
some_array = np.array(range(9),dtype=np.int)
some_array = some_array.reshape((3,3))
        
print(np.sum(np.log((5*some_array))[:,2]))

np.log(some_array*5)


9.210340371976182
/Users/harmsm/miniconda3/lib/python3.7/site-packages/ipykernel_launcher.py:15: RuntimeWarning: divide by zero encountered in log
  from ipykernel import kernelapp as app
/Users/harmsm/miniconda3/lib/python3.7/site-packages/ipykernel_launcher.py:17: RuntimeWarning: divide by zero encountered in log
Out[12]:
array([[      -inf, 1.60943791, 2.30258509],
       [2.7080502 , 2.99573227, 3.21887582],
       [3.40119738, 3.55534806, 3.68887945]])
  • Write a function that takes a string and returns it in all uppercase. (Hint, google this one)

In [13]:
def capitalize(some_string):
    return some_string.upper()
capitalize("test")


Out[13]:
'TEST'
  • Use matplotlib to plot $sin(x)$ for x $\in$ [$0$, $\pi/4$, $\pi /2$, $3 \pi /4$... $2 \pi$]. Use both orange points and a green line.

In [14]:
%matplotlib inline
from matplotlib import pyplot as plt
import numpy as np

x = np.arange(0,2.25*np.pi,0.25*np.pi)
y = np.sin(x)
plt.plot(x,y,"-",color="green")
plt.plot(x,y,"1",color="orange",markersize=12)


Out[14]:
[<matplotlib.lines.Line2D at 0x1100892e8>]

You measure the doubling times of bacterial strains A-D under identical conditions.

strain doubling time (min)
A 20
B 25
C 39
D 53

Assuming you start with a single cell and have nutrients in excess, you can calculate the number of bacteria $N(t)$ in a culture after $t$ minutes according to:

$$N(t) = 2^{t/d}$$

  • Write a function called num_bacteria that takes the time and doubling time and returns the number of bacteria present.

In [15]:
def num_bacteria(t,doubling_time):
    
    return 2**(t/doubling_time)
  • Create a dictionary called doubling that keys the name of each strain to its population after 12 hours.

In [16]:
doubling = {}
doubling["A"] = num_bacteria(12*60,20)
doubling["B"] = num_bacteria(12*60,25)
doubling["C"] = num_bacteria(12*60,39)

doubling


Out[16]:
{'A': 68719476736.0, 'B': 467373274.8589041, 'C': 360974.76557387016}
  • Use matplotlib to create a single graph that shows $N(t)$ for all four bacterial strains from 0 to 18 hr. Make sure you label your axes appropriately.

In [17]:
for k in doubling.keys():
    print(k)


A
B
C

In [18]:
%matplotlib inline
from matplotlib import pyplot as plt
import numpy as np

t = np.arange(0,18*60+1,1)
some_dict = {"A":20.0,"B":25.0}
for k in some_dict.keys():
    plt.plot(t,num_bacteria(t,some_dict[k]),".")
    
plt.yscale("log")



In [ ]: