Luciano Ramalho
                           luciano@ramalho.org
                                   @ramalhoorg




Fácil para começar, difícil de superar

     Palestra apresentada na UNIFESP
   São José dos Campos em 10/dez/2012
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...
                                           @ramalhoorg
@ramalhoorg
@ramalhoorg
@ramalhoorg
@ramalhoorg
@ramalhoorg
@ramalhoorg
@ramalhoorg
@ramalhoorg
@ramalhoorg
@ramalhoorg
Google em 1998
Google App Engine
code.google.com/edu/languages
YouTube
Globo.com
Mozilla Firefox Add-Ons
Dropbox
The Foundry, NUKE
Industrial Light & Magic
Autodesk Maya
Invesalius
Civilization IV
Frets on Fire
FBI e CIA
brasil.gov.br
Câmara dos Deputados
http://redmonk.com/sogrady/2012/09/12/
“Vocês são
  o centro
 do Vale do
Silício hoje”


 Paul Graham,
 Pycon US 2012
Linguagem
“expressiva”

  O que isso
   significa
  na prática?




       Linguagem
         COBOL
Java
Java


Python
Python tem sido uma parte
importante do Google desde
o início, e continua sendo à
medida que o sistema cresce
e evolui... estamos procurando
mais pessoas com habilidade
nesta linguagem.




Peter Norvig, Google, Inc.
http://aima.cs.berkeley.edu/code.html
lis.py: interpretador
   Lisp (Scheme) em
113 linhas de Python,
      por Peter Norvig
>>> from lis import repl

                                    Demo: lis.py
>>> repl()
lis.py> (* 7 3)
21
lis.py> (define resposta (* 6 7))
lis.py> resposta
42
lis.py> (define ! (lambda (n) (if (= n 0) 1 (* n (! (- n 1))))))
lis.py> (! 4)
24
lis.py> (! 5)
120
lis.py> (! 197)
10007840558408082122130389497134473659904776124145643156372043719
15587343235626799299914070366966935566947378481954772384977466613
67777918006944650646265409257583733981874437495228286501182991424
47739508657606635346735333579872783783532869428043930552260307311
88238628318646302096556423610922923784067025686796088553504768000
00000000000000000000000000000000000000000000
lis.py> !
<function <lambda> at 0x1004cbd70>
lis.py>
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
2.5


                                    Python: evolução
       2006-09…2011-05




 2.6

                                     • Versões do CPython em dez/2012
2008-10                  3.0
                  2008-12…2009-07



                         3.1
                      2009-06        • 3.0, 2.5 e anteriores: fossilizadas
                                     • 2.6 e 3.1: manutenção por 5 anos
 2.7
2010-07
                         3.2
                      2011-02



                         3.3
                                     • 2.7 e 3.2: versões atuais
                                     • 2.7: versão final da série 2.x
                      2012-09




                                     • 3.3: lançada em set/2012
                         3.4
                      2014-02




                         ⋮                                       @ramalhoorg
Pythonista: app para iPad

                      @ramalhoorg
Pythonista
        @ramalhoorg
Pythonista
        @ramalhoorg
@ramalhoorg
Pythonista
        @ramalhoorg
Pythonista
        @ramalhoorg
Pythonista
        @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
pythontutor.com
pythontutor.com
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
                • online
• bpython
                  • http://shell.appspot.com/
• IDLE            • 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("%sn", 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 charlie
             alfa
             bravo
             charlie                      @ramalhoorg
Iteração em Java ≥1.5                        ano:
                                             2004

 • Enhanced for (for melhorado)
class Argumentos2 {
    public static void main(String[] args) {
        for (String arg : args)
            System.out.println(arg);
    }
}


              $ java Argumentos2 alfa bravo charlie
              alfa
              bravo
              charlie                      @ramalhoorg
Iteração em Java ≥1.5                   ano:
                                        2004

 • Enhanced for (for melhorado)
class Argumentos2 {
    public static void main(String[] args) {
        for (String arg : args)
            System.out.println(arg);
    }
}
                                        ano:
                      import sys        1991

                      for arg in sys.argv:
                          print arg @ramalhoorg
Exemplos de iteração

• Iteração em Python não se limita a tipos primitivos
• Exemplos
 • string
 • arquivo
 • Django QuerySet
                                             @ramalhoorg
>>> 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ás                             demonstração:
MG Abadia dos Dourados
GO Abadiânia                                   queryset é um
MG Abaeté                                      iterável lazy
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'}]
List comprehension
List comprehensions          ●   Compreensão de lista ou abrangência
                             ●   Exemplo: usar todos os elementos:
•   Expressões que consomem L2 = [n*10 for n in L]
                           – iteráveis e


    produzem listas
     qualquer iterável
    resultado: uma lista

>>> 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]

                           ≈ 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   • frozenset
   • str         • list
   • unicode     • set
  • dict         • tuple
  • file          • xrange
                               @ramalhoorg
Funções embutidas que
consomem iteráveis
• all     • max
• any     • min
• filter   • reduce
• iter    • sorted
• len     • sum
• map     • 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 : %sn", i, argv[i]);
     return 0;
 }
                      $   ./args2 alfa bravo charlie
                      0   : ./args2
                      1   : alfa
                      2   : bravo
                      3   : charlie          @ramalhoorg
Iteração em Python (ex. 2)
                                     não
import sys
                                  Pythonico!
for i in range(len(sys.argv)):
    print i, ':', sys.argv[i]


             $   python args2.py alfa bravo charlie
             0   : args2.py
             1   : alfa
             2   : bravo
             3   : charlie                 @ramalhoorg
Iteração em Python (ex. 2)
import sys                        Pythonico!
for i, arg in enumerate(sys.argv):
    print i, ':', arg


             $   python args2.py alfa bravo charlie
             0   : args2.py
             1   : alfa
             2   : bravo
             3   : charlie                 @ramalhoorg
Iteração em Python (ex. 2)
import sys                              isso constroi
                                         um gerador
for i, arg in enumerate(sys.argv):
    print i, ':', arg
o gerador produz uma
                            o gerador é um iterável preguiçoso!
  tupla (indice, item)
     sob demanda $ python args2.py alfa bravo charlie
    a cada iteração 0 : args2.py
                   1 : alfa
                   2 : bravo
                   3 : charlie                          @ramalhoorg
Construtores embutidos
que consomem e
produzem iteráveis
• dict        • reversed
• enumerate   • set
• frozenset   • tuple
• list
                           @ramalhoorg
Módulo itertools
• 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()...    @ramalhoorg
Exercício: construir e
 controlar Tkinter.Label
import Tkinter
rel = Tkinter.Label()
rel['text'] = '10:42:29'
rel.grid()
rel['font'] = 'Helvetica 120 bold'

from time import strftime
rel['text'] = strftime('%H:%M:%S')

def tic():
    rel['text'] = strftime('%H:%M:%S')
                                               Para instalar
def tac():
     tic()
                                                Tkinter no
    rel.after(100, tac)                        Ubuntu Linux:

tac()                     $ sudo apt-get install python-tk
                                                  @ramalhoorg
Relógio com classe
import Tkinter
from 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
Uma pequena
                                                    parte da
                                                    hierarquia de
                                                    classes do
                                                    Tkinter
                                 herança múltipla


mixin




        he
          ran
             ça
                  mú
                     ltipl
                             a
Um pouco mais da hierarquia de classes do Tkinter
Hierarquia de classes dos objetos gráficos doTkinter
Tudo é um objeto
• Não existem “tipos primitivos” como em Java
 • desde Python 2.2, dezembro de 2001
           >>> 5 + 3
           8
           >>> 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
'|x00x00dx01x00jx00x00ox05x00x01dx02x00Sx01|x00x00tx00x00|
x00x00dx02x00x18x83x01x00x14S'
>>> 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
         12 POP_TOP
                                5 (to 17)
                                                  Bytecode da
         13 LOAD_CONST
         16 RETURN_VALUE
                                2 (2)
                                                     função
    >>   17 POP_TOP
         18 LOAD_FAST           0 (0)
                                                    fatorial
         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
>>>                                                            @ramalhoorg
Tipos

        @ramalhoorg
Alguns tipos básicos
>>> i = 7          Python 2.7            >>> i = 7         Python 3.2
>>> type(i)                              >>> type(i)
<type 'int'>                             <class 'int'>
>>> j = 2**100                           >>> j = 2**100
>>> type(j)
                           int e long    >>> type(j)
<type 'long'>            unificados no   <class 'int'>
>>> f = 7.                 Python 3      >>> f = 7.
>>> type(f)                              >>> type(f)
<type 'float'>                           <class 'float'>
>>> s = 'abc'                            >>> s = 'abc'
>>> type(s)                   str        >>> type(s)
<type 'str'>                   x         <class 'str'>     SyntaxError
>>> u = u'abc'              unicode      >>> u = u'abc'
                                                                ou
>>> type(u)                    x
<type 'unicode'>                                           <class ‘s tr’>
                             bytes
>>> b = b'ABC'                           >>> b = b'ABC'    (Python 3.3)
>>> type(b)                              >>> type(b)
<type 'str'>                             <class 'bytes'>
>>> b[0]                                 >>> b[0]
'A'                                      65
                                                            @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 + b
    Traceback (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 * None
    Traceback (most recent    call last):
       File "<stdin>", line   1, in <module>                 @ramalhoorg
    TypeError: unsupported    operand type(s) for *: 'int' and 'NoneType'
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 dobro
TypeError: 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
Projeto da tômbola




• UML:
 diagrama de classe


                      @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
           @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() >>> t = TombolaInvocavel()
      apenas t()               >>> t.carregar([1, 2, 3])
                                    >>> t()
                                    3
                                                >>> t()
from tombola import Tombola                        2
class TombolaInvocavel(Tombola):
    '''Sorteia itens sem repetir;
       a instância é invocável como uma função'''

    def __call__(self):
        return self.sortear()                             @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)
y
                                          • Campos: x, y
                                          • Métodos:
                                           • distancia
                        Vetor(4, 5)

Vetor(2, 4)


                                           • abs (distância até 0,0)
                                           • + (__add__)
              Vetor(2, 1)
                                      x    • * (__mul__) escalar
               oopy/exemplos/vetor.py                       @ramalhoorg
Vetor
from 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                  >>> from vetor import Vetor
        dy = self.y - v2.y                      >>> v = Vetor(3, 4)
        return sqrt(dx*dx + dy*dy)                  >>> abs(v)
                                                        5.0
    def __abs__(self):                         >>> v1 = Vetor(2, 4)
        return self.distancia(Vetor(0,0))
                                               >>> v2 = Vetor(2, 1)
                                                    >>> v1 + v2
    def __add__(self, v2):
        dx = self.x + v2.x                          Vetor(4, 5)
        dy = self.y + v2.y                          >>> v1 * 3
        return Vetor(dx, dy)                       Vetor(6, 12)

    def __mul__(self, n):
        return Vetor(self.x*n, self.y*n)                     @ramalhoorg
Baralho polimórfico




                     @ramalhoorg
Carta de
 baralho
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 de
                                                >>> zape = Carta('4',
                                                       'paus')
                                                   >>> zape.valor
                                                         '4'

 baralho                                              >>> zape
                                                 Carta('4', 'paus')
                                             >>> monte = Carta.todas()
                                                   >>> len(monte)
class Carta(object):                                     52
                                                    >>> monte[0]
    naipes = 'paus ouros copas espadas'.split() Carta('2', 'espadas')
    valores = '2 3 4 5 6 7 8 9 10 J Q K A'.split() >>> monte[-3:]
                                                [Carta('Q', 'copas'),
    def __init__(self, valor, naipe):            Carta('K', 'copas'),
        self.valor = valor                       Carta('A', 'copas')]
       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
Baralho
polimó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
Baralho
polimó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
                                            @ramalhoorg
http://xkcd.com/353/

Introdução a linguagem Python

  • 1.
    Luciano Ramalho luciano@ramalho.org @ramalhoorg Fácil para começar, difícil de superar Palestra apresentada na UNIFESP São José dos Campos em 10/dez/2012
  • 2.
    Ada Lovelace • AdaA. Byron King, condessa de Lovelace • nasceu em 10/dez/1815 • primeira programadora (antes de qualquer homem) @ramalhoorg
  • 3.
    Python: linguagem de usogeral • 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... @ramalhoorg
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 16.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 34.
  • 38.
    “Vocês são o centro do Vale do Silício hoje” Paul Graham, Pycon US 2012
  • 39.
    Linguagem “expressiva” Oque isso significa na prática? Linguagem COBOL
  • 40.
  • 41.
  • 42.
    Python tem sidouma parte importante do Google desde o início, e continua sendo à medida que o sistema cresce e evolui... estamos procurando mais pessoas com habilidade nesta linguagem. Peter Norvig, Google, Inc.
  • 43.
  • 44.
    lis.py: interpretador Lisp (Scheme) em 113 linhas de Python, por Peter Norvig
  • 45.
    >>> from lisimport repl Demo: lis.py >>> repl() lis.py> (* 7 3) 21 lis.py> (define resposta (* 6 7)) lis.py> resposta 42 lis.py> (define ! (lambda (n) (if (= n 0) 1 (* n (! (- n 1)))))) lis.py> (! 4) 24 lis.py> (! 5) 120 lis.py> (! 197) 10007840558408082122130389497134473659904776124145643156372043719 15587343235626799299914070366966935566947378481954772384977466613 67777918006944650646265409257583733981874437495228286501182991424 47739508657606635346735333579872783783532869428043930552260307311 88238628318646302096556423610922923784067025686796088553504768000 00000000000000000000000000000000000000000000 lis.py> ! <function <lambda> at 0x1004cbd70> lis.py>
  • 46.
    Sobre Python • Linguagemdinâ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
  • 47.
    Implementações • CPython: aprincipal, 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
  • 48.
    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
  • 51.
    2.5 Python: evolução 2006-09…2011-05 2.6 • Versões do CPython em dez/2012 2008-10 3.0 2008-12…2009-07 3.1 2009-06 • 3.0, 2.5 e anteriores: fossilizadas • 2.6 e 3.1: manutenção por 5 anos 2.7 2010-07 3.2 2011-02 3.3 • 2.7 e 3.2: versões atuais • 2.7: versão final da série 2.x 2012-09 • 3.3: lançada em set/2012 3.4 2014-02 ⋮ @ramalhoorg
  • 52.
    Pythonista: app paraiPad @ramalhoorg
  • 53.
    Pythonista @ramalhoorg
  • 54.
    Pythonista @ramalhoorg
  • 55.
  • 56.
    Pythonista @ramalhoorg
  • 58.
    Pythonista @ramalhoorg
  • 59.
    Pythonista @ramalhoorg
  • 60.
    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
  • 61.
  • 62.
  • 63.
    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
  • 64.
    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
  • 65.
    Consoles interativos • python •integrado em IDEs • iPython • online • bpython • http://shell.appspot.com/ • IDLE • http://pythonwebconsole.thomnichols.org/ • http://www.pythonanywhere.com/ @ramalhoorg
  • 66.
    IDEs, algumas opções • PyDev (Eclipse) • PyCharm (JetBrains) $$$ • Komodo Edit • Komodo IDE $$$ • TextMate $ - OSX • SublimeText $ • WingIDE $$$ @ramalhoorg
  • 67.
    Em vez deIDE: 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
  • 68.
    Configure o editorpara... • 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
  • 69.
    Comparando: C ePython #include <stdio.h> int main(int argc, char *argv[]) { int i; for(i = 0; i < argc; i++) printf("%sn", argv[i]); return 0; } import sys for arg in sys.argv: print arg @ramalhoorg
  • 70.
    Iteração em Java classArgumentos { public static void main(String[] args) { for (int i=0; i < args.length; i++) System.out.println(args[i]); } } $ java Argumentos alfa bravo charlie alfa bravo charlie @ramalhoorg
  • 71.
    Iteração em Java≥1.5 ano: 2004 • Enhanced for (for melhorado) class Argumentos2 { public static void main(String[] args) { for (String arg : args) System.out.println(arg); } } $ java Argumentos2 alfa bravo charlie alfa bravo charlie @ramalhoorg
  • 72.
    Iteração em Java≥1.5 ano: 2004 • Enhanced for (for melhorado) class Argumentos2 { public static void main(String[] args) { for (String arg : args) System.out.println(arg); } } ano: import sys 1991 for arg in sys.argv: print arg @ramalhoorg
  • 73.
    Exemplos de iteração •Iteração em Python não se limita a tipos primitivos • Exemplos • string • arquivo • Django QuerySet @ramalhoorg
  • 74.
    >>> from django.dbimport 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ás demonstração: MG Abadia dos Dourados GO Abadiânia queryset é um MG Abaeté iterável lazy 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'}]
  • 75.
    List comprehension List comprehensions ● Compreensão de lista ou abrangência ● Exemplo: usar todos os elementos: • Expressões que consomem L2 = [n*10 for n in L] – iteráveis e produzem listas qualquer iterável resultado: uma lista >>> 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] ≈ notação matemática de conjuntos @ramalhoorg
  • 76.
    Set & dictcomprehensions • 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
  • 77.
    Tipos iteráveis embutidos • basestring • frozenset • str • list • unicode • set • dict • tuple • file • xrange @ramalhoorg
  • 78.
    Funções embutidas que consomemiteráveis • all • max • any • min • filter • reduce • iter • sorted • len • sum • map • zip @ramalhoorg
  • 79.
    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 : %sn", i, argv[i]); return 0; } $ ./args2 alfa bravo charlie 0 : ./args2 1 : alfa 2 : bravo 3 : charlie @ramalhoorg
  • 80.
    Iteração em Python(ex. 2) não import sys Pythonico! for i in range(len(sys.argv)): print i, ':', sys.argv[i] $ python args2.py alfa bravo charlie 0 : args2.py 1 : alfa 2 : bravo 3 : charlie @ramalhoorg
  • 81.
    Iteração em Python(ex. 2) import sys Pythonico! for i, arg in enumerate(sys.argv): print i, ':', arg $ python args2.py alfa bravo charlie 0 : args2.py 1 : alfa 2 : bravo 3 : charlie @ramalhoorg
  • 82.
    Iteração em Python(ex. 2) import sys isso constroi um gerador for i, arg in enumerate(sys.argv): print i, ':', arg o gerador produz uma o gerador é um iterável preguiçoso! tupla (indice, item) sob demanda $ python args2.py alfa bravo charlie a cada iteração 0 : args2.py 1 : alfa 2 : bravo 3 : charlie @ramalhoorg
  • 83.
    Construtores embutidos que consomeme produzem iteráveis • dict • reversed • enumerate • set • frozenset • tuple • list @ramalhoorg
  • 84.
    Módulo itertools • 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()... @ramalhoorg
  • 85.
    Exercício: construir e controlar Tkinter.Label import Tkinter rel = Tkinter.Label() rel['text'] = '10:42:29' rel.grid() rel['font'] = 'Helvetica 120 bold' from time import strftime rel['text'] = strftime('%H:%M:%S') def tic():     rel['text'] = strftime('%H:%M:%S')      Para instalar def tac(): tic() Tkinter no     rel.after(100, tac) Ubuntu Linux: tac() $ sudo apt-get install python-tk @ramalhoorg
  • 86.
    Relógio com classe importTkinter from 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
  • 87.
    Uma pequena parte da hierarquia de classes do Tkinter herança múltipla mixin he ran ça mú ltipl a
  • 88.
    Um pouco maisda hierarquia de classes do Tkinter
  • 89.
    Hierarquia de classesdos objetos gráficos doTkinter
  • 90.
    Tudo é umobjeto • Não existem “tipos primitivos” como em Java • desde Python 2.2, dezembro de 2001 >>> 5 + 3 8 >>> 5 .__add__(3) 8 >>> type(5) <type 'int'> @ramalhoorg
  • 91.
    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
  • 92.
    Funções são objetos >>>fatorial.__code__.co_code '|x00x00dx01x00jx00x00ox05x00x01dx02x00Sx01|x00x00tx00x00| x00x00dx02x00x18x83x01x00x14S' >>> 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 12 POP_TOP 5 (to 17) Bytecode da 13 LOAD_CONST 16 RETURN_VALUE 2 (2) função >> 17 POP_TOP 18 LOAD_FAST 0 (0) fatorial 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 >>> @ramalhoorg
  • 93.
    Tipos @ramalhoorg
  • 94.
    Alguns tipos básicos >>>i = 7 Python 2.7 >>> i = 7 Python 3.2 >>> type(i) >>> type(i) <type 'int'> <class 'int'> >>> j = 2**100 >>> j = 2**100 >>> type(j) int e long >>> type(j) <type 'long'> unificados no <class 'int'> >>> f = 7. Python 3 >>> f = 7. >>> type(f) >>> type(f) <type 'float'> <class 'float'> >>> s = 'abc' >>> s = 'abc' >>> type(s) str >>> type(s) <type 'str'> x <class 'str'> SyntaxError >>> u = u'abc' unicode >>> u = u'abc' ou >>> type(u) x <type 'unicode'> <class ‘s tr’> bytes >>> b = b'ABC' >>> b = b'ABC' (Python 3.3) >>> type(b) >>> type(b) <type 'str'> <class 'bytes'> >>> b[0] >>> b[0] 'A' 65 @ramalhoorg
  • 95.
    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
  • 96.
    Tipagem forte • Otipo de um objeto nunca muda, e não existem “tipos variantes” • Raramente Python faz conversão automática >>> a = 10 >>> b = '9' >>> a + b Traceback (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 * None Traceback (most recent call last): File "<stdin>", line 1, in <module> @ramalhoorg TypeError: unsupported operand type(s) for *: 'int' and 'NoneType'
  • 97.
    Tipagem dinâmica: variáveis nãotê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 dobro TypeError: unsupported operand type(s) for *: 'NoneType' and 'int' @ramalhoorg
  • 98.
    Duck typing • “Sevoa 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
  • 99.
    Exemplo: tômbola • Sortearum a um todos os itens de uma coleção finita, sem repetir • A mesma lógica é usada em sistemas para gerenciar banners online @ramalhoorg
  • 100.
    Interface da tômbola •Carregar itens • Misturar itens • Sortear um item • Indicar se há mais itens @ramalhoorg
  • 101.
    Projeto da tômbola •UML: diagrama de classe @ramalhoorg
  • 102.
    TDD: Test DrivenDesign • 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
  • 103.
    Doctests • Um dosmó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
  • 104.
  • 105.
    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
  • 106.
    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
  • 107.
    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() >>> t = TombolaInvocavel() apenas t() >>> t.carregar([1, 2, 3]) >>> t() 3 >>> t() from tombola import Tombola 2 class TombolaInvocavel(Tombola): '''Sorteia itens sem repetir; a instância é invocável como uma função''' def __call__(self): return self.sortear() @ramalhoorg
  • 108.
    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
  • 109.
    Exemplo: vetor (2d) y • Campos: x, y • Métodos: • distancia Vetor(4, 5) Vetor(2, 4) • abs (distância até 0,0) • + (__add__) Vetor(2, 1) x • * (__mul__) escalar oopy/exemplos/vetor.py @ramalhoorg
  • 110.
    Vetor from math importsqrt 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 >>> from vetor import Vetor dy = self.y - v2.y >>> v = Vetor(3, 4) return sqrt(dx*dx + dy*dy) >>> abs(v) 5.0 def __abs__(self): >>> v1 = Vetor(2, 4) return self.distancia(Vetor(0,0)) >>> v2 = Vetor(2, 1) >>> v1 + v2 def __add__(self, v2): dx = self.x + v2.x Vetor(4, 5) dy = self.y + v2.y >>> v1 * 3 return Vetor(dx, dy) Vetor(6, 12) def __mul__(self, n): return Vetor(self.x*n, self.y*n) @ramalhoorg
  • 111.
  • 112.
    Carta de baralho classCarta(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
  • 113.
    Carta de >>> zape = Carta('4', 'paus') >>> zape.valor '4' baralho >>> zape Carta('4', 'paus') >>> monte = Carta.todas() >>> len(monte) class Carta(object): 52 >>> monte[0] naipes = 'paus ouros copas espadas'.split() Carta('2', 'espadas') valores = '2 3 4 5 6 7 8 9 10 J Q K A'.split() >>> monte[-3:] [Carta('Q', 'copas'), def __init__(self, valor, naipe): Carta('K', 'copas'), self.valor = valor Carta('A', 'copas')] 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
  • 114.
    Baralho polimó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
  • 115.
    Baralho polimó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 @ramalhoorg
  • 116.