Introdução
Python
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
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
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
Link-Editores
Link Editor
Prog
objeto 1
Prog
objeto N
Biblioteca Biblioteca
Programa
executável
Interpretadores
 Simulam uma “máquina virtual”
 Programa fonte é lido, entendido e as instruções
são executadas imediatamente
Interpretador
Programa
fonte
Entrada Saída
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
 Python
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!
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.
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
No Mundo
 NASA (vários projetos)
 Yahoo! (Yahoo mail & groups)
 Apple, H.P., Microsoft
 Muitas Universidades, como MIT, e Stanford
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
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
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
Python Interativo
 Rode o interpretador (Python Shell)
 Digite comandos python
 Cada comando é executado imediatamente!
>>> print "Hello World!"
Hello World!
>>> a = 2
>>> print a
2
>>>
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!
Executando um programa Python
 Interfaces gráficas normalmente já associam os
sufixos .py e .pyc com o interpretador
 Programando em Python
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
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
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)
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
Variáveis
>>> a=1
>>> a
1
>>> a=2*a
>>> a
2
>>> a,b=3*a,a
>>> a,b
(6, 2)
>>> a,b=b,a
>>> a,b
(2, 6)
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
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
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
Números inteiros
>>> a=2**30 # Potenciação
>>> a
1073741824
>>> b=a*1000
>>> b
1073741824000L
>>> b/1000
1073741824L
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
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
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)
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"
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)
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í
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
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
>>>
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
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'
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
Strings – Fatias (slices)
>>> a
'abcde'
>>> a[0:2]
'ab'
>>> a [2:]
'cde'
>>> a[:]
'abcde'
>>> a[-1:]
'e'
>>> a[:-1]
'abcd'
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
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'
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
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
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
Funções Embutidas
>>> abs (10)
10
>>> abs (-19)
19
>>> chr (95)
'_'
>>> chr (99)
'c'
>>> ord ('a')
97
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 *
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.)
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
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)
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
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)
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
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
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'
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'
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
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 ...
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
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!
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!
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!
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
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
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
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
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
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
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']]
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]
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']]
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)]
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']]
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
Incrementos em Fatias
 Exemplo
>>> a = ['a', 2, 3, 'd', 'x']
>>> a [:3:2]
['a', 3]
>>> a [::-1]
['x', 'd', 3, 2, 'a']
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
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
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]
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]
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'
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']
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'
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]
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
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ê!
Comparando listas
>>> [1,2] < [2, 3]
True
>>> [1,2] < [1, 2, 3]
True
>>> [1,2] != [1,2]
False
>>> min([[1],[2,3],[3,4],[]])
[]
>>> max([[1],[2,3],[3,4],[]])
[3, 4]
>>> min(0,[],"")
0
>>> max(0,[],"")
''
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
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]
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)
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]]
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]
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]
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
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]
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]
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
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]
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]
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]
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]
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']
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]]
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)
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]
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
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)
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]
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
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===='
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
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
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)
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'
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])
Exemplo: resultados
--------------------------
Item Preço
--------------------------
Abacate 2.13
Limão 0.19
Tangerina 1.95
Melancia 0.87
Laranja da China 12.00
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
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
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
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'
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
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'
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']
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'
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
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'
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
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”]
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
Exemplo
>>> dic = {"joao":100,"maria":150}
>>> dic["joao"]
100
>>> dic["maria"]
150
>>> dic["pedro"] = 10
>>> dic
{'pedro': 10, 'joao': 100, 'maria': 150}
>>> dic = {'joao': 100, 'maria': 150,
'pedro': 10}
>>> dic
{'pedro': 10, 'joao': 100, 'maria': 150}
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!
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
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
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'
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'}
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]}
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}
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
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
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']
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}
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'}
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}
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
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
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
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
Exemplo
>>> def f():
return
>>> print f()
None
>>> def f():
return "Oi"
>>> print f()
Oi
>>> def f(nome):
return "Oi, "+nome+"!"
>>> print f("Joao")
Oi, Joao!
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
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
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
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)
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
Exemplo
>>> def f(nome,saudacao="Oi",pontuacao="!!"):
return saudacao+","+nome+pontuacao
>>> print f("Joao")
Oi,Joao!!
>>> print f("Joao","Parabens")
Parabens,Joao!!
>>> print f("Joao","Ah","...")
Ah,Joao...
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!!
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
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
Exemplo
>>> def f(x):
x[:] = [5]
>>> a = [1]
>>> f(a)
>>> a
[5]
>>> b = a
>>> b[:] = [7]
>>> a
[7]
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.
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
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}
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'
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
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
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}
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
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
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
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
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'
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]
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)
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
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
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
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
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
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)
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
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
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
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
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:])
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
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
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
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
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
Torres de Hanói: Exemplo
| | |
* | |
*** | |
***** | |
=======================
| | |
| | |
*** | |
***** * |
=======================
| | |
| | |
| | |
***** * ***
=======================
| | |
| | |
| | *
***** | ***
=======================
| | |
| | |
| | *
| ***** ***
=======================
| | |
| | |
| | |
* ***** ***
=======================
| | |
| | |
| *** |
* ***** |
=======================
| | |
| * |
| *** |
| ***** |
=======================
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
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
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
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
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
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 ()
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
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
Exemplo
>>> class C:
def init(self,a=2,b=3):
self.a = a
self.b = b
def f(self,x):
return self.a*x+self.b
>>> obj1 = C()
>>> obj1.init(2,3)
>>> obj2 = C()
>>> obj2.init(8,1)
>>> obj1.f(7)
17
>>> obj2.f(7)
57
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
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)
Exemplo
>>> class C:
def __init__(self,a=2,b=3):
self.a = a
self.b = b
def f(self,x):
return self.a*x+self.b
>>> obj1 = C()
>>> obj2 = C(8,1)
>>> obj1.f(7)
17
>>> obj2.f(7)
57
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
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
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
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
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 é, __
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'
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
Exemplo
>>> class vetor:
def __init__(self,x,y):
self.x, self.y = x,y
def __add__(self,v):
return vetor(self.x+v.x, self.y+v.y)
def __sub__(self,v):
return vetor(self.x-v.x, self.y-v.y)
def __repr__(self):
return "vetor("+str(self.x)+","+str(self.y)+")"
>>> a=vetor(1,2)
>>> a += vetor(3,5)
>>> a-vetor(2,2)
vetor(2,5)
>>> print a
vetor(4,7)
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.
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
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
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
Exemplo
>>> class Retangulo:
def __init__(self,tamanho):
self.setTamanho(tamanho)
def setTamanho(self,tamanho):
if min(tamanho)<0: raise ValueError
self.__tamx,self.__tamy = tamanho
def getTamanho(self):
return (self.__tamx,self.__tamy)
>>> r = Retangulo((20,30))
>>> r.getTamanho()
(20, 30)
>>> r.setTamanho((-1,0))
Traceback (most recent call last):
...
ValueError
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
Exemplo
>>> class Retangulo:
def __init__(self,tamanho):
self.setTamanho(tamanho)
def setTamanho(self,tamanho):
if min(tamanho)<0: raise ValueError
self.__tamx,self.__tamy = tamanho
def getTamanho(self):
return (self.__tamx,self.__tamy)
tamanho = property(getTamanho,setTamanho)
>>> r = Retangulo((20,30))
>>> r.tamanho
(20, 30)
>>> r.tamanho = (30,30)
>>> r.tamanho
(30, 30)
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
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
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
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
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', ...
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
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
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!
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
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!
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!
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'
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
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
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
A cláusula else
 É possível completar um comando try com uma
cláusula else que introduz um trecho de código que
só é executado quando nenhuma exceção ocorre:
try:
Código
except Exceções:
Código de tratamento da exceção
else:
Código executado se não ocorrem exceções
Exemplo 6
>>> while True:
try:
a = input("Entre com um numero ")
b = input("Entre com outro numero ")
print a, "/", b, "=", a/b
except Exception,e:
print "Deu bode:",e
print "Tente novamente"
else:
break
Entre com um numero 1
Entre com outro numero xxx
Deu bode: name 'xxx' is not defined
Tente novamente
Entre com um numero 1
Entre com outro numero 2
1 / 2 = 0
A cláusula finally
 A cláusula finally pode ser usada para se
assegurar que mesmo que ocorra algum erro, uma
determinada seqüência de comandos vai ser
executada
 Pode ser usada para restabelecer alguma variável para
um valor default, por exemplo
 Até a versão 2.4 do python, as cláusula finally e
except eram mutuamente exclusivas
 Exceções nesse caso não eram tratadas
 Era possível combinar ambas usando comandos try
aninhados
Exemplo 7 (Python 2.5)
>>> try:
... x = input("Entre com um número")
... except:
... print "Deu Bode"
... finally:
... print "restabelecendo um valor para
x"
... x = None
...
Entre com um número 1xx
Deu Bode
restabelecendo um valor para x
Exemplo 7 (Python 2.4)
>>> try:
... try:
... x = input("Entre com um número")
... finally:
... print "restabelecendo um valor para x"
... x = None
... except:
... print "Deu Bode"
...
Entre com um número 1xx
restabelecendo um valor para x
Deu Bode
Iteradores
 São maneiras genéricas de implementar iterações
com classes
 Permite o uso do comando for
 É muitas vezes mais econômico do que usar uma lista
pois não é preciso armazenar todos os valores, mas
apenas computar um por vez
 Um iterador é uma classe que implementa o método
mágico __iter__
 É um método que, por sua vez, retorna um objeto que
implementa um método chamado next
 O método next deve retornar o “próximo” valor a ser iterado
 Se não há próximo valor, next deve “levantar” a exceção
StopIteration
Exemplo
>>> class MeuIterador:
a = 0
def __iter__(self): return self
def next(self):
if self.a>10: raise StopIteration
self.a += 1
return self.a
>>> iter = MeuIterador()
>>> for i in iter:
print i,
1 2 3 4 5 6 7 8 9 10 11
Geradores
 Geradores são funções especiais que retornam
iteradores
 Em resumo, uma função geradora é uma que
contém a o comando yield valor
 Uma função geradora normalmente é chamada para
obter o iterador para um comando for
 O comando for automaticamente iterará sobre todos os
valores que yield “retorna”
 Observe que o iterador produzido pela função geradora é
tal que o código que gera os valores e o código dentro do
for se sucedem alternadamente
 Geradores são especialmente úteis em códigos
recursivos
Exemplo
>>> def gerador():
for i in range(10):
print "i = ", i
yield i
>>> for j in gerador():
print "j = ",j
i = 0
j = 0
i = 1
j = 1
....
i = 9
j = 9
Módulos
 Módulos são programas feitos para serem
reaproveitados em outros programas
 Eles tipicamente contêm funções, variáveis, classes
e objetos que provêm alguma funcionalidade comum
 Por exemplo, já vimos que o módulo math contém
funções matemáticas como sin, exp, etc, além da
constante pi
 Toda a biblioteca padrão do Python é dividida em
módulos e pacotes (veremos mais tarde)
 Alguns dos mais comuns são: sys, os, time,
random, re, shelve
Escrevendo módulos
 Na verdade, qualquer programa que você escreva e salve
num arquivo pode ser importado como um módulo
 Por exemplo, se você salva um programa com o nome
prog.py, ele pode ser importado usando o comando import
prog
 Entretanto, a “importação” só ocorre uma vez
 Python assume que variáveis e funções não são
mudados e que o código do módulo serve meramente
para inicializar esses elementos
 Após a importação de um módulo, este é compilado,
gerando um arquivo .pyc correspondente
 No exemplo, um arquivo prog.pyc será criado
 Python só recompila um programa se o arquivo .py for
mais recente que o arquivo .pyc
Exemplo (em Unix)
$ cat teste.py
def f():
print "alo"
f()
$ python
...
>>> import teste
alo
>>> import teste
>>> teste.f()
alo
>>>
$ dir teste*
teste.py teste.pyc
Tornando módulos disponíveis
 Em que diretório os módulos são buscados durante a
importação?
 No diretório corrente
 Nos diretórios da lista sys.path
 Se for desejável especificar o local onde os módulos
residem, há essencialmente duas opções
 Alterar diretamente a variável sys.path
 Alterar a variável de ambiente PYTHONPATH
 É o método recomendável pois não requer que o programa que
importará o módulo seja alterado
Exemplo
$ mkdir python
$ mv teste.py python/
$ cat python/teste.py
def f():
print "alo"
f()
$ export PYTHONPATH=~/python
$ python
Python 2.4.2 (#2, Sep 30 2005, 21:19:01)
...
>>> import teste
alo
A variável __name__
 Se um programa pode ser executado por si só ou
importado dentro de outro, como distinguir as duas
situações?
 A variável __name__ é definida para cada programa:
 Se é um módulo, retorna o nome do módulo
 Se é um programa sendo executado, retorna '__main__'
 Para saber se o código está sendo executado como
módulo, basta testar:
 If __name__ == '__main__': código
 Isto é útil em diversas circunstâncias
 Por exemplo, para colocar código de teste, código para
instalação do módulo ou exemplos de utilização
Exemplo
$ cat teste.py
def f():
print "alo"
if __name__ == '__main__':
f()
$ python teste.py
alo
$ python
Python 2.4.2 (#2, Sep 30 2005, 21:19:01)
...
>>> import teste
>>> print __name__
__main__
>>> print teste.__name__
teste
Pacotes
 São hierarquias de módulos
 Um pacote é um diretório que contém um arquivo chamado
__init__.py
 O pacote deve estar em um dos diretórios nos quais o Python
busca por módulos
 Para importar o pacote, use o nome do diretório
 O programa correspondente ao pacote é __init__.py
 Os demais arquivos e diretórios dentro do pacote são encarados
recursivamente como módulos
 Por exemplo, se um pacote se chama p e contém um arquivo
chamado m.py, então podemos importar
 p (arquivo p/__init__.py)
 p.m (arquivo p/m.py)
 Semelhantemente, p poderia ter um outro pacote sob a forma
de outro diretório contendo um arquivo __init__.py
Exemplo
$ dir python/
pacote teste.py
$ dir python/pacote/
__init__.py teste2.py
$ cat python/teste.py
print "teste"
$ cat python/pacote/__init__.py
print "pacote"
$ cat python/pacote/teste2.py
print "teste2"
$ python
...
>>> import teste
teste
>>> import pacote
pacote
>>> import pacote.teste2
teste2
Arquivos
 Entrada e saída são operações de comunicação de
um programa com o mundo externo
 Essa comunicação se dá usualmente através de
arquivos
 Arquivos estão associados a dispositivos
 Por exemplo, disco, impressora, teclado
 Em Python, um arquivo pode ser lido/escrito através
de um objeto da classe file
Arquivos default
 Já usamos, sem saber, três arquivos default
 Sempre que um comando print é executado, o
resultado vai para um arquivo chamado sys.stdout
 Sempre que lemos um dado através do comando input
ou raw_input, na verdade estamos lendo de um
arquivo chamado sys.stdin
 Mensagens de erro ou de rastreamento de exceções são
enviadas para um arquivo chamado sys.stderr
Exemplo
>>> import sys
>>> sys.stdout.write("alo")
alo
>>> print "alo"
alo
>>> sys.stdin.readline()
sfadfas
'sfadfasn'
>>> raw_input()
fasdfadsf
'fasdfadsf'
Redirecionamento
 Os arquivos sys.stdin, sys.stdout e sys.stderr
normalmente estão associados ao teclado e ao display do terminal
sendo usado, mas podem ser reassociados a outros dispositivos
 Em Unix/Linux e Windows:
 programa > arquivo
 Executa programa redirecionando stdout para arquivo
 programa < arquivo
 Executa programa redirecionando stdin de arquivo
 programa1 | programa2
 Executa programa1 e programa2 sendo que a saída de
programa1 é redirecionanda para a entrada de programa2
 Em Linux com shell bash
 programa 2> arquivo
 Executa programa redirecionando stderr para arquivo
Abrindo arquivos
 open (name, mode, buffering)
 name : nome do arquivo a abrir
 mode : (opcional) modo de abertura – string contendo
 r : leitura (default)
 w : escrita
 b : binário
 a : escrita a partir do final
 + : (usado com r) indica leitura e escrita
 buffering : (opcional) indica se memória (buffers) é usada
para acelerar operações de entrada e saída
 0 : buffers não são usados
 1 (ou qq número negativo): um buffer de tamanho padrão
(default)
 2 ou maior: tamanho do buffer em bytes
O objeto file
 O comando open retorna um objeto do tipo file
(arquivo)
 Na verdade, em Python 2.4 em diante, open é o mesmo
que file, e portanto o comando é um construtor
 O objeto retornado é usado subseqüentemente para
realizar operações de entrada e saída:
>>> arq = open ("teste", "w")
>>> arq.write ("Oi")
>>> arq.close ()
>>> arq = open ("teste")
>>> x = arq.read()
>>> x
'Oi'
Métodos Read, Write e Close
 read(num)
 Lê num bytes do arquivo e os retorna numa string
 Se num não é especificado, todos os bytes desde o ponto
atual até o fim do arquivo são rretornados
 write(string)
 Escreve string no arquivo
 Devido ao uso de buffers, a escrita pode não ser feita
imediatamente
 Use o método flush() ou close() para assegurar a escrita
física
 close()
 Termina o uso do arquivo para operações de leitura e
escrita
Convenção de fim de linha
 Arquivos de texto são divididos em linhas usando
caracteres especiais
 Linux/Unix: n
 Windows: rn
 Mac: r
 Python usa sempre n para separar linhas
 Ao se ler/escrever um arquivo aberto em modo texto (não
binário) faz traduções de n para se adequar ao sistema
operacional
 Em modo binário, entretanto, a conversão não é feita
Interação com o Sistema Operacional
 Operações de entrada e saída são na verdade
realizadas pelo sistema operacional
 O módulo os possui diversas variáveis e funções
que ajudam um programa Python a se adequar ao
sistema operacional, por exemplo:
 os.getcwd() retorna o diretório corrente
 os.chdir(dir) muda o diretório corrente para dir
 os.sep é uma string com o caractere que separa
componentes de um caminho ('/' para Unix, '' para
Windows)
 os.path.exists(path) diz se path se refere ao nome
de um arquivo existente
Lendo e escrevendo linhas
 readline(n)
 Se n não é especificado, retorna exatamente uma linha lida do
arquivo
 Caso contrário, lê uma linha, mas busca no máximo n
caracteres pelo final de linha
 readlines(n)
 Se n não é especificado, retorna o restante do conteúdo do
arquivo em uma lista de strings
 Caso n seja especificado, a leitura é limitada a n caracteres no
máximo
 writelines(seqüência)
 Escreve a lista (ou qualquer seqüência) de strings, uma por
uma no arquivo
 Caracteres terminadores de linha não são acrescentados
Acesso direto
 É possível ler e escrever não seqüencialmente em
alguns tipos de arquivo
 Devem estar associados a dispositivos que permitem acesso
direto, como discos, por exemplo
 seek(offset,whence)
 offset indica o número do byte a ser lido e escrito pela próxima
operação de entrada e saída
 whence indica a partir de onde offset será contado
 0 (default) : do início
 1 : do ponto corrente
 2 : do final
 tell()
 Indica a posição corrente (número de bytes a partir do início do
arquivo)
Interfaces Gráficas
 Também chamadas de Graphical User Interfaces (GUI)
 Usadas em aplicações modernas que requerem uma
interação constante com o usuário
 Maior usabilidade e naturalidade do que interfaces textuais
 Aplicação apresenta uma ou mais janelas com
elementos gráficos que servem para comandar ações,
especificar parâmetros, desenhar e exibir gráficos, etc
 Bibliotecas (toolkits) para construção de interfaces como
 Qt
 Gtk
 wxWindows
 Tk
Interfaces Gráficas em Python
 Python possui camadas de portabilidade (bindings)
para várias bibliotecas de construção de interfaces.
Ex.:
 PyQt (Qt)
 PyGtk (Gtk)
 wxPython (wxWindows)
 Tkinter (Tk)
 Multiplataforma (MS-Windows, Unix/Linux, OSX)
Tk
 Toolkit originalmente criado para utilização com a
linguagem script Tcl
 Bastante leve, portátil e robusto
 Um tanto obsoleto frente a outros toolkits mais
modernos como Qt ou Gtk
 Camada Tkinter normalmente distribuída com o
Python
 Inicia um processo Tcl que toma conta dos elementos de
interface
 Classes e funções do Tkinter se comunicam com o
interpretador Tcl para especifcar aspecto e
comportamento da interface
Usando Tkinter
 Importar o módulo Tkinter
 from Tkinter import *
 Elementos de interface (widgets) correspondem a
objetos de diversas classes. Por exemplo:
 Frame (Área retangular)
 Button (botão)
 Label (rótulo)
 Text (caixa de texto)
 Canvas (caixa de desenho)
 Posição e tamanho dos elementos controlados por
gerentes de geometria
 Pack (mais comum), Place, Grid
Usando Tkinter (2)
 Para criar um widget, tem-se que informar o widget-pai
(parâmetro master) onde geometricamente deverá ser
encaixado e as opções de configuração para o widget.
Ex.:
w =
Button(pai,text=”Cancelar”,command=cancelar)
 Tk já define por default uma janela principal
 master=None (default) indica que o widget será filho da janela
principal
 Outras janelas pode ser criadas criando objetos da classe
Toplevel
 A função mainloop tem que ser invocada para que a
aplicação entre no modo de tratamento de eventos
Exemplo
from Tkinter import *
class Application(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.msg = Label(self, text="Hello World")
self.msg.pack ()
self.bye = Button (self, text="Bye",
command=self.quit)
self.bye.pack ()
self.pack()
app = Application()
mainloop()
Exemplo
from Tkinter import *
class Application(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.msg = Label(self, text="Hello World")
self.msg.pack ()
self.bye = Button (self, text="Bye",
command=self.quit)
self.bye.pack ()
self.pack()
app = Application()
mainloop()
Exemplo
from Tkinter import *
class Application(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.msg = Label(self, text="Hello World")
self.msg.pack ()
self.bye = Button (self, text="Bye",
command=self.quit)
self.bye.pack ()
self.pack()
app = Application()
mainloop()
Elemento principal
derivado de Frame
Construtor da classe base
Janela tem um
rótulo e um botão
Interface é
instanciada
Laço de tratamento de
eventos é iniciado
Classes de componentes
 Button Um botão simples usado para executar um comando
 Canvas Provê facilidades de gráficos estruturados
 Checkbutton Representa uma variável que pode ter dois
valores distintos (tipicamente um valor booleano). Clicando no
botão alterna-se entre os valores
 Entry Um campo para entrada de uma linha de texto
 Frame Usado como agrupador de widgets
 Label Mostra um texto ou uma imagem
 Listbox Mostra uma lista de alternativas. Pode ser
configurado para ter comportamento de checkbutton ou
radiobutton
Classes de componentes (cont.)
 Menu Um painel de menu. Implementa menus de janela, pulldowns e
popups
 Message Similar ao widget Label, mas tem mais facilidade para
mostrar texto quebrado em linhas
 Radiobutton Representa um possível valor de uma variável que
tem um de muitos valores. Clicando o botão, a variável assume
aquele valor
 Scale Permite especificar um valor numérico através de um
ponteiro em uma escala linear
 Scrollbar Barra de rolamento para widgets que têm superfície
útil variável (Text, Canvas, Entry, Listbox)
 Text Exibe e permite editar texto formatado. Também suporta
imagens e janelas embutidas
 Toplevel Uma janela separada
A Classe Tk
 É a que define uma janela principal e o interpretador
Tcl
 Em geral, nunca precisa ser instanciada
 É instanciada automaticamente quando um widget filho é
criado
 Pode ser instanciada explicitamente
 Possui vários métodos, entre os quais
 title (string) Especifica o título da janela
 geometry(string) Especifica tamanho e posição da
janela
 String tem a forma larguraxaltura+x+y
Exemplo
from Tkinter import *
class Application(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.msg = Label(self, text="Hello World")
self.msg.pack ()
self.bye = Button (self, text="Bye",
command=self.quit)
self.bye.pack ()
self.pack()
app = Application()
app.master.title("Exemplo")
app.master.geometry("200x200+100+100")
mainloop()
Opções de Widgets
 Widgets (elementos de interface) têm opções com
nomenclatura unificada. Ex.:
 text Texto mostrado no elemento
 background cor de fundo
 foreground cor do texto
 font fonte do texto
 relief relevo da borda ('flat', 'raised', 'ridge',
'sunken', 'groove')
 Opções são especificadas
 No construtor
 Através do método configure
Exemplo
from Tkinter import *
top = Frame() ; top.pack()
rotulo = Label (top, text="Rótulo Exemplo",
foreground="blue")
rotulo.pack ()
rotulo.configure(relief="ridge", font="Arial 24 bold",
border=5, background="yellow")
O método configure
 Usado com pares do tipo opção=valor, modifica os valores
dos atributos
 Usado com uma string “nomeopção” retorna a configuração
da opção com esse nome
 A configuração é uma tupla com 5 valores
 nome do atributo
 nome do atributo no banco de dados (X11)
 nome da classe no banco de dados (X11)
 objeto que representa a opção
 valor corrente da opção
 Se configure é usado sem argumentos, retorna um
dicionário com todas as opções
 Pode-se obter diretamente o valor de uma opção
usando o método cget
Exemplo
>>> rotulo.configure(relief="ridge")
>>> rotulo.configure("relief")
('relief', 'relief', 'Relief', <index object at
0x85f9530>, 'ridge')
>>> rotulo.configure()["relief"]
('relief', 'relief', 'Relief', <index object at
0x85f9530>, 'ridge')
>>> rotulo.configure("relief")[4]
'ridge'
>>> rotulo.cget("relief")
'ridge'
Gerenciando geometrias
 Todos os elementos de interface ocupam uma área
retangular na janela
 A posição e tamanho de cada elemento é
determinada por um gerenciador de geometria
 O elemento não “aparece” enquanto não for informado ao
gerenciador
 A geometria resultante depende de
 Propriedades dos elementos (tamanho mínimo, tamanho
da moldura, etc)
 Opções do gerenciador
 Algoritmo usado pelo gerenciador
 O gerenciador mais usado em Tk é o pack
Usando o pack
 Para informar que um elemento deve ser gerenciado
pelo pack, use o método pack (opções)
 O pack considera o espaço do elemento “pai” como
uma cavidade a ser preenchida pelos elementos
filhos
 O algoritmo usado pelo pack consiste em empacotar
os filhos de um elemento “pai” segundo o lado
(side) especificado
 Os lados possíveis são 'top', 'left', 'right' e 'bottom'
 Deve-se imaginar que sempre que um elemento filho
escolhe um lado, a cavidade disponível fica restrita ao
lado oposto
Exemplo
from Tkinter import *
top = Frame() ; top.pack()
a = Label (top, text="A") ; a.pack (side="left")
b = Label (top, text="B") ; b.pack (side="bottom")
c = Label (top, text="C") ; c.pack (side="right")
d = Label (top, text="D") ; d.pack (side="top")
for widget in (a,b,c,d):
widget.configure(relief="groove", border=10,
font="Times 24 bold")
top.mainloop()
Redimensionamento
 Por default, o pack não redimensiona os filhos quando o
pai é redimensionado
 Duas opções controlam o redimensionamento dos filhos
 expand (booleano)
 Se verdadeiro, indica que o filho deve tomar toda a cavidade
disponível no pai
 Caso contrário, toma apenas o espaço necessário (default)
 fill ('none', 'x', 'y' ou 'both')
 Indica como o desenho do elemento irá preencher o espaço
alocado
 'x' / 'y' indica que irá preencher a largura / altura
 'both' indica preenchimento de todo o espaço
 'none' indica que apenas o espaço necessário será ocupado
(default)
Exemplo
from Tkinter import *
top = Frame() ; top.pack()
a = Label (top, text="A") ; a.pack (side="left",
fill="y")
b = Label (top, text="B") ; b.pack (side="bottom",
fill="x")
c = Label (top, text="C") ; c.pack (side="right")
d = Label (top, text="D") ; d.pack (side="top")
for widget in (a,b,c,d):
widget.configure(relief="groove", border=10,
font="Times 24 bold")
top.mainloop()
Exemplo
from Tkinter import *
top = Frame() ; top.pack(fill='both', expand=True)
a = Label (top, text="A") ; a.pack
(side="left",fill="y")
b = Label (top, text="B") ; b.pack
(side="bottom",fill="x")
c = Label (top, text="C") ; c.pack (side="right")
d = Label (top, text="D") ; d.pack (side="top")
for widget in (a,b,c,d):
widget.configure(relief="groove", border=10,
font="Times 24 bold")
top.mainloop()
Exemplo
from Tkinter import *
top = Frame() ; top.pack(fill='both', expand=True)
a = Label (top, text="A") ; a.pack
(side="left",expand=True,fill="y")
b = Label (top, text="B") ; b.pack
(side="bottom",expand=True,fill="both")
c = Label (top, text="C") ; c.pack (side="right")
d = Label (top, text="D") ; d.pack (side="top")
for widget in (a,b,c,d):
widget.configure(relief="groove", border=10,
font="Times 24 bold")
top.mainloop()
Usando frames
 Frames podem ser usados para auxiliar no layout dos
elementos com pack. Ex.:
from Tkinter import *
top = Frame() ; top.pack(fill='both', expand=True)
f = Frame (top); f.pack (fill='x')
a = Label (f, text="A")
b = Label (f, text="B")
c = Label (f, text="C")
d = Label (top, text="D")
for w in (a,b,c,d):
w.configure(relief="groove", border=10, font="Times 24
bold")
w.pack(side="left", expand=True, fill="both")
top.mainloop()
Programação com eventos
 Diferente da programação convencional
 O programa não está sob controle 100% do tempo
 Programa entrega controle ao sistema
 Em Tk: método(função) mainloop
 Interação gera eventos. Ex:
 Acionamento de um menu ou de um botão
 Mouse arrastado sobre uma janela
 Uma caixa de texto teve seu valor alterado
 O tratamento de um evento é feito por uma rotina
“Callback”
A opção command
 Muitos componentes do Tk suportam a opção
command que indica uma função a ser invocada
sempre que o widget é acionado
 Tipicamente, a função (ou método) usado obtém
valores de outros widgets para realizar alguma
operação
Exemplo
from Tkinter import *
def inc():
n=int(rotulo.configure("text")[4])+1
rotulo.configure(text=str(n))
b = Button(text="Incrementa",command=inc)
b.pack()
r = Label(text="0")
r.pack()
mainloop()
Eventos e Bind
 Widgets que não dispõem da opção command
também podem receber eventos e responder a eles
 O método bind permite especificar um padrão de
eventos ao qual o widget será sensível e uma rotina
callback para tratá-lo
bind(padrão,rotina)
 padrão é uma string que descreve quais eventos a rotina
irá tratar
 rotina é uma função ou método com exatamente um
parâmetro: o evento que deve ser tratado
Exemplo
from Tkinter import *
def clica (e):
txt = "Mouse clicado emn%d,%d"%(e.x,e.y)
r.configure(text=txt)
r = Label()
r.pack(expand=True, fill="both")
r.master.geometry("200x200")
r.bind("<Button-1>", clica)
mainloop()
Campos do objeto evento
 x,y : posição do mouse com relação ao canto superior
esquerdo do widget
 x_root, y_root: posição do mouse com relação ao canto
superior esquerdo da tela
 char: caractere digitado (eventos de teclado)
 keysym: representação simbólica da tecla
 keycode: representação numérica da tecla
 num: número do botão – 1/2/3=Esquerdo/Meio/Direito –
(eventos de mouse)
 widget: o objeto que gerou o evento
 width,height: largura e altura do widget (evento Configure)
Padrões de evento (mouse)
 <Button-i> para i = 1,2,3: botão i do mouse pressionado
sobre o widget
 <Motion> : mouse arrastado sobre o widget
 <Bi-Motion> : mouse arrastado sobre o widget com o botão
i pressionado
 <ButtonRelease-i> : botão i do mouse solto sobre o
widget
 <Double-Button-i>: botão i do mouse clicado duas vezes
em seguida
 <Enter>: O mouse entrou na área do widget
 <Leave>: O mouse saiu da área do widget
Padrões de evento (teclado)
 caracter : O caracter foi digitado sobre o widget
 <Key>: Algum caracter foi digitado sobre o widget
 <Return>: Tecla enter foi digitada
 <Tab>, <F1>, <Up>...: A tecla correspondente foi digitada
 <Shift-Tab>, <Alt-F1>, <Ctrl-Up>...: Tecla com
modificador
 Para os eventos serem gerados, é preciso que o foco de
teclado esteja sobre o widget
 Depende do sistema de janelas
 O foco para um widget pode ser forçado usando o
método focus
Exemplo
from Tkinter import *
def clica (e):
txt = "Mouse clicado emn%d,%d"%(e.x,e.y)
r.configure(text=txt)
r.focus()
def tecla(e):
txt="Keysym=%snKeycode=%snChar=%s"
%(e.keysym,e.keycode,e.char)
r.configure(text=txt)
r = Label()
r.pack(expand=True, fill="both")
r.master.geometry("200x200")
r.bind("<Button-1>", clica)
r.bind("<Key>", tecla)
Menus
 Podem ser associados a uma janela (menus
toplevel), pulldown, popup e em cascata a partir de
outro menu
 Todos são instâncias da classe Menu
 Um menu é composto de itens que podem ser
 command quando pressionado executa uma callback
 checkbox parecido com command, mas tem um valor
booleano associado
 radiobutton como command, mas representa um de
vários estados mutuamente exclusivos
 cascade ativa um outro menu em cascata
 Para adicionar um item a um menu, use métodos da
forma add (“tipo”, opções) ou add_tipo(opções)
Menu de janela (toplevel)
 É tipicamente exibido horizontalmente no topo da
janela
 Aspecto depende do sistema operacional
 Se um outro menu é associado como item cascade,
ele é tratado como pulldown, isto é, é exibido sob o
item do menu de janela
 Assim como outros menus, não necessita ter sua
geometria gerenciada (e.g., pack ou grid)
 Para associar a uma janela, usa-se a opção menu
do objeto janela.
Exemplo
from Tkinter import *
def abrir(): print "abrir"
def salvar(): print "salvar"
def ajuda() : print "ajuda"
top=Tk()
principal=Menu(top)
arquivo=Menu(principal)
arquivo.add_command(label="Abrir",command=abrir)
arquivo.add_command(label="Salvar",command=salvar)
principal.add_cascade(label="Arquivo",menu=arquivo)
principal.add_command(label="Ajuda",command=ajuda)
top.configure(menu=principal)
Menus Popup
 Um menu popup é aquele que é exibido numa janela
independente
 Para que o menu seja exibido, é preciso invocar o
método post:
post (x, y)
 onde x e y são as coordenadas do canto superior
esquerdo do menu com relação ao canto superior
esquerdo da tela
Exemplo
from Tkinter import *
def alo(): print "Alo!"
root = Tk()
menu = Menu(root, tearoff=0)
menu.add_command(label="Alo 1", command=alo)
menu.add_command(label="Alo 2", command=alo)
def popup(e): menu.post(e.x_root, e.y_root)
frame = Frame(root, width=200, height=200)
frame.pack()
frame.bind("<Button-3>", popup)
mainloop()
Variáveis
 Tk é controlado por um interpretador Tcl (e não
diretamente pelo python)
 Em alguns casos, deseja-se usar usar variáveis na
interface
 Por exemplo, é possível especificar que o texto exibido em um
Label é o valor de uma variável (e não uma constante)
 Nesse caso, usa-se a opção textvar ao inves de text
 Variáveis Tcl são expostas à aplicaçãoPython através
das classes StringVar, IntVar e DoubleVar
 O construtor é da forma StringVar(master) onde master é
uma janela ou widget
 Instâncias dessas classes possuem os métodos get e
set que podem ser usados para acessar os valores
armazenados no interpretador Tcl
Exemplo
from Tkinter import *
root = Tk()
soma = DoubleVar(root)
parcela = DoubleVar(root)
def aritmetica (e):
soma.set(soma.get()+parcela.get())
lsoma = Label(textvar=soma)
eparcela = Entry(textvar=parcela)
eparcela.bind("<Return>", aritmetica)
lsoma.pack()
eparcela.pack()
Checkbuttons
 Checkbutton Representa uma variável que pode ter dois
valores distintos (tipicamente um valor booleano). Clicando no
botão alterna-se entre os valores
 A callback especificada pela opção command é chamada
sempre que a variável muda de valor
 Estado é armazenado pela variável Tcl especificada pela
opção variable
 Se a variável é inteira, o valor correspondente ao checkbutton
“desligado”/“ligado” é 0/1
 É possível usar um checkbutton com uma variável string
 Nesse caso, os valores correspondentes a
“desligado”/“ligado” são especificados com as opções
offvalue e onvalue
Exemplo
from Tkinter import *
root = Tk()
v1 = IntVar(root)
v2 = StringVar(root)
def exibe():
l.config (text="v1=%d,v2=%s"%(v1.get(),v2.get()))
c1 = Checkbutton (text="V1", var=v1, command=exibe)
c2 = Checkbutton (text="V2", var=v2, command=exibe,
onvalue="Sim", offvalue="Nao")
l = Label()
for w in (c1,c2,l):w.pack()
exibe()
Exemplo
from Tkinter import *
root = Tk()
v1 = IntVar(root)
v2 = StringVar(root)
def exibe():
l.config (text="v1=%d,v2=%s"%(v1.get(),v2.get()))
c1 = Checkbutton (text="V1", var=v1, command=exibe)
c2 = Checkbutton (text="V2", var=v2, command=exibe,
onvalue="Sim", offvalue="Nao")
l = Label()
for w in (c1,c2,l):w.pack()
exibe()
Radiobuttons
 Radiobutton representa um possível valor de uma variável
que tem um de muitos valores. Clicando o botão, a variável
assume aquele valor
 A variável é especificada com a opção variable e o valor
associado com a opção value
 Os radiobuttons que se referem à mesma variável funcionam
em conjunto
 Ex.: ligar um faz com que outro seja desligado
 Um radiobutton é mostrado com um indicador ao lado
 Pode-se desabilitar o indicador usando a opcao
indicatoron=False
 Nesse caso, é mostrado como um botão normal
Exemplo
from Tkinter import *
root=Tk()
cor = StringVar(root)
cor.set("black")
l = Label(background=cor.get())
l.pack(fill='both',expand=True)
def pinta(): l.configure(background=cor.get())
for txt,val in (("preto","black"),
("vermelho","red"),
("azul","blue"), ("verde","green")):
Radiobutton(text=txt,value=val,variable=cor,
command=pinta).pack(anchor=W)
mainloop()
Exemplo
from Tkinter import *
root=Tk()
cor = StringVar(root)
cor.set("black")
l = Label(background=cor.get())
l.pack(fill='both',expand=True)
def pinta(): l.configure(background=cor.get())
for txt,val in (("preto","black"),
("vermelho","red"),
("azul","blue"), ("verde","green")):
Radiobutton(text=txt,value=val,variable=cor,
command=pinta,indicatoron=False).pack(fill='x')
mainloop()
Entry
 Um Entry permite entrada/edição de uma linha de texto
 O texto associado ao Entry é normalmente armazenado
numa variável indicada pela opção textvariable
 Se não indicada, é usada uma variável interna cujo valor pode
ser obtido usando o método get()
 Há diversos métodos para manipular diretamente o texto
 Usam o conceito de índices (não confundir com os índices
usado pelo Python)
 Por exemplo, o índice INSERT indica a posição do texto onde
o cursor de inserção se encontra, 0 a posição antes do
primeiro caractere e END a posição ao final do texto
Exemplo
from Tkinter import *
def insere(): e.insert(INSERT,"*")
def limpa(): e.delete(INSERT,END)
e=Entry(font="Arial 24")
i=Button(text="Insere*",command=insere)
l=Button(text="Limpa",command=limpa)
e.pack()
for w in (i,l): w.pack(side='left')
mainloop()
Canvas
 Permite a exibição e edição de gráficos estruturados 2D
 Elementos gráficos (itens) são introduzidos usando
métodos da forma create_tipo (...), onde tipo pode ser
 arc arco de círculo
 bitmap imagem binária
 image imagem colorida
 line linha poligonal
 oval círculos e elipses
 polygon polígonos
 rectangle retângulo
 text texto
 window um widget tk
Exemplo
from Tkinter import *
c = Canvas()
c.pack()
o = c.create_oval(1,1,200,100,outline="blue",
width=5,fill="red")
widget = Button(text="Tk Canvas")
w =
c.create_window(10,120,window=widget,anchor=W
)
l = c.create_line(100,0,120,30,50,60,100,120,
fill="black",width=2)
r =
c.create_rectangle(40,150,100,200,fill="white
")
img = PhotoImage(file="python.gif")
i = c.create_image (150,150,image=img,anchor=NW)
a = c.create_arc
(150,90,250,190,start=30,extent=60,
outline="green",fill="orange")
t = c.create_text(200,35,text="TextonTexto",
font="Arial 22")
Coordenadas de Itens
 Todos os métodos create_item têm como primeiros argumentos
um par de coordenadas x,y do item
 Os itens oval e rectangle requerem mais um par de
coordenadas para delimitar a extensão (caixa envolvente)
 Os itens line e polygon podem ser seguidos por outros
pares de coordenadas que especificam demais vértices
 As coordenadas referem-se a um sistema de coordenadas próprio
que pode ser diferente do da janela
 A área do canvas que deve ser mostrada na janela pode ser
modificada pela opção scrollarea=(xmin,ymin,xmax,ymax)
 Para obter as coordenadas do canvas dadas as coordenadas
da janela usa-se os métodos canvasx(x) e canvasy(y)
Identificação de Itens
 Todo item de um canvas tem um identificador numérico
que é retornado pelo método create_item
 Pode-se também associar tags (etiquetas) a itens
 Usa-se a opção tags=tags onde tags pode ser uma string ou
uma tupla com várias strings
 Uma mesma etiqueta pode ser associada a mais de um item
 O identificador ALL refere-se a todos os itens do canvas
 O identificador CURRENT refere-se ao item do canvas
sob o cursor do mouse
 Usado em callbacks de canvas para alterar propriedades dos
itens clicados
Métodos de Canvas
 itemconfig (itemOuTag, ...) altera opções do(s) item(s)
 tag_bind(itemOuTag, padrão, callback) associa uma
callback a um padrão de eventos sobre o(s) item(s)
 delete(itemOuTag) remove o(s) item(s)
 move(itemOuTag, dx,dy) translada o(s) item(s)
 coords(itemOuTag, x1,x2,..xN,yN) altera as coordenadas
do(s) item(s)
 coords(item) retorna as coordenadas do item
 bbox(itemOuTag) retorna uma tupla com a caixa envolvente
dos itens
 itemcget(item,opção) retorna o valor da opção dada do item
Exemplo
from Tkinter import *
c = Canvas()
c.pack()
def novalinha(e):
x,y = c.canvasx(e.x), c.canvasy(e.y)
c.create_line(x,y,x,y,tags="corrente")
def estendelinha(e):
x,y = c.canvasx(e.x), c.canvasy(e.y)
coords = c.coords("corrente") + [x,y]
c.coords("corrente",*coords)
def fechalinha(e):
c.itemconfig("corrente",tags=())
c.bind("<Button-1>", novalinha)
c.bind("<B1-Motion>", estendelinha)
c.bind("<ButtonRelease-1>", fechalinha)
c.pack()
Exemplo
...
def selecionalinha(e):
global x0,y0
x0,y0 = c.canvasx(e.x), c.canvasy(e.y)
c.itemconfig(CURRENT, tags="sel")
def movelinha (e):
global x0,y0
x1,y1 = c.canvasx(e.x), c.canvasy(e.y)
c.move("sel",x1-x0,y1-y0)
x0,y0=x1,y1
def deselecionalinha(e): c.itemconfig("sel",
tags=())
c.bind("<Button-3>", selecionalinha)
c.bind("<B3-Motion>", movelinha)
c.bind("<ButtonRelease-3>", deselecionalinha)
Scrollbar
 Barras de rolamento são usadas com outros widgets
com área útil maior do que pode ser exibida na
janela (Canvas, Text, Listbox, Entry)
 Uma barra de rolamento horizontal (vertical)
funciona chamando o método xview (yview) do
widget associado
 Isto é feito configurando a opção command da barra
 Por outro lado, sempre que a visão do widget muda,
a barra de rolamento precisa ser atualizada
 Isto é feito configurando a opção xscrollcommand (ou
yscrollcommand) do widget ao método set da barra
Exemplo
from Tkinter import *
lb = Listbox()
lb.pack(side=LEFT,expand=True,fill=
"both")
sb = Scrollbar()
sb.pack(side=RIGHT,fill="y")
sb.configure(command=lb.yview)
lb.configure(yscrollcommand=sb.set)
for i in range(100):
lb.insert(END,i)

Python.pptx

  • 1.
  • 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 quetraduzem 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-objetonem 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
  • 5.
    Link-Editores Link Editor Prog objeto 1 Prog objetoN Biblioteca Biblioteca Programa executável
  • 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  Compiladorgera 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
  • 8.
  • 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  Criadapor 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 dejaneiro 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 deajuda 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  Jornaldo 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 umcó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  Rodeo interpretador (Python Shell)  Digite comandos python  Cada comando é executado imediatamente! >>> print "Hello World!" Hello World! >>> a = 2 >>> print a 2 >>>
  • 17.
    Executando um programaPython  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 programaPython  Interfaces gráficas normalmente já associam os sufixos .py e .pyc com o interpretador
  • 19.
  • 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 nomesdados 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
  • 24.
    Variáveis >>> a=1 >>> a 1 >>>a=2*a >>> a 2 >>> a,b=3*a,a >>> a,b (6, 2) >>> a,b=b,a >>> a,b (2, 6)
  • 25.
    Variáveis  Variáveis sãocriadas 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áriostipos 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  Osints 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  Constantespodem 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 pontoflutuante  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  Representadoscom 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 cadeiasde 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 usaa 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çãobarra-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 stringpodem 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
  • 40.
    Strings – Fatias(slices) >>> a 'abcde' >>> a[0:2] 'ab' >>> a [2:] 'cde' >>> a[:] 'abcde' >>> a[-1:] 'e' >>> a[:-1] 'abcd'
  • 41.
    Expressões booleanas  Tambémchamadas 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  Asconstantes 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 >>> 0or 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émdos 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
  • 46.
    Funções Embutidas >>> abs(10) 10 >>> abs (-19) 19 >>> chr (95) '_' >>> chr (99) 'c' >>> ord ('a') 97
  • 47.
    Importando módulos  Muitasfunçõ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  Porexemplo:  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 >>> importmath >>> 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 emprogramaçã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 emprogramaçã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 programaque 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 comandoinput 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  É semelhanteao 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 umaseqüê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  Comoem 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  É ocomando 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 dadosabstrata  É 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 arranjosseqü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 eRepetiçã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  Ooperador 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 afatias  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”  Permitesaber 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  Nouso 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 emax  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  Permiteiterar 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  Listassã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ê!
  • 86.
    Comparando listas >>> [1,2]< [2, 3] True >>> [1,2] < [1, 2, 3] True >>> [1,2] != [1,2] False >>> min([[1],[2,3],[3,4],[]]) [] >>> max([[1],[2,3],[3,4],[]]) [3, 4] >>> min(0,[],"") 0 >>> max(0,[],"") ''
  • 87.
    Variáveis do tipolist  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 tipolist >>> 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 daclasse 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 daclasse 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 daclasse 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 daclasse 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 daclasse 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 daclasse 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 daclasse 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 daclasse list  reverse()  Inverte a ordem dos elementos da lista  Ex.: >>> lista=[1,2,3] >>> lista.reverse() >>> lista [3, 2, 1]
  • 98.
    Alguns métodos daclasse 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 daclasse 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 daclasse 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 daclasse 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 podemser 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 fori 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 estruturasde 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 tuplavazia 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 deformataçã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  Umtemplate 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çõesde 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 umatabela 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])
  • 115.
    Exemplo: resultados -------------------------- Item Preço -------------------------- Abacate2.13 Limão 0.19 Tangerina 1.95 Melancia 0.87 Laranja da China 12.00
  • 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 lowere 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 estruturasde 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  Umaconstante 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
  • 129.
    Exemplo >>> dic ={"joao":100,"maria":150} >>> dic["joao"] 100 >>> dic["maria"] 150 >>> dic["pedro"] = 10 >>> dic {'pedro': 10, 'joao': 100, 'maria': 150} >>> dic = {'joao': 100, 'maria': 150, 'pedro': 10} >>> dic {'pedro': 10, 'joao': 100, 'maria': 150}
  • 130.
    Dicionários não têmordem  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, keyse 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  É umaté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  EmPython, 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
  • 147.
    Exemplo >>> def f(): return >>>print f() None >>> def f(): return "Oi" >>> print f() Oi >>> def f(nome): return "Oi, "+nome+"!" >>> print f("Joao") Oi, Joao!
  • 148.
    Variáveis locais eglobais  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(): printa >>> 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): returnx*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
  • 153.
    Exemplo >>> def f(nome,saudacao="Oi",pontuacao="!!"): returnsaudacao+","+nome+pontuacao >>> print f("Joao") Oi,Joao!! >>> print f("Joao","Parabens") Parabens,Joao!! >>> print f("Joao","Ah","...") Ah,Joao...
  • 154.
    Passando argumentos comnomes  É 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  Noteque 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
  • 157.
    Exemplo >>> def f(x): x[:]= [5] >>> a = [1] >>> f(a) >>> a [5] >>> b = a >>> b[:] = [7] >>> a [7]
  • 158.
    Documentando Funções  Aoinvé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âmetrosvariá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âmetrosvariá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âmetrosvariá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  Nomesde 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()  Odicioná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 emfunçõ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 emfunçõ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ãopequenas 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ãopequenas 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 (lambdaa,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  É umprincí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  Implementaum 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 deftesta(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  Assimcomo 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çõesrecursivas  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  Aoinvé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 defe_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 dadosrecursivas  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 todasas 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
  • 188.
    Torres de Hanói:Exemplo | | | * | | *** | | ***** | | ======================= | | | | | | *** | | ***** * | ======================= | | | | | | | | | ***** * *** ======================= | | | | | | | | * ***** | *** ======================= | | | | | | | | * | ***** *** ======================= | | | | | | | | | * ***** *** ======================= | | | | | | | *** | * ***** | ======================= | | | | * | | *** | | ***** | =======================
  • 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  É oque 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  É oque 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 umaclasse  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
  • 197.
    Exemplo >>> class C: definit(self,a=2,b=3): self.a = a self.b = b def f(self,x): return self.a*x+self.b >>> obj1 = C() >>> obj1.init(2,3) >>> obj2 = C() >>> obj2.init(8,1) >>> obj1.f(7) 17 >>> obj2.f(7) 57
  • 198.
    Atributos herdados daclasse  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étodocomo 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)
  • 200.
    Exemplo >>> class C: def__init__(self,a=2,b=3): self.a = a self.b = b def f(self,x): return self.a*x+self.b >>> obj1 = C() >>> obj2 = C(8,1) >>> obj1.f(7) 17 >>> obj2.f(7) 57
  • 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  Emprincí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ãomé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
  • 208.
    Exemplo >>> class vetor: def__init__(self,x,y): self.x, self.y = x,y def __add__(self,v): return vetor(self.x+v.x, self.y+v.y) def __sub__(self,v): return vetor(self.x-v.x, self.y-v.y) def __repr__(self): return "vetor("+str(self.x)+","+str(self.y)+")" >>> a=vetor(1,2) >>> a += vetor(3,5) >>> a-vetor(2,2) vetor(2,5) >>> print a vetor(4,7)
  • 209.
    Protocolos  Diferentemente deoutras 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 eSetters  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
  • 213.
    Exemplo >>> class Retangulo: def__init__(self,tamanho): self.setTamanho(tamanho) def setTamanho(self,tamanho): if min(tamanho)<0: raise ValueError self.__tamx,self.__tamy = tamanho def getTamanho(self): return (self.__tamx,self.__tamy) >>> r = Retangulo((20,30)) >>> r.getTamanho() (20, 30) >>> r.setTamanho((-1,0)) Traceback (most recent call last): ... ValueError
  • 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
  • 215.
    Exemplo >>> class Retangulo: def__init__(self,tamanho): self.setTamanho(tamanho) def setTamanho(self,tamanho): if min(tamanho)<0: raise ValueError self.__tamx,self.__tamy = tamanho def getTamanho(self): return (self.__tamx,self.__tamy) tamanho = property(getTamanho,setTamanho) >>> r = Retangulo((20,30)) >>> r.tamanho (20, 30) >>> r.tamanho = (30,30) >>> r.tamanho (30, 30)
  • 216.
    Dicas para usode 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 umprograma 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çõesexcepcionais 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 deExceçã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 Classede 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  Paracapturar 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
  • 231.
    A cláusula else É possível completar um comando try com uma cláusula else que introduz um trecho de código que só é executado quando nenhuma exceção ocorre: try: Código except Exceções: Código de tratamento da exceção else: Código executado se não ocorrem exceções
  • 232.
    Exemplo 6 >>> whileTrue: try: a = input("Entre com um numero ") b = input("Entre com outro numero ") print a, "/", b, "=", a/b except Exception,e: print "Deu bode:",e print "Tente novamente" else: break Entre com um numero 1 Entre com outro numero xxx Deu bode: name 'xxx' is not defined Tente novamente Entre com um numero 1 Entre com outro numero 2 1 / 2 = 0
  • 233.
    A cláusula finally A cláusula finally pode ser usada para se assegurar que mesmo que ocorra algum erro, uma determinada seqüência de comandos vai ser executada  Pode ser usada para restabelecer alguma variável para um valor default, por exemplo  Até a versão 2.4 do python, as cláusula finally e except eram mutuamente exclusivas  Exceções nesse caso não eram tratadas  Era possível combinar ambas usando comandos try aninhados
  • 234.
    Exemplo 7 (Python2.5) >>> try: ... x = input("Entre com um número") ... except: ... print "Deu Bode" ... finally: ... print "restabelecendo um valor para x" ... x = None ... Entre com um número 1xx Deu Bode restabelecendo um valor para x
  • 235.
    Exemplo 7 (Python2.4) >>> try: ... try: ... x = input("Entre com um número") ... finally: ... print "restabelecendo um valor para x" ... x = None ... except: ... print "Deu Bode" ... Entre com um número 1xx restabelecendo um valor para x Deu Bode
  • 236.
    Iteradores  São maneirasgenéricas de implementar iterações com classes  Permite o uso do comando for  É muitas vezes mais econômico do que usar uma lista pois não é preciso armazenar todos os valores, mas apenas computar um por vez  Um iterador é uma classe que implementa o método mágico __iter__  É um método que, por sua vez, retorna um objeto que implementa um método chamado next  O método next deve retornar o “próximo” valor a ser iterado  Se não há próximo valor, next deve “levantar” a exceção StopIteration
  • 237.
    Exemplo >>> class MeuIterador: a= 0 def __iter__(self): return self def next(self): if self.a>10: raise StopIteration self.a += 1 return self.a >>> iter = MeuIterador() >>> for i in iter: print i, 1 2 3 4 5 6 7 8 9 10 11
  • 238.
    Geradores  Geradores sãofunções especiais que retornam iteradores  Em resumo, uma função geradora é uma que contém a o comando yield valor  Uma função geradora normalmente é chamada para obter o iterador para um comando for  O comando for automaticamente iterará sobre todos os valores que yield “retorna”  Observe que o iterador produzido pela função geradora é tal que o código que gera os valores e o código dentro do for se sucedem alternadamente  Geradores são especialmente úteis em códigos recursivos
  • 239.
    Exemplo >>> def gerador(): fori in range(10): print "i = ", i yield i >>> for j in gerador(): print "j = ",j i = 0 j = 0 i = 1 j = 1 .... i = 9 j = 9
  • 240.
    Módulos  Módulos sãoprogramas feitos para serem reaproveitados em outros programas  Eles tipicamente contêm funções, variáveis, classes e objetos que provêm alguma funcionalidade comum  Por exemplo, já vimos que o módulo math contém funções matemáticas como sin, exp, etc, além da constante pi  Toda a biblioteca padrão do Python é dividida em módulos e pacotes (veremos mais tarde)  Alguns dos mais comuns são: sys, os, time, random, re, shelve
  • 241.
    Escrevendo módulos  Naverdade, qualquer programa que você escreva e salve num arquivo pode ser importado como um módulo  Por exemplo, se você salva um programa com o nome prog.py, ele pode ser importado usando o comando import prog  Entretanto, a “importação” só ocorre uma vez  Python assume que variáveis e funções não são mudados e que o código do módulo serve meramente para inicializar esses elementos  Após a importação de um módulo, este é compilado, gerando um arquivo .pyc correspondente  No exemplo, um arquivo prog.pyc será criado  Python só recompila um programa se o arquivo .py for mais recente que o arquivo .pyc
  • 242.
    Exemplo (em Unix) $cat teste.py def f(): print "alo" f() $ python ... >>> import teste alo >>> import teste >>> teste.f() alo >>> $ dir teste* teste.py teste.pyc
  • 243.
    Tornando módulos disponíveis Em que diretório os módulos são buscados durante a importação?  No diretório corrente  Nos diretórios da lista sys.path  Se for desejável especificar o local onde os módulos residem, há essencialmente duas opções  Alterar diretamente a variável sys.path  Alterar a variável de ambiente PYTHONPATH  É o método recomendável pois não requer que o programa que importará o módulo seja alterado
  • 244.
    Exemplo $ mkdir python $mv teste.py python/ $ cat python/teste.py def f(): print "alo" f() $ export PYTHONPATH=~/python $ python Python 2.4.2 (#2, Sep 30 2005, 21:19:01) ... >>> import teste alo
  • 245.
    A variável __name__ Se um programa pode ser executado por si só ou importado dentro de outro, como distinguir as duas situações?  A variável __name__ é definida para cada programa:  Se é um módulo, retorna o nome do módulo  Se é um programa sendo executado, retorna '__main__'  Para saber se o código está sendo executado como módulo, basta testar:  If __name__ == '__main__': código  Isto é útil em diversas circunstâncias  Por exemplo, para colocar código de teste, código para instalação do módulo ou exemplos de utilização
  • 246.
    Exemplo $ cat teste.py deff(): print "alo" if __name__ == '__main__': f() $ python teste.py alo $ python Python 2.4.2 (#2, Sep 30 2005, 21:19:01) ... >>> import teste >>> print __name__ __main__ >>> print teste.__name__ teste
  • 247.
    Pacotes  São hierarquiasde módulos  Um pacote é um diretório que contém um arquivo chamado __init__.py  O pacote deve estar em um dos diretórios nos quais o Python busca por módulos  Para importar o pacote, use o nome do diretório  O programa correspondente ao pacote é __init__.py  Os demais arquivos e diretórios dentro do pacote são encarados recursivamente como módulos  Por exemplo, se um pacote se chama p e contém um arquivo chamado m.py, então podemos importar  p (arquivo p/__init__.py)  p.m (arquivo p/m.py)  Semelhantemente, p poderia ter um outro pacote sob a forma de outro diretório contendo um arquivo __init__.py
  • 248.
    Exemplo $ dir python/ pacoteteste.py $ dir python/pacote/ __init__.py teste2.py $ cat python/teste.py print "teste" $ cat python/pacote/__init__.py print "pacote" $ cat python/pacote/teste2.py print "teste2" $ python ... >>> import teste teste >>> import pacote pacote >>> import pacote.teste2 teste2
  • 249.
    Arquivos  Entrada esaída são operações de comunicação de um programa com o mundo externo  Essa comunicação se dá usualmente através de arquivos  Arquivos estão associados a dispositivos  Por exemplo, disco, impressora, teclado  Em Python, um arquivo pode ser lido/escrito através de um objeto da classe file
  • 250.
    Arquivos default  Jáusamos, sem saber, três arquivos default  Sempre que um comando print é executado, o resultado vai para um arquivo chamado sys.stdout  Sempre que lemos um dado através do comando input ou raw_input, na verdade estamos lendo de um arquivo chamado sys.stdin  Mensagens de erro ou de rastreamento de exceções são enviadas para um arquivo chamado sys.stderr
  • 251.
    Exemplo >>> import sys >>>sys.stdout.write("alo") alo >>> print "alo" alo >>> sys.stdin.readline() sfadfas 'sfadfasn' >>> raw_input() fasdfadsf 'fasdfadsf'
  • 252.
    Redirecionamento  Os arquivossys.stdin, sys.stdout e sys.stderr normalmente estão associados ao teclado e ao display do terminal sendo usado, mas podem ser reassociados a outros dispositivos  Em Unix/Linux e Windows:  programa > arquivo  Executa programa redirecionando stdout para arquivo  programa < arquivo  Executa programa redirecionando stdin de arquivo  programa1 | programa2  Executa programa1 e programa2 sendo que a saída de programa1 é redirecionanda para a entrada de programa2  Em Linux com shell bash  programa 2> arquivo  Executa programa redirecionando stderr para arquivo
  • 253.
    Abrindo arquivos  open(name, mode, buffering)  name : nome do arquivo a abrir  mode : (opcional) modo de abertura – string contendo  r : leitura (default)  w : escrita  b : binário  a : escrita a partir do final  + : (usado com r) indica leitura e escrita  buffering : (opcional) indica se memória (buffers) é usada para acelerar operações de entrada e saída  0 : buffers não são usados  1 (ou qq número negativo): um buffer de tamanho padrão (default)  2 ou maior: tamanho do buffer em bytes
  • 254.
    O objeto file O comando open retorna um objeto do tipo file (arquivo)  Na verdade, em Python 2.4 em diante, open é o mesmo que file, e portanto o comando é um construtor  O objeto retornado é usado subseqüentemente para realizar operações de entrada e saída: >>> arq = open ("teste", "w") >>> arq.write ("Oi") >>> arq.close () >>> arq = open ("teste") >>> x = arq.read() >>> x 'Oi'
  • 255.
    Métodos Read, Writee Close  read(num)  Lê num bytes do arquivo e os retorna numa string  Se num não é especificado, todos os bytes desde o ponto atual até o fim do arquivo são rretornados  write(string)  Escreve string no arquivo  Devido ao uso de buffers, a escrita pode não ser feita imediatamente  Use o método flush() ou close() para assegurar a escrita física  close()  Termina o uso do arquivo para operações de leitura e escrita
  • 256.
    Convenção de fimde linha  Arquivos de texto são divididos em linhas usando caracteres especiais  Linux/Unix: n  Windows: rn  Mac: r  Python usa sempre n para separar linhas  Ao se ler/escrever um arquivo aberto em modo texto (não binário) faz traduções de n para se adequar ao sistema operacional  Em modo binário, entretanto, a conversão não é feita
  • 257.
    Interação com oSistema Operacional  Operações de entrada e saída são na verdade realizadas pelo sistema operacional  O módulo os possui diversas variáveis e funções que ajudam um programa Python a se adequar ao sistema operacional, por exemplo:  os.getcwd() retorna o diretório corrente  os.chdir(dir) muda o diretório corrente para dir  os.sep é uma string com o caractere que separa componentes de um caminho ('/' para Unix, '' para Windows)  os.path.exists(path) diz se path se refere ao nome de um arquivo existente
  • 258.
    Lendo e escrevendolinhas  readline(n)  Se n não é especificado, retorna exatamente uma linha lida do arquivo  Caso contrário, lê uma linha, mas busca no máximo n caracteres pelo final de linha  readlines(n)  Se n não é especificado, retorna o restante do conteúdo do arquivo em uma lista de strings  Caso n seja especificado, a leitura é limitada a n caracteres no máximo  writelines(seqüência)  Escreve a lista (ou qualquer seqüência) de strings, uma por uma no arquivo  Caracteres terminadores de linha não são acrescentados
  • 259.
    Acesso direto  Épossível ler e escrever não seqüencialmente em alguns tipos de arquivo  Devem estar associados a dispositivos que permitem acesso direto, como discos, por exemplo  seek(offset,whence)  offset indica o número do byte a ser lido e escrito pela próxima operação de entrada e saída  whence indica a partir de onde offset será contado  0 (default) : do início  1 : do ponto corrente  2 : do final  tell()  Indica a posição corrente (número de bytes a partir do início do arquivo)
  • 260.
    Interfaces Gráficas  Tambémchamadas de Graphical User Interfaces (GUI)  Usadas em aplicações modernas que requerem uma interação constante com o usuário  Maior usabilidade e naturalidade do que interfaces textuais  Aplicação apresenta uma ou mais janelas com elementos gráficos que servem para comandar ações, especificar parâmetros, desenhar e exibir gráficos, etc  Bibliotecas (toolkits) para construção de interfaces como  Qt  Gtk  wxWindows  Tk
  • 261.
    Interfaces Gráficas emPython  Python possui camadas de portabilidade (bindings) para várias bibliotecas de construção de interfaces. Ex.:  PyQt (Qt)  PyGtk (Gtk)  wxPython (wxWindows)  Tkinter (Tk)  Multiplataforma (MS-Windows, Unix/Linux, OSX)
  • 262.
    Tk  Toolkit originalmentecriado para utilização com a linguagem script Tcl  Bastante leve, portátil e robusto  Um tanto obsoleto frente a outros toolkits mais modernos como Qt ou Gtk  Camada Tkinter normalmente distribuída com o Python  Inicia um processo Tcl que toma conta dos elementos de interface  Classes e funções do Tkinter se comunicam com o interpretador Tcl para especifcar aspecto e comportamento da interface
  • 263.
    Usando Tkinter  Importaro módulo Tkinter  from Tkinter import *  Elementos de interface (widgets) correspondem a objetos de diversas classes. Por exemplo:  Frame (Área retangular)  Button (botão)  Label (rótulo)  Text (caixa de texto)  Canvas (caixa de desenho)  Posição e tamanho dos elementos controlados por gerentes de geometria  Pack (mais comum), Place, Grid
  • 264.
    Usando Tkinter (2) Para criar um widget, tem-se que informar o widget-pai (parâmetro master) onde geometricamente deverá ser encaixado e as opções de configuração para o widget. Ex.: w = Button(pai,text=”Cancelar”,command=cancelar)  Tk já define por default uma janela principal  master=None (default) indica que o widget será filho da janela principal  Outras janelas pode ser criadas criando objetos da classe Toplevel  A função mainloop tem que ser invocada para que a aplicação entre no modo de tratamento de eventos
  • 265.
    Exemplo from Tkinter import* class Application(Frame): def __init__(self, master=None): Frame.__init__(self, master) self.msg = Label(self, text="Hello World") self.msg.pack () self.bye = Button (self, text="Bye", command=self.quit) self.bye.pack () self.pack() app = Application() mainloop()
  • 266.
    Exemplo from Tkinter import* class Application(Frame): def __init__(self, master=None): Frame.__init__(self, master) self.msg = Label(self, text="Hello World") self.msg.pack () self.bye = Button (self, text="Bye", command=self.quit) self.bye.pack () self.pack() app = Application() mainloop()
  • 267.
    Exemplo from Tkinter import* class Application(Frame): def __init__(self, master=None): Frame.__init__(self, master) self.msg = Label(self, text="Hello World") self.msg.pack () self.bye = Button (self, text="Bye", command=self.quit) self.bye.pack () self.pack() app = Application() mainloop() Elemento principal derivado de Frame Construtor da classe base Janela tem um rótulo e um botão Interface é instanciada Laço de tratamento de eventos é iniciado
  • 268.
    Classes de componentes Button Um botão simples usado para executar um comando  Canvas Provê facilidades de gráficos estruturados  Checkbutton Representa uma variável que pode ter dois valores distintos (tipicamente um valor booleano). Clicando no botão alterna-se entre os valores  Entry Um campo para entrada de uma linha de texto  Frame Usado como agrupador de widgets  Label Mostra um texto ou uma imagem  Listbox Mostra uma lista de alternativas. Pode ser configurado para ter comportamento de checkbutton ou radiobutton
  • 269.
    Classes de componentes(cont.)  Menu Um painel de menu. Implementa menus de janela, pulldowns e popups  Message Similar ao widget Label, mas tem mais facilidade para mostrar texto quebrado em linhas  Radiobutton Representa um possível valor de uma variável que tem um de muitos valores. Clicando o botão, a variável assume aquele valor  Scale Permite especificar um valor numérico através de um ponteiro em uma escala linear  Scrollbar Barra de rolamento para widgets que têm superfície útil variável (Text, Canvas, Entry, Listbox)  Text Exibe e permite editar texto formatado. Também suporta imagens e janelas embutidas  Toplevel Uma janela separada
  • 270.
    A Classe Tk É a que define uma janela principal e o interpretador Tcl  Em geral, nunca precisa ser instanciada  É instanciada automaticamente quando um widget filho é criado  Pode ser instanciada explicitamente  Possui vários métodos, entre os quais  title (string) Especifica o título da janela  geometry(string) Especifica tamanho e posição da janela  String tem a forma larguraxaltura+x+y
  • 271.
    Exemplo from Tkinter import* class Application(Frame): def __init__(self, master=None): Frame.__init__(self, master) self.msg = Label(self, text="Hello World") self.msg.pack () self.bye = Button (self, text="Bye", command=self.quit) self.bye.pack () self.pack() app = Application() app.master.title("Exemplo") app.master.geometry("200x200+100+100") mainloop()
  • 272.
    Opções de Widgets Widgets (elementos de interface) têm opções com nomenclatura unificada. Ex.:  text Texto mostrado no elemento  background cor de fundo  foreground cor do texto  font fonte do texto  relief relevo da borda ('flat', 'raised', 'ridge', 'sunken', 'groove')  Opções são especificadas  No construtor  Através do método configure
  • 273.
    Exemplo from Tkinter import* top = Frame() ; top.pack() rotulo = Label (top, text="Rótulo Exemplo", foreground="blue") rotulo.pack () rotulo.configure(relief="ridge", font="Arial 24 bold", border=5, background="yellow")
  • 274.
    O método configure Usado com pares do tipo opção=valor, modifica os valores dos atributos  Usado com uma string “nomeopção” retorna a configuração da opção com esse nome  A configuração é uma tupla com 5 valores  nome do atributo  nome do atributo no banco de dados (X11)  nome da classe no banco de dados (X11)  objeto que representa a opção  valor corrente da opção  Se configure é usado sem argumentos, retorna um dicionário com todas as opções  Pode-se obter diretamente o valor de uma opção usando o método cget
  • 275.
    Exemplo >>> rotulo.configure(relief="ridge") >>> rotulo.configure("relief") ('relief','relief', 'Relief', <index object at 0x85f9530>, 'ridge') >>> rotulo.configure()["relief"] ('relief', 'relief', 'Relief', <index object at 0x85f9530>, 'ridge') >>> rotulo.configure("relief")[4] 'ridge' >>> rotulo.cget("relief") 'ridge'
  • 276.
    Gerenciando geometrias  Todosos elementos de interface ocupam uma área retangular na janela  A posição e tamanho de cada elemento é determinada por um gerenciador de geometria  O elemento não “aparece” enquanto não for informado ao gerenciador  A geometria resultante depende de  Propriedades dos elementos (tamanho mínimo, tamanho da moldura, etc)  Opções do gerenciador  Algoritmo usado pelo gerenciador  O gerenciador mais usado em Tk é o pack
  • 277.
    Usando o pack Para informar que um elemento deve ser gerenciado pelo pack, use o método pack (opções)  O pack considera o espaço do elemento “pai” como uma cavidade a ser preenchida pelos elementos filhos  O algoritmo usado pelo pack consiste em empacotar os filhos de um elemento “pai” segundo o lado (side) especificado  Os lados possíveis são 'top', 'left', 'right' e 'bottom'  Deve-se imaginar que sempre que um elemento filho escolhe um lado, a cavidade disponível fica restrita ao lado oposto
  • 278.
    Exemplo from Tkinter import* top = Frame() ; top.pack() a = Label (top, text="A") ; a.pack (side="left") b = Label (top, text="B") ; b.pack (side="bottom") c = Label (top, text="C") ; c.pack (side="right") d = Label (top, text="D") ; d.pack (side="top") for widget in (a,b,c,d): widget.configure(relief="groove", border=10, font="Times 24 bold") top.mainloop()
  • 279.
    Redimensionamento  Por default,o pack não redimensiona os filhos quando o pai é redimensionado  Duas opções controlam o redimensionamento dos filhos  expand (booleano)  Se verdadeiro, indica que o filho deve tomar toda a cavidade disponível no pai  Caso contrário, toma apenas o espaço necessário (default)  fill ('none', 'x', 'y' ou 'both')  Indica como o desenho do elemento irá preencher o espaço alocado  'x' / 'y' indica que irá preencher a largura / altura  'both' indica preenchimento de todo o espaço  'none' indica que apenas o espaço necessário será ocupado (default)
  • 280.
    Exemplo from Tkinter import* top = Frame() ; top.pack() a = Label (top, text="A") ; a.pack (side="left", fill="y") b = Label (top, text="B") ; b.pack (side="bottom", fill="x") c = Label (top, text="C") ; c.pack (side="right") d = Label (top, text="D") ; d.pack (side="top") for widget in (a,b,c,d): widget.configure(relief="groove", border=10, font="Times 24 bold") top.mainloop()
  • 281.
    Exemplo from Tkinter import* top = Frame() ; top.pack(fill='both', expand=True) a = Label (top, text="A") ; a.pack (side="left",fill="y") b = Label (top, text="B") ; b.pack (side="bottom",fill="x") c = Label (top, text="C") ; c.pack (side="right") d = Label (top, text="D") ; d.pack (side="top") for widget in (a,b,c,d): widget.configure(relief="groove", border=10, font="Times 24 bold") top.mainloop()
  • 282.
    Exemplo from Tkinter import* top = Frame() ; top.pack(fill='both', expand=True) a = Label (top, text="A") ; a.pack (side="left",expand=True,fill="y") b = Label (top, text="B") ; b.pack (side="bottom",expand=True,fill="both") c = Label (top, text="C") ; c.pack (side="right") d = Label (top, text="D") ; d.pack (side="top") for widget in (a,b,c,d): widget.configure(relief="groove", border=10, font="Times 24 bold") top.mainloop()
  • 283.
    Usando frames  Framespodem ser usados para auxiliar no layout dos elementos com pack. Ex.: from Tkinter import * top = Frame() ; top.pack(fill='both', expand=True) f = Frame (top); f.pack (fill='x') a = Label (f, text="A") b = Label (f, text="B") c = Label (f, text="C") d = Label (top, text="D") for w in (a,b,c,d): w.configure(relief="groove", border=10, font="Times 24 bold") w.pack(side="left", expand=True, fill="both") top.mainloop()
  • 284.
    Programação com eventos Diferente da programação convencional  O programa não está sob controle 100% do tempo  Programa entrega controle ao sistema  Em Tk: método(função) mainloop  Interação gera eventos. Ex:  Acionamento de um menu ou de um botão  Mouse arrastado sobre uma janela  Uma caixa de texto teve seu valor alterado  O tratamento de um evento é feito por uma rotina “Callback”
  • 285.
    A opção command Muitos componentes do Tk suportam a opção command que indica uma função a ser invocada sempre que o widget é acionado  Tipicamente, a função (ou método) usado obtém valores de outros widgets para realizar alguma operação
  • 286.
    Exemplo from Tkinter import* def inc(): n=int(rotulo.configure("text")[4])+1 rotulo.configure(text=str(n)) b = Button(text="Incrementa",command=inc) b.pack() r = Label(text="0") r.pack() mainloop()
  • 287.
    Eventos e Bind Widgets que não dispõem da opção command também podem receber eventos e responder a eles  O método bind permite especificar um padrão de eventos ao qual o widget será sensível e uma rotina callback para tratá-lo bind(padrão,rotina)  padrão é uma string que descreve quais eventos a rotina irá tratar  rotina é uma função ou método com exatamente um parâmetro: o evento que deve ser tratado
  • 288.
    Exemplo from Tkinter import* def clica (e): txt = "Mouse clicado emn%d,%d"%(e.x,e.y) r.configure(text=txt) r = Label() r.pack(expand=True, fill="both") r.master.geometry("200x200") r.bind("<Button-1>", clica) mainloop()
  • 289.
    Campos do objetoevento  x,y : posição do mouse com relação ao canto superior esquerdo do widget  x_root, y_root: posição do mouse com relação ao canto superior esquerdo da tela  char: caractere digitado (eventos de teclado)  keysym: representação simbólica da tecla  keycode: representação numérica da tecla  num: número do botão – 1/2/3=Esquerdo/Meio/Direito – (eventos de mouse)  widget: o objeto que gerou o evento  width,height: largura e altura do widget (evento Configure)
  • 290.
    Padrões de evento(mouse)  <Button-i> para i = 1,2,3: botão i do mouse pressionado sobre o widget  <Motion> : mouse arrastado sobre o widget  <Bi-Motion> : mouse arrastado sobre o widget com o botão i pressionado  <ButtonRelease-i> : botão i do mouse solto sobre o widget  <Double-Button-i>: botão i do mouse clicado duas vezes em seguida  <Enter>: O mouse entrou na área do widget  <Leave>: O mouse saiu da área do widget
  • 291.
    Padrões de evento(teclado)  caracter : O caracter foi digitado sobre o widget  <Key>: Algum caracter foi digitado sobre o widget  <Return>: Tecla enter foi digitada  <Tab>, <F1>, <Up>...: A tecla correspondente foi digitada  <Shift-Tab>, <Alt-F1>, <Ctrl-Up>...: Tecla com modificador  Para os eventos serem gerados, é preciso que o foco de teclado esteja sobre o widget  Depende do sistema de janelas  O foco para um widget pode ser forçado usando o método focus
  • 292.
    Exemplo from Tkinter import* def clica (e): txt = "Mouse clicado emn%d,%d"%(e.x,e.y) r.configure(text=txt) r.focus() def tecla(e): txt="Keysym=%snKeycode=%snChar=%s" %(e.keysym,e.keycode,e.char) r.configure(text=txt) r = Label() r.pack(expand=True, fill="both") r.master.geometry("200x200") r.bind("<Button-1>", clica) r.bind("<Key>", tecla)
  • 293.
    Menus  Podem serassociados a uma janela (menus toplevel), pulldown, popup e em cascata a partir de outro menu  Todos são instâncias da classe Menu  Um menu é composto de itens que podem ser  command quando pressionado executa uma callback  checkbox parecido com command, mas tem um valor booleano associado  radiobutton como command, mas representa um de vários estados mutuamente exclusivos  cascade ativa um outro menu em cascata  Para adicionar um item a um menu, use métodos da forma add (“tipo”, opções) ou add_tipo(opções)
  • 294.
    Menu de janela(toplevel)  É tipicamente exibido horizontalmente no topo da janela  Aspecto depende do sistema operacional  Se um outro menu é associado como item cascade, ele é tratado como pulldown, isto é, é exibido sob o item do menu de janela  Assim como outros menus, não necessita ter sua geometria gerenciada (e.g., pack ou grid)  Para associar a uma janela, usa-se a opção menu do objeto janela.
  • 295.
    Exemplo from Tkinter import* def abrir(): print "abrir" def salvar(): print "salvar" def ajuda() : print "ajuda" top=Tk() principal=Menu(top) arquivo=Menu(principal) arquivo.add_command(label="Abrir",command=abrir) arquivo.add_command(label="Salvar",command=salvar) principal.add_cascade(label="Arquivo",menu=arquivo) principal.add_command(label="Ajuda",command=ajuda) top.configure(menu=principal)
  • 296.
    Menus Popup  Ummenu popup é aquele que é exibido numa janela independente  Para que o menu seja exibido, é preciso invocar o método post: post (x, y)  onde x e y são as coordenadas do canto superior esquerdo do menu com relação ao canto superior esquerdo da tela
  • 297.
    Exemplo from Tkinter import* def alo(): print "Alo!" root = Tk() menu = Menu(root, tearoff=0) menu.add_command(label="Alo 1", command=alo) menu.add_command(label="Alo 2", command=alo) def popup(e): menu.post(e.x_root, e.y_root) frame = Frame(root, width=200, height=200) frame.pack() frame.bind("<Button-3>", popup) mainloop()
  • 298.
    Variáveis  Tk écontrolado por um interpretador Tcl (e não diretamente pelo python)  Em alguns casos, deseja-se usar usar variáveis na interface  Por exemplo, é possível especificar que o texto exibido em um Label é o valor de uma variável (e não uma constante)  Nesse caso, usa-se a opção textvar ao inves de text  Variáveis Tcl são expostas à aplicaçãoPython através das classes StringVar, IntVar e DoubleVar  O construtor é da forma StringVar(master) onde master é uma janela ou widget  Instâncias dessas classes possuem os métodos get e set que podem ser usados para acessar os valores armazenados no interpretador Tcl
  • 299.
    Exemplo from Tkinter import* root = Tk() soma = DoubleVar(root) parcela = DoubleVar(root) def aritmetica (e): soma.set(soma.get()+parcela.get()) lsoma = Label(textvar=soma) eparcela = Entry(textvar=parcela) eparcela.bind("<Return>", aritmetica) lsoma.pack() eparcela.pack()
  • 300.
    Checkbuttons  Checkbutton Representauma variável que pode ter dois valores distintos (tipicamente um valor booleano). Clicando no botão alterna-se entre os valores  A callback especificada pela opção command é chamada sempre que a variável muda de valor  Estado é armazenado pela variável Tcl especificada pela opção variable  Se a variável é inteira, o valor correspondente ao checkbutton “desligado”/“ligado” é 0/1  É possível usar um checkbutton com uma variável string  Nesse caso, os valores correspondentes a “desligado”/“ligado” são especificados com as opções offvalue e onvalue
  • 301.
    Exemplo from Tkinter import* root = Tk() v1 = IntVar(root) v2 = StringVar(root) def exibe(): l.config (text="v1=%d,v2=%s"%(v1.get(),v2.get())) c1 = Checkbutton (text="V1", var=v1, command=exibe) c2 = Checkbutton (text="V2", var=v2, command=exibe, onvalue="Sim", offvalue="Nao") l = Label() for w in (c1,c2,l):w.pack() exibe()
  • 302.
    Exemplo from Tkinter import* root = Tk() v1 = IntVar(root) v2 = StringVar(root) def exibe(): l.config (text="v1=%d,v2=%s"%(v1.get(),v2.get())) c1 = Checkbutton (text="V1", var=v1, command=exibe) c2 = Checkbutton (text="V2", var=v2, command=exibe, onvalue="Sim", offvalue="Nao") l = Label() for w in (c1,c2,l):w.pack() exibe()
  • 303.
    Radiobuttons  Radiobutton representaum possível valor de uma variável que tem um de muitos valores. Clicando o botão, a variável assume aquele valor  A variável é especificada com a opção variable e o valor associado com a opção value  Os radiobuttons que se referem à mesma variável funcionam em conjunto  Ex.: ligar um faz com que outro seja desligado  Um radiobutton é mostrado com um indicador ao lado  Pode-se desabilitar o indicador usando a opcao indicatoron=False  Nesse caso, é mostrado como um botão normal
  • 304.
    Exemplo from Tkinter import* root=Tk() cor = StringVar(root) cor.set("black") l = Label(background=cor.get()) l.pack(fill='both',expand=True) def pinta(): l.configure(background=cor.get()) for txt,val in (("preto","black"), ("vermelho","red"), ("azul","blue"), ("verde","green")): Radiobutton(text=txt,value=val,variable=cor, command=pinta).pack(anchor=W) mainloop()
  • 305.
    Exemplo from Tkinter import* root=Tk() cor = StringVar(root) cor.set("black") l = Label(background=cor.get()) l.pack(fill='both',expand=True) def pinta(): l.configure(background=cor.get()) for txt,val in (("preto","black"), ("vermelho","red"), ("azul","blue"), ("verde","green")): Radiobutton(text=txt,value=val,variable=cor, command=pinta,indicatoron=False).pack(fill='x') mainloop()
  • 306.
    Entry  Um Entrypermite entrada/edição de uma linha de texto  O texto associado ao Entry é normalmente armazenado numa variável indicada pela opção textvariable  Se não indicada, é usada uma variável interna cujo valor pode ser obtido usando o método get()  Há diversos métodos para manipular diretamente o texto  Usam o conceito de índices (não confundir com os índices usado pelo Python)  Por exemplo, o índice INSERT indica a posição do texto onde o cursor de inserção se encontra, 0 a posição antes do primeiro caractere e END a posição ao final do texto
  • 307.
    Exemplo from Tkinter import* def insere(): e.insert(INSERT,"*") def limpa(): e.delete(INSERT,END) e=Entry(font="Arial 24") i=Button(text="Insere*",command=insere) l=Button(text="Limpa",command=limpa) e.pack() for w in (i,l): w.pack(side='left') mainloop()
  • 308.
    Canvas  Permite aexibição e edição de gráficos estruturados 2D  Elementos gráficos (itens) são introduzidos usando métodos da forma create_tipo (...), onde tipo pode ser  arc arco de círculo  bitmap imagem binária  image imagem colorida  line linha poligonal  oval círculos e elipses  polygon polígonos  rectangle retângulo  text texto  window um widget tk
  • 309.
    Exemplo from Tkinter import* c = Canvas() c.pack() o = c.create_oval(1,1,200,100,outline="blue", width=5,fill="red") widget = Button(text="Tk Canvas") w = c.create_window(10,120,window=widget,anchor=W ) l = c.create_line(100,0,120,30,50,60,100,120, fill="black",width=2) r = c.create_rectangle(40,150,100,200,fill="white ") img = PhotoImage(file="python.gif") i = c.create_image (150,150,image=img,anchor=NW) a = c.create_arc (150,90,250,190,start=30,extent=60, outline="green",fill="orange") t = c.create_text(200,35,text="TextonTexto", font="Arial 22")
  • 310.
    Coordenadas de Itens Todos os métodos create_item têm como primeiros argumentos um par de coordenadas x,y do item  Os itens oval e rectangle requerem mais um par de coordenadas para delimitar a extensão (caixa envolvente)  Os itens line e polygon podem ser seguidos por outros pares de coordenadas que especificam demais vértices  As coordenadas referem-se a um sistema de coordenadas próprio que pode ser diferente do da janela  A área do canvas que deve ser mostrada na janela pode ser modificada pela opção scrollarea=(xmin,ymin,xmax,ymax)  Para obter as coordenadas do canvas dadas as coordenadas da janela usa-se os métodos canvasx(x) e canvasy(y)
  • 311.
    Identificação de Itens Todo item de um canvas tem um identificador numérico que é retornado pelo método create_item  Pode-se também associar tags (etiquetas) a itens  Usa-se a opção tags=tags onde tags pode ser uma string ou uma tupla com várias strings  Uma mesma etiqueta pode ser associada a mais de um item  O identificador ALL refere-se a todos os itens do canvas  O identificador CURRENT refere-se ao item do canvas sob o cursor do mouse  Usado em callbacks de canvas para alterar propriedades dos itens clicados
  • 312.
    Métodos de Canvas itemconfig (itemOuTag, ...) altera opções do(s) item(s)  tag_bind(itemOuTag, padrão, callback) associa uma callback a um padrão de eventos sobre o(s) item(s)  delete(itemOuTag) remove o(s) item(s)  move(itemOuTag, dx,dy) translada o(s) item(s)  coords(itemOuTag, x1,x2,..xN,yN) altera as coordenadas do(s) item(s)  coords(item) retorna as coordenadas do item  bbox(itemOuTag) retorna uma tupla com a caixa envolvente dos itens  itemcget(item,opção) retorna o valor da opção dada do item
  • 313.
    Exemplo from Tkinter import* c = Canvas() c.pack() def novalinha(e): x,y = c.canvasx(e.x), c.canvasy(e.y) c.create_line(x,y,x,y,tags="corrente") def estendelinha(e): x,y = c.canvasx(e.x), c.canvasy(e.y) coords = c.coords("corrente") + [x,y] c.coords("corrente",*coords) def fechalinha(e): c.itemconfig("corrente",tags=()) c.bind("<Button-1>", novalinha) c.bind("<B1-Motion>", estendelinha) c.bind("<ButtonRelease-1>", fechalinha) c.pack()
  • 314.
    Exemplo ... def selecionalinha(e): global x0,y0 x0,y0= c.canvasx(e.x), c.canvasy(e.y) c.itemconfig(CURRENT, tags="sel") def movelinha (e): global x0,y0 x1,y1 = c.canvasx(e.x), c.canvasy(e.y) c.move("sel",x1-x0,y1-y0) x0,y0=x1,y1 def deselecionalinha(e): c.itemconfig("sel", tags=()) c.bind("<Button-3>", selecionalinha) c.bind("<B3-Motion>", movelinha) c.bind("<ButtonRelease-3>", deselecionalinha)
  • 315.
    Scrollbar  Barras derolamento são usadas com outros widgets com área útil maior do que pode ser exibida na janela (Canvas, Text, Listbox, Entry)  Uma barra de rolamento horizontal (vertical) funciona chamando o método xview (yview) do widget associado  Isto é feito configurando a opção command da barra  Por outro lado, sempre que a visão do widget muda, a barra de rolamento precisa ser atualizada  Isto é feito configurando a opção xscrollcommand (ou yscrollcommand) do widget ao método set da barra
  • 316.
    Exemplo from Tkinter import* lb = Listbox() lb.pack(side=LEFT,expand=True,fill= "both") sb = Scrollbar() sb.pack(side=RIGHT,fill="y") sb.configure(command=lb.yview) lb.configure(yscrollcommand=sb.set) for i in range(100): lb.insert(END,i)