def double(x):
"""this is where you can put an optional docstring
that explains what the function does.
for example, this function multiplies its input by 2"""
return x * 2
y = double(10) # doubles integer value 10
y # prints it
A function may or may not return an output value. For example, the fib function below calculates and prints the Fibonacci series. It does not return any output values.
def fib(n): # write Fibonacci series up to n
"""Print a Fibonacci series up to n."""
a, b = 0, 1
while a < n:
print(a, end=' ')
a, b = b, a + b
print()
# Now call the function we just defined:
fib(100)
When a functions needs to return an output value, it uses the return operator. In the example below, the fib2 function returns a list of the numbers of the Fibonacci series instead of printing them:
def fib2(n): # return Fibonacci series up to n
"""Return a list containing the Fibonacci series up to n."""
result = []
a, b = 0, 1
while a < n:
result.append(a) # see below
a, b = b, a + b
return result
f100 = fib2(100) # call it
f100 # write the result
Task 1 Write a Python function to check
whether a number is in a given range
Input
number_in_range(x, start, until)
Output
YES, 4 is in the range from 1 to 6
Task 2 Write a Python function that accepts
a string and calculate the number of upper case
letters and lower case letters.
Input
The quick Brown Fox
Output
No. of Upper case characters : 3
No. of Lower case Characters : 13
A Hint: use .isalpha() method (also .islower() and .isupper())
Python allows functions to call themselves to loop. This technique is known as recursion.
For example, here is how we can use recursion to write a function that sums a list of numbers:
def mysum(L):
if not L:
return 0
else:
return L[0] + mysum(L[1:]) # Call mysum recursively
x = mysum([1,2,3,4,5])
x
Here is how we can calculate a factorial using recursion:
def factorial(n):
if n < 1: # base case
return 1
else:
return n * factorial(n - 1) # recursive call
for i in range(10):
print(f"{i}! = {factorial(i)}")
print("{}! = {}".format(i, factorial(i)))
Task 3 Write a Python program to calculate the value of 'a' to the power 'b'
Use recursion.
Input:
power_func(3,4)
Output
81
Python functions are first-class, which means that we can assign them to variables and pass them into functions just like any other arguments:
def double(x):
return x * 2
def apply_to_one(f):
"""calls the function f with 1 as its argument"""
return f(1)
print(double(2))
my_double = double # refers to the previously defined
print(my_double)
x = apply_to_one(my_double) # equals 2
print(x)
It is also easy to create short anonymous functions, or lambdas:
def add_four(x):
return x + 4
def apply_to_one(f):
return f(1)
def apply_to_two(f):
return f(2)
a = 4
"4"
y = apply_to_one(add_four) # equals 5
print(y)
You can assign lambdas to variables, although most people will tell you that you should just use def instead:
another_double1 = lambda x: 2 * x # don't do this
def another_double2(x): return 2 * x # do this instead
print(another_double1(4))
print(another_double2(6))
We can pass lambdas to other functions as arguments and return them from functions as return values.
def doubler(f):
return lambda x: 2 * f(x)
g = doubler(lambda x: x + 1)
print(g)
print(g(-1))
print(g(0))
# it's ok to have a little headache at this point, don't give up
In practice, using functions as variables can be helpful for optimization.
import numpy as np
from scipy.optimize import fmin
import math
def simple_function(x):
# minimum is at x = 2 (-b/2a)
return x*x - 4*x + 1
def complex_function(x):
# x is a vector
# the coordinates of a point are (x[0], x[1])
exp = (math.pow(x[0], 2) + math.pow(x[1], 2)) * -1
return math.exp(exp) * math.cos(x[0] * x[1]) * math.sin(x[0] * x[1])
(xopt, fopt, *info) = fmin(simple_function,np.array([0]), full_output=1)
print('The minimum is achieved at the point x = {}. The minimum value is {}'.format(xopt[0], fopt))
(xopt, fopt, *info) = fmin(complex_function,np.array([0,0]), full_output=1)
print('The minimum is achieved at the point x = {}, y = {}. The minimum value is {}'.format(xopt[0], xopt[1], fopt))
A function can has from zero to many arguments.
def func0(): # Zero parameters
pass
def func1(x): # One parameter
pass
def func5(a, b, c, d, e): # Five parameters
pass
Sometimes you may want to pass an arbitrary number of arguments:
print(1, 2, 3, 4, 5, 6 ,7, 8)
def funcx(*args):
print(type(args))
for arg in args:
print(arg)
funcx(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Function parameters can be given default arguments, which only need to be specified when you want a value other than the default:
def my_print(message="my default message"):
print(message)
my_print("hello") # prints 'hello'
my_print(message="keyword message") # prints 'my default message'
It is sometimes useful to specify arguments by name:
def subtract(a=0, b=0):
return a - b
# Passing arguments without specifying their names:
print(subtract()) # prints 0
print(subtract(10, 5)) # prints 5
print(subtract(0, 5)) # prints -5
# Arguments with names"
print(subtract(b=5)) # prints -5
print(subtract(b=5, a=10)) # prints 5
print(subtract(a=10, b=5)) # prints 5
Scope rules:
This is an example demonstrating how to reference the different scopes and namespaces, and how global and nonlocal affect variable binding:
def scope_test():
def do_local():
spam = "local spam"
def do_nonlocal():
nonlocal spam
spam = "nonlocal spam"
def do_global():
global spam
spam = "global spam"
spam = "test spam"
do_local()
print("After local assignment:", spam)
do_nonlocal()
print("After nonlocal assignment:", spam)
do_global()
print("After global assignment:", spam)
scope_test()
print("In global scope:", spam)
def outer():
x = "local"
def inner():
nonlocal x
x = "nonlocal"
print("inner:", x)
inner()
print("outer:", x)
outer()
Note how the local assignment (which is default) did not change scope_test’s binding of spam. The nonlocal assignment changed scope_test’s binding of spam, and the global assignment changed the module-level binding.
You can also see that there was no previous binding for spam before the global assignment.
x = mysum([1,2,3,4,5]) if not L: return L[0] + mysum(L[1:]) if not L: return L[0] + mysum(L[1:])