Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

Códigos parecidos e o Template Method: classes abstratas

Mesmo criaqndo a classe abstrata a minha aplicação executou, sem definir a classe abstrata na classe filha

C:\Caca\Alura\Python\DesignPatternsPython\ProjetoAPP>python calculador_de_impostos.py ISS e ICMS 50.0 30.0 ICPP e IKCV 25.0 30.0

C:\Caca\Alura\Python\DesignPatternsPython\ProjetoAPP>python calculador_de_impostos.py

# -*- coding: UTF-8 -*-
#impostos.py

#este import é utilizado para criação de classes abstratas
#toda classe abstrata tem que ter esta "meta" informação
from abc import ABCMeta, abstractmethod


#esta classe foi criada pra resolver o problema das classes ICPP e IKCN
#que tem regras semelhantes
class Template_de_imposto_condicional(object):

    #classe abstrata
    __metaclass__ = ABCMeta

    def calcula(self, orcamento):
        if self.deve_usar_maxima_taxacao(orcamento):
            return self.maxima_taxacao(orcamento)
        else:
            return self.minima_taxacao(orcamento)

    # o @abstractmethod faz com que a classe filha seja obrigada a implementar a classe abstrata
    @abstractmethod
    def deve_usar_maxima_taxacao(self, orcamento):
        pass

    @abstractmethod
    def maxima_taxacao(self, orcamento):
        pass

    @abstractmethod
    def minima_taxacao(self, orcamento):
        pass        

#o que antes era função agora vai virar classe
#def calculo_ISS(orcamento):
#   return orcamento.valor * 0.1

#def calculo_ICMS(orcamento):
#    return orcamento.valor * 0.06

class ISS(object):
    def calcula(self, orcamento):
        return orcamento.valor * 0.1

class ICMS(object):
    def calcula(self, orcamento):
        return orcamento.valor * 0.06

class ICPP(object):
    def calcula(self, orcamento):
        if orcamento.valor > 500:
            return orcamento.valor * 0.07
        else:
            return orcamento.valor * 0.05

class IKCV(object):
    def calcula(self, orcamento):
        if orcamento.valor > 500 and self.__tem_item_maior_que_100_reais(orcamento):
            return orcamento.valor * 0.01
        else:
            return orcamento.valor * 0.06

    def __tem_item_maior_que_100_reais(self, orcamento):
        for item in orcamento.obter_item():
            if item.valor > 100:
                return True
            else:
                return False

-----
# -*- coding: UTF-8 -*-
#calculo_de_imposto.py
from impostos import * 

class Calculador_de_impostos(object):

    #o parametro imposto passa a receber o nome da função que deve ser executaeda
    def realiza_calculo(self, orcamento, imposto): 
        imposto_calculado = imposto.calcula(orcamento)
        print imposto_calculado

#quando arquivo calculador_de_impostos.py for executado, no terminal do python
#todos os comandos embaixo do "if __name__ == '__main__':" serão executados
#este comando sera utilizado durante o curso para evitar a criação de classes para testar os métodos

if __name__ == '__main__':
    #importando a classe Orcamento do arquivo orcamento.copyright
    from orcamento import Orcamento, Item
    calculador = Calculador_de_impostos()
    orcamento = Orcamento()

    orcamento.adiciona_item(Item('Item 1', 50.0))
    orcamento.adiciona_item(Item('Item 2', 200.0))
    orcamento.adiciona_item(Item('Item 3', 250.0))
    print 'ISS e ICMS'
    calculador.realiza_calculo(orcamento, ISS())
    calculador.realiza_calculo(orcamento, ICMS())

    print 'ICPP e IKCV'
    calculador.realiza_calculo(orcamento, ICPP())
    calculador.realiza_calculo(orcamento, IKCV())
-----
# -*- coding: UTF-8 -*-
# orcamento.py
class Orcamento(object):

    def __init__(self):
        self.__itens = []

    # quando a propriedade for acessada, ela soma cada item retornando o valor do orçamento
    @property
    def valor(self):
        total = 0.0
        for item in self.__itens:
            total+= item.valor
        return total

    # retornamos uma tupla, já que não faz sentido alterar os itens de um orçamento
    def obter_itens(self):

        return tuple(self.__itens)

    # perguntamos para o orçamento o total de itens
    @property
    def total_itens(self):
        return len(self.__itens)

    def adiciona_item(self, item):
        self.__itens.append(item)

# um item criado não pode ser alterado, suas propriedades são somente leitura
class Item(object):

    def __init__(self, nome, valor):
        self.__nome = nome
        self.__valor = valor

    @property
    def valor(self):
        return self.__valor

    @property
    def nome(self):
        return self.__nome
1 resposta
solução!

Essa é a beleza de uma linguagem dinâmica :). Em tempo de execução, o objeto passado como argumento possui o método calcula, vc não precisa de uma classe abstrata para garantir isso.

A classe abstrata aí serve para organizar, reaproveitar código e tal.. mas não é obrigatória.

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software