Python Functions¶
Functions are used everywhere and are very useful.
- Reusing code blocks
- Organizing code
- Many libraries provide and require functions
Think of a function f(x) like a machine:
- You put something in:
x - You operate on
xinside the function - The function returns some result
f(x).
Keywords
defreturn:
Format
def myFuncName(var_1, var_2, others):
# Insert any python code here
# You can create new variables, they can use var_1, var_2, etc.
# You can print things, load data from files, make plots, etc.
return XYZ # Often a function returns a value
# This is not required though
# XYZ can be be an expression, a variable you defined, etc.
Then we call the function like so:
myValue = myFuncName(5.5,8.8, etc)
Or define variables and use them in calling the function
x = 5.5
y = 8.8
z = myFuncName(x, y)
Or use the function where a value is wanted:
radius = 3
cylinder_volume = circle_area(radius)*height
Or:
print("cylinder volume =", height*circle_area(radius))
Practice¶
- Write a function called
my_sumthat takes two numbers as arguments and returns The sum. - Then call the function and store it as a variable.
- Then print the result
def my_sum(n1, n2):
return n1 + n2
my_sum(3,4)
my_sum(5,6)
Examples¶
- Compare the various versions of sum functions below
def sum_1(x,y):
z = x + y
return z
my_sum = sum_1(5,6)
print("The sum of 5 and 6 is", my_sum)
def sum_2(x,y):
print("The sum of", x, "and", y, "is", x+y)
print(sum_2(5,6))
a = sum_2(5,6)
a
The sum of 5 and 6 is 11 None The sum of 5 and 6 is 11
def sum_3(x,y):
z = x+y
return z
print("This will not print: it's after the return")
print( sum_3(5,6) )
def sum_and_times(x,y):
return x+y, x*y
11 11 30
def sum_4(x,y):
the_sum = x+y
return the_sum
a = 6
b = 7
c = sum_4(a, b)
print("The sum of", a, "and", b, "is", c)
def add_and_multiply(x,y):
return x+y, x*y
sp = add_and_multiply(5,6)
print(sp[0], sp[1])
s, p = add_and_multiply(5,6)
print(s, p)
Key points¶
- Remember the
defand the:and thereturn - Return statements are optional, depending on what you want to do.
- We can call functions with arguments as values, like
sum_3(5,6). - We can create variables to hold values, then pass those variables as function arguments, like
x=5 y=7 z = sum_5(x,y) - The names of variables in the function argument list are independent of the variable names you pass to the function.
- If I write $f(x) = x^2$, it is fine to write $f(5)$.
- The function will take $x$ to be 5, then compute $5^2$.
- If I write $f(x) = x^2$, it is fine to write $a=3$, $f(a)$.
- The function will take $x$ to be $a$, then will compute $a^2$.
- Since $a=3$, the result will be $3^2$.
- If I write $f(x) = x^2$, it is fine to write $f(5)$.
- If the function returns a value, we can use it wherever a value is expected
- As in
z = sum_3(x,y) - Or this
print(sum_3(x,y))
- As in
Practice¶
- Write a function called
ft_to_mthat will take a length in feet and convert it to a length in meters. - Use the converstion 1 m = 3.28084 ft.
def ft_to_m(Lft):
return Lft / 3.28084
Lm = ft_to_m(6.0)
Lm
1.828799941478402
Practice¶
- Write a function called
P_IGthat takes the number of moles, temperature, and volume as aguments, and returns the ideal gas pressure. - Try out the function.
- Don't forget to comment your code, including comments.
- Use good variable names.
def P_IG(n, T, V):
'''
Ideal gas pressure, given stuff
SI units
n: kmoles
T: temperature (K)
V: volume (m3)
returns P (Pa)
'''
Rg = 8314.46 # J/kmol*K
P = n*Rg*T/V # Pa
return P
P = P_IG(1, 300, 1)
P_IG?
Signature: P_IG(n, T, V) Docstring: Ideal gas pressure, given stuff SI units n: kmoles T: temperature (K) V: volume (m3) returns P (Pa) File: /var/folders/7p/8pv6mqv57zqch5cjq3vxp0940000gn/T/ipykernel_96237/4064544002.py Type: function
Docstrings: documentation¶
A triple quoted string at the beginning of the function is a docstring that is output when getting "help" on the function.
def square_it(x):
"""
input: x
return: x**2
type "help(square_it)" to see these comments.
"""
return x*x
help(square_it)
Functions can have default arguments¶
get_force- $f = mg$ with default g=9.81
- explicit arguments
def get_force(m, g=9.81):
return m*g
print(5,6,7,8,9, sep=" kittens ", end='abc')
print('hi there')
5 kittens 6 kittens 7 kittens 8 kittens 9abchi there
Practice¶
- Rewrite your
P_IGfunction above to use a default value forRg.
Type help(print) and see the default arguments.
print(1,2,3, sep="\n")
Function arguments can be specified out of order if we are explicit about the names¶
def myfunc(a,b) :
print("a = ", a)
print("b = ", b)
myfunc(b=7,a=5) # note, calling with the opposite argument order
import this
a = 5 b = 7 The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than *right* now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those!
Functions can be passed as arguments to other functions¶
Example
- For given $x_1$, and $x_2$, compute $S = f(x_1)+f(x_2)$ for any function $f$
#-------------- Define the sum function
def sum_func(f, x1, x2):
return f(x1) + f(x2)
#-------------- Define the functions to be summed
def f_a(x):
return 2*x
def f_b(x):
return x**0.5
import numpy as np
#-------------- Define the values of x and call sum_func
x1 = 4
x2 = 9
print( sum_func(f_a, x1, x2) )
print( sum_func(f_b, x1, x2) )
print( sum_func(np.sin, x1, x2) )
Practice¶
- Write a function that computes the following integral for any function $f(x)$ $$I = \int_a^bf(x)dx$$
- Evaluate the integral using the areas of two trapazoids.
- Find a midpoint $m=(a+b)/2$.
$$I = \underbrace{(m-a)\frac{f(a)+f(m)}{2}}_{\text{trapazoid 1}} + \underbrace{(b-m)\frac{f(m)+f(b)}{2}}_{\text{trapazoid 2}}$$
- Try this on $I = \int_1^2x^2dx = 2.33333$
- Question: what is the structure?
- How many functions do you need to define?
- How to call the function?
- What order to define things in.
- After you have thought about this, look at the previous example and consider it's structure.
Scope: global, local¶
- Variables or functions defined inside a function are local to that function and cannot be seen outside of it.
- Variables or functions defined outside a function are global and can be seen inside later functions.
a = 5.5 # a has global scope
def ff():
print("a = ", a) # a isn't passed in, but is known
ff()
a = 1.1
def ff2():
a = 2.2 # this is a NEW local a, not the same as above
print("inside: a = ", a)
ff2()
print("outside: a = ", a)
Note¶
- Often you are given problems with many known parameters.
- It is normally best to put the parameters inside the function, rather than outside the function.
- This lets the function stand alone.
- (There may be reasonable exceptions to this rule though.)
Previously we used the following vapor pressure equation, with values of A, B, C given for Benzene. $$P_i^{sat}(T) = \exp\left(A_i - \frac{B_i}{T+C_i}\right)$$.
- A = 13.7819
- B = 2726.81
- C = 217.572
Code this function.
import numpy as np
#---------- DO THIS
def Psat_B(T):
A = 13.7819
B = 2726.81
C = 217.572
return np.exp(A - B/(T+C))
#---------- NOT THIS
A = 13.7819
B = 2726.81
C = 217.572
def Psat_B(T):
return np.exp(A - B/(T+C))
A function must be defined before it is USED¶
- If you write some code that uses functions that are not defined until later, it won't work, because python doesn't know about the functions yet.
a = 5.5
print(f_below(a)) # function that is not defined yet!
30.25
def f_below(x):
return x*x
But note that the following works just fine.
- function
auses functionb, butbis defined belowa - But this works because both
aandbare defined whenais actually called
def a(x):
return b(x)
def b(x):
return x**2
print( a(3) )
Similarly, consider this example
- The function uses
g, which is not defined until after the function is defined. - Will this work?
def fma(m):
return m*g
g = 9.81
F = fma(100)
print(F)
- This works because g is defined when the function is called, that is, it is defined at the time it is needed.
See also:¶
- Built-in Python functions
- There are tons of other functions available through Python libraries, like numpy
- anonymous (lambda) functions
- *args and **kwargs
help(print)
Help on built-in function print in module builtins:
print(*args, sep=' ', end='\n', file=None, flush=False)
Prints the values to a stream, or to sys.stdout by default.
sep
string inserted between values, default a space.
end
string appended after the last value, default a newline.
file
a file-like object (stream); defaults to the current sys.stdout.
flush
whether to forcibly flush the stream.
a = 5
b = 6
print(a,b, sep = ' kittens ')
5 kittens 6