🧩 Exercícios: Paradigmas Declarativo, Lógico e Reativo
Módulo 10: Paradigmas & Padrões • Bloco 1 • Trilha em 4 Níveis
🎯 Nível 1: Fundamentos
Problema 04.1 — Motor de Inferência Lógica e Dedução por Unificação
Contexto: No paradigma lógico, o desenvolvedor declara uma base de conhecimento e consulta relações sem prescrever o algoritmo de busca.
Requisitos de Execução:
- Crie uma estrutura em Python
BaseConhecimentoLogicacontendo fatos de parentesco:pai("Carlos", "Ana"),pai("Carlos", "Bruno"),pai("Bruno", "Lucas"). - Implemente a regra dedutiva
obter_avo(neto: str) -> List[str]eobter_irmaos(pessoa: str) -> List[str]. - Retorne as deduções automaticamente a partir da unificação dos fatos.
Resultado Esperado
=== Deduções da Base de Conhecimento ===
Avô de 'Lucas': ['Carlos']
Irmãos de 'Ana': ['Bruno']
📤 Instruções de Entrega (Microsoft Teams)
- Salve o arquivo como:
Atividade_04_1_SeuNome.py - Envie na tarefa:
Atividade Cap 04 - Paradigmas Declarativo, Lógico e Reativo
🔑 Gabarito de Código & Solução Comentada
# Atividade_04_1_Gabarito.py
from typing import List, Tuple
class BaseConhecimentoLogica:
def __init__(self):
# Fatos: (pai, filho)
self.fatos_pai: List[Tuple[str, str]] = []
def adicionar_fato_pai(self, pai: str, filho: str):
self.fatos_pai.append((pai, filho))
def obter_avo(self, neto: str) -> List[str]:
"""Regra: avo(X, Y) :- pai(X, Z), pai(Z, Y)."""
pais_do_neto = [p for p, f in self.fatos_pai if f == neto]
avos = []
for pai in pais_do_neto:
avos.extend([avo for avo, f in self.fatos_pai if f == pai])
return avos
def obter_irmaos(self, pessoa: str) -> List[str]:
"""Regra: irmao(X, Y) :- pai(Z, X), pai(Z, Y), X \= Y."""
pais = [p for p, f in self.fatos_pai if f == pessoa]
irmaos = set()
for pai in pais:
for p, f in self.fatos_pai:
if p == pai and f != pessoa:
irmaos.add(f)
return list(irmaos)
if __name__ == "__main__":
kb = BaseConhecimentoLogica()
kb.adicionar_fato_pai("Carlos", "Ana")
kb.adicionar_fato_pai("Carlos", "Bruno")
kb.adicionar_fato_pai("Bruno", "Lucas")
print("=== Deduções da Base de Conhecimento ===")
print(f"Avô de 'Lucas': {kb.obter_avo('Lucas')}")
print(f"Irmãos de 'Ana': {kb.obter_irmaos('Ana')}")
🔍 Nível 2: Prática
Problema 04.2 — Observable Reativo com Emissão e Filtragem Push
Contexto: Em programação reativa, consumidores se inscrevem para receber valores propagados ativamente pelo emissor (Push Notification).
Requisitos de Execução:
- Implemente a classe
StreamObservable. - Adicione os operadores encadeáveis
.filter(predicate)e.map(transform). - Conecte um fluxo de telemetria de velocidade veicular, filtrando apenas excessos ($v > 100\text{ km/h}$) e emitindo avisos de infração aos observadores.
Resultado Esperado
=== Monitoramento Reativo de Rodovia ===
Emitindo leituras de radar:
[MULTA DISPARADA]: Veículo a 115.0 km/h na Rodovia SP-330!
[MULTA DISPARADA]: Veículo a 132.5 km/h na Rodovia SP-330!
📤 Instruções de Entrega (Microsoft Teams)
- Salve o arquivo como:
Atividade_04_2_SeuNome.py - Envie na tarefa:
Atividade Cap 04 - Paradigmas Declarativo, Lógico e Reativo
🔑 Gabarito de Código & Solução Comentada
# Atividade_04_2_Gabarito.py
from typing import Callable, List, Any
class StreamObservable:
def __init__(self, items: List[Any]):
self._items = items
def filter(self, predicate: Callable[[Any], bool]) -> 'StreamObservable':
return StreamObservable([x for x in self._items if predicate(x)])
def map(self, transform: Callable[[Any], Any]) -> 'StreamObservable':
return StreamObservable([transform(x) for x in self._items])
def subscribe(self, on_next: Callable[[Any], None]):
for item in self._items:
on_next(item)
if __name__ == "__main__":
velocidades = [85.0, 92.0, 115.0, 70.0, 132.5, 99.0]
print("=== Monitoramento Reativo de Rodovia ===")
print("Emitindo leituras de radar:")
(StreamObservable(velocidades)
.filter(lambda v: v > 100.0)
.map(lambda v: f"[MULTA DISPARADA]: Veículo a {v:.1f} km/h na Rodovia SP-330!")
.subscribe(lambda alerta: print(alerta)))
🚀 Nível 3: Integração
Problema 04.3 — Controle de Contrapressão (Backpressure Sampling / Debounce)
Contexto: Em sistemas IoT de alta frequência, receptores lentos podem sofrer esgotamento de recursos (Out Of Memory). A técnica de amostragem (Sampling) descarta dados intermediários em rajadas.
Requisitos de Execução:
- Crie uma fila reativa
BackpressureSamplercom taxa de amostragem parametrizável. - Emita uma rajada de $10\text{ pacotes}$ em sequência rápida.
- Configure o consumidor para processar apenas a cada $3\text{ amostras}$ (Sampling Rate = 3), descartando leituras redundantes com segurança.
Resultado Esperado
=== Emissão Reativa com Backpressure Sampler ===
[Produtor] Emitindo pacote #1
[Produtor] Emitindo pacote #2
[Produtor] Emitindo pacote #3 -> [CONSUMIDOR RECEBEU]: Pacote #3
[Produtor] Emitindo pacote #4
[Produtor] Emitindo pacote #5
[Produtor] Emitindo pacote #6 -> [CONSUMIDOR RECEBEU]: Pacote #6
📤 Instruções de Entrega (Microsoft Teams)
- Salve o arquivo como:
Atividade_04_3_SeuNome.py - Envie na tarefa:
Atividade Cap 04 - Paradigmas Declarativo, Lógico e Reativo
🔑 Gabarito de Código & Solução Comentada
# Atividade_04_3_Gabarito.py
from typing import Callable, Any
class BackpressureSampler:
def __init__(self, sample_interval: int, on_sample: Callable[[Any], None]):
self._interval = sample_interval
self._counter = 0
self._on_sample = on_sample
def emit(self, item: Any):
self._counter += 1
print(f"[Produtor] Emitindo {item}", end="")
if self._counter % self._interval == 0:
print(f" -> [CONSUMIDOR RECEBEU]: {item}")
self._on_sample(item)
else:
print()
if __name__ == "__main__":
print("=== Emissão Reativa com Backpressure Sampler ===")
sampler = BackpressureSampler(sample_interval=3, on_sample=lambda _: None)
for i in range(1, 8):
sampler.emit(f"pacote #{i}")
🏆 Nível 4: Desafio
Problema 04.4 — Motor Declarativo de Regras de Negócio e Unificação Dinâmica
Contexto: Sistemas bancários corporativos e motores de crédito usam motores declarativos (como Drools / Datalog) para avaliar dezenas de políticas sem código procedural acoplado.
Requisitos de Execução:
- Construa um motor declarativo
RuleEngineonde políticas de crédito sejam cadastradas como regras (Regra(nome, condicao_lambda, acao_lambda)). - O motor deve avaliar um perfil de cliente e disparar automaticamente todas as regras satisfeitas em lote.
- Demonstre a inclusão dinâmica de uma nova regra fiscal sem alterar nenhuma linha do motor de execução.
Resultado Esperado
=== Motor Declarativo de Políticas de Crédito ===
Avaliando Cliente: Mariana (Score: 820, Renda: R$ 12000.00, Idade: 29)
-> [Regra Satisfeita: CartaoBlack] Concedido limite especial de R$ 50.000,00!
-> [Regra Satisfeita: TaxaJurosReduzida] Taxa de financiamento fixada em 0.79% a.m.!
📤 Instruções de Entrega (Microsoft Teams)
- Salve o arquivo como:
Atividade_04_4_SeuNome.py - Envie na tarefa:
Atividade Cap 04 - Paradigmas Declarativo, Lógico e Reativo
🔑 Gabarito de Código & Solução Comentada
# Atividade_04_4_Gabarito.py
from dataclasses import dataclass
from typing import Callable, List, Dict, Any
@dataclass
class Regra:
nome: str
condicao: Callable[[Dict[str, Any]], bool]
acao: Callable[[Dict[str, Any]], None]
class RuleEngine:
def __init__(self):
self._regras: List[Regra] = []
def registrar_regra(self, regra: Regra):
self._regras.append(regra)
def executar(self, contexto: Dict[str, Any]):
for r in self._regras:
if r.condicao(contexto):
r.acao(contexto)
if __name__ == "__main__":
print("=== Motor Declarativo de Políticas de Crédito ===")
cliente = {"nome": "Mariana", "score": 820, "renda": 12000.0, "idade": 29}
print(f"Avaliando Cliente: {cliente['nome']} (Score: {cliente['score']}, Renda: R$ {cliente['renda']:.2f}, Idade: {cliente['idade']})")
engine = RuleEngine()
engine.registrar_regra(Regra(
"CartaoBlack",
lambda c: c["score"] >= 800 and c["renda"] >= 10000.0,
lambda _: print("-> [Regra Satisfeita: CartaoBlack] Concedido limite especial de R$ 50.000,00!")
))
engine.registrar_regra(Regra(
"TaxaJurosReduzida",
lambda c: c["score"] >= 750,
lambda _: print("-> [Regra Satisfeita: TaxaJurosReduzida] Taxa de financiamento fixada em 0.79% a.m.!")
))
engine.executar(cliente)