Functions#
The general concept of programming is to define a set of operations for a computer to execute. The building blocks
making up a program can be written in terms of a function
that take in input values and return a result. In its
simplest form, a function (or method) is defined with:
def fun(arg):
"""
Some function.
:param arg: Some input argument.
"""
return arg
Let’s brake this down.
The
def
keyword marks the beginning of the function signature. Everything that is part of a function must be indented (1 tab or 4 spaces) below it.Input arguments (
arg
) are added within the parenthesis. The signature ends with a column:
.It is good practice adding
docstrings
to document what the function does and what the input parameters are. The block of text is bookended by triple quotes ("""
).
See the Best Practice section for additional styling guides.
In this case, the fun
function simply takes an input argument arg
and returns it back.
print(fun("abc"))
abc
For loop#
We will try again with a slightly more interesting example that uses a for
loop iterator. Say we are given assay
results down a drillhole.
grades = [0.1, 0.02, 1.3, 2.4, 3.5, 0.01]
depths = [10, 55, 80, 105, 115, 120]
We would like to know the depths
where grades
are above 1.
There are many (faster) to solve this problem, but let’s first find the grade values above some threshold.
def anomalous(values, threshold):
"""
Find the elements of a list above threshold
"""
bool_list = []
for val in values:
bool_list.append(val > threshold)
return bool_list
The anomalous
function takes in as input a list of grade values
and a threshold
,
then returns a list of bool
’s (true or false) to indicate which elements are above 1.
This function performs three steps
Use a
for
loop iterator to visit every element of the list.Check if the element is above threshold with logic “>”.
Add the result to a
logic
list using the.append
method.
Calling this method on our grades
with a threshold
= 1.0 yields
logic = anomalous(grades, 1.0)
logic
[False, False, True, True, True, False]
Note that the same operation could also have been done with an in-line
approach such that
logic = [val > 1.0 for val in grades]
logic
[False, False, True, True, True, False]
In-line operations are more compact (and usually faster) than appending values within a for
loop operation,
and would have not required to create the anomalous
function. In the end, both gives back the same result.
Keyword Arguments#
Other than the required input arguments, Python also allows for default values to be stored
in the signature of the function as keyword arguments (kwargs
). Let’s suppose we would like to set a default
value for the threshold
. We could re-write the anomalous
function as:
def anomalous(values, threshold=1.0): # pylint: disable=E0102
"""
Find the elements of a list above threshold
"""
bool_list = []
for val in values:
bool_list.append(val > threshold)
return bool_list
Since threshold
already has a value, then the argument becomes optional and the function still runs without it.
anomalous(grades)
[False, False, True, True, True, False]
If not assigned specifically as keyword arguments, Python will simply distribute the extra arguments in the order defined in the signature of the function. For example
anomalous(grades, 2.0)
[False, False, False, True, True, False]
Example 2: If statement#
Next in our assay analysis, we would like get the depth interval for the anomalous grades. We can write a second
function that takes the result of anomalous
such that
def get_depths(values: list, conditions: list[bool]):
"""
Extract interval of values from bool logic
"""
output = []
for val, cond in zip(values, conditions):
if cond:
output.append(val)
return output
The get_depths
function takes in two lists, one of values and another one for the logic (bool
), and returns a
subset of values if the conditions
are True
. Here are a few Python details to highlight
The
if
statement used to test a condition (true or false). Other conditions areelif
: Always follows and if statement, requires a condition.else
: Always used at the end ofif
statements, no condition used.
The
zip
method allows iterating over multiple lists at the same time. If the inputs have different lengths, the iteration will stop once it reaches the end of the shortest list.We use
typing
(e.g.conditions: list[bool]
) in the signature of the function to specify the type required for the input arguments. The type is not enforced on runtime, but mainly good-practice as it can be used for code analysis and documentation.
Calling the get_depths
method with the grades
and logic
previously computed we get
get_depths(grades, logic)
[1.3, 2.4, 3.5]
Copyright (c) 2022 Mira Geoscience Ltd.