Skip to content
Snippets Groups Projects
Commit ecadb822 authored by karcher's avatar karcher
Browse files

still tweaking

parent 2c4b6f10
No related branches found
No related tags found
No related merge requests found
%% Cell type:markdown id: tags:
# Defensive Programming
Defensive programming describes concepts and approaches we can use to ensure that...
* Code does what we think it does (i.e. is free of bugs)
* Our programs fail when they should...
* ... and do so with informative error messages (throwback to last session)
%% Cell type:markdown id: tags:
Let's say we want a function that takes in a list and computes the mean of all elements in that list
%% Cell type:markdown id: tags:
# Assert statement
The simplest tool we have to ensure that our functions are doing what we intend them to do are assert statements
%% Cell type:code id: tags:
``` python
def get_sum_of_numbers(alist):
tmp = 0
for element in alist:
tmp = alist[0]
for element in alist[1:]:
tmp = tmp + element
return(tmp)
```
%% Cell type:code id: tags:
``` python
get_sum_of_numbers([1,2,3,4,5])
```
%% Cell type:code id: tags:
``` python
get_sum_of_numbers(["a", "b", "c", "d", "e"])
```
%% Cell type:code id: tags:
``` python
def get_sum_of_numbers(alist):
assert all([isinstance(element, int) for element in alist]), "Not all elements are integers"
tmp = 0
for element in alist:
tmp = alist[0]
for element in alist[1:]:
tmp = tmp + element
return(tmp)
```
%% Cell type:code id: tags:
``` python
get_sum_of_numbers([1,2,3,4,5])
```
%% Cell type:code id: tags:
``` python
get_sum_of_numbers(["a", "b", "c", "d", "e"])
```
%% Cell type:code id: tags:
``` python
get_sum_of_numbers([1,2,3,4,5.01])
```
%% Cell type:code id: tags:
``` python
import numbers
def get_sum_of_numbers(alist):
assert all([isinstance(element, numbers.Number) for element in alist]), "Not all elements are Numbers"
tmp = 0
for element in alist:
tmp = alist[0]
for element in alist[1:]:
tmp = tmp + element
return(tmp)
```
%% Cell type:code id: tags:
``` python
get_sum_of_numbers([1,2,3,4,5.01])
```
%% Cell type:code id: tags:
``` python
get_sum_of_numbers([])
```
%% Cell type:code id: tags:
``` python
import numbers
def get_sum_of_numbers(alist):
assert len(alist) > 0, "List is empty"
assert all([isinstance(element, numbers.Number) for element in alist]), "Not all elements are Numbers"
tmp = 0
for element in alist:
tmp = alist[0]
for element in alist[1:]:
tmp = tmp + element
return(tmp)
```
%% Cell type:code id: tags:
``` python
get_sum_of_numbers([])
```
%% Cell type:markdown id: tags:
# Preconditions, postconditions and invariants
Assertions can be grouped into:
* Preconditions, which should be true the computional part of a function
* Postconditions, which should be true afterwards
* (Invariants, which should be true anywhere)
%% Cell type:code id: tags:
``` python
import numbers
def get_sum_of_numbers(alist):
# Preconditions
assert len(alist) > 0, "List is empty"
assert all([isinstance(element, numbers.Number) for element in alist]), "Not all elements are Numbers"
tmp = 0
for element in alist:
tmp = alist[0]
for element in alist[1:]:
tmp = tmp + element
return(tmp)
```
%% Cell type:code id: tags:
``` python
get_sum_of_numbers([1,2,3,4,5])
```
%% Cell type:code id: tags:
``` python
import numbers
def get_sum_of_numbers(alist):
# Preconditions
assert len(alist) > 0, "List is empty"
assert all([isinstance(element, numbers.Number) for element in alist]), "Not all elements are Numbers"
tmp = 0
for element in alist:
tmp = alist[0]
for element in alist[1:]:
tmp = tmp + element
tmp = 'Your code has been visited by an evil spirit!'
return(tmp)
```
%% Cell type:code id: tags:
``` python
get_sum_of_numbers([1, 2, 3])
```
%% Cell type:code id: tags:
``` python
import numbers
def get_sum_of_numbers(alist):
# Preconditions
assert len(alist) > 0, "List is empty"
assert all([isinstance(element, numbers.Number) for element in alist]), "Not all elements are Numbers"
tmp = 0
for element in alist:
tmp = alist[0]
for element in alist[1:]:
tmp = tmp + element
tmp = 'Your code has been visited by an evil spirit!'
# Postcondition
assert isinstance(tmp, numbers.Number), "Your sum isn't numerical..."
return(tmp)
```
%% Cell type:code id: tags:
``` python
get_sum_of_numbers([1, 2, 3])
```
%% Cell type:markdown id: tags:
# Test-Driven Development
Some programmers write code and then test that code somehow to be confident enough that it's bug free.
Other programms create tests and then write code that has to pass these tests in an iterative manner. This approach is called test-driven development.
%% Cell type:markdown id: tags:
We want to write a function that calculates the largest overlap between numerical ranges. Each numerical range is a two-element tuple specifying the upper and lower boundaries.
%% Cell type:markdown id: tags:
![caption](python-overlapping-ranges.png)
%% Cell type:code id: tags:
``` python
# Single range
assert range_overlap([ (0.0, 1.0) ]) == (0.0, 1.0)
# Two overlapping ranges
assert range_overlap([ (2.0, 3.0), (2.0, 4.0) ]) == (2.0, 3.0)
# Three overlapping ranges
assert range_overlap([ (0.0, 1.0), (0.0, 2.0), (-1.0, 1.0) ]) == (0.0, 1.0)
# What else is missing?
# Twice the same range
assert range_overlap([(0, 2), (0, 2)]) == (0.0, 2.0)
# Two non-overlapping ranges. What is the desired output? (0, 0)? None?
assert range_overlap([ (0.1, 1.0), (3.0, 4.0) ]) == None
# More than two non-overlapping ranges. See above.
assert range_overlap([ (0.1, 1.0), (3.0, 4.0), (10, 12) ]) == None
# Two intervals touching
assert range_overlap([(0, 2), (2, 4)]) == None
# empty input?
assert range_overlap([]) == None
```
%% Cell type:code id: tags:
``` python
def range_overlap(ranges):
max_left = ranges[0][0]
min_right = ranges[0][1]
# ranges[2:] returns an empty list if len(ranges) == 1 and nothing is being looped over.
for (left, right) in ranges[1:]:
max_left = max(max_left, left)
min_right = min(min_right, right)
return (max_left, min_right)
```
%% Cell type:code id: tags:
``` python
# Single range
assert range_overlap([ (0.0, 1.0) ]) == (0.0, 1.0)
# Two overlapping ranges
assert range_overlap([ (2.0, 3.0), (2.0, 4.0) ]) == (2.0, 3.0)
# Three overlapping ranges
assert range_overlap([ (0.0, 1.0), (0.0, 2.0), (-1.0, 1.0) ]) == (0.0, 1.0)
# What else is missing?
# Twice the same range
assert range_overlap([(0, 2), (0, 2)]) == (0.0, 2.0)
# Two non-overlapping ranges. What is the desired output? (0, 0)? None?
assert range_overlap([ (0.1, 1.0), (3.0, 4.0) ]) == None
# More than two non-overlapping ranges. See above.
assert range_overlap([ (0.1, 1.0), (3.0, 4.0), (10, 12) ]) == None
# Two touching intervals
assert range_overlap([(0, 2), (2, 4)]) == None
# empty input?
assert range_overlap([]) == None
```
%% Cell type:code id: tags:
``` python
def range_overlap(ranges):
max_left = ranges[0][0]
min_right = ranges[0][1]
# ranges[2:] returns an empty list if len(ranges) == 0 and nothing is being looped over.
for (left, right) in ranges[1:]:
max_left = max(max_left, left)
min_right = min(min_right, right)
if max_left > min_right:
return(None)
return (max_left, min_right)
```
%% Cell type:code id: tags:
``` python
# Single range
assert range_overlap([ (0.0, 1.0) ]) == (0.0, 1.0)
# Two overlapping ranges
assert range_overlap([ (2.0, 3.0), (2.0, 4.0) ]) == (2.0, 3.0)
# Three overlapping ranges
assert range_overlap([ (0.0, 1.0), (0.0, 2.0), (-1.0, 1.0) ]) == (0.0, 1.0)
# What else is missing?
# Twice the same range
assert range_overlap([(0, 2), (0, 2)]) == (0.0, 2.0)
# Two non-overlapping ranges. What is the desired output? (0, 0)? None?
assert range_overlap([ (0.1, 1.0), (3.0, 4.0) ]) == None
# More than two non-overlapping ranges. See above.
assert range_overlap([ (0.1, 1.0), (3.0, 4.0), (10, 12) ]) == None
# Two touching intervals
assert range_overlap([(0, 2), (2, 4)]) == None
# empty input?
assert range_overlap([]) == None
```
%% Cell type:code id: tags:
``` python
def range_overlap(ranges):
max_left = ranges[0][0]
min_right = ranges[0][1]
# ranges[2:] returns an empty list if len(ranges) == 1 and nothing is being looped over.
for (left, right) in ranges[1:]:
max_left = max(max_left, left)
min_right = min(min_right, right)
if max_left >= min_right:
return(None)
return (max_left, min_right)
```
%% Cell type:code id: tags:
``` python
# Single range
assert range_overlap([ (0.0, 1.0) ]) == (0.0, 1.0)
# Two overlapping ranges
assert range_overlap([ (2.0, 3.0), (2.0, 4.0) ]) == (2.0, 3.0)
# Three overlapping ranges
assert range_overlap([ (0.0, 1.0), (0.0, 2.0), (-1.0, 1.0) ]) == (0.0, 1.0)
# What else is missing?
# Twice the same range
assert range_overlap([(0, 2), (0, 2)]) == (0.0, 2.0)
# Two non-overlapping ranges. What is the desired output? (0, 0)? None?
assert range_overlap([ (0.1, 1.0), (3.0, 4.0) ]) == None
# More than two non-overlapping ranges. See above.
assert range_overlap([ (0.1, 1.0), (3.0, 4.0), (10, 12) ]) == None
# Two touching intervals
assert range_overlap([(0, 2), (2, 4)]) == None
# empty input?
assert range_overlap([]) == None
```
%% Cell type:code id: tags:
``` python
def range_overlap(ranges):
if len(ranges) == 0:
return(None)
max_left = ranges[0][0]
min_right = ranges[0][1]
# ranges[2:] returns an empty list if len(ranges) == 1 and nothing is being looped over.
for (left, right) in ranges[1:]:
max_left = max(max_left, left)
min_right = min(min_right, right)
if max_left >= min_right:
return(None)
return (max_left, min_right)
```
%% Cell type:code id: tags:
``` python
# Single range
assert range_overlap([ (0.0, 1.0) ]) == (0.0, 1.0)
# Two overlapping ranges
assert range_overlap([ (2.0, 3.0), (2.0, 4.0) ]) == (2.0, 3.0)
# Three overlapping ranges
assert range_overlap([ (0.0, 1.0), (0.0, 2.0), (-1.0, 1.0) ]) == (0.0, 1.0)
# What else is missing?
# Twice the same range
assert range_overlap([(0, 2), (0, 2)]) == (0.0, 2.0)
# Two non-overlapping ranges. What is the desired output? (0, 0)? None?
assert range_overlap([ (0.1, 1.0), (3.0, 4.0) ]) == None
# More than two non-overlapping ranges. See above.
assert range_overlap([ (0.1, 1.0), (3.0, 4.0), (10, 12) ]) == None
# Two touching intervals
assert range_overlap([(0, 2), (2, 4)]) == None
# empty input?
assert range_overlap([]) == None
```
......
%% Cell type:markdown id: tags:
# Defensive Programming
Defensive programming describes concepts and approaches we can use to ensure that...
* Code does what we think it does (i.e. is free of bugs)
* Our programs fail when they should...
* ... and do so with informative error messages (throwback to last session)
%% Cell type:markdown id: tags:
Let's say we want a function that takes in a list and computes the mean of all elements in that list
%% Cell type:markdown id: tags:
# Assert statement
The simplest tool we have to ensure that our functions are doing what we intend them to do are assert statements
%% Cell type:code id: tags:
``` python
def get_sum_of_numbers(alist):
tmp = 0
for element in alist:
tmp = alist[0]
for element in alist[1:]:
tmp = tmp + element
return(tmp)
```
%% Cell type:code id: tags:
``` python
get_sum_of_numbers([1,2,3,4,5])
```
%% Cell type:code id: tags:
``` python
get_sum_of_numbers(["a", "b", "c", "d", "e"])
```
%% Cell type:code id: tags:
``` python
def get_sum_of_numbers(alist):
assert all([isinstance(element, int) for element in alist]), "Not all elements are integers"
tmp = 0
for element in alist:
tmp = alist[0]
for element in alist[1:]:
tmp = tmp + element
return(tmp)
```
%% Cell type:code id: tags:
``` python
get_sum_of_numbers([1,2,3,4,5])
```
%% Cell type:code id: tags:
``` python
get_sum_of_numbers(["a", "b", "c", "d", "e"])
```
%% Cell type:code id: tags:
``` python
get_sum_of_numbers([1,2,3,4,5.01])
```
%% Cell type:code id: tags:
``` python
import numbers
def get_sum_of_numbers(alist):
assert all([isinstance(element, numbers.Number) for element in alist]), "Not all elements are Numbers"
tmp = 0
for element in alist:
tmp = alist[0]
for element in alist[1:]:
tmp = tmp + element
return(tmp)
```
%% Cell type:code id: tags:
``` python
get_sum_of_numbers([1,2,3,4,5.01])
```
%% Cell type:code id: tags:
``` python
get_sum_of_numbers([])
```
%% Cell type:code id: tags:
``` python
import numbers
def get_sum_of_numbers(alist):
assert len(alist) > 0, "List is empty"
assert all([isinstance(element, numbers.Number) for element in alist]), "Not all elements are Numbers"
tmp = 0
for element in alist:
tmp = alist[0]
for element in alist[1:]:
tmp = tmp + element
return(tmp)
```
%% Cell type:code id: tags:
``` python
get_sum_of_numbers([])
```
%% Cell type:markdown id: tags:
# Preconditions, postconditions and invariants
Assertions can be grouped into:
* Preconditions, which should be true the computional part of a function
* Postconditions, which should be true afterwards
* (Invariants, which should be true anywhere)
%% Cell type:code id: tags:
``` python
import numbers
def get_sum_of_numbers(alist):
# Preconditions
assert len(alist) > 0, "List is empty"
assert all([isinstance(element, numbers.Number) for element in alist]), "Not all elements are Numbers"
tmp = 0
for element in alist:
tmp = alist[0]
for element in alist[1:]:
tmp = tmp + element
return(tmp)
```
%% Cell type:code id: tags:
``` python
get_sum_of_numbers([1,2,3,4,5])
```
%% Cell type:code id: tags:
``` python
import numbers
def get_sum_of_numbers(alist):
# Preconditions
assert len(alist) > 0, "List is empty"
assert all([isinstance(element, numbers.Number) for element in alist]), "Not all elements are Numbers"
tmp = 0
for element in alist:
tmp = alist[0]
for element in alist[1:]:
tmp = tmp + element
tmp = 'Your code has been visited by an evil spirit!'
return(tmp)
```
%% Cell type:code id: tags:
``` python
get_sum_of_numbers([1, 2, 3])
```
%% Cell type:code id: tags:
``` python
import numbers
def get_sum_of_numbers(alist):
# Preconditions
assert len(alist) > 0, "List is empty"
assert all([isinstance(element, numbers.Number) for element in alist]), "Not all elements are Numbers"
tmp = 0
for element in alist:
tmp = alist[0]
for element in alist[1:]:
tmp = tmp + element
tmp = 'Your code has been visited by an evil spirit!'
# Postcondition
assert isinstance(tmp, numbers.Number), "Your sum isn't numerical..."
return(tmp)
```
%% Cell type:code id: tags:
``` python
get_sum_of_numbers([1, 2, 3])
```
%% Cell type:markdown id: tags:
# Test-Driven Development
Some programmers write code and then test that code somehow to be confident enough that it's bug free.
Other programms create tests and then write code that has to pass these tests in an iterative manner. This approach is called test-driven development.
%% Cell type:markdown id: tags:
We want to write a function that calculates the largest overlap between numerical ranges. Each numerical range is a two-element tuple specifying the upper and lower boundaries.
%% Cell type:markdown id: tags:
![caption](python-overlapping-ranges.png)
%% Cell type:code id: tags:
``` python
# Single range
assert range_overlap([ (0.0, 1.0) ]) == (0.0, 1.0)
# Two overlapping ranges
assert range_overlap([ (2.0, 3.0), (2.0, 4.0) ]) == (2.0, 3.0)
# Three overlapping ranges
assert range_overlap([ (0.0, 1.0), (0.0, 2.0), (-1.0, 1.0) ]) == (0.0, 1.0)
# What else is missing?
# Twice the same range
assert range_overlap([(0, 2), (0, 2)]) == (0.0, 2.0)
# Two non-overlapping ranges. What is the desired output? (0, 0)? None?
assert range_overlap([ (0.1, 1.0), (3.0, 4.0) ]) == None
# More than two non-overlapping ranges. See above.
assert range_overlap([ (0.1, 1.0), (3.0, 4.0), (10, 12) ]) == None
# Two intervals touching
assert range_overlap([(0, 2), (2, 4)]) == None
# empty input?
assert range_overlap([]) == None
```
%% Cell type:code id: tags:
``` python
def range_overlap(ranges):
max_left = ranges[0][0]
min_right = ranges[0][1]
# ranges[2:] returns an empty list if len(ranges) == 1 and nothing is being looped over.
for (left, right) in ranges[1:]:
max_left = max(max_left, left)
min_right = min(min_right, right)
return (max_left, min_right)
```
%% Cell type:code id: tags:
``` python
# Single range
assert range_overlap([ (0.0, 1.0) ]) == (0.0, 1.0)
# Two overlapping ranges
assert range_overlap([ (2.0, 3.0), (2.0, 4.0) ]) == (2.0, 3.0)
# Three overlapping ranges
assert range_overlap([ (0.0, 1.0), (0.0, 2.0), (-1.0, 1.0) ]) == (0.0, 1.0)
# What else is missing?
# Twice the same range
assert range_overlap([(0, 2), (0, 2)]) == (0.0, 2.0)
# Two non-overlapping ranges. What is the desired output? (0, 0)? None?
assert range_overlap([ (0.1, 1.0), (3.0, 4.0) ]) == None
# More than two non-overlapping ranges. See above.
assert range_overlap([ (0.1, 1.0), (3.0, 4.0), (10, 12) ]) == None
# Two touching intervals
assert range_overlap([(0, 2), (2, 4)]) == None
# empty input?
assert range_overlap([]) == None
```
%% Cell type:code id: tags:
``` python
def range_overlap(ranges):
max_left = ranges[0][0]
min_right = ranges[0][1]
# ranges[2:] returns an empty list if len(ranges) == 0 and nothing is being looped over.
for (left, right) in ranges[1:]:
max_left = max(max_left, left)
min_right = min(min_right, right)
if max_left > min_right:
return(None)
return (max_left, min_right)
```
%% Cell type:code id: tags:
``` python
# Single range
assert range_overlap([ (0.0, 1.0) ]) == (0.0, 1.0)
# Two overlapping ranges
assert range_overlap([ (2.0, 3.0), (2.0, 4.0) ]) == (2.0, 3.0)
# Three overlapping ranges
assert range_overlap([ (0.0, 1.0), (0.0, 2.0), (-1.0, 1.0) ]) == (0.0, 1.0)
# What else is missing?
# Twice the same range
assert range_overlap([(0, 2), (0, 2)]) == (0.0, 2.0)
# Two non-overlapping ranges. What is the desired output? (0, 0)? None?
assert range_overlap([ (0.1, 1.0), (3.0, 4.0) ]) == None
# More than two non-overlapping ranges. See above.
assert range_overlap([ (0.1, 1.0), (3.0, 4.0), (10, 12) ]) == None
# Two touching intervals
assert range_overlap([(0, 2), (2, 4)]) == None
# empty input?
assert range_overlap([]) == None
```
%% Cell type:code id: tags:
``` python
def range_overlap(ranges):
max_left = ranges[0][0]
min_right = ranges[0][1]
# ranges[2:] returns an empty list if len(ranges) == 1 and nothing is being looped over.
for (left, right) in ranges[1:]:
max_left = max(max_left, left)
min_right = min(min_right, right)
if max_left >= min_right:
return(None)
return (max_left, min_right)
```
%% Cell type:code id: tags:
``` python
# Single range
assert range_overlap([ (0.0, 1.0) ]) == (0.0, 1.0)
# Two overlapping ranges
assert range_overlap([ (2.0, 3.0), (2.0, 4.0) ]) == (2.0, 3.0)
# Three overlapping ranges
assert range_overlap([ (0.0, 1.0), (0.0, 2.0), (-1.0, 1.0) ]) == (0.0, 1.0)
# What else is missing?
# Twice the same range
assert range_overlap([(0, 2), (0, 2)]) == (0.0, 2.0)
# Two non-overlapping ranges. What is the desired output? (0, 0)? None?
assert range_overlap([ (0.1, 1.0), (3.0, 4.0) ]) == None
# More than two non-overlapping ranges. See above.
assert range_overlap([ (0.1, 1.0), (3.0, 4.0), (10, 12) ]) == None
# Two touching intervals
assert range_overlap([(0, 2), (2, 4)]) == None
# empty input?
assert range_overlap([]) == None
```
%% Cell type:code id: tags:
``` python
def range_overlap(ranges):
if len(ranges) == 0:
return(None)
max_left = ranges[0][0]
min_right = ranges[0][1]
# ranges[2:] returns an empty list if len(ranges) == 1 and nothing is being looped over.
for (left, right) in ranges[1:]:
max_left = max(max_left, left)
min_right = min(min_right, right)
if max_left >= min_right:
return(None)
return (max_left, min_right)
```
%% Cell type:code id: tags:
``` python
# Single range
assert range_overlap([ (0.0, 1.0) ]) == (0.0, 1.0)
# Two overlapping ranges
assert range_overlap([ (2.0, 3.0), (2.0, 4.0) ]) == (2.0, 3.0)
# Three overlapping ranges
assert range_overlap([ (0.0, 1.0), (0.0, 2.0), (-1.0, 1.0) ]) == (0.0, 1.0)
# What else is missing?
# Twice the same range
assert range_overlap([(0, 2), (0, 2)]) == (0.0, 2.0)
# Two non-overlapping ranges. What is the desired output? (0, 0)? None?
assert range_overlap([ (0.1, 1.0), (3.0, 4.0) ]) == None
# More than two non-overlapping ranges. See above.
assert range_overlap([ (0.1, 1.0), (3.0, 4.0), (10, 12) ]) == None
# Two touching intervals
assert range_overlap([(0, 2), (2, 4)]) == None
# empty input?
assert range_overlap([]) == None
```
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment