{ "metadata": { "name": "03_function" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Functions" ] }, { "cell_type": "code", "collapsed": false, "input": [ "def multiply2(x):\n", " \"\"\"Multiply by two\"\"\"\n", " return x * 2\n", "\n", "def divide(numerator, denominator):\n", " pass" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 1 }, { "cell_type": "code", "collapsed": false, "input": [ "multiply2(4)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 2, "text": [ "8" ] } ], "prompt_number": 2 }, { "cell_type": "markdown", "metadata": {}, "source": [ "A function return alwais something, even if is not specify" ] }, { "cell_type": "code", "collapsed": false, "input": [ "divide(1, 0) is None" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 3, "text": [ "True" ] } ], "prompt_number": 3 }, { "cell_type": "code", "collapsed": false, "input": [ "def func0(x):\n", " return\n", "\n", "def func1(x):\n", " return None\n", "\n", "def func2(x):\n", " y = x**x\n", "\n", "x = 2\n", "print func0(x) == func1(x) == func2(x) == None" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "True\n" ] } ], "prompt_number": 4 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Define a simple function, again, and use it a parameter of another function!" ] }, { "cell_type": "code", "collapsed": false, "input": [ "def add(a, b):\n", " return a + b\n", "\n", "def fun(a, b, func):\n", " return func(a, b)\n", "\n", "fun('c','d', add)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 5, "text": [ "'cd'" ] } ], "prompt_number": 5 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Exercise 8" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Write the divide function in order to manage zero division and not numeric values [5 minutes]" ] }, { "cell_type": "code", "collapsed": false, "input": [ "def divide(numerator, denominator):\n", " pass" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 9 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Use the code below as a test:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "divide(4, 2) # return 2" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "2\n" ] } ], "prompt_number": 12 }, { "cell_type": "code", "collapsed": false, "input": [ "divide(4, 0) # print Divide a number with 0 is not a valid operation!" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Divide a number with 0 is not a valid operation!\n" ] } ], "prompt_number": 11 }, { "cell_type": "code", "collapsed": false, "input": [ "divide(1,'a') # print Not a valid parameter!" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Not a valid parameter!\n" ] } ], "prompt_number": 10 }, { "cell_type": "markdown", "metadata": {}, "source": [ "One possible solution is:" ] }, { "cell_type": "code", "collapsed": false, "input": [], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Use a number variable of parameters." ] }, { "cell_type": "code", "collapsed": false, "input": [ "def summatory(*args):\n", " result = 0\n", " for num in args:\n", " result += num\n", " return result\n", "\n", "summatory(1, 2, 3, 4, 5)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 13, "text": [ "15" ] } ], "prompt_number": 13 }, { "cell_type": "code", "collapsed": false, "input": [ "summatory(*range(1, 6))" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 14, "text": [ "15" ] } ], "prompt_number": 14 }, { "cell_type": "code", "collapsed": false, "input": [ "range(1, 6) # start, stop, step" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 15, "text": [ "[1, 2, 3, 4, 5]" ] } ], "prompt_number": 15 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Define a custom function with some default parameters" ] }, { "cell_type": "code", "collapsed": false, "input": [ "def multiply(number, mult=2):\n", " return number * mult" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 16 }, { "cell_type": "code", "collapsed": false, "input": [ "multiply(4)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 17, "text": [ "8" ] } ], "prompt_number": 17 }, { "cell_type": "code", "collapsed": false, "input": [ "multiply('a')" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 18, "text": [ "'aa'" ] } ], "prompt_number": 18 }, { "cell_type": "code", "collapsed": false, "input": [ "multiply('a', 6)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 19, "text": [ "'aaaaaa'" ] } ], "prompt_number": 19 }, { "cell_type": "code", "collapsed": false, "input": [ "multiply('a', mult=8)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 20, "text": [ "'aaaaaaaa'" ] } ], "prompt_number": 20 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Undefined number of key-value parameter" ] }, { "cell_type": "code", "collapsed": false, "input": [ "def contact(**kargs):\n", " for key, val in kargs.items():\n", " print \"%s => %r\" % (key, val)" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 21 }, { "cell_type": "code", "collapsed": false, "input": [ "contact(pietro=33312388, john=2345678)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "pietro => 33312388\n", "john => 2345678\n" ] } ], "prompt_number": 22 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Exercise 9" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Define a function that given a number variable of parameters and key-value parameters, print: [5 minutes]\n", "\n", " arg: 1\n", " arg: 2\n", " arg: a\n", " arg: [1, 2, 3]\n", " karg[other]: 'ciao'\n", " karg[key]: 'value'" ] }, { "cell_type": "code", "collapsed": false, "input": [ "args_kargs(1,2,'a',[1,2,3], key='value', other='ciao')" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "arg: 1\n", "arg: 2\n", "arg: 'a'\n", "arg: [1, 2, 3]\n", "karg[other]: 'ciao'\n", "karg[key]: 'value'\n" ] } ], "prompt_number": 25 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Solution" ] }, { "cell_type": "code", "collapsed": false, "input": [ "def args_kargs(*args, **kargs):\n", " pass" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 24 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Function containig other functions" ] }, { "cell_type": "code", "collapsed": false, "input": [ "def summ_mult(list_of_tuple):\n", " # define a new function inside\n", " def summ(tupl):\n", " res = 0\n", " for x in tupl:\n", " res += x\n", " return res\n", " \n", " result = 1\n", " for el in list_of_tuple:\n", " result *= summ(el)\n", " return result" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "summ_mult([(1,2,3), (4,5,6)])" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A function could return something using the command `return` or inside a cycle using `yield`:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "def use_yield(*args):\n", " for a in args:\n", " yield a * 2" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "use_yield(1, 2, 3, 4, 'a')" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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." ] }, { "cell_type": "code", "collapsed": false, "input": [ "[i for i in use_yield(1, 2, 3, 4, 'a')]" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "usy = use_yield(1, 2, 3, 4, 'a')" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "usy.next()" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Useful functions in the python standard library: http://docs.python.org/2/library/functions.html#built-in-functions" ] }, { "cell_type": "code", "collapsed": false, "input": [ "str(2.8)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "range(1,10,2)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "xrange(1,10,2)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "[i for i in xrange(1,10,2)]" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "len([1, 2, 3, 4]) # return the lenght of an object" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "names = ['one', 'two', 'three', 'four', 'five']\n", "values = [1, 2, 3, 4, 5]\n", "zip(names, values) # return a list of pairs" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "for name, value in zip(names, values):\n", " print '%5s = %d' % (name, value)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "dir('a') # return all the attributes of an object" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Decorator" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Decorator are object that are called to do something before and after a method or a function." ] }, { "cell_type": "code", "collapsed": false, "input": [ "VERBOSE = True\n", "\n", "def verbose(func):\n", " def wrapper(*args):\n", " if VERBOSE:\n", " print \"Before to execute: %s\" % func.func_name\n", " result = func(*args)\n", " if VERBOSE:\n", " print \"After the execution: %s\" % func.func_name\n", " return result\n", " return wrapper" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can test our decorator with:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "verbose(multiply2)(1)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Usually decorators are used with \"@\", and are very useful when you want to avoid to repeat the same operations to different functions." ] }, { "cell_type": "code", "collapsed": false, "input": [ "VERBOSE = True # try to change\n", "\n", "@verbose\n", "def mult(*args):\n", " result = args[0]\n", " for i in args[1:]:\n", " result *= i\n", " return result\n", "\n", "mult(1, 2, 3, 4)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Write another decorator that print the execution time of a function." ] }, { "cell_type": "code", "collapsed": false, "input": [ "import time\n", "\n", "def timeit(function):\n", " def timed(*args, **kargs):\n", " # do something before\n", " time_start = time.time()\n", " # execute the function\n", " result = function(*args, **kargs)\n", " # do something after\n", " time_end = time.time()\n", " print 'name=%r (args=%r, kargs=%r) processing time=%10.8f sec' % (function.__name__, args, kargs, time_end - time_start)\n", " return result\n", "\n", " return timed" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "timeit(multiply2)(2)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "@timeit\n", "def mult(*args):\n", " result = 1\n", " for a in args:\n", " result *= a\n", " return result" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "mult(1,2,3,4)" ], "language": "python", "metadata": {}, "outputs": [] } ], "metadata": {} } ] }