{ "metadata": { "name": "Chapter6_Functions" }, "nbformat": 3, "nbformat_minor": 0, "orig_nbformat": 2, "worksheets": [ { "cells": [ { "cell_type": "markdown", "source": [ "[Python for Developers](http://ricardoduarte.github.io/python-for-developers/#content)\n", "===================================\n", "First Edition\n", "-----------------------------------\n", "\n", "Chapter 6: Functions\n", "=============================\n", "_____________________________\n", "Functions are blocks of code identified by a name, which can receive predetermined parameters.\n", "\n", "In Python, functions:\n", "\n", "+ Can return objects or not.\n", "+ Accept *Doc Strings*.\n", "+ Accept optional parameters (with *defaults* ). If no parameter is passed, it will be equal to the *default* defined in the function.\n", "+ Accepts parameters to be passed by name. In this case, the order in which the parameters were passed does not matter.\n", "+ Have their own namespace (local scope), and therefore may obscure definitions of global scope.\n", "+ Can have their properties changed (usually by decorators).\n", "\n", "*Doc Strings* are strings that are attached to a\u00a0Python structure. In functions, *Doc strings* are placed within the body of the function, usually at the beginning. The goal of *Doc Strings* is to be used as documentation for this structure.\n", "\n", "Syntax:\n", "\n", " def func(parameter1, parameter2=default_value):\n", " \"\"\"\n", " Doc String\n", " \"\"\"\n", " \n", " return value\n", "\n", "The parameters with *default* value must be declared after the ones without *default* value.\n", "\n", "Example (factorial with recursion):" ] }, { "cell_type": "code", "collapsed": false, "input": [ "# Fatorial implemented with recursion\n", "\n", "def factorial(num):\n", "\n", " if num <= 1:\n", " return 1\n", " else:\n", " return(num * factorial(num - 1))\n", "\n", "# Testing factorial()\n", "print factorial(5)" ], "language": "python", "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "120\n" ] } ], "prompt_number": 2 }, { "cell_type": "markdown", "source": [ "Example (factorial without recursion):" ] }, { "cell_type": "code", "collapsed": false, "input": [ "def fatorial(n):\n", "\n", " n = n if n > 1 else 1\n", " j = 1\n", " for i in range(1, n + 1):\n", " j = j * i\n", " return j\n", "\n", "# Testing...\n", "for i in range(1, 6):\n", " print i, '->', fatorial(i)" ], "language": "python", "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "1 -> 1\n", "2 -> 2\n", "3 -> 6\n", "4 -> 24\n", "5 -> 120\n" ] } ], "prompt_number": 3 }, { "cell_type": "markdown", "source": [ "Example (Fibonacci series with recursion):" ] }, { "cell_type": "code", "collapsed": false, "input": [ "def fib(n):\n", " \"\"\"Fibonacci:\n", " fib(n) = fib(n - 1) + fib(n - 2) se n > 1\n", " fib(n) = 1 se n <= 1\n", " \"\"\"\n", " if n > 1:\n", " return fib(n - 1) + fib(n - 2)\n", " else:\n", " return 1\n", "\n", "# Show Fibonacci from 1 to 5\n", "for i in [1, 2, 3, 4, 5]:\n", " print i, '=>', fib(i)" ], "language": "python", "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "1 => 1\n", "2 => 2\n", "3 => 3\n", "4 => 5\n", "5 => 8\n" ] } ], "prompt_number": 4 }, { "cell_type": "markdown", "source": [ "Example (Fibonacci series without recursion):" ] }, { "cell_type": "code", "collapsed": false, "input": [ "def fib(n):\n", " \"\"\"Fibonacci:\n", " fib(n) = fib(n - 1) + fib(n - 2) se n > 1\n", " fib(n) = 1 se n <= 1\n", " \"\"\"\n", " \n", " # the first two values\n", " l = [1, 1]\n", " \n", " # Calculating the others\n", " for i in range(2, n + 1):\n", " l.append(l[i -1] + l[i - 2])\n", " \n", " return l[n]\n", "\n", "# Show Fibonacci from 1 to 5\n", "for i in [1, 2, 3, 4, 5]:\n", " print i, '=>', fib(i)" ], "language": "python", "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "1 => 1\n", "2 => 2\n", "3 => 3\n", "4 => 5\n", "5 => 8\n" ] } ], "prompt_number": 5 }, { "cell_type": "markdown", "source": [ "Example (RGB conversion):" ] }, { "cell_type": "code", "collapsed": false, "input": [ "def rgb_html(r=0, g=0, b=0):\n", " \"\"\"Converts R, G, B to #RRGGBB\"\"\"\n", "\n", " return '#%02x%02x%02x' % (r, g, b)\n", "\n", "def html_rgb(color='#000000'):\n", " \"\"\"Converts #RRGGBB em R, G, B\"\"\"\n", "\n", " if color.startswith('#'): color = color[1:]\n", "\n", " r = int(color[:2], 16)\n", " g = int(color[2:4], 16)\n", " b = int(color[4:], 16)\n", "\n", " return r, g, b # a sequence\n", "\n", "print rgb_html(200, 200, 255)\n", "print rgb_html(b=200, g=200, r=255) # what's happened? \n", "print html_rgb('#c8c8ff')" ], "language": "python", "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "#c8c8ff\n", "#ffc8c8\n", "(200, 200, 255)\n" ] } ], "prompt_number": 6 }, { "cell_type": "markdown", "source": [ "Observations:\n", "\n", "+ The\u00a0 arguments with default value must come last, after the non-default arguments.\n", "+ The default value for a parameter is calculated when the function is defined.\n", "+ The arguments passed without an identifier are received by the function in the form of a list.\n", "+ The arguments passed to the function with an identifier are received in the form of a dictionary.\n", "+ The parameters passed to the function with an identifier should come at the end of the parameter list.\n", "\n", "Example of how to get all parameters:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "# *args - arguments without name (list)\n", "# **kargs - arguments with name (ditcionary)\n", "\n", "def func(*args, **kargs):\n", " print args\n", " print kargs\n", "\n", "func('weigh', 10, unit='k')" ], "language": "python", "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "('weigh', 10)\n", "{'unit': 'k'}\n" ] } ], "prompt_number": 7 }, { "cell_type": "markdown", "source": [ "In the example, `kargs` will receive the named arguments and `args` will receive the others.\n", "\n", "The interpreter has some *builtin* functions defined, including `sorted()`, which orders sequences, and `cmp()`, which makes comparisons between two arguments and returns -1 if the first element is greater, 0 (zero) if they are equal, or 1 if the latter is higher. This function is used by the routine of ordering, a behavior that can be modified.\n", "\n", "Example:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "data = [(4, 3), (5, 1), (7, 2), (9, 0)]\n", "\n", "# Comparing by the last element\n", "def _cmp(x, y):\n", " return cmp(x[-1], y[-1])\n", "\n", "print 'List:', data\n", "\n", "# Ordering using _cmp()\n", "print 'Ordered:', sorted(data, _cmp)" ], "language": "python", "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "List: [(4, 3), (5, 1), (7, 2), (9, 0)]\n", "Ordered: [(9, 0), (5, 1), (7, 2), (4, 3)]\n" ] } ], "prompt_number": 8 }, { "cell_type": "markdown", "source": [ "Python also has a *builtin* function `eval()`, which evaluates code (source or object) and returns the value.\n", "\n", "Example:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "print eval('12. / 2 + 3.3')" ], "language": "python", "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "9.3\n" ] } ], "prompt_number": 9 }, { "cell_type": "markdown", "source": [ "With that it's possible to mount code to be passed to the interpreter during the execution of a program. This feature should be used with caution because code assembled from system inputs open up security holes." ] }, { "cell_type": "code", "collapsed": false, "input": [], "language": "python", "outputs": [ { "html": [ "\n", "" ], "output_type": "pyout", "prompt_number": 1, "text": [ "" ] } ], "prompt_number": 1 } ] } ] }