Protect the user:
Make assumptions and expectations explicit.
Produce errors when expectations are not met.
Consider error options, and perform error management:
Protect the developer (you!)
Test the expected behavior of your functions:
Capture unexpected errors to identify further options for error management
You can automate running tests when pushing to Github using Continuous Integration
Tests are definitely worth learning when your project increases in size!
More on tests later…
def read_vector_value(index=0, my_vector=[10,5,4,12,25]):
if index > len(my_vector) - 1:
raise IndexError('Index higher than vector length.')
return my_vector[index]
read_vector_value(index=6)
. . .
Why not simply adjust the function output?
def read_vector_value(index=0, my_vector=[10,5,4,12,25]):
if index > len(my_vector) - 1:
return None
return my_vector[index]
print(read_vector_value(index=6))
. . .
Because it is unclear if None
is expected behavior or indicative of a problem.
If you do not want to interrupt your script when an error is raised: use try/catch (‘except’ in Python). NB: Note that Python allows you to distinguish by error type!
# ensure that the function is correctly in memory
def read_vector_value(index=0, my_vector=[10,5,4,12,25]):
if index > len(my_vector) - 1:
raise IndexError('Index higher than vector length.')
return my_vector[index]
Compare:
and
In R you can use tryCatch():
read_vector_value <- function(index=1,my_vector=c(10,5,4,12,25)){
if(index>length(my_vector)){
stop("Index higher than vector length.")}
return(my_vector[index])
}
Catch the exception:
Consider early statements in the script to validate (data) input.
With if/else (Python):
With try/catch (R):
Expect the worst:
Identify assumptions in your code
Make the input/data assumptions explicit
Test the input for a function
Workshop Computational Reproducibility