Apuntes
Programação OO: Python
Contenido del apunte (11)
Página 1
Iniciando
Um Ojeto é uma unidade de software que encapsula e os dados sobre os quais os algoritmos atuam.
Um objeto é um tipo abstrato de dados na prática.
Os seguintes conceitos são importantes:
Polimofismo - Permite que dois objetos diferente possam ser utilizado de forma semelhantes. Possibilitando o aproveitamento de algoritmos.
Abtração - Permitir usar objetos sabendo-se somente a interface que ele oferece.
Herança - Permite criar classes genericas e instancia-las em classes mais especificas.
Polimorfismo:
for i in range( len X ) : print( i , X[i] )
Esse pedaço de software tanto pode ser empregado por uma lista ou uma tupla ( ou até uma string ).
Abstração e Encapsulamento:
O objeto é uma unidade de software, que podemos atribuir objetos, passar objetos como argumentos sem necessariamente saber como o objeto é implementado.
Exemplo Java: pessoa1. peso ; tenho o objeto pessoa1 que pude ter acesso ao atributo peso.
Herança:
É muito importante quando queremos fazer reuso de software. Exemplo: A lista é uma estrutura que podemos inserir, remover e guardar elemento mas temos a fila ( queue) que é uma lista com restrição podemos apenas remover elementos no começo da fila e inserir apenas no final.
O python suporta OO através do conceito de classes. Uma classe pode ser entendida como uma fábrica de objetos. Um objeto fabricado por uma classe podemos dizer que esse objeto é uma instancia dessa classe.
A rigor, uma classe também é um objeto que possui dados e algoritmos mas não é fabricada por nenhum outro classe. Ela definida atravé de um construtor. Deus kkkk
Um objeto tem dados, algoritmos, variáveis e métodos chamamos essas variáveis e métodos de atributos.
Usando OO:
Tratar exceções.
Encapsular métodos e dados.
re-utilizar código.
Definnir class:
class nome ( object ):
var = valor;
def metodo( self, arg1 ):
As variáveis e métodos são escritos precedidos pelo nome da classe e por um ponto( . ).
Assim uma variável v definida em uma classe c pode é escrita como c.v ;
Uma nova instância da classe é criada usando nome().
cod.: ( Maneira padrão de definir uma classe )
class C ( object ):
a = 2 # inicialização da variável a com 2.
b = 3 # inicialiação da variável b com 3.
def f( self, x):
return C.a *x + C.b # atributos da classe
exemplo = C() # Instanciamento da classe em um objeto exemplo
print( exemplo.f( 17 ) )
# Um atributo associado a uma instância obj tem nome obj.atributo
>> C.a = 9
>>> exemplo.f( 17 ) # Obtemos um valor diferente.
Atributos e Intâncias
Frequentimente atributos são associado a instância individuais.
cod.:
class C(object):
def init( self, a = 2 , b =3 ):
self.a = a;
self.b = b;
def f(self, x) :
return self.a*x + self.b
>>>exemplo1 = C()
>>>print( exemplo.f( 17) )
>>> exemplo1.init( 4 , 5 )
>>> exemplo2 = C() # Segundo instanciamento.
cod.:
class Time( object):
## Classe do times de futebol
def __init__( self, nome, campeao , divisao): # Com 3 argumentos
self.nome = nome # Variáveis internas
self.campeao = campeao
self.divisao = divisao
def f( self):
ff = " Eu sou %s. Somos %s." %( self.nome, self.campeao)
print( ff )
def div( self ) :
if( self.divisao ) :
print( " Primeira divisao")
else:
printt( "Segunda divisão")
Página 2
Classes
Atributos herdados da classe .
Método init.
Especialização da classe.
Herença Múltipla.
Atributos privados.
Métodos Mágicos.
Getters, Setters e Propriedades.
Atributoss herdados de uma classe
cod.:
>>> class C(object):
a = 1;
def f(self, x):
self.a += x;
>>> c = C() # instanciamento
>>>c.f(2)
>>>c.a
3
>>>C.a # o valor da variável ( classe ) C é inauterável.
1
Método init
Utilizado para inicializar, um método mágico, que é chamado na instanciação de uma classe.
Python suporta construtores que podem ser chamados automáticamente na criação de instâncias. No caso do __init__ é invocado como padrão.
class C( object ):
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,5)
>>>obj1.f(7)
17
Especialização de classes
Para uma classe C herdar B temos de declarar a classe C da seguinte forma: class C(B):
Dizemos que C é uma sub-classe de B( ou derivada) ou que B é uma super classe ( ou base ) de C.
C herda todos atributos de B.
A especialização de C se dará acrescentando novos atributos ( variáveis e métodos ).
cod.:
class B( object ):
n= 2
def f( self, x):
return B.n * x
class C(B):
def f( self, x) :
return B.f(x)**2
def g(self, x):
return self.f(x) + 1
>>> b = B()
>>> c = C()
>>> b.f(3)
6
>>>c.f(3)
36
>>>B.n = 5
>>>c.f(3)
225
Se desejamos que a classe C seja inicializada devemos fazer explicitamente.
cod.:
class C( object ): # O "object" é uma maneira própria de parametrizar no python 3
def __init__(self):
print( " Construtor de C")
self.x = 1
class D( C) :
def __init__( self ):
print( " Contrutor de D")
C.__init__(self) # Isso não é feito automaticamente devemos inicializa-lo
self..y = 2
>>> d = D()
Construtor de D
Construtor de C
>>> d.x
1
>>> d.y
2
Herança Múltipla
É possível que uma classe herde de 2 ou mais classes, sendo assim devemos escrever da seguinte forma class C( D, E) .
class C(object) :
def __init__( self, a, b):
self.a = a
self.b = b
def f( self, x ):
return self.a*x + self.b
class D( object):
def __init__( self, legenda):
self.legenda = legenda
def escreve( self, valor ):
print( self.legenda, "=", valor)
Atributos privados
A principio todos os atributos podem ser acessados dentro e fora dos objetos. Mas as vezes desejamos limitar o acesso a usuários.
>>> Class C( object ):
def __init__( self, x ) : self.__x = x
def incr( self ):
self.__x += 1
return self.__x
>>>a = C( 5 ) #instanciação
>>> print( a.incr() ) # será impresso o valor
>> a.__x # não conseguiremos acessar o valor pois é uma variável privada.
Métodos Mágicos
Eles permitem redefinir operações de maneira que você possa utilizar de maneira intuitiva : ( . Soma, subtração, representação , etc.
São métodos que são invocados usando operadores sobre o objeto ao invés de ser pelo nome.
cod.:
class vetor:
def __init__( self, x, y ):
self.x , self.y = x , y
def __add__ ( self, v ):
return vetor( self.x+ v.x, self.y+ v.y)
def __repr__(self):
return "vetor(" + str( self.x ) +", " + str( self.y ) + ")"
>>> a = vetor( 1, 2 )
>>> a += vetor( 3, 5 ) #Veja o sinal de "+" foi redefinido pelo método __add__
>>> print( a )
Getters, Setters e Propriedades
Muitas vezes queremos que determinados atributos possam ser acessados de forma controlada, isto é, vigiados por métodos.
Os métodos de que controlam o acesso a tais atributos são conhecidos como getters e setters, referindo-se a métodos de leitura e escrita. (sic).
Os atributos controlados são chamados de propriedades.
Úteis para Encapsulamento e proteger atributos.
class C:
def __init__( self, x ):
self.setX(x)
def getX( self ):
return self.__x
def setX( self, x ) :
if x < 0: print ( "Valor menor que 0")
elif x > 1000: print( " Valor maior que 1000")
else
self.__ x = x
>>> c1 = C( 100 ) #instanciação
>>> c2 = C( 150 ) #instanciação
>> c1.setX( c1.getX( ) + c2.getX( ) )
>>> c1.getX( ) # get retornará algo
250
>>> c1.setX( - 10 )
A ideia é não settar a variável diretamente.
A função property pode ser usada para evitar a repetição de getters e setters.
Ela é usada o 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.
O doc é uma docstring para o atributo.
Obs: Leitura e escrita pode ficar confuso de entender.
cod.:
class Retangulo:
def __init__( self, tamanho ):
self.setTamanho( tamanho )
def setTamanho( self, tamanho ):
if min( tamanho )< 0: print ( "Erro!" )
self.__tamx, self.__tamy = tamanho
def getTamanho( self ):
return( self.__tamx, self__tamy )
tamanho = property( getTamanho, setTamanho )
>> r = Retangulo((20,30))
>> r.tamanho
( 20, 30 )
>> r.tamanho = ( 30 , 30 )
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 amb sejam definidas numa classe como atributo e método.
Não permita promiscuidade entre classes e instâncias de classe.
Não escreva métodos extensos.
Em geral, um método deve ser o mais simples possível.
Página 3
Exceções
Mario Benevides
>Exceções
Objetos de Exceção.
Avisos.
Comando raisse.
Classes de Exceções.
Mais de um except.
Comando else.
Comando finally.
Iteradores e Geradores.
Quando um programa encontra uma dificuldade não prevista, diz-se que uma condição excepcional ou uma exceção ocorre.
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 )
Onde classe é uma das classes de exceções definidas pelo Python.
Para saber todos os tipos de exceção consulte o manual.
Se quiser uma classe genérica usa a classe Exception.
>>> raise Exception
Traceback ...
>>> raise Exception ( " Hello danger" )
Criando uma Classe de Exceção
Basta criar uma classe da forma habitual derivando-a da classe Exception.
Não é preciso redefinir qualquer método.
cod.:
>>> class MinhaExcecao( Exception): pass
...
>>> raise MinhaExcecao( " E agora? ")
Capturando Exceções
Para capturar uma exceção possivelmente levanta por um trecho de código, pode-se usar a construção try/except:
cod.:
try:
a = input( " Entre com um numero:")
b = input(" Entre com outro número: ")
print ( a, " /" , b, "=" a/b )
except ZeroDivisionError:
print( " Erro, segundo número não pode ser zero!" )
try:
a = input( " Entre com um numero:")
b = input(" Entre com outro número: ")
print ( a, " /" , b, "=" a/b )
except (ZeroDivisionError, TypeError) :
print( " Erro, segundo número não pode ser zero!" )
try:
a = input( " Entre com um numero:")
b = input(" Entre com outro número: ")
print ( a, " /" , b, "=" a/b )
except (ZeroDivisionError, TypeError) as e :
print( " Erro:" , e )
A variável e é uma resposta do sistema.
except
É possivel tratar diferentemente as diversas exceções usando duas ou mais cláusulas except.
Se quisemos nos prevenir contra qualquer tipo de erro, podemos usar uma cláusula except sem nome de classe.
Se não quisermos tratar um erro em uma cláusula except, podemos passá-la adiante usando o comando raise.
cod.:
try:
a = input( " Entre com um numero:")
b = input(" Entre com outro número: ")
print ( a, " /" , b, "=" a/b )
except ( ZeroDivisionError):
print( " Erro: Divisão por zero.")
except :
print( " Erro!" )
except ( Exception) as e:
print ( " Erro:" , e )
raise
else
cod.:
While True:
try:
a = input( " Entre com um numero:")
b = input(" Entre com outro número: ")
print ( a, " /" , b, "=" a/b )
except ( Exception) as e:
print( "Erro:" , e )
print( " Tente novamente" )
else:
break
Ou seja, o else nesse caso é flag que interrompe o loop de erro.
finally
A cláusula finally pode ser usada para se assegurar que mesmo que osorra algum erro, uma determinada sequencia de comandos vai ser executada.
O comando finally e comando except são mutuamente exclusivas.
Neste caso exceções não são tratadas.
É possível combinar ambas usando comando try aninhados.
cod.
try:
try:
x = input( " Entre com um numero: ")
finally:
print( " Fazendo x igual ao valor default None")
x = None
except:
print( "Ocorreu um erro.")
>>> Entre com um número: f
Fazendo x igual ao valor default None.
Ocorreu um erro.
Iteradores
São maneiras genéricas de implementar iterações com classes
Usados no comando for
É geralmente mais economico do que usar 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.
cod.:
class MeuIterador:
a = 0;
def __iter__( self ): return self
def __next__( self ):
if self.a > 10: raise StopIteration
self.a += 1
return self.a
itt = MeuIterador()
for i in itt:
print( i, end=" " )
O iterador é incrementado a cada passo.
Se usamos range a lista fica na memória. Mais eficiente.
Geradores
Geradores são funções especiais que retornam iteradores.
fonte - Pesquisar
Página 4
Projeto Frações
Escreva uma classe para manipular objetos do tipo fração. Frações são números racionais da forma n/d, onde n e d são inteiros.
cod.:
class Fracao( Object):
def __init__(self, num = 1 , den = 1) :
if( den == 0 ): raise ValueError( " Zero no denominador")
if( den< 0 ):
self.den = - den
self.num = -num
self.den = den
self.num = num
self.simpifica() # simplifica fração
def simplifica( self ):
max = 1
if self.num != 0 :
max = mdc( self.num, self.den )
if max > 1:
self.num //= max
self.den //= max
return self
def mdc ( self, x, y ):
while y != 0;
resto = x % y
x = y
y = resto
return x
# Operator ==
def __eq__( self, f ) :
a = self.simplifica()
b = f.simplifica()
return( a.num == b.num && a.den == b.den )
def __add__( self, f):
if isinstance ( f, int ) : # checa se o valor f é inteiro
num = self.num + f * self.den
den = self.den
elif isinstance( f, Fracao) :
num = self.num * self.den + f.num* self.den
den = f.den * self.den
else: raise TypeError( " __add__")
def __sub__( self, f):
if isinstance ( f, int ) : # checa se o valor f é inteiro
num = self.num - f * self.den
den = self.den
elif isinstance( f, Fracao) :
num = self.num * self.den - f.num* self.den
den = f.den * self.den
else: raise TypeError( " __sub__")
def __iadd__( self, f):
if isinstance ( f, int ) : # checa se o valor f é inteiro
self.num += f * self.den
elif isinstance( f, Fracao) :
num = self.num * self.den + f.num* self.den
self.den *= f.den
else: raise TypeError( " __iadd__")
return self.simplifica()
# Esse método é mais eficiente porque não gera cópias.
def __mul__( self, f):
if isinstance ( f, int ) : # checa se o valor f é inteiro
num = self.num * f
den = self.den
elif isinstance( f, Fracao) :
num = self.num * f.num
den = f.den * self.den
else: raise TypeError( " __mul __")
return Fracao( num, den) # Retorna uma cópia
def __truediv__( self, f):
if isinstance ( f, int ) : # checa se o valor f é inteiro
num = self.num
den = self.den * f
elif isinstance( f, Fracao) :
num = self.num * self.den
den = f.num* self.den
else: raise TypeError( " __truediv__")
return Fracao( num, den )
def __str__( self):
if self.num == 0 :
return "0"
elif self.den == 1:
return str( self.num)
else:
return str(self.num)+ " / " + str( self.den)
if __name__ == "__main__":
sys.exit( main())
Página 5
Módulo
Módulos são programas feitos para serem reaproveitados por outros programas.
Eles tipicamente possuem funções, variáveis, métodos, etc.
Toda bibliotecas em python são divididos em módulo e pacote.
Qualquer programa que você crie e salve pode ser importado como módulo.
Ele pode ser importado pelo comando import
A importação ocorre uma única vez;
Após a importação do módulo é gerado um arquivo .pyc, este é compilado.
O python só recompila o arquivo .py se o arquivo for mais recente que .pyc
Variável __name__
Página 6
Arquivos
Em Python um arquivo pode ser lido/escrito através de uma objeto da classe file.
Arquivos Default
Sempre quando um comando print é executado, o resultado vai para um arquivo chamado sys.stdout.
Sempre quando lemos um dado através do comando input pu raw_input, na verdade estamos lendo de um arquivo chamado sys.stdin.
Mensagens de erro ou rastreamento de exceções são enviadas para arquivo chamado sys.stderr.
Abrindo arquivos
open( name, mode, buffering)
name = nome do arquivo;
mode = leitura ou escrita ( w, r , b, a, r+b, w+b )
buffering = opcional tamanho de número de bytes
cod.:
>>> arq = open( "teste", w)
>>>arq.write( "Oi")
>>>arq.close()
>>>arq = open( " teste")
>>> x = arq.read( )
>>> x
" Oi"
read( num )
num é um parâmetro de número de bytes de leitura caso não seja passado será feita a leitura do arquivo inteiro
write( string)
Escreve a string no arquivo
close()
Termina o uso do arquivo leitura e escrita.
Interações com o sistema operacional
Usa-se o módulo OS, oferece vários funcionalidade de entrada e saída do sistema.
os.getcwd() retorna o diretório corrente.
os.chdir( dir ) muda o diretório corrente para um diretório dir.
os.path.exists( path ) diz se path se refere ao nome de um arquivo existente.
Lendo e escrevendo linhas
readline( n )
Faz a leitura de apenas uma linha de arquivo. Caso n seja especificado será o número de caracteres ( bytes ) que serão lidos.
readlines( n )
Faz a leitura de mais de uma linha de arquivo.
writelines( sequencia )
Escreve a lista ou qualquer sequencia de strings, uma por uma no arquivo.
Acesso direto
É possível ler e escrever não sequencialmente em um arquivo. Devendo estar associados a dispositivos que permitem acesso direto, com o disco, por exemplo.
seek( offset, whence) :
offet: indica o número de bytes a ser lido ou escrito pela próxima operação de entrada e saída.
whence: indica a partir de onde o offeset será contado.
0: inicio
1: ponto corrente
2: final
telll() :
Indica a posição corrente ( número de bytes a partir do início ).
Página 7
Projeto: Fração com arquivos
class Fracao( Object):
def __init__(self, num = 1 , den = 1) :
if( den == 0 ): raise ValueError( " Zero no denominador")
if( den< 0 ):
self.den = - den
self.num = -num
self.den = den
self.num = num
self.simpifica() # simplifica fração
def simplifica( self ):
max = 1
if self.num != 0 :
max = mdc( self.num, self.den )
if max > 1:
self.num //= max
self.den //= max
return self
def mdc ( self, x, y ):
while y != 0;
resto = x % y
x = y
y = resto
return x
# Operator ==
def __eq__( self, f ) :
a = self.simplifica()
b = f.simplifica()
return( a.num == b.num && a.den == b.den )
def __add__( self, f):
if isinstance ( f, int ) : # checa se o valor f é inteiro
num = self.num + f * self.den
den = self.den
elif isinstance( f, Fracao) :
num = self.num * self.den + f.num* self.den
den = f.den * self.den
else: raise TypeError( " __add__")
def __sub__( self, f):
if isinstance ( f, int ) : # checa se o valor f é inteiro
num = self.num - f * self.den
den = self.den
elif isinstance( f, Fracao) :
num = self.num * self.den - f.num* self.den
den = f.den * self.den
else: raise TypeError( " __sub__")
def __iadd__( self, f):
if isinstance ( f, int ) : # checa se o valor f é inteiro
self.num += f * self.den
elif isinstance( f, Fracao) :
num = self.num * self.den + f.num* self.den
self.den *= f.den
else: raise TypeError( " __iadd__")
return self.simplifica()
# Esse método é mais eficiente porque não gera cópias.
def __mul__( self, f):
if isinstance ( f, int ) : # checa se o valor f é inteiro
num = self.num * f
den = self.den
elif isinstance( f, Fracao) :
num = self.num * f.num
den = f.den * self.den
else: raise TypeError( " __mul __")
return Fracao( num, den) # Retorna uma cópia
def __truediv__( self, f):
if isinstance ( f, int ) : # checa se o valor f é inteiro
num = self.num
den = self.den * f
elif isinstance( f, Fracao) :
num = self.num * self.den
den = f.num* self.den
else: raise TypeError( " __truediv__")
return Fracao( num, den )
def __str__( self):
if self.num == 0 :
return "0"
elif self.den == 1:
return str( self.num)
else:
return str(self.num)+ " / " + str( self.den)
class Fracoes( Object) :
def __init__(self, filename):
self.lfracoes = []
try:
f = open( filename, 'r')
except IOError:
print( " Fracoes : Cannot open file %s for reading" %filename)
raise
self.Reader( f )
def Reader( self, f ):
for line in f:
temp = line.split( None )
if len( temp ) == 2 :
try:
self.lfracoes.append( Fracao( int( temp[0]) , int( temp[1])))
except:
print( " Fração invalida: s%\n", %temp)
continue
f.close()
def __str__( self ):
sb = " "
f = Fracao ( 0, 1) # um acumulador fracionado
g = Fracao( 1,1)
for i in range ( 0, len( self.lfracoes))
f += self.fracoes[ i ]
g += self.lfracoes[ i ]
sb += "Soma: s \n Produto: s \n" %( f, g )
return sb
def __repr__( self ):
sb = " "
f i in range( 0, len(self.lfracoes) :
sb += " Fracao %d: %s\n" %( i, self.lfracoes[ i ] )
return sb
Para testar essa classe:
cod.:
def main( argv = None ):
f = "fracoes.txt"
if argv is None:
argv = sys.argv
if( len(argv> 1 ):
f = argv[1]
try:
m = Fracoes( f )
print( repr(m))
print ( m )
except IOError:
sys.exit ( "File %s not found." %f)
if __name__ == "__main__":
sys.exit( main() )
Página 8
Projeto: Impressora
Escreva um programa para implementar uma classe impressora para controlar a quantidade tinta e papel na impressora.
Papel pode ser adicionado à impressora a qualquer momento, e assume-se que não há nenhuma capacidade máxima para papel.
Uma impressora recém construida tem um cartucho de tinta completo contendo a quantidade de tinta dado pela constante INK_CAPACITY.
A impressora pode imprimir em um lado ou em frente e verso.
Para cada lado impresso, uma pequena quantidade da tinta é usada, como determinado pela constante INK_USAGE.
O cartucho de tinta pode ser substituído em qualquer altura, restaurando a quantidade da tinta para o valor INK_CAPACITY.
cod.:
class Printer:
INK_CAPACITY = 2.0
INK_USAGE = 0.0023
# inicialization
def __init__( self, givenNumberOfSheets ):
self.__numberOfSheets = abs( givenNumberSheets)
self.___totalPaperUsed = 0
self.__inkQuantity = printer.INK_CAPACITY
def addPaper( self, additionalSheets):
if additionalSheets > 0:
self.__numberOfSheets += additionalSheets
def isInkOut( self): #
return self.__inkQuantity < printer.INK_USAGE
def replaceInk( self):
return self.__inkQuantity = printer.INK_CAPACITY
# Imprimir um lado de folha
def printOneSided( self, numberOfPages):
np = max( numberOfPages, 0) #Testar se o número de paginas é maior que 0.
nf = min( np, self.__numberOfSheets) # Número de folhas que necessitamos usar.
self.__totalPasedUsed += np #
self.__inkQuantity -= printer.INK_USAGE*np
self.__inkQuantity =max( self.__inkQuantity, 0)
self.__numberOfSheets -= np
#Imprimir frente e Verso
def printTwoSides( self, numberOfPages):
np = max( numberOfPages, 0)
nf = min( np//2+np%, self.__numberOfSheets)
# rnp is real number pages printed
rnp = min(numberOfPages, 2*self.__numberOfSheets) # Já que cada pagina equivale a 2 Paginas.
# Atualizando os dados da impressora
self.__totalPaperUsed += nf
self.__inkQuantity -= printer.INK_USAGE*rnp
self.__inkQuantity = max( self.__inkQuantity, 0 )
self.__numberOfSheets -= nf
def __str__( self):
return "Total paper = %d\n Ink quantity = %f\n Num.Sheets = %d\n" \ %(self.getTotPagesUsed(), self.__inkQuantity, self.getCurrentPaper()
Página 9
Projeto: Calcular consumo de um Carro
Escreva um programa para implementar uma classe para controlar o consumo de um carro a partir de um arquivo contendo uma série de medidas de distância e quantidade de combustível consumida.
Construa uma classe para ler uma série de leitura de hodômetro e galões consumidos após encher o tanque de gasolina de um veículo, e calcular o consumo entre cada parada no posto de gasolina.
import sys
class FillUp:
odometer = 0.0
gallons = 0.0
def __init__( self, givenOdometer, givenGallons):
self.odometer = givenOdometer
self.gallons = givenGallons
def getOdometer( self):
return self.odometer
def getGallons( self):
return self.gallons
classe MileageCalculator:
fillup = []
debug = False
def __init__(self, filename):
try:
f = open( filename, 'r')
except IOError:
print( 'Cannot open file %s for reading' %filename)
raise
self.Reader( f )
def Reader ( self, f ):
for line in f:
tempwords = line.split( None )
if len( tempwords) == 2:
try:
self.fillup.append( FillUp (float( tempwords[0]), float ( tempwords[1]))
# A exceção vai fazer o que se valor passado não corresponder for uma string ou caso não haja um segundo valor, etc.
except:
print( 'Invalid reading: %s\n' %tempwords)
f.close()
def consumption( self, k):
if k<1 or k>= len(self.fillup ): return None
previous = self.fillup[k-1].getOdometer()
current = self.fillup[ k ].getOdometer()
gallons = self.fillup[ k ].getGallons()
if MileageCalculator.debug:
print( "current %f \n previuous %f \n gallons %f\n"%(current, previous,gallons ))
return ( current-previous)//gallons
def __repr__( self):
sb = "Miles per gallon\n"
for i in range(1 , len(self.fillup):
b += "Consump. %d: %.f\n" %(i, self.consumprion(i))
return sb
def __str__( self):
sb = "Kilometers per litro\n"
for i in range(1, len( self.fillup)):
sb += "Consump.%d: %.3f\n" %( i, self.consumption(i)*1.609344/3.7854118)
return sb
def main( argv= None ):
f = " mileage.txt"
d = False
if argv is None:
argv = sys.argv
if ( len(argv)>2):
f = argv[1]
d = argv[2] =='True'
try:
m = MileageCalculator( f )
MileageCalculator.debug = d
print( m)
print ( repr( m ) )
except IOError:
sys.exit( " File %s not found." %f)
if __name__ ==" __main__":
sys.exit( main() )
Página 10
Projeto: Ordenar
Faça programa para ordenar linhas num arquivo e imprimi-las ordenadas.
import fileinput, sys
def sort_file():
lines = []
for line in fileinput.npu():
lines.append( line.rstrip() )
lines.sort()
for line in lines:
print( line )
if __name__ == "__main__":
sys.exit( sort_file() )
python sort_file.py test_in.txt > test_out.txt
more test_in.txt
Página 11
Python: Interfaces Gráficas com Tk
Também chamada de GUI ( Graphical User Interfaces )
Bibliotecas ( toolkits ) para construção de interfaces como
Qt
Gtk
wxWindows
Tk
Python possui camada de portabilidade ( bindings) para várias bibliotecas de construção de interfaces .
PyQt ( Qt )
PyGtk ( Gtk)
Tkinter ( Tk)
Sendo Multiplataforma.
Toolkit originalmente criado para utilização com a linguagem criado para utilização com a linguagem script Tcl
Camada Tkinter: inicia um processp Tcl que toma conta dos elementos de interface.
Classes e funções do Tkinter se comunicam com o interpretador Tcl para especificar aspecto e comportamento da interface.
Não devemos nos preocupar com Tcl.
# Importar o módulo Tkinter
from Tkinter import*
# Elementos de interface( widge) 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
# 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 .
w = Button( pai, text= "Cancelar", command = cancelar)
# Tk já define por default uma janela principal
master = None ( default ) indica que widget será filho da janela principal
Outras janelas podem ser criadas instanciando-se objetos da classe Toplevel
#A função mainloop tem que ser invocada para que a aplicação entre no modo de tratamento de eventos.
Principais componentes do tkinter:
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 de widgets ( Diagramação da interface gráfica ).
Label Mostra um texto ou uma imagem
Listbox Mostra uma lista de alternativas. Pode ser configurado para ter comportamento de checkbutton ou radiobutton.
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.
Scale Permie especificar um valor numérico através de um ponteiro em uma escala linear.
Scrolbar Barra de rolamento para widgets que têm superficie útil variável ( Text, Canvas, Entry, Lisbox )
Text Exibe e permite editar texto formatado. Também suporta imagens e janelas embutidas
Toplevel Uma janela separada.
Classe TK
É a que define uma janela principal e o interpretador Tcl
Em geral, nunca precisa ser instanciada.
Pode ser instanciada explicitamente.
Possui métodos, entre eles:
Title : especifica o título da Janela.
geometry: especifica tamanho e posição da janela.
Opções de Widgets
Widgets ( elementos de interface) têm opções com nomenclatura unificada.
text Texto mostrado no elemento
background cor de fundo
foreground cor de texto
font fonte de texto
relief relevo da borda( 'flat' , 'raised','ridge','sunken','groove')
O método configure
Usado com pares do tipo opção=valor, modifica os valores dos atributos.
>>> rotulo.configure(relief="ridge")
>>> rotulo.configure(" relief")
Gerenciando geometrias
Todos os elementos de interface ocupam uma área retangular da janela.
Então a posição e tamanho de cada elemento é determinada por um gerenciador.
O gerenciador mais usado é o pack().
Usando o pack
Para informar que um elemento deve ser gerenciado pelo pack, use o método pack()
O pack considera o espaço do elemento "pai" como uma cavidade a ser preenchida pelos elementos filhos.
top, left, right e bottom
Redimendionamento
Por default, o pack não redimensiona os filhos quando o i é redimensionado
Duas opções controlam o redimensinamento dos filhos.
expand : ( booleano)
fill( 'non', 'x','y' ou both'
Usando Frames
Programação com eventos
Qualquer interção do usuário com o sistema ele será tratado.
O tratamento de um evento é feito por uma rotina chamada Callback.
Muitos componentes do Tk suportam a opção command que indica uma função a ser invocada sempre que o widget é acionado.
Eventos e Bind
Widgets não dispõem da opção command, também podem receber eventos e responde-los.
A forma de fazer isso é pelo método bind. bind ( padrão, rotina )
padrão - é uma string que define qual evento será tratado.
Campos do objeto evento
x,y :posição do mouse com relação ao campo superior e esquerdo do widget.
x_root , y_root : mouse em relação ao canto superior esquerdo do mouse
char : caractere que eventualmente tenha sido digitado.
keysym: representação simbolica da tecla.
keycode : representação numérica da tecla.
num: número do botão. 1/2/3 = Esquerdo / Meio Direito
widget: o objeto que gerou o evento
height width: altura e lagura do widget.
------------------------------------------------------------------------------------------------------------------------
Criação de Menus
Menu de janela ( toplevel )
É tipicamente horizontal no topo da janela
Se um outro menu é assionado como item cascade, ele é tratado como pulldown isto é, é exibido sob item do menu de janela. Uma caixinha com várias opições.
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
Um menu popup é que é exibido numa janela independente
Para que o menu seja exibido, é preciso invocar o método post:
pos(x,y)
Variáveis
Tk é controlado por um interpretador Tcl( Tcl era uma linguagem antiga que roda no background) ( e não diretamente pelo python)
Em alguns casos deseja-se usar variáveis na interface.
Variáveis Tcl são expostas á aplicação Python 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 usadas para acessar os valores armazenados no interpretador Tcl.
from tkinter import*
root = Tk()
soma = DoubleVar(root)
parcela = DoubleVar(root)
def aritmetica(e):
soma.set(soma.get()+parcela.get())
lsoma =Label(textvar=soma)
eparcela = Entry(textvar = parcela)
eparcela.bind("", aritmetica)
lsoma.pack()
eparcela.pack()
root.geometry("500x500")
root.mainloop()
Checkbuttons
Radiobuttons
Canvas
Permite a exibição e edição de gáficos estrturados 2D.
Elementos gráficos ( itens) são introduzidos usando métodos da forma create_tipo() onde tipo pode ser
arc arco de circulo
bitmap imagem binaria
image imagem colorida
line linha poligonal
oval circulos e elipses
polygon poligonos
rectangle retangulo
text texto
window um widget tk
Información
- Descripción
- Fonte graduação em Sistemas da Computação cederj
- Creado por
- Jorge Borges
- Visitas
- 7
- Etiquetas
- Valoración