Skip to content
Snippets Groups Projects
Commit 033b6a0a authored by Renato Alves's avatar Renato Alves :seedling:
Browse files

No parenthesis needed on return

In Python, return is a keyword not a function
parent a54984e5
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 = None
for element in alist:
if tmp == None:
tmp = element
else:
tmp = tmp + element
return(tmp)
return tmp
```
%% Cell type:code id: tags:
``` python
get_sum_of_numbers([1,2,3,4,5])
```
%% Output
15
%% Cell type:code id: tags:
``` python
get_sum_of_numbers(["a", "b", "c", "d", "e"])
```
%% Output
'abcde'
%% 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 = None
for element in alist:
if tmp == None:
tmp = element
else:
tmp = tmp + element
return(tmp)
return tmp
```
%% Cell type:code id: tags:
``` python
get_sum_of_numbers([1,2,3,4,5])
```
%% Output
15
%% Cell type:code id: tags:
``` python
get_sum_of_numbers(["a", "b", "c", "d", "e"])
```
%% Output
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
<ipython-input-90-7bd3d4f8528b> in <module>
----> 1 get_sum_of_numbers(["a", "b", "c", "d", "e"])
<ipython-input-88-a16d13d448b4> in get_sum_of_numbers(alist)
1 def get_sum_of_numbers(alist):
----> 2 assert all([isinstance(element, int) for element in alist]), "Not all elements are integers"
3 tmp = None
4 for element in alist:
5 if tmp == None:
AssertionError: Not all elements are integers
%% Cell type:code id: tags:
``` python
get_sum_of_numbers([1,2,3,4,5.01])
```
%% Output
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
<ipython-input-91-d71b6bf3bcf6> in <module>
----> 1 get_sum_of_numbers([1,2,3,4,5.01])
<ipython-input-88-a16d13d448b4> in get_sum_of_numbers(alist)
1 def get_sum_of_numbers(alist):
----> 2 assert all([isinstance(element, int) for element in alist]), "Not all elements are integers"
3 tmp = None
4 for element in alist:
5 if tmp == None:
AssertionError: Not all elements are integers
%% 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 = None
for element in alist:
if tmp == None:
tmp = element
else:
tmp = tmp + element
return(tmp)
return tmp
```
%% Cell type:code id: tags:
``` python
get_sum_of_numbers([1,2,3,4,5.01])
```
%% Output
15.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 = None
for element in alist:
if tmp == None:
tmp = element
else:
tmp = tmp + element
return(tmp)
return tmp
```
%% Cell type:code id: tags:
``` python
get_sum_of_numbers([])
```
%% Output
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
<ipython-input-96-408adf4db5ec> in <module>
----> 1 get_sum_of_numbers([])
<ipython-input-95-7d1e398e65a2> in get_sum_of_numbers(alist)
1 import numbers
2 def get_sum_of_numbers(alist):
----> 3 assert len(alist) > 0, "List is empty"
4 assert all([isinstance(element, numbers.Number) for element in alist]), "Not all elements are Numbers"
5 tmp = None
AssertionError: List is empty
%% 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 = None
for element in alist:
if tmp == None:
tmp = element
else:
tmp = tmp + element
return(tmp)
return tmp
```
%% Cell type:code id: tags:
``` python
get_sum_of_numbers([1,2,3,4,5])
```
%% Cell type:code id: tags:
``` python
def get_sum_of_numbers(alist):
# Preconditions
assert len(alist) > 0, "Cannot compute the mean of nothing"
assert all([isinstance(element, int) for element in alist]), "Not all elements of your list are integer"
tmp = None
for element in alist:
if tmp == None:
tmp = element
else:
tmp = tmp + element
tmp = 'Your code has been visited by an evil spirit!'
return(tmp)
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 = 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)
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