def multiply2(x):
"""Multiply by two"""
return x * 2
def divide(numerator, denominator):
pass
multiply2(4)
8
A function return alwais something, even if is not specify
divide(1, 0) is None
True
def func0(x):
return
def func1(x):
return None
def func2(x):
y = x**x
x = 2
print func0(x) == func1(x) == func2(x) == None
True
Define a simple function, again, and use it a parameter of another function!
def add(a, b):
return a + b
def fun(a, b, func):
return func(a, b)
fun('c','d', add)
'cd'
Write the divide function in order to manage zero division and not numeric values [5 minutes]
def divide(numerator, denominator):
pass
Use the code below as a test:
divide(4, 2) # return 2
2
divide(4, 0) # print Divide a number with 0 is not a valid operation!
Divide a number with 0 is not a valid operation!
divide(1,'a') # print Not a valid parameter!
Not a valid parameter!
One possible solution is:
Use a number variable of parameters.
def summatory(*args):
result = 0
for num in args:
result += num
return result
summatory(1, 2, 3, 4, 5)
15
summatory(*range(1, 6))
15
range(1, 6) # start, stop, step
[1, 2, 3, 4, 5]
Define a custom function with some default parameters
def multiply(number, mult=2):
return number * mult
multiply(4)
8
multiply('a')
'aa'
multiply('a', 6)
'aaaaaa'
multiply('a', mult=8)
'aaaaaaaa'
Undefined number of key-value parameter
def contact(**kargs):
for key, val in kargs.items():
print "%s => %r" % (key, val)
contact(pietro=33312388, john=2345678)
pietro => 33312388 john => 2345678
Define a function that given a number variable of parameters and key-value parameters, print: [5 minutes]
arg: 1
arg: 2
arg: a
arg: [1, 2, 3]
karg[other]: 'ciao'
karg[key]: 'value'
args_kargs(1,2,'a',[1,2,3], key='value', other='ciao')
arg: 1 arg: 2 arg: 'a' arg: [1, 2, 3] karg[other]: 'ciao' karg[key]: 'value'
Solution
def args_kargs(*args, **kargs):
pass
Function containig other functions
def summ_mult(list_of_tuple):
# define a new function inside
def summ(tupl):
res = 0
for x in tupl:
res += x
return res
result = 1
for el in list_of_tuple:
result *= summ(el)
return result
summ_mult([(1,2,3), (4,5,6)])
A function could return something using the command return
or inside a cycle using yield
:
def use_yield(*args):
for a in args:
yield a * 2
use_yield(1, 2, 3, 4, 'a')
Using yield
transform the function in to a generator, every time that we ask to the generator the next
value, the generator compute the next and it will return the resulting object, in this way we don't need to reserve the memory for the list, therefore consume less memory and is generally faster.
[i for i in use_yield(1, 2, 3, 4, 'a')]
usy = use_yield(1, 2, 3, 4, 'a')
usy.next()
Useful functions in the python standard library: http://docs.python.org/2/library/functions.html#built-in-functions
str(2.8)
range(1,10,2)
xrange(1,10,2)
[i for i in xrange(1,10,2)]
len([1, 2, 3, 4]) # return the lenght of an object
names = ['one', 'two', 'three', 'four', 'five']
values = [1, 2, 3, 4, 5]
zip(names, values) # return a list of pairs
for name, value in zip(names, values):
print '%5s = %d' % (name, value)
dir('a') # return all the attributes of an object
Decorator are object that are called to do something before and after a method or a function.
VERBOSE = True
def verbose(func):
def wrapper(*args):
if VERBOSE:
print "Before to execute: %s" % func.func_name
result = func(*args)
if VERBOSE:
print "After the execution: %s" % func.func_name
return result
return wrapper
We can test our decorator with:
verbose(multiply2)(1)
Usually decorators are used with "@", and are very useful when you want to avoid to repeat the same operations to different functions.
VERBOSE = True # try to change
@verbose
def mult(*args):
result = args[0]
for i in args[1:]:
result *= i
return result
mult(1, 2, 3, 4)
Write another decorator that print the execution time of a function.
import time
def timeit(function):
def timed(*args, **kargs):
# do something before
time_start = time.time()
# execute the function
result = function(*args, **kargs)
# do something after
time_end = time.time()
print 'name=%r (args=%r, kargs=%r) processing time=%10.8f sec' % (function.__name__, args, kargs, time_end - time_start)
return result
return timed
timeit(multiply2)(2)
@timeit
def mult(*args):
result = 1
for a in args:
result *= a
return result
mult(1,2,3,4)