O documento discute conceitos fundamentais de algoritmos, programas, compiladores, link-editores e interpretadores. Ele também introduz a linguagem de programação Python, discutindo brevemente sua história, versões, aplicações e características.
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
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
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
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
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
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
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ê!
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])
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
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
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
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
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
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 ()
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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.
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
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
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
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)