294 KiB
Session 3¶
Functions¶
A function is a block of code that is first defined, and thereafter can be called to run as many times as needed. A function might have arguments, some of which can be optional if a default value is specified.
A function is called by parantheses: function_name()
. Arguments are placed inside the paranthes and comma separated if there are more than one.
Similar to f(x, y)
from mathematics.
A function can return one or more values to the caller. The values to return are put in the return
statement, which ends the function. If no return
statement is given, the function will return None
.
The general syntax of a function is:
def function_name(arg1, arg2, default_arg1=0, default_arg2=None):
'''This is the docstring
The docstring explains what the function does, so it is like a multi line comment. It does have to be here,
but it is good practice to use them to document the code. They are especially useful for more complicated
functions.
Arguments could be explained togehter with their types (e.g. strings, lists, dicts etc.).
'''
# Function code goes here
# Possible 'return' statement terminating the function. If 'return' is not specified, function returns None.
return return_val1, return_val2
If multiple values are to be returned, they can be separeted by commas. The returned entity will by default be a tuple.
Note that when using default arguments, it is good practice to only use immutable types as defaults. An example further below will demonstrate why this is recmommended.
Basic functions¶
A simple function with one argument is defined below.
def f(x):
return 6.25 + x + x**2
Note: No code has been executed yet. It has merely been defined and ready to run when called.
Calling the function with an argument returns:
print(f(5))
If we define a function without returning anything, it returns None
:
def first_char(word):
word[0] # <--- No return statment, function returns None
a = first_char('hello') # Variable a will be equal to None
print(a)
Often a return value is wanted from a function, but there could be scenarios where it is not wanted. E.g. if you want to mutate a list by the function. Consider this example:
def say_hello_to(name):
''' Say hello to the input name '''
print(f'Hello {name}')
say_hello_to('Anders') # <--- Calling the function prints 'Hello {name}'
r = say_hello_to('Anders')
print(r) # <--- Prints None, since function does not return anyhing
The function was still useful even though it did not return anything.
Local vs. global variables¶
- Global variables: Variables defined outside a function
- Local variables: Varaiables defined inside a function
Local variables cannot be accessed outside the function. By returning a local variable and saving it into a global variable we can use the result outside the function, in the global namespace.
Default arguments¶
A little side note¶
A good practice is to use only immutable types as default arguments. Python will allow mutable arguments to be given as defaults, but the behavior can be confusing if the default argument is mutated within the function.
The enumerate
function¶
The enumerate
function is useful whenever you want to loop over an iterable together with the index of each value:
letters = ['a', 'b', 'c', 'd', 'c']
for idx, letter in enumerate(letters):
print(idx, letter)
for idx, letter in enumerate(letters, start=1): # Starting at 1 (internally, enumerate has start=0 set as default)
print(idx, letter)
The zip
function¶
The zip
function is useful when you want to put two lists up beside eachother and loop over them.
diameters = [10, 12, 16, 20, 25]
areas = [3.14 * (d/2)**2 for d in diameters]
for d, A in zip(diameters, areas):
print(d, A)
Imports¶
Libraries¶
A quick overview of imports of libraries in Python, here shown for the math library:
import math # Let's you access everything in the math library by dot-notation (e.g math.pi)
from math import pi # Let's you use pi directly
from math import * # Let's you use everything in the math library directly
The last one is not considered good practice, since varaibles will be untracable. It can be good for making quick tests though.
Your own modules¶
You can also import your own .py files this way and access the functions inside them. It is easiest if the file to import is located in the same folder as the .py file you want to import to. Note that Python files .py are normally called modules.
An example:
import my_module # my_module could be your own python file located in same directory
If you have a function inside my_module
called my_func
, you can now call it as my_module.my_func()
.
Exercise 1¶
Finish the function below that takes a radius as input and make it return the circle area.
def circle_area(r):
'''Return circle area'''
# Your code goes here
Try to call it to see if it works. If you wan to access pi
to avoid typing it out yourself, put the line from math import pi
at some point before calling the function.
Exercise 2¶
Write a function that takes a list radii
as input and returns a list of the corresponding circle areas. Try to set it up from scrath and test it.
You can use the function from the previous exercise if you want.
Exercise 3¶
Write the function described in the docstring below.
def is_pile_long(pile_lengths):
''' Return a list with elements `True` for all piles longer than or equal to 5m, `False` otherwise.
Args:
pile_length : A list containing pile lengths
Example:
is_pile_long([[4.51, 6.12, 4.15, 7.31, 5.01, 4.99, 5.00]])
---> [False, True, False, True, True, False, True]
'''
# Your code goes here
Exercise 4¶
Finish the function below so it does as described in the docstring. Remember to import the sqrt
function from the math module.
def dist_point_to_line(x, y, x1, y1, x2, y2):
'''Return distance between a point and a line defined by two points.
Args:
x : x-coordinate of point
y : y-coordinate of point
x1 : x-coordinate of point 1 defining the line
y1 : y-coordinate of point 1 defining the line
x2 : x-coordinate of point 2 defining the line
y2 : y-coordinate of point 2 defining the line
Returns:
The distance between the point and the line
'''
# Your code goes here
The distance between a point $(x, y)$ and a line passing through points $(x_1, y_1)$ and $(x_2, y_2)$ can be found as
\begin{equation*} \textrm{ distance}(P_1, P_2, (x, y)) = \frac{|(y_2-y_1)x - (x_2-x_1)y + x_2 y_1 - y_2 x_1|}{\sqrt{ (x_2-x_1)^2 + (y_2-y_1)^2 }} \end{equation*}Call the function to test if it works. Some examples to test against:
dist_point_to_line(2, 1, 5, 5, 1, 6) --> 4.61
dist_point_to_line(1.4, 5.2, 10.1, 2.24, 34.142, 13.51) --> 6.37
Exercise 5¶
Given a line defined by points $(x_1, y_1)=(2, 3)$ and $(x_2, y_2)=(8, 7)$, compute the distance to the points with the coordinates below and put the results into a list
x_coords = [4.1, 22.2, 7.7, 62.2, 7.8, 1.1]
y_coords = [0.3, 51.2, 3.5, 12.6, 2.7, 9.8]
You can either use a list comprehension or create a traditional for
loop where results get appended to the list in every loop.
Exercise 6¶
Create a function that calculates the area of a simple (non-self-intersecting) polygon by using the so-called Shoelace Formula
$$ A_p = \frac{1}{2} \sum_{i=0}^{n-1} (x_i y_{i+1} - x_{i+1} y_i) $$The area is signed depending on the ordering of the polygon being clockwise or counter-clockwise. The numerical value of the formula will always be equal to the actual area.
The function should take three input parameters:
xv
- list of x-coordinates of all verticesyv
- list of y-coordinates of all verticessigned
- boolean value that dictates whether the function returns the signed area or the actual area. Default should be actual area.
Assume that the polygon is closed, i.e. the first and last elements of xv
are identical and the same is true for yv
.
A function call with these input coordinates should return 12.0
:
x = [3, 4, 7, 8, 8.5, 3]
y = [5, 3, 0, 1, 3, 5]
Exercise 7¶
Write a function that calculates and returns the centroid $(C_x, C_y)$ of a polygon by using the formula:
$$ C_x = \frac{1}{6A} \sum_{i=0}^{n-1} (x_i+x_{i+1}) (x_i y_{i+1} - x_{i+1} y_i) $$$$ C_y = \frac{1}{6A} \sum_{i=0}^{n-1} (y_i+y_{i+1}) (x_i y_{i+1} - x_{i+1} y_i) $$x
and y
are lists of coordinates of a closed simple polygon.
Here, $A$ is the signed area. When you need $A$, call the function from the previous exercise to get it. Be sure to call it with the non-default signed=True
.
A function call with the input coordinates below should return (6.083
, 2.583
):
x = [3, 4, 7, 8, 8.5, 3]
y = [5, 3, 0, 1, 3, 5]
If you are up for more¶
Try to write a function that can calculate the elastic centroid of a section with materials of two different stiffness values. E.g. a reinforced polygon concrete section.