def test_poupanca_adequada(self):
        bl = BancoLogico()
        bl.quantia_poupada(22000)
        bl.ganhos(25000, bl.ESTAVEL)
        bl.dependentes(3)

        bl.poupanca() |should| equal_to(bl.ADEQUADA)
    def test_inadequada(self):
        bl = BancoLogico()

        bl.condicao = bl.ESTAVEL
        bl.dependentes = 1
        bl.ganhos = 9999999999
        bl.renda() | should_not | equal_to(bl.INADEQUADA)
        bl.condicao = bl.INSTAVEL
        bl.renda() | should | equal_to(bl.INADEQUADA)

        bl.condicao = bl.ESTAVEL

        bl.dependentes = 1
        bl.ganhos = 18999
        bl.renda() | should | equal_to(bl.INADEQUADA)
        bl.ganhos = 19000
        bl.renda() | should_not | equal_to(bl.INADEQUADA)
        bl.ganhos = 19001
        bl.renda() | should_not | equal_to(bl.INADEQUADA)

        bl.dependentes = 2
        bl.ganhos = 22999
        bl.renda() | should | equal_to(bl.INADEQUADA)
        bl.ganhos = 23000
        bl.renda() | should_not | equal_to(bl.INADEQUADA)
        bl.ganhos = 23001
        bl.renda() | should_not | equal_to(bl.INADEQUADA)

        bl.dependentes = 3
        bl.ganhos = 26999
        bl.renda() | should | equal_to(bl.INADEQUADA)
        bl.ganhos = 27000
        bl.renda() | should_not | equal_to(bl.INADEQUADA)
        bl.ganhos = 27001
        bl.renda() | should_not | equal_to(bl.INADEQUADA)
    def test_inadequada(self):
        bl = BancoLogico()

        bl.condicao = bl.ESTAVEL
        bl.dependentes = 1
        bl.ganhos = 9999999999
        bl.renda() |should_not| equal_to(bl.INADEQUADA)
        bl.condicao = bl.INSTAVEL
        bl.renda() |should| equal_to(bl.INADEQUADA)

        bl.condicao = bl.ESTAVEL

        bl.dependentes = 1
        bl.ganhos = 18999
        bl.renda() |should| equal_to(bl.INADEQUADA)
        bl.ganhos = 19000
        bl.renda() |should_not| equal_to(bl.INADEQUADA)
        bl.ganhos = 19001
        bl.renda() |should_not| equal_to(bl.INADEQUADA)

        bl.dependentes = 2
        bl.ganhos = 22999
        bl.renda() |should| equal_to(bl.INADEQUADA)
        bl.ganhos = 23000
        bl.renda() |should_not| equal_to(bl.INADEQUADA)
        bl.ganhos = 23001
        bl.renda() |should_not| equal_to(bl.INADEQUADA)

        bl.dependentes = 3
        bl.ganhos = 26999
        bl.renda() |should| equal_to(bl.INADEQUADA)
        bl.ganhos = 27000
        bl.renda() |should_not| equal_to(bl.INADEQUADA)
        bl.ganhos = 27001
        bl.renda() |should_not| equal_to(bl.INADEQUADA)
    def test_poupanca_adequada(self):
        bl = BancoLogico()
        bl.quantia_poupada(22000)
        bl.ganhos(25000, bl.ESTAVEL)
        bl.dependentes(3)

        bl.poupanca() | should | equal_to(bl.ADEQUADA)
class ArvoreBidirecional:
    def __init__(self):
        self.g = nx.DiGraph()
        self.bl = BancoLogico()

        self.montar_arvore()

    def determinar_parametros_teste(self):
        self.bl.quantia_poupada(30000)
        self.bl.ganhos(27000, self.bl.ESTAVEL)
        self.bl.dependentes(3)

    def montar_arvore(self):
        self.g.add_path(
            (self.bl, self.bl.poupanca_inadequada,
             self.bl.investimento_poupanca, self.bl.investimento_seguro))
        self.g.add_path(
            (self.bl, self.bl.poupanca_adequada, self.bl.renda_adequada,
             self.bl.investimento_acoes, self.bl.investimento_seguro))

        self.g.add_path(
            (self.bl, self.bl.poupanca_adequada, self.bl.renda_inadequada,
             self.bl.investimento_ambos, self.bl.investimento_seguro))

    def buscar_investimento_seguro(self):
        """Um investimento seguro só é possível se todos nós, do pai ao filho,
        são validados como verdadeiros no caminho correspondente. O próprio
        caminho diz qual investimento seguir."""
        buscador_do_inicio = Buscador(graph=self.g,
                                      no_inicial=self.bl,
                                      objetivo=self.bl.investimento_seguro,
                                      funcao_proximo_no=self.g.successors)
        #buscador "espelho" do buscador_do_inicio
        buscador_do_fim = Buscador(
            graph=buscador_do_inicio.graph,
            no_inicial=buscador_do_inicio.objetivo,
            objetivo=buscador_do_inicio.no_atual,  #nó inicial
            funcao_proximo_no=self.g.predecessors)

        buscadores = [None, buscador_do_inicio, buscador_do_fim]
        flag = 1

        while not (buscador_do_inicio.esbarrou(buscador_do_fim) or \
                    buscador_do_inicio.atingiu_objetivo() or \
                    buscador_do_fim.esbarrou(buscador_do_inicio) or \
                    buscador_do_fim.atingiu_objetivo()):
            #flag para fazer apenas um buscador caminhar a cada passo ("loop")
            buscadores[flag].step()
            flag *= -1

        self.mostrar_resultados(buscador_do_inicio, buscador_do_fim)

    def mostrar_resultados(self, buscador_do_inicio, buscador_do_fim):
        print "Caminhos: "
        print "Buscador do início: " + str(buscador_do_inicio.path)
        print "Buscador do fim: " + str(buscador_do_fim.path)
        print "Nó no buscador do início: " + str(buscador_do_inicio.no_atual)
        print "Nó no buscador do fim: " + str(buscador_do_fim.no_atual)
class ArvoreBidirecional:

    def __init__(self):
        self.g = nx.DiGraph()
        self.bl = BancoLogico()

        self.montar_arvore()

    def determinar_parametros_teste(self):
        self.bl.quantia_poupada(30000)
        self.bl.ganhos(27000, self.bl.ESTAVEL)
        self.bl.dependentes(3)

    def montar_arvore(self):
        self.g.add_path((self.bl,
                          self.bl.poupanca_inadequada,
                          self.bl.investimento_poupanca,
                          self.bl.investimento_seguro
                         ))
        self.g.add_path((self.bl,
                          self.bl.poupanca_adequada,
                          self.bl.renda_adequada,
                          self.bl.investimento_acoes,
                          self.bl.investimento_seguro
                         ))

        self.g.add_path((self.bl,
                          self.bl.poupanca_adequada,
                          self.bl.renda_inadequada,
                          self.bl.investimento_ambos,
                          self.bl.investimento_seguro
                         ))

    def buscar_investimento_seguro(self):
        """Um investimento seguro só é possível se todos nós, do pai ao filho,
        são validados como verdadeiros no caminho correspondente. O próprio
        caminho diz qual investimento seguir."""
        buscador_do_inicio = Buscador(graph=self.g,
                                      no_inicial=self.bl,
                                      objetivo=self.bl.investimento_seguro,
                                      funcao_proximo_no=self.g.successors)
        #buscador "espelho" do buscador_do_inicio
        buscador_do_fim    = Buscador(graph = buscador_do_inicio.graph,
                                      no_inicial = buscador_do_inicio.objetivo,
                                      objetivo = buscador_do_inicio.no_atual, #nó inicial
                                      funcao_proximo_no=self.g.predecessors)

        buscadores = [None, buscador_do_inicio, buscador_do_fim]
        flag = 1

        while not (buscador_do_inicio.esbarrou(buscador_do_fim) or \
                    buscador_do_inicio.atingiu_objetivo() or \
                    buscador_do_fim.esbarrou(buscador_do_inicio) or \
                    buscador_do_fim.atingiu_objetivo()):
            #flag para fazer apenas um buscador caminhar a cada passo ("loop")
            buscadores[flag].step()
            flag *= -1

        self.mostrar_resultados(buscador_do_inicio, buscador_do_fim)

    def mostrar_resultados(self, buscador_do_inicio, buscador_do_fim):
        print "Caminhos: "
        print "Buscador do início: " + str(buscador_do_inicio.path)
        print "Buscador do fim: " + str(buscador_do_fim.path)
        print "Nó no buscador do início: " + str(buscador_do_inicio.no_atual)
        print "Nó no buscador do fim: " + str(buscador_do_fim.no_atual)