💻 Exemplos: Capítulo 03: Estruturas Repetitivas (while, for), Iteradores, enumerate e zip
Especialização em Sistemas com Python 3.12+ • Capítulo 03
🎯 Demonstração Prática: Conciliação Financeira com zip, enumerate e for-else
O exemplo abaixo implementa um simulador corporativo de conciliação bancária e amortização de carteira de crédito:
- Emprego de
zip(..., strict=True)para sincronização estrita de lotes de dados contábeis. - Utilização de
enumerate(..., start=1)para numeração e rastreamento de lançamentos. - Construção
for-elsepara validação de conformidade de integridade sem uso de variáveis sentinelas. - Aritmética financeira com o módulo
decimal.
"""
demonstracao_conciliacao_repetitiva.py
Conciliação e Amortização de Lançamentos com Protocolo de Iteração e Python 3.12+.
"""
from __future__ import annotations
from dataclasses import dataclass
from decimal import Decimal, ROUND_HALF_EVEN
from typing import Final, Iterator
# ==============================================================================
# 1. MODELOS DE DADOS PARA AUDITORIA
# ==============================================================================
@dataclass(slots=True)
class LancamentoExtrato:
documento: str
descricao: str
valor_esperado: Decimal
@dataclass(slots=True)
class ConciliacaoItem:
numero_linha: int
documento: str
valor_sistema: Decimal
valor_banco: Decimal
divergencia: Decimal
conformidade: bool
# ==============================================================================
# 2. MOTOR DE CONCILIAÇÃO COM ITERAÇÃO E ZIP STRICT
# ==============================================================================
TOLERANCIA_CENTAVOS: Final[Decimal] = Decimal("0.05")
def conciliar_lotes(
lancamentos_internos: list[LancamentoExtrato],
extrato_bancario_valores: list[Decimal]
) -> Iterator[ConciliacaoItem]:
"""
Pareia lançamentos do ledger interno com os valores retornados pelo banco.
Garante sincronização 1:1 via zip(strict=True).
"""
# zip com strict=True lança ValueError caso as listas tenham tamanhos divergentes
for indice, (interno, valor_banco) in enumerate(
zip(lancamentos_internos, extrato_bancario_valores, strict=True),
start=1
):
diferenca = (interno.valor_esperado - valor_banco).quantize(
Decimal("0.01"), rounding=ROUND_HALF_EVEN
)
esta_conforme = abs(diferenca) <= TOLERANCIA_CENTAVOS
yield ConciliacaoItem(
numero_linha=indice,
documento=interno.documento,
valor_sistema=interno.valor_esperado,
valor_banco=valor_banco,
divergencia=diferenca,
conformidade=esta_conforme
)
# ==============================================================================
# 3. ROTINA DE AMORTIZAÇÃO COM WHILE E WALRUS OPERATOR
# ==============================================================================
def calcular_cronograma_amortizacao(
saldo_devedor_inicial: Decimal,
taxa_juros_mensal: Decimal,
pagamento_mensal_fixo: Decimal,
limite_meses: int = 12
) -> list[tuple[int, Decimal, Decimal, Decimal]]:
"""Gera o extrato de amortização decrescente até liquidação total da dívida."""
cronograma: list[tuple[int, Decimal, Decimal, Decimal]] = []
saldo_atual: Decimal = saldo_devedor_inicial
mes: int = 1
# While com critério duplo de parada
while saldo_atual > Decimal("0.00") and mes <= limite_meses:
juros = (saldo_atual * taxa_juros_mensal).quantize(Decimal("0.01"), ROUND_HALF_EVEN)
# Ajuste da última parcela se o pagamento superar a dívida restante
parcela = min(pagamento_mensal_fixo, saldo_atual + juros)
amortizacao = parcela - juros
saldo_atual = (saldo_atual - amortizacao).quantize(Decimal("0.01"), ROUND_HALF_EVEN)
cronograma.append((mes, juros, amortizacao, saldo_atual))
mes += 1
return cronograma
# ==============================================================================
# 4. EXECUÇÃO PRINCIPAL
# ==============================================================================
if __name__ == "__main__":
# Dados de teste para conciliação
lote_interno: list[LancamentoExtrato] = [
LancamentoExtrato("DOC-9801", "Assinatura Cloud Pro", Decimal("450.00")),
LancamentoExtrato("DOC-9802", "Licenciamento JetBrains", Decimal("890.50")),
LancamentoExtrato("DOC-9803", "Gateway SMS Twilio", Decimal("125.30")),
LancamentoExtrato("DOC-9804", "Domínios e DNS Route53", Decimal("75.00")),
]
valores_recebidos_banco: list[Decimal] = [
Decimal("450.00"),
Decimal("890.50"),
Decimal("125.28"), # Divergência de R$ 0.02 (Dentro da tolerância)
Decimal("75.00"),
]
print("=" * 80)
print(" RELATÓRIO DE CONCILIAÇÃO BANCÁRIA (ZIP STRICT + ENUMERATE)")
print("=" * 80)
print(f"{'Linha':<6} | {'Documento':<10} | {'Sistema':>12} | {'Banco':>12} | {'Dif':>8} | {'Status':<12}")
print("-" * 80)
# Consumo do gerador e validação com for-else
for item in conciliar_lotes(lote_interno, valores_recebidos_banco):
status_txt = "CONFORME" if item.conformidade else "DIVERGENTE"
print(
f"{item.numero_linha:<6} | "
f"{item.documento:<10} | "
f"R$ {item.valor_sistema:>9.2f} | "
f"R$ {item.valor_banco:>9.2f} | "
f"R$ {item.divergencia:>5.2f} | "
f"[{status_txt}]"
)
if not item.conformidade:
print(f"\n[ALERTA] Divergência grave detectada na linha {item.numero_linha}. Auditoria abortada.")
break
else:
# Apenas executa se nenhum break disparou
print("-" * 80)
print(">> SUCESSO: Todos os lançamentos do lote foram homologados sem divergências impeditivas!")
print("=" * 80)
# Demonstração de Amortização
print("\n" + "=" * 80)
print(" CRONOGRAMA DE AMORTIZAÇÃO DE CAPITAL (WHILE)")
print("=" * 80)
print(f"{'Mês':<6} | {'Juros':>14} | {'Amortização':>14} | {'Saldo Devedor':>18}")
print("-" * 80)
plano = calcular_cronograma_amortizacao(
saldo_devedor_inicial=Decimal("5000.00"),
taxa_juros_mensal=Decimal("0.015"), # 1.5% ao mês
pagamento_mensal_fixo=Decimal("1200.00"),
limite_meses=6
)
for mes, juros, amortizacao, saldo in plano:
print(f"{mes:<6} | R$ {juros:>11.2f} | R$ {amortizacao:>11.2f} | R$ {saldo:>15.2f}")
print("=" * 80)