Programação I / Introdução à Programação - Capítulo D...
Transcript of Programação I / Introdução à Programação - Capítulo D...
Programação I / Introdução à ProgramaçãoCapítulo D, "Classes and Objects"
João Pedro Pedroso
2019/2020
Últimas aulas:I Programação orientada a objetos
Hoje:I Programação orientada a objetos (cont.).
Programação orientada a objetos: exemplo com frações
I Classe para representar frações:I métodos: operações habituais com frações
I Frações:I dois inteiros: numerador e denominadorI devem ser dados ao construtor
Fração: construtor
1 class Fraction:2 def __init__(self, top, bottom):3 self.num = top # the numerator is on top4 self.den = bottom # the denominator is on the bottom5
6 def __str__(self):7 return str(self.num) + "/" + str(self.den)8
9 def getNum(self):10 return self.num11
12 def getDen(self):13 return self.den
I output:
>>> myfraction = Fraction(3,4)>>> print(myfraction)3/4>>> myfraction.getNum()3>>> myfraction.getDen()4
Objectos são mutáveis
I Podemos alterar os atributos de uma instância:
myfraction.num = 5myfraction.den = 3
I Podemos fazer o mesmo em métodos da classe, utilizadoself.num e self.den
I Situação em que isto é útil: simplificação de fraçõesI Exemplo: as frações 12/16 e 6/8 podem ambas ser
representadas por uma fração irredutível: 3/4I Redução: divisão do numerador e do denominados pelo maior
divisor comum
Estado e métodos: Fraction
Algoritmo de Euclides:I Para reduzirmos uma fracção aos termos mais simples:
I encontrar o maior divisor comum (GCD)I dividir numerador e denominador por GCDI → reduzir objectos Fraction sempre que são credos
I Algoritmo de Euclides:Se n divide m, então n é o GCD. Caso contrário, o GCD éo GCD a n e ao resto da divisão de m por n.
I Versão recursiva
1 def gcd (m, n):2 if m % n == 0:3 return n4 else:5 return gcd(n, m%n)
I Versão iterativa:
1 def gcd(m,n):2 while m%n != 0:3 m, n = n, m%n4 return n
I Utilização:
>>> gcd(12,16)4
Simplificação de frações
I Com a função gcd podemos implementar um método parasimplificar frações:
class Fraction:[... ]def simplify(self):
common = gcd(self.num, self.den)
self.num = self.num // commonself.den = self.den // common
I Notas:I gcd é uma função, não é um método da classe (helper
function);I o método simplify não devolve nada, apenas altera o objeto
(mutator method);
Identicidade de dois objetosI Tal como na realidade, dois objetos podem ser iguais sem
serem o mesmo; esta ambiguidade existe também em objetosPython;
I Para verificar se duas referências dizem respeito ao mesmoobjeto, utiliza-se o operador is:
>>> myfraction = Fraction(3,5)>>> yourfraction = Fraction(3,5)>>> myfraction is yourfractionFalse
Igualdade superficial de dois objetos
I Se atribuirmos outro a a, as variáveis passam a ser aliasespara o mesmo objecto: igualdade superficial — shallow identity
>>> ourfraction = myfraction>>> myfraction is ourfractionTrue
Comparação de dois objetos
I O operador ==, se não for redefinido, devolve a igualdadesuperficial:
>>> a = Fraction(3,5)>>> b = Fraction(3,5)>>> a == bFalse
I Para compararmos o conteúdo de dois objectos — igualdadeprofunda — podemos definir uma função:
def sameFraction(f1,f2):return (f1.getNum() == f2.getNum()) \
and (f1.getDen() == f2.getDen())>>> sameFraction(a, b)True
Comparação e os seus riscos
I Python permite-nos escolher o significado dos operadores, taiscomo ==
p = Point(4, 2)s = Point(4, 2)print("== on Points returns", p == s) # shallow equality test here
a = [2,3]b = [2,3]print("== on lists returns", a == b) # deep equality test on lists
I em Point comparação com == devolve False;I em list comparação com == devolve True.
Recomendação:
Beware of ==“When I use a word,” Humpty Dumpty said, in a ratherscornful tone, “it means just what I choose it to mean —neither more nor less.”
Alice in Wonderland
Cópia de objectosI Para duplicarmos um objecto (cópia shallow):
>>> import copy>>> a = Fraction(4,5)>>> b = copy.copy(a)>>> a == b>>> a == bFalse>>> sameFraction(a,b)True
I Cópia em profundidade: deepcopy (copia o objecto, e todosobjectos nele embebidos):
>>> a = [[1,2,3],4]>>> b = copy.copy(a)>>> a[0][1] = 999>>> b[[1, 999, 3], 4]
>>> a = [[1,2,3],4]>>> b = copy.deepcopy(a)>>> a[0][1] = 999>>> b[[1, 2, 3], 4]
I Com deepcopy, a e b ficam objectos completamenteseparados.
Fração: construtor
class Fraction:def __init__(self,top,bottom):
self.num = top # the numerator is on topself.den = bottom # the denominator is on the bottom
def __str__(self):return str(self.num) + "/" + str(self.den)
def getNum(self):return self.num
def getDen(self):return self.den
def simplify(self):common = gcd(self.num, self.den)self.num = self.num // commonself.den = self.den // common
Operações aritméticasI Podemos definir uma função que calcula a soma de duas
frações:a
b+
c
d=
ad + cb
bd
class Fraction:[...]def add(self,otherfraction):
newnum = self.num*otherfraction.den + self.den*otherfraction.numnewden = self.den * otherfraction.den
common = gcd(newnum,newden)
return Fraction(newnum//common,newden//common)
I Utilização:
>>> f1 = Fraction(1,2)>>> f2 = Fraction(1,4)>>> f3 = f1.add(f2)>>> print(f3)3/4
Operações aritméticas: métodos especiaisI Podemos definir um método especial para a adição de duas
frações, que torna a utilização de frações mais natural;I O método existente para isso é __add__:
class Fraction:[...]def __add__(self,otherfraction):
newnum = self.num*otherfraction.den + self.den*otherfraction.numnewden = self.den * otherfraction.den
common = gcd(newnum,newden)
return Fraction(newnum//common,newden//common)
I Utilização:
>>> f1 = Fraction(1,2)>>> f2 = Fraction(1,4)>>> f3 = f1 + f2>>> print(f3)3/4
I Nota: nas operações com inteiros e em vírgula flutuante, asituação é exatamente a mesma: executar 4+5 é equivalente a<
Operações aritméticas: métodos especiais
Método Resultado__add__ self + other__sub__ self - other__mul__ self * other__truediv__ self / other__floordiv__ self // other. . .
Operadores relacionais: métodos especiais
Método Uso Descrição__lt__ x < y devolve True se x for menor do que y__le__ x <= y devolve True se x for menor do que, ou igual a y__eq__ x == y devolve True se x for igual a y__ne__ x != y devolve True se x for diferente y__ge__ x >= y devolve True se x for maior do que, ou igual a y__gt__ x > y devolve True se x for maior do que y
Métodos especiais
I A lista completa de métodos especiais pode ser consultada em:https://docs.python.org/3.8/reference/datamodel.html
I Incluí metodos para:I Adaptação/personalização de tipos (type customization);I Comparação/relação entre objetos;I Controlar acesso a atributos da classe;I Implementar tipos compostos e o respetivo acesso (e.g.,
mapas/dicionários personalizados);I Emular tipos e conversões numéricos;I . . .
Noções estudadas esta semanaclasse tipo composto definido pelo programador
instanciar criar um objeto de uma determinada classeinstância o mesmo que objeto
objeto variável de um determinado tipo (a sua classe),frequentemente utilizada para modelar uma coisa ouconceito do mundo real; junta informação (dados) eoperações relevantes para esse tipo composto dedados
construtor cada classe é uma fábrica de objetos; se tiver definidoum método de inicialização, esse método seráexecutado ao criar um objeto, para dar um valorcorreto aos atributos
método de inicialização em Python: __init__método função definida dentro de uma classe, que é invocada
partindo de instâncias dessa classeatributo um dos dados que constituí uma instância
Noções estudadas esta semana
programação orientada a objetos estilo de programação em quedados e operações que os manipulam são definidosem classes e métodos
linguagem orientada a objetos linguagem com capacidades deprogramação orientada a objetos
igualdade superficial (shallow equality) igualdade de referências:verifica se duas variáveis se referem ao mesmo objeto
igualdade profunda (deep equality) igualdade dos valores guardadosnum objeto
cópia superficial (shallow copy) cópia do conteúdo de um objeto edas referências a outros objetos nele imbricados
cópia profunda (deep copy) cópia do conteúdo de um objeto e,recursivamente, de todos os objetos que nele estãodefinidos
Aula de hoje:I Programação orientada a objetos
Próximas aulasI Programação orientada a objetos (continuação)