{ "metadata": { "name": "Capitulo6_Funcoes" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "[Python para Desenvolvedores](http://ricardoduarte.github.io/python-para-desenvolvedores/#conteudo)\n", "===================================\n", "2ª edi\u00e7\u00e3o, revisada e ampliada\n", "-----------------------------------\n", "\n", "Cap\u00edtulo 6: Fun\u00e7\u00f5es\n", "=============================\n", "_____________________________\n", "Fun\u00e7\u00f5es s\u00e3o blocos de c\u00f3digo identificados por um nome, que podem receber par\u00e2metros pr\u00e9-determinados.\n", "\n", "No Python, as fun\u00e7\u00f5es:\n", "\n", "+ Podem retornar ou n\u00e3o objetos.\n", "+ Aceitam *Doc Strings*.\n", "+ Aceitam par\u00e2metros opcionais (com *defaults*). Se n\u00e3o for passado o par\u00e2metro ser\u00e1 igual ao *default* definido na fun\u00e7\u00e3o.\n", "+ Aceitam que os par\u00e2metros sejam passados com nome. Neste caso, a ordem em que os par\u00e2metros foram passados n\u00e3o importa.\n", "+ Tem *namespace* pr\u00f3prio (escopo local), e por isso podem ofuscar defini\u00e7\u00f5es de escopo global.\n", "+ Podem ter suas propriedades alteradas (geralmente por decoradores).\n", "\n", "*Doc Strings* s\u00e3o *strings* que est\u00e3o associadas a uma estrutura do Python. Nas fun\u00e7\u00f5es, as *Doc Strings* s\u00e3o colocadas dentro do corpo da fun\u00e7\u00e3o, geralmente no come\u00e7o. O objetivo das *Doc Strings* \u00e9 servir de documenta\u00e7\u00e3o para aquela estrutura.\n", "\n", "Sintaxe:\n", "\n", " def func(parametro1, parametro2=padrao):\n", " \"\"\"\n", " Doc String\n", " \"\"\"\n", " \n", " return valor\n", "\n", "Os par\u00e2metros com *default* devem ficar ap\u00f3s os que n\u00e3o tem *default*.\n", "\n", "Exemplo (fatorial com recurs\u00e3o):" ] }, { "cell_type": "code", "collapsed": false, "input": [ "# Fatorial implementado de forma recursiva\n", "\n", "def fatorial(num):\n", "\n", " if num <= 1:\n", " return 1\n", " else:\n", " return(num * fatorial(num - 1))\n", "\n", "# Testando fatorial()\n", "print fatorial(5)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "120\n" ] } ], "prompt_number": 2 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Exemplo (fatorial sem recurs\u00e3o):" ] }, { "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", "# Testando...\n", "for i in range(1, 6):\n", " print i, '->', fatorial(i)" ], "language": "python", "metadata": {}, "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", "metadata": {}, "source": [ "Exemplo (s\u00e9rie de Fibonacci com recurs\u00e3o):" ] }, { "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", "# Mostrar Fibonacci de 1 a 5\n", "for i in [1, 2, 3, 4, 5]:\n", " print i, '=>', fib(i)" ], "language": "python", "metadata": {}, "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", "metadata": {}, "source": [ "Exemplo (s\u00e9rie de Fibonacci sem recurs\u00e3o):" ] }, { "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", " # Dois primeiros valores\n", " l = [1, 1]\n", " \n", " # Calculando os outros\n", " for i in range(2, n + 1):\n", " l.append(l[i -1] + l[i - 2])\n", " \n", " return l[n]\n", "\n", "# Mostrar Fibonacci de 1 a 5\n", "for i in [1, 2, 3, 4, 5]:\n", " print i, '=>', fib(i)" ], "language": "python", "metadata": {}, "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", "metadata": {}, "source": [ "Exemplo (convers\u00e3o de RGB):" ] }, { "cell_type": "code", "collapsed": false, "input": [ "def rgb_html(r=0, g=0, b=0):\n", " \"\"\"Converte R, G, B em #RRGGBB\"\"\"\n", "\n", " return '#%02x%02x%02x' % (r, g, b)\n", "\n", "def html_rgb(color='#000000'):\n", " \"\"\"Converte #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 # Uma sequ\u00eancia\n", "\n", "print rgb_html(200, 200, 255)\n", "print rgb_html(b=200, g=200, r=255) # O que houve?\n", "print html_rgb('#c8c8ff')" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "#c8c8ff\n", "#ffc8c8\n", "(200, 200, 255)\n" ] } ], "prompt_number": 6 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Observa\u00e7\u00f5es:\n", "\n", "+ Os argumentos com padr\u00e3o devem vir por \u00faltimo, depois dos argumentos sem padr\u00e3o.\n", "+ O valor do padr\u00e3o para um par\u00e2metro \u00e9 calculado quando a fun\u00e7\u00e3o \u00e9 definida.\n", "+ Os argumentos passados sem identificador s\u00e3o recebidos pela fun\u00e7\u00e3o na forma de uma lista.\n", "+ Os argumentos passados com identificador s\u00e3o recebidos pela fun\u00e7\u00e3o na forma de um dicion\u00e1rio.\n", "+ Os par\u00e2metros passados com identificador na chamada da fun\u00e7\u00e3o devem vir no fim da lista de par\u00e2metros.\n", "\n", "Exemplo de como receber todos par\u00e2metros:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "# *args - argumentos sem nome (lista)\n", "# **kargs - argumentos com nome (dicion\u00e1rio)\n", "\n", "def func(*args, **kargs):\n", " print args\n", " print kargs\n", "\n", "func('peso', 10, unidade='k')" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "('peso', 10)\n", "{'unidade': 'k'}\n" ] } ], "prompt_number": 7 }, { "cell_type": "markdown", "metadata": {}, "source": [ "No exemplo, `kargs` receber\u00e1 os argumentos nomeados e `args` receber\u00e1 os outros.\n", "\n", "O interpretador tem definidas algumas fun\u00e7\u00f5es *builtin*, incluindo `sorted()`, que ordena sequ\u00eancias, e `cmp()`, que faz compara\u00e7\u00f5es entre dois argumentos e retorna -1 se o primeiro elemento for maior , 0 (zero) se forem iguais ou 1 se o \u00faltimo for maior. Essa fun\u00e7\u00e3o \u00e9 usada pela rotina de ordena\u00e7\u00e3o, um comportamento que pode ser modificado.\n", "\n", "Exemplo:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "dados = [(4, 3), (5, 1), (7, 2), (9, 0)]\n", "\n", "# Comparando pelo \u00faltimo elemento\n", "def _cmp(x, y):\n", " return cmp(x[-1], y[-1])\n", "\n", "print 'Lista:', dados\n", "\n", "# Ordena usando _cmp()\n", "print 'Ordenada:', sorted(dados, _cmp)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Lista: [(4, 3), (5, 1), (7, 2), (9, 0)]\n", "Ordenada: [(9, 0), (5, 1), (7, 2), (4, 3)]\n" ] } ], "prompt_number": 8 }, { "cell_type": "markdown", "metadata": {}, "source": [ "O Python tamb\u00e9m possui como *builtin* a fun\u00e7\u00e3o `eval()`, que avalia c\u00f3digo (fonte ou objeto) retornando o valor.\n", "\n", "Exemplo:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "print eval('12. / 2 + 3.3')" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "9.3\n" ] } ], "prompt_number": 9 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Com isso \u00e9 poss\u00edvel montar c\u00f3digo para ser passado para o interpretador durante a execu\u00e7\u00e3o de um programa. Esse recurso deve ser usado com cuidado, pois c\u00f3digo montados a partir de entradas do sistema abrir brechas de seguran\u00e7a." ] }, { "cell_type": "code", "collapsed": false, "input": [], "language": "python", "metadata": {}, "outputs": [ { "html": [ "\n", "" ], "output_type": "pyout", "prompt_number": 1, "text": [ "" ] } ], "prompt_number": 1 } ], "metadata": {} } ] }