O documento discute conceitos fundamentais de algoritmos, programas, compiladores, link-editores e interpretadores. Ele também introduz a linguagem de programação Python, discutindo brevemente sua história, versões, aplicações e características.
2. Algoritmos e Programas
Algoritmo =
método para solucionar um problema
Estruturas de dados =
método para organizar informações
Programa =
algoritmos + estruturas de dados expressos de forma a ser
entendidos pelo computador
Programas tipicamente processam dados de entrada e
produzem dados de saída
Programa
Entrada Saída
3. Compiladores
Programas que traduzem programas escritos em linguagem de
programação para programas equivalentes escritos em linguagem
de máquina
O primeiro é chamado de programa fonte, enquanto que o segundo
é chamado de programa objeto
Compilador
Programa
fonte
Programa
objeto
4. Link-Editores
O programa-objeto nem sempre está pronto para
ser executado
Outros trechos de código precisam ser incluídos
Bibliotecas
Subprogramas
Programa executável é montado por um programa
chamado link-editor ou linking-loader
Compilador normalmente chama o link-editor
automaticamente
6. Interpretadores
Simulam uma “máquina virtual”
Programa fonte é lido, entendido e as instruções
são executadas imediatamente
Interpretador
Programa
fonte
Entrada Saída
7. Esquemas Híbridos
Compilador gera código para uma máquina virtual
(pseudo-código)
Máquina virtual é executada separadamente lendo
pseudo-código e interpretando-o
Compilador
Prog.
Fonte
Prog
objeto
Dados
Entrada
Interpretador Saída
9. Por que Python?
Orientação a Objetos
Grande variedade de aplicações e bibliotecas
Conceitos fundamentais simples
Sintaxe clara – muito próxima de um pseudo-
código
Código curto e legível
Ciclo de desenvolvimento rápido
Linguagem interpretada (script)
Multi-plataforma
Grátis!
10. Breve História
Criada por Guido van Rossum em 1989 no
Centrum voor Wiskunde en Informatica (CWI),
em Amsterdã,Holanda.
Linguagem de scripts para o sistema operacional
distribuído Amoeba.
Baseada na linguagem ABC, desenvolvida no
CWI por Guido e outros nas décadas de 70 e 80.
O nome Python teve origem no grupo
humorístico britânico Monty Python.
11. Versões
26 de janeiro de 1994 – versão 1.0
16 de outubro de 2000 – versão 2.0
19 de setembro de 2006 – versão 2.5 (estável)
31 de agosto de 2007 – versão 3.0 (alpha)
Versão estável previsto para Agosto de 2008
12. No Mundo
NASA (vários projetos)
Yahoo! (Yahoo mail & groups)
Apple, H.P., Microsoft
Muitas Universidades, como MIT, e Stanford
13. Google
Sistema de ajuda do GMail
Google Groups
Sistema de compilação de aplicativos (build
system).
Sistema de empacotamento e entrega de dados
(packaging system).
Sistema de monitoramento e manutenção do
cluster
Sistema de testes
14. No Brasil
Jornal do Brasil, AOL Brasil
Embratel: monitoramento das interfaces de
backbone e clientes de internet, também existem
scripts de uso interno.
CPqD: monitoramento de centrais telefônicas.
Conectiva: Gerenciamento de pacotes da
distribuição Linux e ferramentas de uso interno.
Async: desenvolvimento de software de
automação comercial
15. Como rodar um código Python
Interpretador
http://www.python.org
Implementação pronta para baixar (windows)
Linux normalmente já vem com python instalado
Um editor de textos
Qualquer editor serve
Ambiente IDLE inclui um editor
Incluído na distribuição windows
16. Python Interativo
Rode o interpretador (Python Shell)
Digite comandos python
Cada comando é executado imediatamente!
>>> print "Hello World!"
Hello World!
>>> a = 2
>>> print a
2
>>>
17. Executando um programa Python
Escreva um programa python
Invoque o interpretador para executá-lo
> cat prog.py
#! /usr/bin/env python
print “Hello World!“
> Python prog.py
Hello World!
> ./prog.py
Hello World!
18. Executando um programa Python
Interfaces gráficas normalmente já associam os
sufixos .py e .pyc com o interpretador
20. Python como calculadora
O Interpretador python pode ser usado como
calculadora
Por exemplo, as quatro operações aritméticas são
denotadas pelos símbolos
+ adição
- subtração
* multiplicação
/ divisão
% resto
** potênciação
21. Python como calculadora
>>> 10
10
>>> # Um comentário é precedido do caracter "#"
... # Comentários são ignorados pelo interpretador
... 10+5
15
>>> 10-15 # Comentários podem aparecer também após código
-5
>>> 10*3
30
>>> 10/3
3
>>> 10/-3 # Divisão inteira retorna o piso
-4
>>> 10%3 # Resto de divisão inteira simbolizado por %
1
22. Tipos de dados
São categorias de valores que são processados de
forma semelhante
Por exemplo, números inteiros são processados de
forma diferente dos números de ponto flutuante
(decimais) e dos números complexos
Tipos primitivos: são aqueles já embutidos no núcleo
da linguagem
Simples: números (int, long, float, complex) e cadeias de
caracteres (strings)
Compostos: listas, dicionários, tuplas e conjuntos
Tipos definidos pelo usuário: são correspondentes a
classes (Orientação Objeto)
23. Variáveis
São nomes dados a áreas de memória
Nomes podem ser compostos de algarismos,letras ou _
O primeiro caractere não pode ser um algarismo
Palavras reservadas (if, while, etc) são proibidas
Servem para:
Guardar valores intermediários
Construir estruturas de dados
Uma variável é modificada usando o comando de atribuição:
Var = expressão
É possível também atribuir a várias variáveis
simultaneamente:
var1,var2,...,varN = expr1,expr2,...,exprN
25. Variáveis
Variáveis são criadas dinamicamente e destruídas
quando não mais necessárias, por exemplo, quando
saem fora de escopo
O tipo de uma variável muda conforme o valor
atribuído: int, float, string, etc.
Não confundir com linguagens sem tipo
Ex.:
>>> a ="1"
>>> b = 1
>>> a+b
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: cannot concatenate 'str' and 'int' objects
26. Números
Há vários tipos numéricos que se pode usar em
python
Int: números inteiros de precisão fixa
1 , 2 , 15 , -19
Long: números inteiros de precisão arbitrária
1L , 10000L , -9999999L
Floats: números racionais de precisão variável
1.0 , 10.5 , -19000.00005 , 15e-5
Complex: números complexos
1+1j , 20j , 1000+100j
27. Números inteiros
Os ints têm precisão fixa ocupando tipicamente uma
palavra de memória
Em PC's são tipicamente representados com 32 bits (de -
231-1 a 232)
Os números inteiros de precisão arbitrária (longs)
são armazenados em tantas palavras quanto
necessário
Constantes do tipo long têm o prefixo L ou l
Longs são manipulados bem mais lentamente que ints
Quando necessário, cálculos usando ints são convertidos
para longs
28. Números inteiros
>>> a=2**30 # Potenciação
>>> a
1073741824
>>> b=a*1000
>>> b
1073741824000L
>>> b/1000
1073741824L
29. Números inteiros
Constantes podem ser escritas com notação
idêntica à usada em C
Hexadecimal: preceder dígitos de 0x
Octal: preceder dígitos de 0
Ex.:
>>> 022
18
>>> 0x10
16
>>> 0x1f
31
30. Números de ponto flutuante
São implementados como os double's da linguagem C –
tipicamente usam 2 palavras
Constantes têm que possuir um ponto decimal ou serem
escritas em notação científica com a letra “e” (ou “E”)
precedendo a potência de 10
Ex:
>>> 10 # inteiro
10
>>> 10.0 # ponto flutuante
10.0
>>> 99e3
99000.0
>>> 99e-3
0.099000000000000005
31. Números complexos
Representados com dois números de ponto flutuante: um para
a parte real e outro para a parte imaginária
Constantes são escritas como uma soma sendo que a parte
imaginária tem o sufixo j ou J
Ex.:
>>> 1+2j
(1+2j)
>>> 1+2j*3
(1+6j)
>>> (1+2j)*3
(3+6j)
>>> (1+2j)*3j
(-6+3j)
32. Strings
São cadeias de caracteres
Constituem outro tipo fundamental do python
Constantes string são escritas usando aspas simples ou
duplas
Ex.: "a" ou 'a'
O operador “+” pode ser usado para concatenar strings
Ex.: "a"+"b" é o mesmo que "ab"
O operador “*” pode ser usado para repetir strings
Ex.: "a"*10 é o mesmo que "aaaaaaaaaa"
33. Strings
Python usa a tabela de caracteres default do S.O.
Ex.: ASCII, UTF-8
Caracteres não imprimíveis podem ser expressos usando
notação “barra-invertida” ()
n é o mesmo que new line
r é o mesmo que carriage return
t é o mesmo que tab
b é o mesmo que backspace
é o mesmo que
x41 é o mesmo que o caractere cujo código hexadecimal é
41 (“A” maiúsculo)
34. Strings
>>> "abrd"
'ard'
>>> print "abrd" # print exibe cars não imprimíveis
db
>>> print "abctd"
abc d
>>> print "abcnd"
abc
d
>>> print "abcnd"
abcnd
>>> print "abbc"
ac
>>> print "x41xA1"
Aí
35. Strings
A notação barra-invertida () pode ser desabilitada
desde que a constante string seja precedida por um
r (erre minúsculo)
São chamadas strings raw (cruas)
Ex.:
>>> print "abcncdtef"
abc
cd ef
>>> print r"abcncdtef"
abcncdtef
36. Strings
Constantes string podem ser escritas com várias linhas
desde que as aspas não sejam fechadas e que cada
linha termine com uma barra invertida
Ex.:
>>> print "abcdn
... efghn
... ijk"
abcd
efgh
ijk
>>> print "abcd
... efgh
... ijk"
abcdefghijk
>>>
37. Strings
Também é possível escrever constantes string em várias linhas
incluindo as quebras de linha usando três aspas como delimitadores
Ex.:
>>> print """
Um tigre
dois tigres
três tigres"""
Um tigre
dois tigres
três tigres
>>> print '''abcd
efgh'''
abcd
efgh
38. Strings – Índices
Endereçam caracteres individuais de uma string
Notação: string[índice]
O primeiro caractere tem índice 0
O último caractere tem índice -1
Ex.:
>>> a = "abcde"
>>> a[0]
'a'
>>> a[-1]
'e'
39. Strings – Fatias (slices)
Notação para separar trechos de uma string
Notação: string[índice1:índice2]
Retorna os caracteres desde o de índice1 (inclusive) até
o de índice1 (exclusive)
Se o primeiro índice é omitido, é assumido 0
Se o último índice é omitido, é assumido o fim da string
41. Expressões booleanas
Também chamadas expressões lógicas
Resultam em verdadeiro (True) ou falso (False)
São usadas em comandos condicionais e de repetição
Servem para analisar o estado de uma computação e permitir
escolher o próximo passo
Operadores mais usados
Relacionais: > , < , ==, !=, >=, <=
Booleanos: and, or, not
Avaliação feita em “Curto-circuito”
Expressão avaliada da esquerda para a direita
Se o resultado (verdadeiro ou falso) puder ser determinado sem
avaliar o restante, este é retornado imediatamente
42. Expressões booleanas
>>> 1==1
True
>>> 1==2
False
>>> 1==1 or 1==2
True
>>> 1==1 and 1==2
False
>>> 1<2 and 2<3
True
>>> not 1<2
False
>>> not 1<2 or 2<3
True
>>> not (1<2 or 2<3)
False
>>> "alo" and 1
1
>>> "alo" or 1
'alo'
43. Expressões booleanas
As constantes True e False são apenas símbolos
convenientes
Qualquer valor não nulo é visto como verdadeiro
enquanto que 0 (ou False) é visto como falso
O operador or retorna o primeiro operando se for
vista como verdadeiro, caso contrário retorna o
segundo
O operador and retorna o primeiro operando se for
vista como falso, caso contrário retorna o segundo
Operadores relacionais são avaliados antes de not,
que é avaliado antes de and, que é avaliado antes
de or
44. Expressões booleanas
>>> 0 or 100
100
>>> False or 100
100
>>> "abc" or 1
'abc'
>>> 1 and 2
2
>>> 0 and 3
0
>>> False and 3
False
>>> 1 and 2 or 3
2
>>> 0 or 2 and 3
3
>>> 1 and not 0
True
45. Funções Embutidas
Além dos operadores, é possível usar funções para
computar valores
As funções podem ser definidas:
Pelo programador
Em módulos da biblioteca padrão
Por default: são as funções embutidas (built-in)
Na verdade, fazem parte do módulo __builtins__, que é sempre
importado em toda aplicação
Ex.:
abs(x) retorna o valor absoluto do número x
chr(x) retorna uma string com um único caractere cujo
código ASCII é x
ord(s) retorna o código ASCII do caractere s
47. Importando módulos
Muitas funções importantes são disponibilizadas em
módulos da biblioteca padrão
Ex.: o módulo math tem funções transcendentais como
sin, cos, exp e outras
Um módulo pode conter não só funções mas também
variáveis ou classes
Por exemplo, o módulo math define a constante pi
Para usar os elementos de um módulo, pode-se usar o
comando import
Formatos:
import modulo
from modulo import nome,...,nome
from modulo import *
48. Importando módulos
Por exemplo:
from math import *
# importa todos os elementos do módulo math
from math import sin
# importa apenas a função sin
import math
# importa o módulo math como um todo
# (todos os elementos têm que ser citados
# precedidos por math.)
49. Importando módulos
>>> import math
>>> a = sin(30)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: name 'sin' is not defined
>>> a = math.sin(30)
>>> from math import sin
>>> a = sin(30)
>>> print a
-0.988031624093
>>> a = sin(radians(30))
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: name 'radians' is not defined
>>> from math import *
>>> a = sin(radians(30))
>>> a
0.49999999999999994
50. Primeiros passos em programação
Até agora só vimos como computar algumas
expressões simples
Expressões são escritas e computadas imediatamente
Variáveis podem ser usadas para valores temporários
Um programa típico entretanto usa vários tipos de
construções tais como:
Comandos condicionais
Comandos de repetição
Definição e uso de procedimentos (subprogramas)
Definição e uso de classes e objetos (programação OO)
51. Primeiros passos em programação
>>> # Série de Fibonacci
... a,b=0,1
>>> while b < 10:
... print b
... a,b=b,a+b
...
1
1
2
3
5
8
Comentário
Atribuição dupla
Comando de repetição
Bloco do
comando de repetição
Expressão booleana
Resultado
Indentação
52. Programas armazenados
À medida que os programas vão se tornando mais
complicados, é mais interessante guardá-los em arquivos e
executá-los quando necessário
Arquivo fibo.py (use um editor de textos como o do IDLE):
# Série de Fibonacci:
a, b = 0, 1
while b < 10:
print b
a, b = b, a+b
Para executar o programa,
Digite python fibo.py no seu shell ou
Clique no ícone do arquivo, ou
De dentro do editor IDLE, selecione Run Module (F5)
53. print
Forma geral: print expr,expr,...
Os valores das expressões são escritos um após o outro sem
pular de linha:
>>> print "1.001 ao quadrado é ",1.001**2
1.001 ao quadrado é 1.002001
Se o comando terminar com vírgula, o próximo print escreverá
na mesma linha. Por exemplo:
>>> a, b = 0, 1
>>> while b < 1000:
... print b,
... a, b = b, a+b
...
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
54. input
O programa que computa elementos da série de Fibonacci termina
quando atinge um elemento com valor superior a uma constante
Podemos tornar o programa mais flexível se ao usuário for permitido
estipular o valor máximo
O comando input permite perguntar ao usuário um valor
(normalmente é atribuído a uma variável)
Formato: input(pergunta)
onde pergunta é uma string opcional que será exibida para indicar
o valor que se espera (i.e., prompt)
Exemplo:
>>> a = input("Entre com um numero: ")
Entre com um numero: 19
>>> print a
19 Usuário digita o número
55. Input
O comando input espera que se digite algo que faça sentido do
lado direito de um sinal de atribuição. Ex:
>>> print a
19
>>> b = input()
a
>>> b
19
>>> c = input("entre com uma cadeia de caracteres: ")
entre com uma cadeia de caracteres: abc
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<string>", line 0, in ?
NameError: name 'abc' is not defined
>>> c = input("entre com uma cadeia de caracteres: ")
entre com uma cadeia de caracteres: "abc"
>>> c
'abc'
56. raw_input
É semelhante ao input, mas não tenta interpretar o
que foi digitado como uma expressão
O resultado é simplesmente uma string com o texto
digitado
Ex.:
>>> curso= raw_input( "Entre o seu curso: " )
Entre o seu curso: Ciências da Computação
>>> print curso
Ciências da Computação
>>> curso
'Cixeancias da Computaxe7xe3o'
57. while
Repete uma seqüência de comandos enquanto uma dada
expressão booleana é avaliada como verdadeira
Formato:
while expressão:
comando
...
comando
Exemplo:
>>> a = 10
>>> while a>8:
... print a,
... a = a-1
...
10 9
58. Laços Infinitos
Como em todo comando de repetição, é importante
evitar os chamados “laços infinitos”
Ex.:
>>> a = 10
>>> while a>8:
... print a,
... a = a+1
...
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
27 28 29 30 31 32 33 ...
59. if
É o comando condicional por excelência
Formatos:
if expressao:
comandos
if expressao:
comandos1
else:
comandos2
if expressao1:
comandos1
elif expressao2:
comandos2
else:
comandos(N)
Executa comandos
apenas se expressão
for verdadeira
Executa seq de comandos 1
caso expressão seja
verdadeira. Caso contrário, executa
seq de comandos 2
Executa seq de comandos 1
caso expressão1 seja
verdadeira. Caso contrário, testa expressao2
e executa seq de comandos 2
se verdadeira
Caso contrário, executa
seq de comandos N
60. if
Exemplo 1
a = input("Entre com um numero:")
if a < 0:
print a," é negativo"
print "Obrigado!“
Execução 1:
Entre com um numero:2
Obrigado!
Execução 2:
Entre com um numero:-2
-2 é negativo
Obrigado!
61. if
Exemplo 2
a = input("Entre com um numero:")
if a < 0:
print a," é negativo"
else:
print a," é zero ou positivo"
print "Obrigado!“
Execução 1:
Entre com um numero:2
2 é zero ou positivo
Obrigado!
Execução 2:
Entre com um numero:-2
-2 é negativo
Obrigado!
62. if
Exemplo 3
a = input("Entre com um numero:")
if a < 0:
print a," é negativo"
elsif a==0:
print a," é zero"
else:
print a," é positivo"
print "Obrigado!“
Execução 1:
Entre com um numero:0
0 é zero
Obrigado!
Execução 2:
Entre com um numero:2
2 é positivo
Obrigado!
63. Estruturas de dados
Maneira de organizar dados de maneira a facilitar seu acesso
Algumas formas são clássicas:
Listas
Arrays (vetores e matrizes)
Tuplas (registros)
Árvores
Linguagens freqüentemente possuem primitivas para
construção dessas E.D.
Estruturas de dados embutidas
Outras E.D. mais complexas podem ser construídas
combinando as E.D. clássicas
64. Estrutura de dados abstrata
É uma especificação matemática que define uma
coleção de dados e uma série de operações sobre ela
É abstrata porque não especifica como as operações
são feitas mas somente os dados de entrada e o
resultado
Numa linguagem de programação, essa coleção de
operações é chamada de interface ou API (Application
Programming Interface)
Usuários da e.d.a devem se preocupar com a interface e
não com a implementação, que pode mudar com o
tempo
A implementação de uma e.d.a. requer cuidados quanto
à correção e a eficiência da mesma
65. Listas
São arranjos seqüenciais de informações mais simples
Caracterizam-se por permitir o acesso eficiente aos seus
elementos em ordem seqüencial
A definição clássica de uma lista como estrutura de
dados abstrata compreende:
Operação de construção de uma lista vazia
Operação que testa se uma dada lista é vazia
Operação para obter o primeiro elemento de uma lista
Uma operação para adicionar um novo elemento no início
de uma lista
Operação para retirar o elemento inicial de uma lista
66. Listas em Python
A estrutura conhecida como lista (list, em inglês) em
Python é bastante mais geral do que e.d.a. lista
clássica
Na verdade, pode ser vista como uma
implementação tanto de listas como de arrays
Além de acesso seqüencial, suportam também acesso
direto através de índices
Listas são variedades de seqüências assim como
strings e portanto têm APIs semelhantes
Podem ser indexadas e fatiadas
Podem ser concatenadas (+) e repetidas
67. Listas em Python
Entretanto, há diferenças importantes entre listas e
strings
Seqüência genérica vs. de seqüência de caracteres
Elementos de listas podem ser alterados individualmente
mas os de strings, não
Listas constituem o tipo de agregação de dados
mais versátil e comum da linguagem Python
Podem ser usadas para implementar estruturas de dados
mais complexas como matrizes e árvores, por exemplo
68. Listas: constantes e índices
Uma constante do tipo lista é escrita entre colchetes
com os elementos separados por vírgula:
[] # lista vazia
[1,2] # lista com 2 elementos
Os elementos de uma lista podem ser de qualquer
tipo, inclusive listas. Ex.:
lista = [1, 'a', 2+3j, ['ab', 'CD']]
Os elementos de uma lista podem ser acessados
por índices como strings
O primeiro elemento tem índice 0
O último elemento tem índice -1
69. Listas: constantes e índices
>>> lista = [1, 'a', 2+3j, ['ab', 'CD']]
>>> lista [0]
1
>>> lista [2]
(2+3j)
>>> lista [3]
['ab', 'CD']
>>> lista [-1]
['ab', 'CD']
>>> lista [0] = 2
>>> lista
[2, 'a', (2+3j), ['ab', 'CD']]
70. Listas: Concatenação e Repetição
O operador + pode ser usado para concatenação e
o operador * para repetição
>>> lista = [0]*4
>>> lista
[0, 0, 0, 0]
>>> lista = lista + [1]*3
>>> lista
[0, 0, 0, 0, 1, 1, 1]
71. Deletando elementos
O operador del pode ser usado para remover
elementos de uma lista
Ex.:
>>> lista
[1, 2, 3, ['ab', 'CD']]
>>> del lista [2]
>>> lista
[1, 2, ['ab', 'CD']]
>>> del lista [2][1]
>>> lista
[1, 2, ['ab']]
72. Listas: fatias (slices)
A notação de fatias também pode ser usada,
inclusive para atribuição:
>>> lista = [1, 'a', 2+3j, ['ab', 'CD']]
>>> lista [1:]
['a', (2+3j), ['ab', 'CD']]
>>> lista [:1]
[1]
>>> lista [1:2]
['a']
>>> lista [0:-1]
[1, 'a', (2+3j)]
73. Listas: atribuição a fatias
A atribuição a uma fatia requer que o valor atribuído seja uma
seqüência (uma lista ou uma string, por exemplo)
A atribuição substitui os elementos da fatia pelos da sequência
>>> lista = [1, 'y', ['ab', 'CD']]
>>> lista [1:1] = ['z']
>>> lista
[1, 'z', 'y', ['ab', 'CD']]
>>> lista [1:3] = [['x']]
>>> lista
[1, ['x'], ['ab', 'CD']]
>>> lista [1:-1]= [2,3,4]
>>> lista
[1, 2, 3, 4, ['ab', 'CD']]
>>> lista [:2] = 'xyz'
>>> lista
['x', 'y', 'z', 3, 4, ['ab', 'CD']]
74. Incrementos em Fatias
É possível usar um terceiro número na notação de
fatias designando o incremento
Default é 1 , ou seja, toma os elementos de um em um do
menor para o maior índice
Pode-se usar qualquer número inteiro diferente de 0
a[0:10:2] retorna uma lista com os 10 primeiros elementos
de a tomados de 2 em 2 (5 elementos, no máximo)
a[0:5:-1] retorna uma lista com os 5 primeiros elementos de
a tomados da esquerda para a direita
Obs.: Esta notação só existe nas versões de Python
a partir da 2.3
75. Incrementos em Fatias
Exemplo
>>> a = ['a', 2, 3, 'd', 'x']
>>> a [:3:2]
['a', 3]
>>> a [::-1]
['x', 'd', 3, 2, 'a']
76. Incrementos em Fatias
Se um incremento de fatia é diferente de 1, uma
atribuição à fatia deve ter o mesmo número de
elementos:
>>> l = [1,2,3,4,5]
>>> l [0::2] = ['x','y','z']
>>> l
['x', 2, 'y', 4, 'z']
>>> l [0::2] = [6,7]
Traceback (most recent call last):
File "<pyshell#17>", line 1, in -toplevel-
l [0::2] = [6,7]
ValueError: attempt to assign sequence of size 2
to extended slice of size 3
77. Operador “in”
Permite saber se um elemento pertence a uma lista
Serve também para strings
Ex.:
>>> lista = [1, 'a', 'bc']
>>> 1 in lista
True
>>> 2 in lista
False
>>> 'b' in lista
False
>>> 'b' in lista[2]
True
>>> 'bc' in 'abcd'
True
78. Inicializando listas
Não é possível atribuir a uma posição inexistente de uma
lista
>>> vetor = []
>>> vetor [0] = 1
Traceback (most recent call last):
File "<pyshell#21>", line 1, in -toplevel-
vetor [0] = 1
IndexError: list assignment index out of range
Se uma lista vai ser usada como um array, isto é, vai
conter um número predeterminado de elementos, é
conveniente iniciá-la
>>> vetor = [0]*10
>>> vetor [0] = 3
>>> vetor
[3, 0, 0, 0, 0, 0, 0, 0, 0, 0]
79. Usando None
No uso de estruturas de dados, às vezes é
importante preencher uma posição com um valor
“não válido”
A melhor opção para esse uso é empregar o valor
especial None
Não faz parte de tipo nenhum
É melhor que usar 0, [] ou uma string vazia
Útil para criar uma lista “vazia” mas com um número
conhecido de posições. Ex.:
>>> lista = [None]*5
>>> lista
[None, None, None, None, None]
80. Len, min e max
len (lista) retorna o número de elementos de lista
min (lista) e max (lista) retornam o menor/maior
elemento de lista
Ex.:
>>> lista = [1, 2, 9, 3, 4]
>>> min(lista)
1
>>> len (lista)
5
>>> max (lista)
9
>>> max (['a', 'b', 'c'])
'c'
81. min e max
Na verdade, min e max podem ser usados também
com vários argumentos ao invés de uma lista
Ex.:
>>> min(1,2,3,4)
1
>>> max (3,4,5)
5
>>> max ([],[1],['a'])
['a']
82. A função list
Pode ser usada para converter uma string numa lista
É útil pois uma lista pode ser modificada, mas uma string, não
Para fazer a transformação inversa, pode-se usar o método
join
Ex.:
>>> lista = list('alo')
>>> lista
['a', 'l', 'o']
>>> lista[1]='xx'
>>> lista
['a', 'xx', 'o']
>>> ''.join(lista)
'axxo'
83. A função range
Retorna uma progressão aritmética de inteiros numa lista
Forma geral: range (início, parada, incremento)
início (opcional) é o primeiro valor a ser gerado (default: 0)
parada é o limite da progressão: a progressão termina no
último valor antes de parada
incremento (opcional) é o passo da progressão (default:1)
Ex.:
>>> range(3)
[0, 1, 2]
>>> range(2,5,2)
[2, 4]
>>> range(5,2,-2)
[5, 3]
84. Comando for
Permite iterar sobre os elementos de uma lista
Forma geral: for var in lista : comandos
Os comandos são repetidos para cada valor de lista
Durante a repetição, var possui o valor corrente da lista
Uma grande utilidade da função range é construir a
lista de iteração
Ex.:
>>>for i in range(1,7): print i,
1 2 3 4 5 6
85. Comparando listas
Listas são comparadas lexicograficamente
Se duas listas são iguais até o k-ésimos elementos, o
resultado da comparação depende da comparação entre
os (k+1)-ésimos elementos
Se alguma das listas tem somente k elementos, então esta é a
menor
Duas listas são iguais se e somente se têm o mesmo
comprimento e todos os elementos de mesma posição
são iguais
Uma lista é maior que um número mas menor que
uma string
Não me pergunte por quê!
87. Variáveis do tipo list
Uma variável do tipo lista na verdade contém uma
referência para um valor do tipo lista
Atribuir uma variável a outra, cria uma nova referência
mas não uma nova lista
Para se criar um novo valor, pode-se usar uma expressão
que retorne o valor desejado
Para saber se duas variáveis se referem ao mesmo valor
pode-se usar o operador is
88. Variáveis do tipo list
>>> a = b = [1,2,3]
>>> c = a
>>> d = c[:]
>>> a is b
True
>>> c is b
True
>>> d is c
False
>>> a [1]=5
>>> b
[1, 5, 3]
>>> d
[1, 2, 3]
89. A Classe list
Uma lista é na verdade um objeto de uma classe
chamada list
Não vimos ainda programação OO, mas alguns pontos
devem ser enfatizados
Listas possuem métodos que podem ser aplicados a
elas
Um método é semelhante a uma função, mas são
invocados de forma diferente: objeto.método(args)
Ex.: lista.reverse() inverte a ordem dos elementos
da lista
Para saber todos os métodos de listas, escreva
help(list)
90. Alguns métodos da classe list
append(elemento)
Acrescenta o elemento no fim da lista
Observe que a operação altera a lista, e não
simplesmente retorna uma lista modificada
Ex.:
>>> lista = [1,2]
>>> lista.append(3)
>>> lista
[1, 2, 3]
>>> lista.append([4,5])
>>> lista
[1, 2, 3, [4, 5]]
91. Alguns métodos da classe list
count(elemento)
Retorna quantas vezes o elemento aparece na lista
Ex.:
>>> [1,2,3,1,2,3,4].count(1)
2
extend(lista2)
Acrescenta os elementos de lista2 ao final da lista
OBS.: Altera a lista ao invés de retornar a lista alterada
Ex.:
>>> lista=[1,2]
>>> lista.extend([3,4])
>>> lista
[1, 2, 3, 4]
92. Alguns métodos da classe list
count(elemento)
Retorna quantas vezes o elemento aparece na lista
Ex.:
>>> [1,2,3,1,2,3,4].count(1)
2
extend(lista2)
Acrescenta os elementos de lista2 ao final da lista
OBS.: Altera a lista ao invés de retornar a lista alterada
Ex.:
>>> lista=[1,2]
>>> lista.extend([3,4])
>>> lista
[1, 2, 3, 4]
93. Alguns métodos da classe list
index(elemento)
Retorna o índice da primeira ocorrência de elemento na
lista
Um erro ocorre se elemento não consta da lista
Ex.:
>>> lista = [9,8,33,12]
>>> lista.index(33)
2
>>> lista.index(7)
Traceback (most recent call last):
File "<pyshell#3>", line 1, in -toplevel-
lista.index(7)
ValueError: list.index(x): x not in list
94. Alguns métodos da classe list
insert(indice, elemento)
insere elemento na lista na posição indicada por índice
Ex.:
>>> lista = [0,1,2,3]
>>> lista.insert(1,'dois')
>>> lista
[0, 'dois', 1, 2, 3]
Como o extend, altera a lista ao invés de retornar a lista
O valor retornado é None!
Atribuições a fatias servem para a mesma finalidade mas são
menos legíveis
>>> lista = [0,1,2,3]
>>> lista [1:1] = ['dois']
>>> lista
[0, 'dois', 1, 2, 3]
95. Alguns métodos da classe list
pop(índice)
Remove da lista o elemento na posição índice e o retorna
Se índice não for mencionado, é assumido o último
Ex.:
>>> lista = [1,2,3,4]
>>> lista.pop()
4
>>> lista
[1, 2, 3]
>>> lista.pop(1)
2
>>> lista
[1, 3]
96. Alguns métodos da classe list
remove(elemento)
Remove da lista o primeiro elemento igual a elemento
Se não existe tal elemento, um erro é gerado
Ex.:
>>> lista = ['oi', 'alo', 'ola']
>>> lista.remove('alo')
>>> lista
['oi', 'ola']
>>> lista.remove('oba')
Traceback (most recent call last):
File "<pyshell#24>", line 1, in -toplevel-
lista.remove('oba')
ValueError: list.remove(x): x not in list
97. Alguns métodos da classe list
reverse()
Inverte a ordem dos elementos da lista
Ex.:
>>> lista=[1,2,3]
>>> lista.reverse()
>>> lista
[3, 2, 1]
98. Alguns métodos da classe list
sort(cmp=None, key=None, reverse=False)
Ordena a lista
Os argumentos são opcionais. Por default, a lista é
ordenada crescentemente
Ex.:
>>> lista = [9,8,7,1,4,2]
>>> lista.sort()
>>> lista
[1, 2, 4, 7, 8, 9]
99. Alguns métodos da classe list
sort(cmp=None, key=None, reverse=False)
É possível obter a ordem inversa, passando True para o
argumento reverse
Ex.:
>>> lista = [9,8,7,1,4,2]
>>> lista.sort(reverse=True)
>>> lista
[9, 8, 7, 4, 2, 1]
OBS.: A notação acima permite passar um argumento
sem especificar os anteriores, mas poderíamos ter
escrito:
>>> lista = [9,8,7,1,4,2]
>>> lista.sort(None,None,True)
>>> lista
[9, 8, 7, 4, 2, 1]
100. Alguns métodos da classe list
sort(cmp=None, key=None, reverse=False)
O argumento cmp especifica uma função de comparação
É uma função que o sort chama para definir se um elemento é
anterior ou posterior a outro
A função a ser passada tem a forma comp(elem1,elem2) e deve
retornar um inteiro negativo caso elem1 seja anterior a elem2,
positivo caso elem2 seja anterior a elem1 e zero se tanto faz
Ex.:
>>> def compara(elem1,elem2):
return elem1%10 - elem2%10
>>> compara(100,22)
-2
>>> lista=[100,22,303,104]
>>> lista.sort(compara)
>>> lista
[100, 22, 303, 104]
101. Alguns métodos da classe list
sort(cmp=None, key=None, reverse=False)
O argumento key especifica uma função aplicada a cada
elemento
Se for passada uma função f, em vez de ordenar os elementos
baseado em seus valores v, ordena baseado em f(v)
Ex.:
>>> lista = ['abc','de','fghi']
>>> lista.sort(key=len)
>>> lista
['de', 'abc', 'fghi']
102. Matrizes
Listas podem ser usadas para guardar matrizes
Por exemplo, podemos criar uma matriz-identidade de
3x3 com o código:
m = []
for i in range(3):
m.append([0]*3)
m[i][i]=1
Obs.: Não é boa idéia iniciar uma matriz assim:
m = [[0]*3]*3
for i in range(3): m[i][i]=1
print m
Resultado:[[1, 1, 1], [1, 1, 1], [1, 1, 1]]
103. Construções Iterativas
É possível construir listas através de processos
iterativos de forma concisa usando a forma
[expressão iteração]
onde
expressão indica como construir um elemento genérico
da lista com base nas variáveis da iteração
iteração é uma ou mais cláusulas for eventualmente
encadeadas com condições sob a forma de cláusulas if
(Veja também as ferramentas para programação
funcional na aula sobre funções)
104. Exemplos
>>> [i*2+3 for i in range(10)]
[3, 5, 7, 9, 11, 13, 15, 17, 19, 21]
>>> [i*2+3 for i in range(10) if i%3==0]
[3, 9, 15, 21]
>>> [[int(i==j) for j in range(3)] for i in
range(3)]
[[1, 0, 0], [0, 1, 0], [0, 0, 1]]
>>> v1 = [1,2,3]
>>> v2 = [3,4,5]
>>> [v1[i]*v2[i] for i in range(len(v1))]
[3, 8, 15]
>>> [a*b for a in v1 for b in v2]
[3, 4, 5, 6, 8, 10, 9, 12, 15]
105. Tuplas
São estruturas de dados parecidas com listas, mas com a
particularidade de serem imutáveis
Tuplas são seqüências e, assim como listas, podem ser indexadas e
fatiadas, mas não é possível modificá-las
Um valor do tipo tupla é uma série de valores separados por vírgulas
e entre parênteses
>>> x = (1,2,3)
>>> x
(1, 2, 3)
>>> x [0]
1
>>> x [0]=1
...
TypeError: object does not support item assignment
106. Tuplas
Uma tupla vazia se escreve ()
Os parênteses são opcionais se não provocar ambigüidade
Uma tupla contendo apenas um elemento deve ser escrita com uma
vírgula ao final
Um valor entre parênteses sem vírgula no final é meramente uma
expressão:
>>> (10)
10
>>> 10,
(10,)
>>> (10,)
(10,)
>>> 3*(10+3)
39
>>> 3*(10+3,)
(13, 13, 13)
107. A função tuple
Assim como a função list constrói uma lista a partir
de uma seqüência qualquer, a função tuple constrói
uma tupla a partir de uma seqüência qualquer
>>> list("abcd")
['a', 'b', 'c', 'd']
>>> tuple("abcd")
('a', 'b', 'c', 'd')
>>> tuple([1,2,3])
(1, 2, 3)
>>> list((1,2,3))
[1, 2, 3]
108. Quando usar tuplas
Em geral, tuplas podem ser substituídas com
vantagem por listas
Entretanto, algumas construções em Python
requerem tuplas ou seqüências imutáveis, por
exemplo:
Tuplas podem ser usadas como chaves de dicionários
mas listas não podem
Funções com número variável de argumentos têm
acesso a esses argumentos por meio de tuplas
O operador de formatação aceita tuplas mas não listas
109. O operador de formatação
Strings suportam o operador % que, dada uma string especial
(template) e uma um valor, produz uma string formatada
O formato geral é
template % valor
O template é uma string entremeada por códigos de
formatação
Um código de formatação é em geral composto do
caractere % seguido de uma letra descritiva do tipo de valor
a formatar (s para string, f para float, d para inteiro, etc)
Exemplo:
>>> '====%d====' % 100
'====100===='
>>> '====%f====' % 1
'====1.000000===='
110. Formatando tuplas
Um template pode ser aplicado aos diversos valores
de uma tupla para construir uma string formatada
Ex.:
>>> template = "%s tem %d anos"
>>> tupla = ('Pedro', 10)
>>> template % tupla
'Pedro tem 10 anos'
Obs: mais tarde veremos que o operador de
formatação também pode ser aplicado a dicionários
111. Anatomia das especificações de formato
Caractere %
Flags de conversão (opcionais):
- indica alinhamento à esquerda
+ indica que um sinal deve preceder o valor convertido
“ ” (um branco) indica que um espaço deve preceder números
positivos
0 indica preenchimento à esquerda com zeros
Comprimento mínimo do campo (opcional)
O valor formatado terá este comprimento no mínimo
Se igual a * (asterisco), o comprimento será lido da tupla
Um “.” (ponto) seguido pela precisão (opcional)
Usado para converter as casas decimais de floats
Se aplicado para strings, indica o comprimento máximo
Se igual a *, o valor será lido da tupla
Caractere indicador do tipo de formato
112. Tipos de formato
d, i Número inteiro escrito em decimal
o Número inteiro sem sinal escrito em octal
u Número inteiro sem sinal escrito em decimal
x Número inteiro sem sinal escrito em hexadecimal (minúsculas)
XNúmero inteiro sem sinal escrito em hexadecimal (maiúsculas)
e Número de ponto flutuante escrito em notação científica ('e' minúsculo)
E Número de ponto flutuante escrito em notação científica ('E'
maiúsculo)
f, F Número de ponto flutuante escrito em notação convencional
g Mesmo que e se expoente é maior que -4. Caso contrario, igual a f
G Mesmo que E se expoente é maior que -4. Caso contrario, igual a F
c Caractere único (usado com inteiro ou string de tamanho 1)
r String (entrada é qualquer objeto Python que é convertido usando a
função repr)
113. Exemplos
>>> "Numero inteiro: %d" % 55
'Numero inteiro: 55'
>>> "Numero inteiro com 3 casas: %3d" % 55
'Numero inteiro com 3 casas: 55'
>>> "Inteiro com 3 casas e zeros a esquerda: %03d" % 55
'Inteiro com 3 casas e zeros a esquerda: 055'
>>> "Inteiro escrito em hexadecimal: %x" % 55
'Inteiro escrito em hexadecimal: 37'
>>> from math import pi
>>> "Ponto flutuante: %f" % pi
'Ponto flutuante: 3.141593'
>>> "Ponto flutuante com 12 decimais: %.12f" % pi
'Ponto flutuante com 12 decimais: 3.141592653590'
>>> "Ponto flutuante com 10 caracteres: %10f" % pi
'Ponto flutuante com 10 caracteres: 3.141593'
>>> "Ponto flutuante em notacao cientifica: %10e" % pi
'Ponto flutuante em notacao cientifica: 3.141593e+00'
>>> "String com tamanho maximo definido: %.3s" % "Pedro"
'String com tamanho maximo definido: Ped'
114. Exemplo: Imprimindo uma tabela
itens = ["Abacate", "Limão", "Tangerina", "Melancia",
"Laranja da China"]
precos = [2.13, 0.19, 1.95, 0.87, 12.00]
len_precos = 10 # Coluna de precos tem 10 caracteres
# Achar a largura da coluna de itens
len_itens = len(itens[0])
for it in itens : len_itens = max(len_itens,len(it))
# Imprimir tabela de precos
print "-"*(len_itens+len_precos)
print "%-*s%*s" % (len_itens, "Item", len_precos,
"Preço")
print "-"*(len_itens+len_precos)
for i in range(len(itens)):
print "%-*s%*.2f" % (len_itens, itens[i],
len_precos, precos[i])
116. O Módulo String
Manipulação de strings é uma atividade freqüente
em programas Python
Existe um módulo chamado string que contém
uma grande quantidade de funcionalidades para
trabalhar com strings
Para usá-las:
from string import *
Entretanto, strings pertencem à classe str e a
maior parte do que existe no módulo string aparece
como métodos da classe str
117. Strings: método find
find (substring, inicio, fim)
Retorna o índice da primeira ocorrência de substring
inicio e fim são opcionais e indicam os intervalos de
índices onde a busca será efetuada
Os defaults são 0 e o comprimento da string, respectivamente
Caso substring não apareça na string, é retornado -1
Observe que o operador in pode ser usado para dizer se
uma substring aparece numa string
118. Strings: método find (exemplo)
>>> s = "quem parte e reparte, fica com a maior
parte"
>>> s.find("parte")
5
>>> s.find("reparte")
13
>>> s.find("parcela")
-1
>>> "parte" in s
True
>>> s.find("parte",6)
15
>>> s.find("parte",6,12)
-1
119. Strings: método join
join(seqüência)
Retorna uma string com todos os elementos da seqüência
concatenados
Obs: Os elementos da seqüência têm que ser strings
A string objeto é usada como separador entre os elementos
Ex.:
>>> "/".join(("usr","bin","python"))
'usr/bin/python'
>>> "Q".join((1,2,3,4,5))
...
TypeError: sequence item 0: expected string, int
found
>>> "Q".join(('1','2','3','4','5'))
'1Q2Q3Q4Q5'
120. Strings: métodos lower e upper
lower()
Retorna a string com todos os caracteres maiúsculos
convertidos para minúsculos
upper()
Retorna a string com todos os caracteres minúsculos
convertidos para maiúsculos
Ex.:
>>> print "Esperança".upper()
ESPERANÇA
>>> print "Pé de Laranja Lima".lower()
pé de laranja lima
121. Strings: método replace
replace(velho,novo,n)
Substitui as instâncias da substring velho por novo
Se n for especificado, apenas n instâncias são trocadas
Caso contrário, todas as instâncias são trocadas
Ex.:
>>> s = "quem parte e reparte, fica com a maior
parte"
>>> s.replace("parte","parcela")
'quem parcela e reparcela, fica com a maior
parcela'
>>> s.replace("parte","parcela",2)
'quem parcela e reparcela, fica com a maior
parte'
122. Strings: método split
split(separador)
Retorna uma lista com as substrings presentes entre cópias
da string separador
Faz o contrário do método join
Se separador não for especificado, é assumido seqüências
de caracteres em branco, tabs ou newlines
Ex.:
>>> s = "xxx yyy zzz xxx yyy zzz"
>>> s.split()
['xxx', 'yyy', 'zzz', 'xxx', 'yyy', 'zzz']
>>> s.split('xxx')
['', ' yyy zzz ', ' yyy zzz']
123. Strings: método strip
strip(ch)
Retorna a string sem caracteres iniciais ou finais que
estejam na string ch
Se ch não for especificada, retira caracteres em branco
Pode-se também usar rstrip() para retirar caracteres à
direita (final) ou lstrip() para retirar caracteres à
esquerda (início)
Ex.:
>>> " xxx afdsfa ".strip()
'xxx afdsfa'
>>> "xxx yyy zzz xxx".strip("xy ")
'zzz'
>>> " xxx ".rstrip()
' xxx'
124. Strings: método translate
translate(trans)
Retorna uma cópia da string onde os caracteres são
substituídos de acordo com a tabela de tradução trans
trans é uma string com 256 caracteres, um para cada
possível código de oito bits
Ex.: se trans tem 'X' na posição 65 (correspondente ao
caractere ASCII 'A'), então, na string retornada, todos os
caracteres 'A' terão sido substituídos por 'X'
Na verdade, as tabelas de tradução são normalmente
construídas com a função maketrans do módulo
string
125. Função string.maketrans
maketrans (velho, novo)
retorna uma tabela de tradução onde os caracteres em
velho são substituídos pelos caracteres em novo
Ex.:
>>> from string import maketrans
>>> trans = maketrans('qs', 'kz')
>>> s = "que surpresa: quebrei a cara"
>>> s.translate(trans)
'kue zurpreza: kuebrei a cara'
126. Dicionários
São estruturas de dados que implementam
mapeamentos
Um mapeamento é uma coleção de associações
entre pares de valores
O primeiro elemento do par é chamado de chave e o
outro de conteúdo
De certa forma, um mapeamento é uma
generalização da idéia de acessar dados por
índices, exceto que num mapeamento os índices (ou
chaves) podem ser de qualquer tipo imutável
127. Chaves vs. Índices
Considere que queiramos representar um caderno
de telefones
Uma solução é ter uma lista de nomes e outra de
telefones
Telefone de nome[i] armazenado em telefone[i]
Acrescentar “Joao” com telefone “20122232”:
nome+= “Joao” telefone+=“20122232”
Para encontrar o telefone de “Joao”:
Tel = telefone[nome.index[“Joao”]]
Dicionários tornam isso mais fácil e eficiente
telefone[“Joao”] = “20122232”
Tel = telefone[“Joao”]
128. Criando dicionários
Uma constante do tipo dicionário é escrita
{ chave1:conteúdo1, ... chaveN:conteúdoN}
Uma variável do tipo dicionário pode ser “indexada”
da maneira habitual, isto é, usando colchetes
O conteúdo associado a uma chave pode ser
alterado atribuindo-se àquela posição do dicionário
Novos valores podem ser acrescentados a um
dicionário fazendo atribuição a uma chave ainda não
definida
Não há ordem definida entre os pares
chave/conteúdo de um dicionário
130. Dicionários não têm ordem
As chaves dos dicionários não são armazenadas em
qualquer ordem específica
Na verdade, dicionários são implementados por tabelas
de espalhamento (Hash Tables)
A falta de ordem é proposital
Diferentemente de listas, atribuir a um elemento de
um dicionário não requer que a posição exista
previamente
X = []
X [10] = 5 # ERRO!
. . .
Y = {}
Y [10] = 5 # OK!
131. A função dict
A função dict é usada para construir dicionários e
requer como parâmetros:
Uma lista de tuplas, cada uma com um par
chave/conteúdo, ou
Uma seqüência de itens no formato chave=valor
Nesse caso, as chaves têm que ser strings, mas são escritas
sem aspas
132. Exemplo
>>> d = dict([(1,2),('chave','conteudo')])
>>> d[1]
2
>>> d['chave']
'conteudo'
>>> d = dict(x=1,y=2)
>>> d['x']
1
>>> d = dict(1=2,3=4)
SyntaxError: keyword can't be an expression
133. Formatando com Dicionários
O operador de formatação quando aplicado a
dicionários requer que os valores das chaves
apareçam entre parênteses antes do código de
formatação
O conteúdo armazenado no dicionário sob aquela chave
é substituído na string de formatação
Ex:
>>> dic = { "Joao":"a", "Maria":"b" }
>>> s = "%(Joao)s e %(Maria)s"
>>> s % dic
'a e b'
134. Método clear
clear()
Remove todos os elementos do dicionário
Ex.:
>>> x = { "Joao":"a", "Maria":"b" }
>>> y = x
>>> x.clear()
>>> print x,y
{} {}
Diferente de atribuir {} à variável:
>>> x = { "Joao":"a", "Maria":"b" }
>>> y = x
>>> x = {}
>>> print x,y
{} {'Joao': 'a', 'Maria': 'b'}
135. Método copy
copy()
Retorna um outro dicionário com os mesmos pares
chave/conteúdo
Observe que os conteúdos não são cópias, mas apenas
referências para os mesmos valores
>>> x = {"Joao":[1,2], "Maria":[3,4]}
>>> y = x.copy()
>>> y ["Pedro"]=[5,6]
>>> x ["Joao"] += [3]
>>> print x
{'Joao': [1, 2, 3], 'Maria': [3, 4]}
>>> print y
{'Pedro': [5, 6], 'Joao': [1, 2, 3], 'Maria': [3, 4]}
136. Método fromkeys
fromkeys(lista,valor)
Retorna um novo dicionário cujas chaves são os
elementos de lista e cujos valores são todos iguais a
valor
Se valor não for especificado, o default é None
>>> {}.fromkeys([2,3])
{2: None, 3: None}
# Podemos usar o nome da classe ao invés
# de um objeto:
>>> dict.fromkeys(["Joao","Maria"],0)
{'Joao': 0, 'Maria': 0}
137. Método get
get(chave,valor)
Obtém o conteúdo de chave
Não causa erro caso chave não exista: retorna valor
Se valor não for especificado chaves inexistentes
retornam None
Ex.:
>>> dic = { "Joao":"a", "Maria":"b" }
>>> dic.get("Pedro")
>>> print dic.get("Pedro")
None
>>> print dic.get("Joao")
a
>>> print dic.get("Carlos","N/A")
N/A
138. Método has_key
has_key(chave)
dic.has_key(chave) é o mesmo que chave in dic
Ex.:
>>> dic = { "Joao":"a", "Maria":"b" }
>>> dic.has_key("Joao")
True
>>> dic.has_key("Pedro")
False
139. Métodos items, keys e values
items() retorna uma lista com todos os pares
chave/conteúdo do dicionário
keys() retorna uma lista com todas as chaves do
dicionário
values() retorna uma lista com todos os valores do
dicionário
Ex.:
>>> dic.items()
[('Joao', 'a'), ('Maria', 'b')]
>>> dic.keys()
['Joao', 'Maria']
>>> dic.values()
['a', 'b']
140. Método pop
pop (chave)
Obtém o valor correspondente a chave e remove o par
chave/valor do dicionário
Ex.:
>>> d = {'x': 1, 'y': 2}
>>> d.pop('x')
1
>>> d
{'y': 2}
141. Método popitem
popitem()
Retorna e remove um par chave/valor aleatório do
dicionário
Pode ser usado para iterar sobre todos os elementos do
dicionário
Ex:
>>> d
{'url': 'http://www.python.org', 'spam': 0,
'title': 'Python Web Site'}
>>> d.popitem()
('url', 'http://www.python.org')
>>> d
{'spam': 0, 'title': 'Python Web Site'}
142. Método update
update(dic)
Atualiza um dicionário com os elementos de outro
Os itens em dic são adicionados um a um ao dicionário original
É possível usar a mesma sintaxe da função dict para
especificar dic
Ex.:
>>> x = {"a":1,"b":2,"c":3}
>>> y = {"z":9,"b":7}
>>> x.update(y)
>>> x
{'a': 1, 'c': 3, 'b': 7, 'z': 9}
>>> x.update(a=7,c="xxx")
>>> x
{'a': 7, 'c': 'xxx', 'b': 7, 'z': 9}
143. Abstração
É uma técnica de programação que nos permite
pensar num problema em diversos níveis
A idéia é que quando estamos pensando num
problema macroscopicamente, não estamos
preocupado com minúcias
Dividir para conquistar:
Um problema é dividido em diversos sub-problemas
As soluções dos sub-problemas são combinadas numa
solução do problema maior
144. Programação Estruturada
É uma disciplina de programação que incorpora o
princípio de “Dividir para Conquistar”
(Programação Orientada a Objetos é outra...)
Programas são divididos em sub-programas
Cada sub-programa é invocado por meio de um
identificador e uma lista de entradas
Permite especificar como um problema pode ser resolvido em
geral
O mesmo sub-programa pode ser invocado para resolver
diversos problemas de mesma natureza mas com valores
específicos diferentes
Os resultados computados por um sub-programa pode
ser combinado com os de outros sub-programas
145. Definindo funções
Em Python, sub-programas têm o nome de funções
Formato geral:
def nome (arg, arg, ... arg):
comando
. . .
comando
Onde:
nome é o nome da função
args são especificações de argumentos da função
Uma função pode ter 0, 1 ou mais argumentos
comandos contêm as instruções a ser executadas
quando a função é invocada
146. Resultado de funções
Uma função tipicamente computa um ou mais valores
Para indicar o valor a ser devolvido como o resultado da
função, usa-se o comando return que tem o formato
return expressão
onde a expressão é opcional e designa o valor a ser retornado
Ao encontrar o comando return, a função termina
imediatamente e o controle do programa volta ao ponto
onde a função foi chamada
Se uma função chega a seu fim sem nenhum valor de
retorno ter sido especificado, o valor de retorno é None
148. Variáveis locais e globais
Variáveis definidas em funções são locais, isto é, só
podem ser usadas nas funções em que foram
definidas
Variáveis definidas fora de funções são conhecidas
como variáveis globais
É possível no código de uma função ler o conteúdo de
uma variável global
Para alterar uma variável global, ela precisa ser
declarada no corpo da função usando o comando
global
149. Exemplo
>>> def f():
print a
>>> a = 1
>>> f()
1
>>> def f():
a = 5
>>> f()
>>> print a
1
>>> def f():
global a
a = 5
>>> f()
>>> print a
5
150. Argumentos de funções
Argumentos (ou parâmetros) são como variáveis
que recebem seus valores iniciais do chamador
Essas variáveis, assim como outras definidas dentro
da função são ditas locais, isto é, só existem no
lugar onde foram definidas
Ao retornar ao ponto de chamada, as variáveis locais são
descartadas
Se uma função define n argumentos, valores para
todos eles devem ser passados pelo chamado
Exceção: argumentos com valores default
151. Exemplo
>>> def f(x):
return x*x
>>> print f(10)
100
>>> print x
....
NameError: name 'x' is not defined
>>> print f()
....
TypeError: f() takes exactly 1 argument (0
given)
152. Argumentos default
É possível dar valores default a argumentos
Se o chamador não especificar valores para esses
argumentos, os defaults são usados
Formato:
def nome (arg1=default1, ..., argN=defaultN)
Se apenas alguns argumentos têm default, esses
devem ser os últimos
Se não fosse assim, haveria ambigüidade na passagem
de argumentos
154. Passando argumentos com nomes
É possível passar os argumentos sem empregar a
ordem de definição desde que se nomeie cada valor
passado com o nome do argumento correspondente
Ex.:
>>> def f(nome,saudacao="Oi",pontuacao="!!"):
return saudacao+","+nome+pontuacao
>>> print f(saudacao="Valeu",nome="Joao")
Valeu,Joao!!
155. Alterando parâmetros
É possível alterar parâmetros?
Sim e não
Como o parâmetro é uma variável local, ele pode ser
alterado sem problemas
Entretanto, se um parâmetro recebe um valor que vem de
uma variável global, esta não é alterada
Ex.:
>>> def f(x):
x = 5
>>> a = 1
>>> f (a)
>>> print a
1
156. Alterando parâmetros
Note que quando passamos uma variável do tipo
lista como parâmetro, estamos passando uma
referência para um valor do tipo lista
Nesse caso, alterar o parâmetro pode influenciar no
“valor” da variável global
Na verdade, o “valor” da variável do tipo lista é uma
referência que não muda
Este caso é idêntico a termos duas variáveis se referindo
ao mesmo valor
158. Documentando Funções
Ao invés de usar comentários para descrever o que uma função, é
mais vantajoso usar docstrings
Uma constante string escrita logo após o cabeçalho da função
(comando def)
Permite o acesso à documentação a partir do interpretador,
usando a notação função . __doc__
>>> def fat(n):
... "Retorna o fatorial de n."
... for i in range(n-1,1,-1): n*=i
... return n
...
>>> fat(4)
24
>>> print fat.__doc__
Retorna o fatorial de n.
159. Lista de parâmetros variável
Se o último argumento de uma definição de função
começa com * , os todos os valores passados a partir
daquele são postos numa tupla
Ex.:
>>> def imprime(nome,*atributos):
... print nome,atributos
...
>>> imprime ('a',1,2,'b')
a (1, 2, 'b')
>>> def media(*valores):
... total=0.0
... for x in valores: total+=x
... return total/len(valores)
...
>>> media(1,2,3,4)
2.5
160. Lista de parâmetros variável (2)
Se o último argumento de uma definição de função
começa com ** , os todos os valores passados
usando chaves a partir daquele são postos num
dicionário
Ex.:
>>> def f(a,b,**c):
print a, b, c
>>> f(1,2,3)
...
TypeError: f() takes exactly 2 arguments (3 given)
>>> f(1,2,x=3)
1 2 {'x': 3}
161. Lista de parâmetros variável (3)
É possível passar os valores de uma tupla para preencher parâmetros
posicionais de uma função bastando para isso precedê-la de *
Um dicionário podem ser usado para preencher parâmetros por chave
bastando para isso precedê-lo de **
É preciso tomar cuidado para não abusar!
Ex.:
>>> def f(a,b,*c,**d):
print a,b,c,d
>>> f(*[1,2,3,4,5])
1 2 (3, 4, 5) {}
>>> f(**{"a":1,"b":2,"c":3,"d":4})
1 2 () {'c': 3, 'd': 4}
>>> f(1,2,3,**{"d":1})
1 2 (3,) {'d': 1}
>>> f(1,2,3,**{"a":1})
...
TypeError: f() got multiple values for keyword argument 'a'
162. Passando funções
Nomes de funções podem ser manipulados como variáveis e mesmo
como argumentos de funções
Para saber se um nome se refere a uma função, use o
predicado callable()
Ex.:
>>> def f(g):
return g(5)
>>> def h(x):
return x*x
>>> f(h)
25
>>> m = h
>>> callable(m)
True
>>> f(m)
25
163. Escopo
Escopo é o nome que se dá ao conjunto de nomes acessíveis
de um determinado ponto de um programa
Também é chamado de espaço de nomes ou namespace
Um programa começa em um escopo (chamado escopo
global) enquanto que cada função acrescenta um escopo
próprio (local)
Módulos e classes também definem escopos
Ao se fazer acesso a um nome, todos os escopos, do mais
interno para o mais externo, são consultados.
Isto explica por que definir uma variável numa função
pode fazer com que uma variável global deixe de ser
acessível
164. Função vars()
O dicionário obtido com a função vars() pode ser
usado para ter acesso a todas as variáveis definidas
num escopo. Ex.:
>>> vars()
{'__builtins__': <module '__builtin__' (built-in)>,
'__name__': '__main__', '__doc__': None}
>>> def f():
x = 1
print vars()
>>> vars()
{'f': <function f at 0xb6e7f56c>, '__builtins__':
<module '__builtin__' (built-in)>, '__name__':
'__main__', '__doc__': None}
>>> f()
{'x': 1}
165. Funções definidas em funções
Funções podem ser definidas dentro de funções
Se uma função g é definida dentro de uma função
f, ela tem acesso ao seu próprio escopo (em
primeiro lugar) e também ao escopo de f
Ex.:
>>> def f(x):
def g(y): return x*y
return g(2)
>>> print f(4)
8
166. Funções definidas em funções (2)
Observe que, se uma função g foi definida dentro de outra função f,
então, se g é armazenada numa variável ou transmitida para outra
função ela carrega com si os valores do escopo de f (mas não o
escopo global). Ex:
>>> x = 2
>>> def f(y):
def g(z): return x*y*z
return g
>>> h = f(3)
>>> print h(1)
6
>>> x = 3
>>> print h(1)
9
167. Formas lambda
São pequenas funções “sem nome”
Tipicamente criadas para serem passadas para outras funções
Historicamente, são relacionadas com o estilo “funcional” de
programar (LISP)
Em Python, funções lambda estão restritas a retornar
unicamente uma expressão
Formato: lambda arg,...arg: expressão
Exemplo:
>>> f = lambda x: 2*x*x+1
>>> f(1)
3
>>> f(3)
19
168. Formas lambda
São pequenas funções “sem nome”
Tipicamente criadas para serem passadas para outras funções
Historicamente, são relacionadas com o estilo “funcional” de
programar (LISP)
Em Python, funções lambda estão restritas a retornar
unicamente uma expressão
Formato: lambda arg,...arg: expressão
Exemplo:
>>> f = lambda x: 2*x*x+1
>>> f(1)
3
>>> f(3)
19
169. Programação Funcional - filter
Além de formas lambda, Python provê algumas
ferramentas clássicas usadas em programação funcional
filter (função, seqüência)
Retorna outra seqüência com os elementos x de seqüência
tais que função(x) é verdadeiro
Se seqüência é uma tupla ou string, o resultado é também uma
tupla ou string, caso contrário, o resultado é uma lista
Exemplos:
>>> filter (lambda x: x%2==0, [1,2,3,4,5,6,7,999])
[2, 4, 6]
>>> filter (lambda x: str(x)==x, [1,2,3,'abc',4])
['abc']
>>> filter (lambda c: c not in 'aeiou', "consoantes")
'cnsnts'
170. Programação Funcional - map
map (função, seqüência)
retorna outra seqüência cujos elementos yi são
computados por função(xi) onde xi são os elementos de
seqüência
Exemplos:
>>> map(lambda x: x+1, [1,2,3,4])
[2, 3, 4, 5]
>>> def f(x):
if x%2==0: return x*x
else: return x
>>> map (f, [1,2,3,4])
[1, 4, 3, 16]
171. Programação Funcional - reduce
reduce (função, seqüência [,inicializador])
Retorna o valor acumulado obtdo aplicando a função
binária função a pares consecutivos de elementos em
seqüência
Ex.: reduce(f,[a,b,c,d]) é equivalente a
f(f(f(a,b),c),d)
Se o argumento opcional inicializador é especificado, ele
determina um valor a ser considerado antes dos
elementos da seqüência
Ex.: reduce(f,[a,b,c,d],0) é equivalente a
f(f(f(f(0,a),b),c),d)
172. Exemplo
>>> reduce (lambda a,b: a+b, [1,2,3,4,5])
15
>>> reduce (lambda a,b: a+b, [])
Traceback (most recent call last):
File "<pyshell#9>", line 1, in ?
reduce (lambda a,b: a+b, [])
TypeError: reduce() of empty sequence with
no initial value
>>> reduce (lambda a,b: a+b, [], 0)
0
173. Recursão
É um princípio muito poderoso para construção de
algoritmos
A solução de um problema é dividido em
Casos simples:
São aqueles que podem ser resolvidos trivialmente
Casos gerais:
São aqueles que podem ser resolvidos compondo soluções de
casos mais simples
Semelhante à prova de teoremas por indução
Casos simples: O teorema é verdadeiro trivialmente
Casos genéricos: são provados assumindo-se que todos
os casos mais simples também são verdadeiros
174. Função recursiva
Implementa um algoritmos recursivo onde a solução dos casos
genéricos requerem chamadas à própria função
Uma função recursiva é a maneira mais direta (mas não
necessariamente a melhor) de se resolver problemas de natureza
recursiva ou para implementar estruturas de dados recursivas
Considere, por exemplo, a definição da seqüência de Fibonacci:
O primeiro e o segundo termo valem 0 e 1, respectivamente
O i-ésimo termo é a soma do (i-1)-ésimo e o (i-2)-ésimo termo
>>> def fib(i):
if i==1: return 0
elif i==2: return 1
else: return fib(i-1)+fib(i-2)
>>> for i in range(1,11):
print fib(i),
0 1 1 2 3 5 8 13 21 34
175. Exemplo: Busca binária
Um exemplo clássico de recursão é o algoritmo conhecido como
busca binária que é usado para pesquisar um valor em uma lista
ordenada
Chamemos de imin e imax os índices mínimo e máximo da lista
onde a busca será feita
Inicialmente, imin = 0 e imax = len(lista)-1
O caso base corresponde a imin == imax
Então, ou o valor é igual a lista [imin] ou não está na lista
Senão, podemos dividir o intervalo de busca em dois
Seja meio = (imin+imax)/2
Se o valor é maior que lista [meio] , então ele se encontra em
algum dos índices entre meio+1 e imax
Caso contrário, deve se encontrar em algum dos índices entre
imin e meio
176. Busca binária: implementação
def testa(lista,valor):
def busca_binaria(imin,imax):
if imin==imax: return imin
else:
meio=(imax+imin)/2
if valor>lista[meio]:
return busca_binaria(meio+1,imax)
else:
return busca_binaria(imin,meio)
i = busca_binaria(0,len(lista)-1)
if lista[i]==valor:
print valor,"encontrado na posicao",i
else:
print valor,"nao encontrado"
>>> testa([1,2,5,6,9,12],3)
3 nao encontrado
>>> testa([1,2,5,6,9,12],5)
5 encontrado na posicao 2
177. Recursão infinita
Assim como nos casos dos laços de repetição, é preciso cuidado
para não escrever funções infinitamente recursivas
Ex.:
def recursiva(x):
if f(x): return True
else: return recursiva(x)
Uma função recursiva tem que
Tratar todos os casos básicos
Usar recursão apenas para tratar casos garantidamente mais
simples do que o caso corrente
Ex.:
def recursiva(x):
if f(x): return True
elif x==0: return False
else: return recursiva(x-1)
178. Eficiência de funções recursivas
Quando uma função é chamada, um pouco de
memória é usado para guardar o ponto de retorno,
os argumentos e variáveis locais
Assim, soluções iterativas são normalmente mais
eficientes do que soluções recursivas equivalentes
Isto não quer dizer que soluções iterativas sempre
sejam preferíveis a soluções recursivas
Se o problema é recursivo por natureza, uma
solução recursiva é mais clara, mais fácil de
programar e, freqüentemente, mais eficiente
179. Pensando recursivamente
Ao invés de pensar construtivamente para para
obter uma solução, às vezes é mais simples pensar
em termos de uma prova indutiva
Considere o problema de testar se uma lista a é
uma permutação da lista b
Caso básico: a é uma lista vazia
Então a é permutação de b se b também é uma lista vazia
Caso básico: a[0] não aparece em b
Então a não é uma permutação de b
Caso genérico: a[0] aparece em b na posição i
Então a é permutação de b se a[1:] é uma permutação de b do
qual foi removido o elemento na posição i
180. Exemplo: Testa permutações
def e_permutacao(a,b):
"""
Retorna True sse a lista a é uma
permutação da lista b
"""
if len(a) == 0 : return len(b)==0
if a[0] in b:
i = b.index(a[0])
return e_permutacao(a[1:],b[0:i]+b[i+1:])
return False
>>> e_permutacao([1,2,3],[3,2,1])
True
>>> e_permutacao([1,2,3],[3,3,1])
False
>>> e_permutacao([1,2,3],[1,1,2,3])
False
>>> e_permutacao([1,1,2,3],[1,2,3])
False
181. Estruturas de dados recursivas
Há estruturas de dados que são inerentemente recursivas, já que
sua própria definição é recursiva
Por exemplo, uma lista pode ser definida recursivamente:
[] é uma lista (vazia)
Se A é uma lista e x é um valor, então A+[x] é uma lista com x
como seu último elemento
Esta é uma definição construtiva, que pode ser usada para escrever
funções que criam listas
Uma outra definição que pode ser usada para analisar listas é:
Se L é uma lista, então:
L == [] , ou seja, L é uma lista vazia, ou
x = L.pop() torna L uma lista sem seu último elemento x
Esta definição não é tão útil em Python já que o comando for
permite iterar facilmente sobre os elementos da lista
182. Exemplo: Subseqüência
def e_subseq(a,b):
""" Retorna True sse a é subseqüência de b,
isto é, se todos os elementos a[0..n-1] de a
aparecem em b[j(0)], b[j(1)]... b[j(n-1)]
onde j(i)<j(i+1) """
if a == []:
# Lista vazia é subseqüência de qq lista
return True
if a[0] not in b:
return False
return e_subseq (a[1:], b[b.index(a[0])+1:])
183. Encontrando a recorrência
Alguns problemas não se apresentam naturalmente
como recursivos, mas pensar recursivamente provê
a solução
Tome o problema de computar todas as
permutações de uma lista
Assumamos que sabemos computar todas as
permutações de uma lista sem seu primeiro elemento x
Seja perm uma dessas permutações
Então, a solução do global contém todas as listas obtidas
inserindo x em todas as possíveis posições de perm
184. Exemplo: computar todas as
permutações de uma lista
def permutacoes(lista):
""" Dada uma lista, retorna uma lista de listas,
onde cada elemento é uma permutação da lista
original """
if len(lista) == 1: # Caso base
return [lista]
primeiro = lista[0]
resto = lista [1:]
resultado = []
for perm in permutacoes(resto):
for i in range(len(perm)+1):
resultado +=
[perm[:i]+[primeiro]+perm[i:]]
return resultado
185. Torres de Hanói
Jogo que é um exemplo clássico de problema recursivo
Consiste de um tabuleiro com 3 pinos no qual são encaixados discos de
tamanho decrescente
A idéia é mover os discos de um pino para outro sendo que:
Só um disco é movimentado por vez
Um disco maior nunca pode ser posto sobre um menor
186. Torres de Hanói: Algoritmo
A solução é simples se supusermos existir um
algoritmo capaz de mover todos os discos menos
um do pino de origem para o pino sobressalente
O algoritmo completo para mover n discos do pino
de origem A para o pino de destino B usando o pino
sobressalente C é
Se n é 1, então a solução é trivial
Caso contrário,
Usa-se o algoritmo para mover n-1 discos de A para C usando
B como sobressalente
Move-se o disco restante de A para B
Usa-se o algoritmo para mover n-1 discos de C para B usando
A como sobressalente
187. Torres de Hanói: Implementação
def hanoi(n,origem,destino,temp):
if n>1: hanoi(n-1,origem,temp,destino)
mover(origem,destino)
if n>1: hanoi(n-1,temp,destino,origem)
def mover(origem,destino):
print “Mover de“, origem, “para”,
“destino”
Com um pouco mais de trabalho, podemos redefinir
a função mover para que ela nos dê uma
representação “gráfica” do movimento dos discos
189. Orientação a Objetos
É uma disciplina de programação assim como a
Programação Estruturada
Tenta unificar as idéias de algoritmos e estruturas de
dados através do conceito de Objeto
Um objeto é uma unidade de software que encapsula
algoritmos e os dados sobre o qual os algoritmos atuam
Os seguintes conceitos são importantes quando
falamos de orientação a objetos:
Polimorfismo
Abstração
Herança
190. Polimorfismo
É o que permite que dois objetos diferentes possam
ser usados de forma semelhante
Por exemplo, tanto listas quanto tuplas ou strings podem
ser indexadas por um número entre colchetes e suportam
o método len
Assim, se escrevemos ...
for i in range(len(X)): print i
...não é possível saber de antemão se X é uma tupla,
uma lista ou uma string
Desta forma, se escrevemos um algoritmo para ser
aplicado um objeto X, então também pode ser
aplicado a um objeto Y desde que Y seja
suficentemente polimórfico a X
191. Abstração (ou encapsulamento)
É o que permite que um objeto seja utilizado
sabendo-se sobre ele apenas a sua interface
Em particular, não precisamos conhecer a
implementação dos seus métodos
Em OO a abstração tem mais alcance pois um
objeto encapsula tanto dados como algoritmos
Assim, podemos atribuir objetos ou passar objetos como
argumentos, sem necessariamente saber como o objeto
está implementado
192. Herança
É o que permite construir objetos que são
especializações de outro objeto
Isso permite o reuso de software já que objetos
especializados herdam dos objetos genéricos uma série
de atributos comuns
Por exemplo, considere um objeto que representa
uma forma geométrica. Então, ele pode ter
características tais como área, perímetro, centróide,
etc.
Um polígono é uma forma geométrica,
Portanto, herda todas as características de formas geometricas
Deve suportar também características específicas como
número de lados e comprimento de arestas
193. Objetos em Python
Python suporta OO através de classes
Uma classe pode ser entendida como uma fábrica de
objetos, todos com as mesmas características
Diz-se que objeto fabricado por uma classe é uma instância da
classe
A rigor, uma classe é também um objeto
Encapsula dados e algoritmos
Entretanto, não é normalmente um objeto fabricado por uma
classe, mas um objeto criado pela construção class
Um objeto encapsula dados e algoritmos sob a forma de
variáveis e métodos
É comum chamar esses elementos constituintes dos objetos
de atributos
194. Declaração de uma classe
A maneira mais simples é:
class nome:
var = valor
...
var = valor
def metodo (self, ... arg):
...
def metodo (self, ... arg):
...
As variáveis e os métodos são escritos precedidos pelo nome
da classe e por um ponto (.)
Assim, uma variavel v definida numa classe c é escrita c.v
Os métodos sempre têm self como primeiro argumento
self se refere a uma instância da classe
Uma nova instância da classe é criada usando nome ()
195. Exemplo
>>> class C:
a = 2
b = 3
def f(self,x):
return C.a*x+C.b
>>> C.a
2
>>> C.b
3
>>> obj=C()
>>> obj.f(7)
17
196. Atributos de instâncias
No exemplo anterior, a e b eram atributos da classe
C e portanto usáveis por qualquer instância de C
Mais freqüentemente, precisamos de atributos
associados a instâncias individuais
Um atributo attr associado a uma instância obj
tem nome obj.attr
Se queremos nos referir a um atributo attr de um
objeto dentro de algum de seus métodos, usamos o
nome self.attr
198. Atributos herdados da classe
Se uma classe define atributos de classe, as instâncias
herdam esses atributos da classe como atributos de
instância
Ex.:
>>> class C:
a = 1
def f(self,x):
self.a += x
>>> c = C()
>>> c.f(2)
>>> c.a
3
>>> C.a
1
199. Construtores
Um método como init do exemplo anterior é bastante útil
para inicializar atributos da instância e é conhecido como
construtor da classe
Na verdade, Python suporta construtores que podem ser
chamados automaticamente na criação de instâncias
Basta definir na classe um método chamado __init__
Este método é chamado automaticamente durante a criação
de um nova instância da classe, sendo que os argumentos são
passados entre parênteses após o nome da classe
Obs.: o método __init__ é apenas um exemplo de
“método mágico” que é invocado de maneira não padrão
(veremos outros adiante)
201. Especialização de classes
Para fazer uma classe C herdar de outra B, basta declarar C
como:
class C(B):
. . .
Diz-se que C é sub-classe (ou derivada) de B ou que B é
super-classe (ou base) de C
C herda todos os atributos de B
A especialização de C se dá acrescentando-se novos
atributos (variáveis e métodos) ou alterando-se métodos
Se, ao escrever um método de C, precisamos invocar um
método m de B, pode-se usar a notação B.m para diferenciar
de m simplesmente, que se refere a C.m
202. Exemplo
>>> class B:
n = 2
def f(self,x): return B.n*x
>>> class C(B):
def f(self,x): return B.f(self,x)**2
def g(self,x): return self.f(x)+1
>>> b = B()
>>> c = C()
>>> b.f(3)
6
>>> c.f(3)
36
>>> c.g(3)
37
>>> B.n = 5
>>> c.f(3)
225
203. Herança múltipla
É possível construir uma classe que herda de duas
ou mais outras. Ex.:
class C(A,B): ...
Nesse caso, a classe derivada herda todos os
atributos de ambas as classes-base
Se ambas as classes base possuem um atributo
com mesmo nome, aquela citada primeiro prevalece
No exemplo acima, se A e B possuem um atributo x,
então C.x se refere ao que foi herdado de A
204. Exemplo
>>> class C:
def __init__(self,a,b):
self.a, self.b = a,b
def f(self,x):
return self.a*x+self.b
>>> class D:
def __init__(self,legenda):
self.legenda = legenda
def escreve(self,valor):
print self.legenda,'=',valor
>>> class E(C,D):
def __init__(self,legenda,a,b):
C.__init__(self,a,b)
D.__init__(self,legenda)
def escreve(self,x):
D.escreve(self,self.f(x))
>>> e = E("f",10,3)
>>> e.escreve(4)
f = 43
205. Atributos privados
Em princípio, todos os atributos de um objeto podem
ser acessados tanto dentro de métodos da classe
como de fora
Quando um determinado atributo deve ser acessado
apenas para implementação da classe, ele não
deveria ser acessível de fora
Em princípio tais atributos não fazem parte da interface
“pública” da classe
Atributos assim são ditos privados
Em Python, atributos privados têm nomes iniciados
por dois caracteres “traço-embaixo”, isto é, __
206. Exemplo
>>> class C:
def __init__(self,x): self.__x = x
def incr(self): self.__x += 1
def x(self): return self.__x
>>> a = C(5)
>>> a.x()
5
>>> a.incr()
>>> a.x()
6
>>> a.__x
Traceback (most recent call last):
File "<pyshell#13>", line 1, in -toplevel-
a.__x
AttributeError: C instance has no attribute '__x'
207. Métodos mágicos
São métodos que são invocados usando operadores
sobre o objeto ao invés de por nome
Já vimos um método desses: o construtor __init__
Alguns outros são:
Adição: __add__
Chamado usando '+'
Subtração: __sub__
Chamado usando '-'
Representação: __repr__
Chamado quando objeto é impresso
Conversão para string: __str__
Chamado quando o objeto é argumento do construtor da classe
str
Se não especificado, a função __repr__ é usada
209. Protocolos
Diferentemente de outras linguagens, não há
necessidade de classes serem relacionadas para
haver polimorfismo entre elas, basta que
implementem métodos semelhantes
Um protocolo é uma especificação de polimorfismo
informal
Por exemplo, listas, strings e tuplas possuem em
comum o fato de poderem iterar sobre uma coleção
de elementos
Todas implementam o protocolo para seqüências
Métodos “mágicos” para indexar, alterar, etc.
210. Protocolo para seqüências
__len__(self) retorna o comprimento da seqüência
Chamada: len(objeto)
__getitem__(self,key) retorna o elemento na
posição key da seqüência
Chamada: objeto[key]
Deve-se implementar também chaves negativas!
__setitem__(self,key,value)
Chamada: objeto[key]=value
Apenas para seqüências mutáveis
__del__(self,key)
Chamada por del objeto[key]
Apenas para (algumas) seqüências mutáveis
211. Exemplo
>>> class ProgressaoAritmetica:
def __init__(self,a1,incr):
self.a1,self.incr=a1,incr
def __getitem__(self,key):
if not isinstance(key,(int,long)):
raise TypeError
if key<=0: raise IndexError
return self.a1+(key-1)*self.incr
def soma(self,n):
return (self[1]+self[n])*n/2
>>> pa = ProgressaoAritmetica(1,2)
>>> pa[1]
1
>>> pa[10]
19
>>> pa.soma(100)
10000
212. Atributos, Getters e Setters
Muitas vezes queremos que determinados atributos
possam ser acessados de forma controlada, isto é,
vigiados por métodos
Os métodos que controlam o acesso a tais atributos
são conhecidos como getters e setters , referindo-se
a métodos de leitura e escrita, respectivamente
Os atributos controlados são chamados de
propriedades
Na verdade, podemos ter propriedades abstratas
que não correspondem 1 para 1 com atributos da
classe
214. A função property
A função property pode ser usada para
consubstanciar uma propriedade implementada por
métodos de tal maneira que ela pareça um atributo
da classe
Ela é usada no corpo de uma declaração de classe
com a forma:
atributo = property(fget, fset, fdel, doc)
...onde
fget, fset, fdel são métodos para ler, escrever e remover o
atributo
doc é uma docstring para o atributo
216. Dicas para uso de OO
Agrupe funções e dados que se referem a um mesmo
problema
Por exemplo, se uma função manipula uma variável
global, é melhor que ambas sejam definidas numa classe
como atributo e método
Não permita promiscuidade entre classes e instâncias de
classe
Por exemplo, se há necessidade de um objeto manipular
um atributo de outro, escreva um método com essa
manipulação e chame o método
Não escreva métodos extensos
Em geral, um método deve ser simples e ser
compreendido conceitualmente em alguns segundos
217. Exceções
Quando um programa encontra dificuldades não
previstas, diz-se que uma condição excepcional ou uma
exceção ocorreu
Um erro é uma exceção mas nem toda exceção é um erro
Para poder representar tais eventos, Python define os
chamados objetos de exceção (exception objects)
Se a condição excepcional não é prevista (e tratada), o
programa termina com uma mensagem de rastreamento:
>>> 1/0
Traceback (most recent call last):
File "<pyshell#0>", line 1, in -toplevel-
1/0
ZeroDivisionError: integer division or modulo by zero
218. Objetos de Exceção
Cada exceção individual corresponde a um objeto
de exceção, que por sua vez é uma instância de
alguma classe de exceção
No exemplo anterior, tal objeto é instância da classe
ZeroDivisionError
Diz-se que o programa gerou ou levantou (raised,
em inglês) uma condição de exceção na forma de
um objeto
Um programa bem elaborado precisa capturar
(catch, em inglês) tais objetos e tratá-los para que a
execução não seja abortada
219. Avisos
Existem condições excepcionais menos sérias que não
provocam o levantamento de um objeto de exceção, mas
apenas são exibidas sob a forma de um aviso
Por exemplo,
>>> import regex
Warning (from warnings module):
File "__main__", line 1
DeprecationWarning: the regex module is
deprecated; please use the re module
Neste caso, o intepretador nos sinaliza que o módulo regex é antigo
e que foi substituido por outro mais atualizado chamado re
O programa não falha, mas o programador fica ciente que
provamelmente deve reescrever seu programa usando o módulo re
para evitar obsolecência
220. O comando raise
Para sinalizar a ocorrência de uma condição
excepcional, pode-se usar o comando raise que tem uma
das formas:
raise classe
raise classe, mensagem
raise classe (mensagem)
Onde classe é uma das classes de exceção definidas
pelo Python
Para saber todos os tipos de exceção consulte o manual
Se quiser uma classe genérica use a classe Exception
Uma listagem pode ser obtida escrevendo
>>> import exceptions
>>> dir(exceptions)
['ArithmeticError', 'AssertionError',
'AttributeError', ...
221. Exemplo
>>> raise Exception
Traceback (most recent call last):
File "<pyshell#3>", line 1, in -toplevel-
raise Exception
Exception
>>> raise Exception,"Deu bode"
Traceback (most recent call last):
File "<pyshell#5>", line 1, in -toplevel-
raise Exception,"Deu bode"
Exception: Deu bode
>>> raise Exception("Deu Bode")
Traceback (most recent call last):
File "<pyshell#7>", line 1, in -toplevel-
raise Exception("Deu Bode")
Exception: Deu Bode
222. Algumas Classes de Exceção
Classe Descrição
Exception Classe base para todas as exceções
AttributeError Falha no acesso ou atribuição a atributo de classe
IOError Falha no acesso a arquivo inexistente ou outros de E/S
IndexError Índice inexistente de seqüência
KeyError Chave inexistente de dicionário
NameError Variável inexistente
SyntaxError Erro de sintaxe (código errado)
TypeError Operador embutido aplicado a objeto de tipo errado
ValueError
Operador embutido aplicado a objeto de tipo certo mas valor
inapropriado
ZeroDivisionError Divisão ou módulo por zero
223. Criando uma Classe de Exceção
Basta criar uma classe da forma habitual derivando-
a da classe Exception
Não é preciso redefinir qualquer método
Ex.:
>>> class MinhaExcecao(Exception): pass
>>> raise MinhaExcecao("Deu bode!")
Traceback (most recent call last):
File "<pyshell#11>", line 1, in -toplevel-
raise MinhaExcecao("Deu bode!")
MinhaExcecao: Deu bode!
224. Capturando Exceções
Para capturar uma exceção possivelmente levantada por um trecho
de código, pode-se usar a construção try/except:
try:
Código
except Exceções:
Código de tratamento da exceção
Sendo que Exceções pode ser:
Classe
Classe,var
(Classe1,...,ClasseN)
(Classe1,...,ClasseN),var
Onde:
Classe, Classe1 e ClasseN são nomes de classes de exceção
Var é uma variável à qual é atribuída um objeto de exceção
225. Exemplo 1
>>> try:
a = input("Entre com um numero ")
b = input("Entre com outro numero ")
print a, "/", b, "=", a/b
except ZeroDivisionError:
print "Ooops, segundo numero não pode ser zero!"
Entre com um numero 1
Entre com outro numero 0
1 / 0 = Ooops, segundo numero não pode ser
zero!
226. Exemplo 2
>>> try:
a = input("Entre com um numero ")
b = input("Entre com outro numero ")
print a, "/", b, "=", a/b
except (ZeroDivisionError,TypeError):
print "Ooops, tente novamente!"
Entre com um numero 1
Entre com outro numero "a"
1 / a = Ooops, tente novamente!
227. Exemplo 3
>>> try:
a = input("Entre com um numero ")
b = input("Entre com outro numero ")
print a, "/", b, "=", a/b
except (ZeroDivisionError,TypeError),e:
print "Ooops, deu erro:",e
Entre com um numero 1
Entre com outro numero "z"
1 / z = Ooops, deu erro: unsupported operand
type(s) for /: 'int' and 'str'
228. Mais except
É possível tratar diferentemente as diversas
exceções usando 2 ou mais cláusulas except
Se quisermos nos prevenir contra qualquer tipo de
erro, podemos usar uma cláusula except sem
nome de classe
Outra opção é usar a classe Exception que é base para
todas as exceções e portanto casa com qualquer
exceção
Se não queremos tratar um erro em uma cláusula
except, podemos passá-la adiante usando o
comando raise
Nesse caso, podemos usar um raise sem argumentos
ou passar explicitamente um objeto de exceção
229. Exemplo 4
>>> try:
a = input("Entre com um numero ")
b = input("Entre com outro numero ")
print a, "/", b, "=", a/b
except ZeroDivisionError:
print "Ooops, divisão por zero"
except TypeError:
print "Ooops, você não deu um número"
except:
print "Deu um bode qualquer"
Entre com um numero 2
Entre com outro numero fads2312
Deu um bode qualquer
230. Exemplo 5
>>> try:
a = input("Entre com um numero ")
b = input("Entre com outro numero ")
print a, "/", b, "=", a/b
except (ZeroDivisionError,TypeError),e:
print "Ooops, deu erro:",e
except Exception,e:
print "Deu bode não previsto:",e
raise
Entre com um numero a
Entre com outro numero
Deu bode não previsto: EOF when reading a line
Traceback (most recent call last):
File "<pyshell#52>", line 3, in -toplevel-
b = input("Entre com outro numero ")
EOFError: EOF when reading a line