Upload
luciano-ramalho
View
2.018
Download
6
Embed Size (px)
DESCRIPTION
Palestra sobre a linguagem Python e seus contextos de uso
Citation preview
Fácil para começar, difícil de superar
Luciano [email protected]
@ramalhoorg
Palestra apresentada na UNIFESPSão José dos Campos em 10/dez/2012
@ramalhoorg
Ada Lovelace
• Ada A. Byron King, condessa de Lovelace
• nasceu em 10/dez/1815
• primeira programadora (antes de qualquer homem)
@ramalhoorg
Python: linguagem de uso geral• Internet: YouTube, Globo.com, Bitly, Mozilla...
• Computação gráfica: Disney, ILM, AutoDesk...
• Desktop: Dropbox, BitTorrent, OpenOffice...
• Operações: Google, Rackspace, Ubuntu, RedHat...
• Enterprise: IBM, Oracle, ERP5, OpenERP...
• Games, computação científica, segurança, etc...
code.google.com/edu/languages
http://redmonk.com/sogrady/2012/09/12/
Python tem sido uma parte importante do Google desdeo início, e continua sendo à medida que o sistema crescee evolui... estamos procurando mais pessoas com habilidade nesta linguagem.
Peter Norvig, Google, Inc.
http://aima.cs.berkeley.edu/code.html
>>> from lis import repl>>> repl()lis.py> (* 7 3)21lis.py> (define resposta (* 6 7))lis.py> resposta42lis.py> (define ! (lambda (n) (if (= n 0) 1 (* n (! (- n 1))))))lis.py> (! 4)24lis.py> (! 5)120lis.py> (! 197)100078405584080821221303894971344736599047761241456431563720437191558734323562679929991407036696693556694737848195477238497746661367777918006944650646265409257583733981874437495228286501182991424477395086576066353467353335798727837835328694280439305522603073118823862831864630209655642361092292378406702568679608855350476800000000000000000000000000000000000000000000000lis.py> !<function <lambda> at 0x1004cbd70>lis.py>
Demo: lis.py
@ramalhoorg
Sobre Python
• Linguagem dinâmica
• compilador é parte do ambiente de runtime
• Tudo são objetos
• Ex.: inteiros, funções, classes, exceções etc.
• Multi-plataforma
• Interpretador, APIs, bytecode, GUIs etc.
@ramalhoorg
Implementações• CPython: a principal, escrita em C
• incluída na maioria das distros GNU Linux e no Mac OS X; vários pacotes para Windows
• Jython: escrita em Java
• parte de IBM WebSphere e Oracle WebLogic
• IronPython: escrita em C#, .net CLR
• desenvolvida pela Microsoft
@ramalhoorg
Implementações (2)
• PyPy: Python em Python
• Implementação em linguagem de alto-nível facilitando a inovação
• Desempenho 5x melhor que CPython
• Incompatível com as extensões em C
@ramalhoorg
Python: evolução• Versões do CPython em dez/2012
• 3.0, 2.5 e anteriores: fossilizadas
• 2.6 e 3.1: manutenção por 5 anos
• 2.7 e 3.2: versões atuais
• 2.7: versão final da série 2.x
• 3.3: lançada em set/2012
2.52006-09…2011-05
2.6 2008-10 3.0
2008-12…2009-07
3.1 2009-06
3.2 2011-02
2.7 2010-07
3.3 2012-09
3.4 2014-02
⋮
@ramalhoorg
CPython 2.7: instaladores
• GNU Linux: pré-instalado em quase toda distro
• usar gerenciador de pacotes ou compilar (é fácil)
• Windows
• Python.org: instaladores MSI para 32 e 64 bits
• ActiveState ActivePython: 32 e 64 bits
• Mac OS: 32 bits (x86 e PPC), 64 bits (x86)
@ramalhoorg
Exemplo de doctest# coding: utf-8"""Calcula a média de uma sequência de números
>>> media([10]) 10.0 >>> media([10, 20]) 15.0 >>> media([1, 2]) 1.5
"""
def media(seq): return float(sum(seq))/len(seq)
@ramalhoorg
Para executar doctests
• Pela linha de comando:
• $ python -m doctest meu_script.py
• Usando um test-runner (unittest, nose, etc.)
• No próprio script (self-test):
if __name__=='__main__': import doctest print doctest.testmod(optionflags=doctest.REPORT_ONLY_FIRST_FAILURE |doctest.REPORT_NDIFF |doctest.NORMALIZE_WHITESPACE)
@ramalhoorg
Consoles interativos• python
• integrado em IDEs
• iPython
• bpython
• IDLE
• online
• http://shell.appspot.com/
• http://pythonwebconsole.thomnichols.org/
• http://www.pythonanywhere.com/
@ramalhoorg
IDEs, algumas opções• PyDev (Eclipse)
• PyCharm (JetBrains) $$$
• Komodo Edit
• Komodo IDE $$$
• TextMate $ - OSX
• SublimeText $
• WingIDE $$$
@ramalhoorg
Em vez de IDE: The Unix environment• Linux ou OSX ou qualquer Unix:
• janelas de editor, console e navegador ou sua aplicação
• alternar entre janelas com alt-tab: simples, poderoso e eficaz
• Emacs: python-mode.el
• vi: http://www.vex.net/~x/python_and_vim.html
• Geany: um Gedit mais esperto para lidar com vários arquivos
@ramalhoorg
Configure o editor para...
• Indentar com 4 caracteres de espaço ao usar a tecla TAB ou comandos de indentação multi-linha
• Salvar tabs como 4 espaços, nunca como tabs
• Limpar brancos no final das linhas ao salvar
• Indentação inteligente: preservar indentação da linha acima e indentar automaticamente após: if, elif, else, for, while, try, except, finally, def, class, with
@ramalhoorg
Comparando: C e Python#include <stdio.h>
int main(int argc, char *argv[]) { int i; for(i = 0; i < argc; i++) printf("%s\n", argv[i]); return 0;} import sys
for arg in sys.argv: print arg
@ramalhoorg
Iteração em Java
class Argumentos { public static void main(String[] args) { for (int i=0; i < args.length; i++) System.out.println(args[i]); }}
$ java Argumentos alfa bravo charliealfabravocharlie
@ramalhoorg
Iteração em Java ≥1.5
class Argumentos2 { public static void main(String[] args) { for (String arg : args) System.out.println(arg); }}
$ java Argumentos2 alfa bravo charliealfabravocharlie
ano:2004
• Enhanced for (for melhorado)
@ramalhoorg
Iteração em Java ≥1.5
class Argumentos2 { public static void main(String[] args) { for (String arg : args) System.out.println(arg); }}
ano:2004
• Enhanced for (for melhorado)
import sys
for arg in sys.argv: print arg
ano:1991
@ramalhoorg
Exemplos de iteração
• Iteração em Python não se limita a tipos primitivos
• Exemplos
• string
• arquivo
• Django QuerySet
>>> from django.db import connection>>> q = connection.queries>>> q[]>>> from municipios.models import *>>> res = Municipio.objects.all()[:5]>>> q[]>>> for m in res: print m.uf, m.nome... GO Abadia de GoiásMG Abadia dos DouradosGO AbadiâniaMG AbaetéPA Abaetetuba>>> q[{'time': '0.000', 'sql': u'SELECT "municipios_municipio"."id", "municipios_municipio"."uf", "municipios_municipio"."nome", "municipios_municipio"."nome_ascii", "municipios_municipio"."meso_regiao_id", "municipios_municipio"."capital", "municipios_municipio"."latitude", "municipios_municipio"."longitude", "municipios_municipio"."geohash" FROM "municipios_municipio" ORDER BY "municipios_municipio"."nome_ascii" ASC LIMIT 5'}]
demonstração: queryset é um iterável lazy
@ramalhoorg
List comprehensions• Expressões que consomem iteráveis e
produzem listas
>>> s = 'abracadabra'>>> l = [ord(c) for c in s]>>> [ord(c) for c in s][97, 98, 114, 97, 99, 97, 100, 97, 98, 114, 97]
List comprehension
● Compreensão de lista ou abrangência de lista
● Exemplo: usar todos os elementos:
– L2 = [n*10 for n in L]
qualquer iterável
resultado: uma lista
≈ notação matemática de conjuntos
@ramalhoorg
Set & dict comprehensions• Expressões que consomem iteráveis e
produzem sets ou dicts
>>> s = 'abracadabra'>>> {c for c in s}set(['a', 'r', 'b', 'c', 'd'])>>> {c:ord(c) for c in s}{'a': 97, 'r': 114, 'b': 98, 'c': 99, 'd': 100}
@ramalhoorg
Tipos iteráveis embutidos
• basestring
• str
• unicode
• dict
• file
• frozenset
• list
• set
• tuple
• xrange
@ramalhoorg
Funções embutidas que consomem iteráveis• all
• any
• filter
• iter
• len
• map
• max
• min
• reduce
• sorted
• sum
• zip
@ramalhoorg
Iteração em C (exemplo 2)
#include <stdio.h>
int main(int argc, char *argv[]) { int i; for(i = 0; i < argc; i++) printf("%d : %s\n", i, argv[i]); return 0;}
$ ./args2 alfa bravo charlie0 : ./args21 : alfa2 : bravo3 : charlie
@ramalhoorg
Iteração em Python (ex. 2)
import sys
for i in range(len(sys.argv)): print i, ':', sys.argv[i]
$ python args2.py alfa bravo charlie0 : args2.py1 : alfa2 : bravo3 : charlie
não Pythonico!
@ramalhoorg
Iteração em Python (ex. 2)
import sys
for i, arg in enumerate(sys.argv): print i, ':', arg
$ python args2.py alfa bravo charlie0 : args2.py1 : alfa2 : bravo3 : charlie
Pythonico!
@ramalhoorg
import sys
for i, arg in enumerate(sys.argv): print i, ':', arg
Iteração em Python (ex. 2)
isso constroium gerador
o gerador produz uma tupla (indice, item)
sob demandaa cada iteração
o gerador é um iterável preguiçoso!$ python args2.py alfa bravo charlie0 : args2.py1 : alfa2 : bravo3 : charlie
@ramalhoorg
Construtores embutidos que consomem e produzem iteráveis
• dict
• enumerate
• frozenset
• list
• reversed
• set
• tuple
@ramalhoorg
• geradores (potencialmente) infinitos
• count(), cycle(), repeat()
• geradores que combinam vários iteráveis
• chain(), tee(), izip(), imap(), product(), compress()...
• geradores que selecionam ou agrupam itens:
• compress(), dropwhile(), groupby(), ifilter(), islice()...
• Iteradores que produzem combinações
• product(), permutations(), combinations()...
Módulo itertools
@ramalhoorg
import Tkinterrel = Tkinter.Label()rel['text'] = '10:42:29'rel.grid()rel['font'] = 'Helvetica 120 bold'
from time import strftimerel['text'] = strftime('%H:%M:%S')
def tic(): rel['text'] = strftime('%H:%M:%S') def tac(): tic() rel.after(100, tac)
tac()
Exercício: construir e controlar Tkinter.Label
$ sudo apt-get install python-tk
Para instalar Tkinter no
Ubuntu Linux:
@ramalhoorg
Relógio com classeimport Tkinterfrom time import strftime
class Relogio(Tkinter.Label): def __init__(self): Tkinter.Label.__init__(self) self.pack() self['text'] = strftime('%H:%M:%S') self['font'] = 'Helvetica 120 bold' self.tictac() def tictac(self): agora = strftime('%H:%M:%S') if agora != self['text']: self['text'] = agora self.after(100, self.tictac)
rel = Relogio()rel.mainloop()
oopy/exemplos/relogio_oo.py
@ramalhoorg
Tudo é um objeto
• Não existem “tipos primitivos” como em Java
• desde Python 2.2, dezembro de 2001
>>> 5 + 38>>> 5 .__add__(3)8>>> type(5)<type 'int'>
@ramalhoorg
Funções são objetos>>> def fatorial(n):... '''devolve n!'''... return 1 if n < 2 else n * fatorial(n-1)... >>> fatorial(5)120>>> fat = fatorial>>> fat<function fatorial at 0x1004b5f50>>>> fat(42)1405006117752879898543142606244511569936384000000000L>>> fatorial.__doc__'devolve n!'>>> fatorial.__name__'fatorial'>>> fatorial.__code__<code object fatorial at 0x1004b84e0, file "<stdin>", line 1>>>> fatorial.__code__.co_varnames('n',)
@ramalhoorg
Funções são objetos>>> fatorial.__code__.co_code'|\x00\x00d\x01\x00j\x00\x00o\x05\x00\x01d\x02\x00S\x01|\x00\x00t\x00\x00|\x00\x00d\x02\x00\x18\x83\x01\x00\x14S'>>> from dis import dis>>> dis(fatorial.__code__.co_code) 0 LOAD_FAST 0 (0) 3 LOAD_CONST 1 (1) 6 COMPARE_OP 0 (<) 9 JUMP_IF_FALSE 5 (to 17) 12 POP_TOP 13 LOAD_CONST 2 (2) 16 RETURN_VALUE >> 17 POP_TOP 18 LOAD_FAST 0 (0) 21 LOAD_GLOBAL 0 (0) 24 LOAD_FAST 0 (0) 27 LOAD_CONST 2 (2) 30 BINARY_SUBTRACT 31 CALL_FUNCTION 1 34 BINARY_MULTIPLY 35 RETURN_VALUE >>>
Bytecode da função
fatorial
@ramalhoorg
Alguns tipos básicos>>> i = 7>>> type(i)<type 'int'>>>> j = 2**100>>> type(j)<type 'long'>>>> f = 7.>>> type(f)<type 'float'>>>> s = 'abc'>>> type(s)<type 'str'>>>> u = u'abc'>>> type(u)<type 'unicode'>>>> b = b'ABC'>>> type(b)<type 'str'>>>> b[0]'A'
>>> i = 7>>> type(i)<class 'int'>>>> j = 2**100>>> type(j)<class 'int'>>>> f = 7.>>> type(f)<class 'float'>>>> s = 'abc'>>> type(s)<class 'str'>>>> u = u'abc'
>>> b = b'ABC'>>> type(b)<class 'bytes'>>>> b[0]65
Python 2.7 Python 3.2
SyntaxErrorou
<class ‘str’>(Python 3.3)
int e long unificados no
Python 3
strx
unicodex
bytes
@ramalhoorg
Tipos embutidos (built-in)
• Implementados em C, por eficiência
• Métodos inalteráveis (como “final”, em Java)
• Texto: str, unicode (Python 2 e Python 3)
• Números: int, long (Python 2), float, complex, bool
• Coleções: list, tuple, dict, set, frozenset, bytes (Python 3)
@ramalhoorg
Tipagem forte• O tipo de um objeto nunca muda, e não existem
“tipos variantes”
• Raramente Python faz conversão automática
>>> a = 10>>> b = '9'>>> a + bTraceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: unsupported operand type(s) for +: 'int' and 'str'>>> a + int(b)19>>> str(a) + b'109'>>> 77 * NoneTraceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: unsupported operand type(s) for *: 'int' and 'NoneType'
@ramalhoorg
Tipagem dinâmica: variáveis não têm tipo>>> def dobro(x):... return x * 2... >>> dobro(7)14>>> dobro(7.1)14.2>>> dobro('bom')'bombom'>>> dobro([10, 20, 30])[10, 20, 30, 10, 20, 30]>>> dobro(None)Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 2, in dobroTypeError: unsupported operand type(s) for *: 'NoneType' and 'int'
@ramalhoorg
Duck typing• “Se voa como um pato, nada como um pato e
grasna como um pato, é um pato.”
• Tipagem dinâmica permite duck typing (tipagem pato): estilo de programação que evita verificar os tipos dos objetos, mas apenas seus métodos
• No exemplo anterior, a função dobro funciona com qualquer objeto x que consiga fazer x * 2
• x implementa o método __mult__(n), para n inteiro
@ramalhoorg
Exemplo: tômbola
• Sortear um a um todos os itens de uma coleção finita, sem repetir
• A mesma lógica é usada em sistemas para gerenciar banners online
@ramalhoorg
Interface da tômbola
• Carregar itens
• Misturar itens
• Sortear um item
• Indicar se há mais itens
@ramalhoorg
TDD: Test Driven Design
• Metodologia de desenvolvimento iterativa na qual, para cada funcionalidade nova, um teste é criado antes do código a ser implementado
• Esta inversão ajuda o programador a desenvolver com disciplina apenas uma funcionalidade de cada vez, mantendo o foco no teste que precisa passar
• Cada iteração de teste/implementação deve ser pequena e simples: “baby steps” (passinhos de bebê)
@ramalhoorg
Doctests
• Um dos módulos para fazer testes automatizados na biblioteca padrão de Python
• o outro módulo é o unittest, da família xUnit
• Doctests foram criados para testar exemplos embutidos na documentação
• Exemplo de uso:
$ python -m doctest cao.rst
oopy/exemplos/cao.rst
@ramalhoorg
Sobrecarga de operadores
• Python permite que as classes definidas pelo usuário (você!) implementem métodos para os operadores definidos na linguagem
• Não é possível redefinir a função dos operadores nos tipos embutidos
• isso evita surpresas desagradáveis
• Nem é possível inventar novos operadores
• não podemos definir ~, <=>, /|\ etc.
@ramalhoorg
Objetos invocáveis
• Você pode definir suas próprias funções...
• E também novas classes de objetos que se comportam como funções: objetos invocáveis
• basta definir um método __call__ para sobrecarregar o operador de invocação: ()
• o(x)
• Exemplo: tômbola invocável
@ramalhoorg
Tômbola invocável
• Já que o principal uso de uma instância de tômbola é sortear, podemos criar um atalho:em vez de t.sortear()apenas t()
from tombola import Tombola
class TombolaInvocavel(Tombola): '''Sorteia itens sem repetir; a instância é invocável como uma função'''
def __call__(self): return self.sortear()
>>> t = TombolaInvocavel()>>> t.carregar([1, 2, 3])>>> t()3
>>> t()2
@ramalhoorg
Alguns operadores existentes• Aritméticos: + - * / ** //
• Bitwise: & ^ | << >>
• Acesso a atributos: a.b
• Invocação: f(x)
• Operações em coleções: c[a], len(c), a in c, iter(c)
• Lista completa em Python Reference: Data Model
http://docs.python.org/reference/datamodel.html
@ramalhoorg
Exemplo: vetor (2d)
• Campos: x, y
• Métodos:
• distancia
• abs (distância até 0,0)
• + (__add__)
• * (__mul__) escalar
oopy/exemplos/vetor.py
Vetor(2, 1)
Vetor(2, 4)
Vetor(4, 5)
x
y
@ramalhoorg
Vetorfrom math import sqrt
class Vetor(object):
def __init__(self, x=0, y=0): self.x = x self.y = y
def __repr__(self): return 'Vetor(%s, %s)' % (self.x, self.y)
def distancia(self, v2): dx = self.x - v2.x dy = self.y - v2.y return sqrt(dx*dx + dy*dy)
def __abs__(self): return self.distancia(Vetor(0,0))
def __add__(self, v2): dx = self.x + v2.x dy = self.y + v2.y return Vetor(dx, dy)
def __mul__(self, n): return Vetor(self.x*n, self.y*n)
>>> from vetor import Vetor>>> v = Vetor(3, 4)
>>> abs(v)5.0
>>> v1 = Vetor(2, 4)>>> v2 = Vetor(2, 1)
>>> v1 + v2Vetor(4, 5)>>> v1 * 3
Vetor(6, 12)
@ramalhoorg
Carta debaralho
class Carta(object):
naipes = 'paus ouros copas espadas'.split() valores = '2 3 4 5 6 7 8 9 10 J Q K A'.split()
def __init__(self, valor, naipe): self.valor = valor self.naipe = naipe
def __repr__(self): return 'Carta(%r, %r)' % (self.valor, self.naipe)
def __str__(self): return self.valor + ' de ' + self.naipe
@classmethod def todas(cls): return [cls(v, n) for n in cls.naipes for v in cls.valores]
@ramalhoorg
Carta debaralho
class Carta(object):
naipes = 'paus ouros copas espadas'.split() valores = '2 3 4 5 6 7 8 9 10 J Q K A'.split()
def __init__(self, valor, naipe): self.valor = valor self.naipe = naipe
def __repr__(self): return 'Carta(%r, %r)' % (self.valor, self.naipe)
def __str__(self): return self.valor + ' de ' + self.naipe
@classmethod def todas(cls): return [cls(v, n) for n in cls.naipes for v in cls.valores]
>>> zape = Carta('4', 'paus')
>>> zape.valor'4'
>>> zapeCarta('4', 'paus')
>>> monte = Carta.todas()>>> len(monte)
52>>> monte[0]
Carta('2', 'espadas')>>> monte[-3:]
[Carta('Q', 'copas'), Carta('K', 'copas'), Carta('A', 'copas')]
@ramalhoorg
Baralhopolimórfico (demo)
from carta_ord import Carta
class Baralho(object):
def __init__(self): self.cartas = Carta.todas()
def __len__(self): return len(self.cartas)
def __getitem__(self, pos): return self.cartas[pos]
def __setitem__(self, pos, valor): self.cartas[pos] = valor
@ramalhoorg
Baralhopolimórfico (final)
from carta_ord import Carta
class Baralho(object):
def __init__(self): self.cartas = Carta.todas()
def __len__(self): return len(self.cartas)
def __getitem__(self, pos): return self.cartas[pos]
def __setitem__(self, pos, valor): self.cartas[pos] = valor