Especialização em Sistemas com Python 3.12+ • Capítulo 06


🎯 Demonstração Prática: Auditoria de Memória Heap e Processamento Matricial 2D

O exemplo abaixo demonstra a inspeção de alocação de memória no CPython e algoritmos de processamento espacial de matrizes 2D:

  • Diagnóstico de consumo em bytes com sys.getsizeof() comparando listas com sobrealocação vs tuplas imutáveis.
  • Demonstração prática do isolamento de memória entre cópias rasas (copy()) e cópias profundas (copy.deepcopy()).
  • Processamento matricial com transposição via zip(*matriz) e detecção de anomalias térmicas em uma malha de sensores industriais.
"""
demonstracao_memoria_e_matrizes.py
Auditoria de Memória no CPython, Coleções Sequenciais e Processamento Matricial 2D.
Compatível com Python 3.12+.
"""

from __future__ import annotations

import copy
import sys
from typing import Final

# ==============================================================================
# 1. AUDITORIA DE ALOCAÇÃO NA HEAP (LIST VS TUPLE)
# ==============================================================================
def demonstrar_pegada_memoria() -> None:
    """Exibe o mecanismo de sobrealocação (over-allocation) do CPython."""
    print("=" * 75)
    print("      AUDITORIA DE CONSUMO DE MEMÓRIA: LISTA VS TUPLA NO CPYTHON")
    print("=" * 75)

    elementos_base: list[int] = list(range(10))
    tupla_imutavel: tuple[int, ...] = tuple(elementos_base)

    lista_dinamica: list[int] = []
    print(f"Lista Vazia Inicial       : {sys.getsizeof(lista_dinamica):>4} bytes")
    print(f"Tupla Imutável (10 itens) : {sys.getsizeof(tupla_imutavel):>4} bytes")
    print("-" * 75)
    print("Demonstração da Sobrealocação Dinâmica da Lista:")

    tamanhos_anteriores: int = sys.getsizeof(lista_dinamica)
    for i in range(15):
        lista_dinamica.append(i)
        tamanho_atual = sys.getsizeof(lista_dinamica)
        if tamanho_atual != tamanhos_anteriores:
            print(f"  * Inserido item {i:>2} -> Alocação saltou para {tamanho_atual} bytes (Capacidade expandida)")
            tamanhos_anteriores = tamanho_atual

# ==============================================================================
# 2. CÓPIA RASA VS CÓPIA PROFUNDA
# ==============================================================================
def demonstrar_semantica_copia() -> None:
    """Evidencia a diferença entre duplicação de referências e duplicação de Heap."""
    print("\n" + "=" * 75)
    print("      COMPARAÇÃO DE MUTABILIDADE: SHALLOW COPY VS DEEP COPY")
    print("=" * 75)

    matriz_original: list[list[int]] = [[10, 20], [30, 40]]
    copia_rasa: list[list[int]] = matriz_original.copy()
    copia_profunda: list[list[int]] = copy.deepcopy(matriz_original)

    # Mutação de subitem interno
    matriz_original[0][0] = 999

    print(f"Original Modificado  : {matriz_original}")
    print(f"Cópia Rasa (Afetada) : {copia_rasa} -> Compartilha os mesmos ponteiros internos!")
    print(f"Cópia Deep (Isolada) : {copia_profunda} -> Preservou o estado intacto!")

# ==============================================================================
# 3. PROCESSAMENTO MATRICIAL 2D DE SENSORES INDUSTRIAIS
# ==============================================================================
LIMIAR_SUPERIOR_CRITICO: Final[float] = 85.0

def processar_malha_termica(malha: list[list[float]]) -> dict[str, object]:
    """Calcula média global, transpõe a grade e identifica células em sobreaquecimento."""
    total_linhas: int = len(malha)
    total_colunas: int = len(malha[0]) if total_linhas > 0 else 0

    todas_leituras: list[float] = [val for linha in malha for val in linha]
    media_temperatura: float = sum(todas_leituras) / len(todas_leituras)

    # Transposição funcional em tempo O(R * C)
    matriz_transposta: list[list[float]] = [list(col) for col in zip(*malha)]

    # Localização de anomalias com coordenadas
    anomalias: list[dict[str, object]] = []
    for r, linha in enumerate(malha):
        for c, temp in enumerate(linha):
            if temp >= LIMIAR_SUPERIOR_CRITICO:
                anomalias.append({
                    "coordenada": f"[{r}, {c}]",
                    "temperatura": temp,
                    "desvio_da_media": round(temp - media_temperatura, 2)
                })

    return {
        "dimensoes": f"{total_linhas}x{total_colunas}",
        "media_global": round(media_temperatura, 2),
        "transposta": matriz_transposta,
        "anomalias_detectadas": anomalias
    }

# ==============================================================================
# 4. EXECUÇÃO
# ==============================================================================
if __name__ == "__main__":
    demonstrar_pegada_memoria()
    demonstrar_semantica_copia()

    print("\n" + "=" * 75)
    print("      MONITORAMENTO INDUSTRIAL DE MALHA TÉRMICA 2D")
    print("=" * 75)

    sensores_turbina: list[list[float]] = [
        [32.5, 34.0, 31.8, 33.1],
        [35.2, 94.6, 36.0, 32.8], # Ponto Crítico na célula [1, 1]
        [33.0, 32.7, 88.2, 34.5], # Ponto Crítico na célula [2, 2]
    ]

    relatorio = processar_malha_termica(sensores_turbina)
    print(f"Dimensões da Matriz : {relatorio['dimensoes']}")
    print(f"Temperatura Média   : {relatorio['media_global']} °C")
    print("-" * 75)
    print("Anomalias Acima de 85.0 °C Localizadas:")

    for alerta in relatorio["anomalias_detectadas"]:
        print(
            f"  * Sensor {alerta['coordenada']:<8} -> {alerta['temperatura']} °C "
            f"(+{alerta['desvio_da_media']} °C acima da média operacional)"
        )

    print("-" * 75)
    print("Grade Transposta (Eixos Invertidos para Análise por Coluna):")
    for linha_t in relatorio["transposta"]:
        print(f"  {linha_t}")
    print("=" * 75)