O GoConqr está de visual novo! Conte para nós o que você achou.

Notas

Programação OO: Python

Jorge Borges Programação Orienta a Objetos Português 11 páginas

Conteúdo das notas (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

Informações

Descrição
Fonte graduação em Sistemas da Computação cederj
Criado por
Jorge Borges
Visualizações
7
Avaliação

Fale Conosco

Sobre o que é sua mensagem?

O que você acha do novo visual?

Você gostou?