Please use the Etherpad to take notes/share code, ask questions and explore
Before we begin…
cd ~/Desktop
cd python-novice-inflammation
LIVE DEMO
Jupyter
At the command-line, start Jupyter
notebook:
jupyter notebook
Jupyter
landing page\[y = f(x)\]
\(y\) is the returned value, or output(s)
Not all functions in code take an input, or produce a usable output, but the principle is generally the same.
fahr_to_kelvin()
to convert Fahrenheit to Kelvin\[f(x) = ((x - 32) \times \frac{5}{9}) + 273.15\]
LIVE DEMO
fahr_to_kelvin()
to convert Fahrenheit to Kelvin\[f(x) = ((x - 32) \times \frac{5}{9}) + 273.15\]
fahr_to_kelvin()
is the same as calling any other functionprint('freezing point of water:', fahr_to_kelvin(32))
print('boiling point of water:', fahr_to_kelvin(212))
def kelvin_to_celsius(temp):
return temp - 273.15
print('freezing point of water', kelvin_to_celsius(273.15))
Python
functions works like mathematical functions: \(y = f(g(x))\)temp_f
) to C (temp_c
) by executing the code:temp_c = kelvin_to_celsius(fahr_to_kelvin(temp_f))
LIVE DEMO
fahr_to_celsius
:def fahr_to_celsius(temp_f):
return kelvin_to_celsius(fahr_to_kelvin(temp_f))
print('freezing point of water in Celsius:', fahr_to_celsius(32.0))
LIVE DEMO
Can you write a function called outer()
that:
string
argumentprint(outer("helium"))
hm
a = "Hello"
def my_fn(a):
a = "Goodbye"
my_fn(a)
print(a)
LIVE DEMO
What would be printed if you ran the code below?
a = 3
b = 7
def swap(a, b):
temp = a
a = b
b = temp
swap(a, b)
print(b, a)
7 3
3 7
3 3
7 7
files.ipynb
notebook from the first lessonanalyse()
analyse()
that plots the datadef analyze(data):
fig = matplotlib.pyplot.figure(figsize=(10.0, 3.0))
axes1 = fig.add_subplot(1, 3, 1)
axes2 = fig.add_subplot(1, 3, 2)
axes3 = fig.add_subplot(1, 3, 3)
axes1.set_ylabel('average')
axes1.plot(numpy.mean(data, axis=0))
axes2.set_ylabel('max')
axes2.plot(numpy.max(data, axis=0))
axes3.set_ylabel('min')
axes3.plot(numpy.min(data, axis=0))
fig.tight_layout()
matplotlib.pyplot.show()
LIVE DEMO
detect_problems()
def detect_problems(data):
if numpy.max(data, axis=0)[0] == 0 and numpy.max(data, axis=0)[20] == 20:
print('Suspicious looking maxima!')
elif numpy.sum(numpy.min(data, axis=0)) == 0:
print('Minima add up to zero!')
else:
print('Seems OK!')
LIVE DEMO
analyse()
and detect_problems()
for file in files:
print(file)
data = numpy.loadtxt(fname=file, delimiter=',')
detect_problems(data)
analyse(data)
def centre(data, desired):
return (data - np.mean(data)) + desired
LIVE DEMO
centre()
on real data
numpy
to create an artificial datasetz = np.zeros((2, 2))
print(centre(z, 3.0))
LIVE DEMO
data = numpy.loadtxt(fname='data/inflammation-01.csv', delimiter=',')
print(centre(data, 0))
LIVE DEMO
mean
, min
, max
, std
centred = centre(data, 0)
print('original min, mean, and max are:', numpy.min(data), numpy.mean(data), numpy.max(data))
print('min, mean, and max of centered data are:', numpy.min(centred),
numpy.mean(centred), numpy.max(centred))
print('std dev before and after:', numpy.std(data), numpy.std(centred))
LIVE DEMO
centre()
function requires two argumentsdef centre(data, desired=0.0):
"""Returns the array in data, recentered around the desired value.
Example: centre([1, 2, 3], 0) => [-1, 0, 1]
"""
return (data - np.mean(data)) + desired
centre(data, 0.0)
centre(data, desired=0.0)
centre(data)
LIVE DEMO
#
) is a good thingPython
provides for docstrings
Python
’s help systemdef centre(data, desired):
"""Returns the array in data, recentered around the desired value."""
return (data - numpy.mean(data)) + desired
help(centre)
LIVE DEMO
Can you write a function called rescale()
that
L
and H
are the lowest and highest values in the original array, then the replacement for a value v
should be (v-L) / (H-L)
.
Python
tries to tell you what has gone wrong by providing a traceback
def favourite_ice_cream():
ice_creams = [
"chocolate",
"vanilla",
"strawberry"
]
print(ice_creams[3])
favourite_ice_cream()
LIVE DEMO
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-1-b0e1f9b712d6> in <module>()
8 print(ice_creams[3])
9
---> 10 favourite_ice_cream()
<ipython-input-1-b0e1f9b712d6> in favourite_ice_cream()
6 "strawberry"
7 ]
----> 8 print(ice_creams[3])
9
10 favourite_ice_cream()
IndexError: list index out of range
LIVE DEMO
Python
def some_function()
msg = "hello, world!"
print(msg)
return msg
LIVE DEMO
File "<ipython-input-3-dbf32ad5d3e8>", line 1
def some_function()
^
SyntaxError: invalid syntax
LIVE DEMO
def some_function():
msg = "hello, world!"
print(msg)
return msg
LIVE DEMO
File "<ipython-input-4-e169556d667b>", line 4
return msg
^
IndentationError: unexpected indent
LIVE DEMO
NameError
s occur when a variable is not defined in scopeprint(a)
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-5-c5a4f3535135> in <module>()
----> 1 print(a)
NameError: name 'a' is not defined
LIVE DEMO
IndexError
letters = ['a', 'b', 'c']
print("Letter #1 is", letters[0])
print("Letter #2 is", letters[1])
print("Letter #3 is", letters[2])
print("Letter #4 is", letters[3])
Letter #1 is a
Letter #2 is b
Letter #3 is c
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-7-656a22fa6ec5> in <module>()
3 print("Letter #2 is", letters[1])
4 print("Letter #3 is", letters[2])
----> 5 print("Letter #4 is", letters[3])
IndexError: list index out of range
LIVE DEMO
abbabbabba
?for number in range(10):
# use a if the number is a multiple of 3, otherwise use b
if (Number % 3) = 0:
message = message + a
else:
message = message + "b"
print(message)
Pythonic
way to see if code runs correctly
Firefox
source code is checks on the rest of the code!assert
that a condition is True
True
, the code may be correctFalse
, the code is not correctassert <condition>, "Some text describing the problem"
numbers = [1.5, 2.3, 0.7, -0.001, 4.4]
total = 0.0
for n in numbers:
assert n > 0.0, 'Data should only contain positive values'
total += n
print('total is:', total)
QUESTION: What does this assertion do?
def normalise_rectangle(rect):
"""Normalises a rectangle to the origin, longest axis 1.0 units."""
x0, y0, x1, y1 = rect
dx = x1 - x0
dy = y1 - y0
if dx > dy:
scaled = float(dx) / dy
upper_x, upper_y = 1.0, scaled
else:
scaled = float(dx) / dy
upper_x, upper_y = scaled, 1.0
return (0, 0, upper_x, upper_y)
rect
has four valuesdef normalise_rectangle(rect):
"""Normalises a rectangle to the origin, longest axis 1.0 units."""
assert len(rect) == 4, "Rectangle must have four co-ordinates"
x0, y0, x1, y1 = rect
dx = x1 - x0
dy = y1 - y0
if dx > dy:
scaled = float(dx) / dy
upper_x, upper_y = 1.0, scaled
else:
scaled = float(dx) / dy
upper_x, upper_y = scaled, 1.0
return (0, 0, upper_x, upper_y)
def normalise_rectangle(rect):
"""Normalises a rectangle to the origin, longest axis 1.0 units."""
assert len(rect) == 4, "Rectangle must have four co-ordinates"
x0, y0, x1, y1 = rect
dx = x1 - x0
dy = y1 - y0
if dx > dy:
scaled = float(dy) / dx
upper_x, upper_y = 1.0, scaled
else:
scaled = float(dx) / dy
upper_x, upper_y = scaled, 1.0
assert 0 < upper_x <= 1.0, "Calculated upper x-coordinate invalid"
assert 0 < upper_y <= 1.0, "Calculated upper y-coordinate invalid"
return (0, 0, upper_x, upper_y)
range_overlap()
range_overlap()
function that should pass those testsrange_overlap()
functionassert range_overlap([ (0.0, 1.0) ]) == (0.0, 1.0)
assert range_overlap([ (2.0, 3.0), (2.0, 4.0) ]) == (2.0, 3.0)
assert range_overlap([ (0.0, 1.0), (0.0, 2.0), (-1.0, 1.0) ]) == (0.0, 1.0)
def test_range_overlap():
assert range_overlap([(0.0, 1.0)]) == (0.0, 1.0)
assert range_overlap([(2.0, 3.0), (2.0, 4.0)]) == (2.0, 3.0)
assert range_overlap([(0.0, 1.0), (0.0, 2.0), (-1.0, 1.0)]) == (0.0, 1.0)
assert range_overlap([(0.0, 1.0), (5.0, 6.0)]) == None
assert range_overlap([(0.0, 1.0), (1.0, 2.0)]) == None
range_overlap()
def range_overlap(ranges):
"""Return common overlap among a set of (low, high) ranges."""
lowest = 0.0
highest = 1.0
for (low, high) in ranges:
lowest = max(lowest, low)
highest = min(highest, high)
return (lowest, highest)
test_range_overlap()
Add the test:
assert range_overlap([]) == None
Can you fix range_overlap()
?