Aula 06

Python para Dados

Um único projeto de vendas para entender como cada biblioteca resolve uma etapa real.

Extrair

Arquivos e APIs.

Tratar

DataFrames e regras.

Entregar

Banco e dashboard.

Escalar

Orquestração, Spark e ML.

O caso da aula

Três arquivos contam uma única história de vendas

clientes.csv

cliente_id
nome
estado
segmento
email

+

vendas.csv

venda_id
data
cliente_id
produto_id
quantidade

+

produtos.csv

produto_id
produto
categoria
preco
custo

O mesmo dado atravessará todas as bibliotecas. O que muda é o problema que estamos resolvendo.

Ao final

Você saberá escolher a ferramenta pela etapa do fluxo

Ler e transformar

CSV, filtros, colunas, grupos, ordenação e junções.

Confiar nos dados

Caminhos portáveis, segredos protegidos e contratos validados.

Persistir e integrar

Banco de dados e APIs sem perder a estrutura tabular.

Entregar valor

Dashboard simples e reproduzível.

Operar em produção

Agendamento, monitoramento e tentativas automáticas.

Escalar e prever

Cluster e primeiro contato com machine learning.

Origem

Python nasceu simples e cresceu com a comunidade

01Início dos anos 1990

Guido van Rossum cria Python no CWI, na Holanda.

021991

As primeiras versões públicas aparecem.

032001

A Python Software Foundation é formada.

04Hoje

Open source, multiplataforma e presente em dados, web, automação e IA.

Código legível reduziu a distância entre uma pergunta e um resultado executável.

Fonte: documentação oficial do Python, “History and License”.

Mercado

Python combina adoção ampla com uma carreira que exige contexto

57,9%

dos respondentes do Stack Overflow 2025 usaram Python.

+7 p.p.

de crescimento de adoção entre 2024 e 2025.

R$ 63,5 mil/ano

salário-base médio informado para Analista de Dados no Brasil.

O número não é promessa

Salário varia por cidade, senioridade, setor, idioma e responsabilidade. Python aumenta repertório; não substitui SQL, negócio e comunicação.

O diferencial

Conseguir automatizar uma análise, validar a origem e entregar um resultado reproduzível.

Fontes: Stack Overflow Developer Survey 2025; Indeed Brasil, atualização de 12/07/2026, 1,6 mil salários informados.

Ecossistema

Uma linguagem conecta áreas que antes viviam separadas

Aprendizado

Sintaxe direta e feedback rápido.

Bibliotecas

Pacotes especializados no PyPI.

Integração

Arquivos, bancos, APIs, nuvem e BI.

Comunidade

Documentação, eventos e código aberto.

Casos reais

Python.org reúne histórias em finanças, manufatura, aviação, ciência, governo e software. Bluevine descreve Python em backend, engenharia, ciência e análise de dados.

O ponto principal

Não existe “biblioteca vencedora” para tudo. Existe uma caixa de ferramentas coerente para problemas diferentes.

Mapa da aula

Do arquivo ao modelo, cada biblioteca tem um papel

Pandas · Polars

Manipular tabelas.

Pathlib · dotenv

Organizar e proteger.

Pydantic

Validar contratos.

SQLAlchemy

Persistir em banco.

Requests

Consumir APIs.

Streamlit

Entregar interface.

Prefect · Airflow

Orquestrar fluxos.

PySpark · sklearn

Escalar e prever.

Onde Python entra

Python pode participar de todas as etapas sem fazer tudo sozinho

01Fonte

CSV, banco ou API.

02Extração

Requests, Pandas.

03Tratamento

Pandas, Polars.

04Validação

Pydantic.

05Persistência

SQLAlchemy.

06Visualização

Streamlit.

07Automação

Prefect, Airflow.

08Escala e ML

Spark, sklearn.

SQL continua no banco. Power BI continua na análise. Python passa a ligar essas peças.

Ambiente

Um ambiente virtual mantém o projeto reproduzível

Estrutura mínima

aula06/
├─ dados/
├─ exemplos/
├─ projeto_bcb/
├─ saida/
├─ .venv/
└─ requirements.txt

# cria um ambiente isolado
python -m venv .venv

# se o PowerShell bloquear, execute uma vez
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

# ativa e instala as dependências
.venv\Scripts\Activate.ps1
python -m pip install -r requirements.txt

Erro comum · ativação bloqueada

Depois da política RemoteSigned, reabra o terminal, confirme python --version e selecione o interpretador da pasta .venv no VS Code.

Jupyter

Um notebook alterna explicação, código e resultado

Célula Markdown

Qual categoria gera mais receita?

Registra hipótese, raciocínio e conclusão.

Célula de código

# executa no kernel ativo
vendas.groupby("categoria")[
    "valor_total"
].sum()

O resultado aparece logo abaixo da célula.

Kernel

Processo que mantém variáveis em memória.

Execução

A ordem real importa mais que a posição visual.

Restart

Reiniciar e executar tudo testa reprodutibilidade.

Comparação

Escolha o ambiente pelo tipo de trabalho

AmbienteMelhor momentoVantagemLimiteUse quando
JupyterExploraçãoResultado próximo do códigoOrdem ocultaInvestigar
VS CodeProjetoArquivos, testes e GitMais configuraçãoAutomatizar
ColabCompartilharRoda no navegadorSessão temporáriaDemonstrar
TerminalOperaçãoRepetição e agendamentoMenos visualExecutar
Exploração vira script quando a análise precisa rodar novamente sem depender de cliques.

Pandas · problema

CSV não responde perguntas até ganhar estrutura

Pandas
DataFrame

Uma tabela com linhas, colunas, índice e tipos.

filtrogrupojunçãoexportação
vendadataprodutoqtdpreço
100101/06Notebook15.499,90
100201/06Monitor21.799,90
100302/06Headset3349,90
100402/06Cadeira41.299,90
O DataFrame não é “um Excel dentro do Python”. Ele é uma estrutura programável e reproduzível.

Pandas · anatomia do código

Ler, selecionar e filtrar são três decisões diferentes

# importa a biblioteca
import pandas as pd

# lê o CSV e interpreta a data
vendas = pd.read_csv(
    "dados/vendas.csv",
    parse_dates=["data"]
)

# seleciona duas colunas
recorte = vendas[
    ["produto_id", "quantidade"]
]
# cria uma condição booleana
concluida = (
    vendas["status"] == "Concluida"
)

# filtra e cria uma cópia segura
resultado = vendas.loc[
    concluida
].copy()

# calcula o valor de cada linha
resultado["valor_total"] = (
    resultado["quantidade"]
    * resultado["preco_unitario"]
)
loc[linhas, colunas] deixa explícito o que entra no resultado.

Pandas · pergunta de negócio

Qual categoria gera mais receita?

Raciocínio

01
Separar

categoria

02
Agregar

somar receita

03
Ordenar

maior primeiro

# agrupa linhas da mesma categoria
resumo = (
    base.groupby(
        "categoria",
        as_index=False
    )
    # calcula duas medidas
    .agg(
        receita=("valor_total", "sum"),
        itens=("quantidade", "sum")
    )
    # ordena pela maior receita
    .sort_values(
        "receita",
        ascending=False
    )
)

Pandas · enriquecimento

Merge conecta chaves para devolver contexto

vendas

cliente_id
produto_id
quantidade

merge

on="cliente_id"
how="left"

on="produto_id"

base completa

nome
estado
produto
categoria

# preserva todas as vendas e acrescenta dimensões
base = vendas.merge(clientes, on="cliente_id", how="left").merge(produtos, on="produto_id", how="left")

# exporta sem criar uma coluna de índice
base.to_csv("saida/vendas_tratadas.csv", index=False)

Pandas · demonstração

Leia o erro como uma pista sobre a etapa que falhou

FileNotFoundError

O arquivo não está no caminho esperado. Confirme a pasta com Path.cwd().

KeyError

A coluna não existe ou contém espaços. Veja df.columns.

TypeError

Uma coluna possui tipo inesperado. Inspecione df.dtypes.

Mercado · ★★★★★

Aprenda primeiro. É a referência de manipulação tabular em análise, notebooks, automações e preparação para BI.

Demo ao vivo

Execute 01_pandas.py, compare o resumo e abra saida/resumo_pandas.csv.

Polars · problema

Quando o volume cresce, o motor do DataFrame importa

Pandas
Eager

Em geral, cada instrução produz um resultado imediato.

ecossistema maduroaprendizado
Polars
Lazy + eager

Pode observar o plano completo e otimizar antes de executar.

RustArrowparalelo
Mais rápido não significa sempre melhor. Compatibilidade, memória, equipe e tamanho da base também contam.

Polars · anatomia do código

Expressões descrevem o resultado; collect executa o plano

# importa o Polars
import polars as pl

# scan_csv cria um plano lazy sem carregar tudo imediatamente
resumo = (
    pl.scan_csv("dados/vendas.csv")
    # aplica o filtro o mais cedo possível
    .filter(pl.col("status") == "Concluida")
    # calcula a receita de cada linha
    .with_columns((pl.col("quantidade") * pl.col("preco_unitario")).alias("valor_total"))
    # agrega e ordena
    .group_by("produto_id").agg(pl.col("valor_total").sum().alias("receita"))
    .sort("receita", descending=True)
    # executa o plano otimizado
    .collect()
)

A API lazy pode aplicar predicate pushdown, projection pushdown e outras otimizações antes da materialização.

Polars · performance

Benchmark é medição, não slogan

Como medir

# inicia o cronômetro
inicio = perf_counter()

# executa a transformação
resultado = consulta.collect()

# calcula o tempo decorrido
tempo = perf_counter() - inicio

Mercado · ★★★★☆

Ótimo segundo passo quando o processamento local precisa de mais velocidade ou menos memória.

Erros comuns

ColumnNotFoundError: confira o schema. SchemaError: normalize tipos. Resultado “instantâneo” sem collect() ainda é apenas um plano lazy.

Execute 02_polars.py na sua máquina e registre volume, operação, versões e memória.

Pathlib · caminhos

Barra invertida não deveria decidir onde seu código roda

Frágil
# depende do computador e do sistema
caminho = "C:\\curso\\dados\\vendas.csv"

Pasta fixa, separador manual e pouca informação sobre o arquivo.

Portável
# parte da localização do próprio script
raiz = Path(__file__).resolve().parent.parent

# monta o caminho correto no sistema atual
arquivo = raiz / "dados" / "vendas.csv"

Mercado · ★★★★★

Biblioteca padrão. Use em qualquer projeto que leia ou grave arquivos.

Erro comum

Path.cwd() é a pasta de onde o comando foi iniciado; __file__ aponta para o script.

dotenv · segurança

Senha no código vira incidente quando o arquivo é compartilhado

# arquivo .env — somente no computador
DATABASE_URL=postgresql://usuario:senha@servidor/vendas
API_TOKEN=segredo-local

# arquivo .env.example — pode ser compartilhado
DATABASE_URL=
API_TOKEN=
# carrega as variáveis do arquivo .env
from dotenv import load_dotenv
load_dotenv()

# lê a configuração sem expor o valor
import os
url = os.getenv("DATABASE_URL")

# falha cedo se estiver ausente
if not url:
    raise RuntimeError("DATABASE_URL ausente")

Mercado · ★★★★☆

Comum no desenvolvimento local. Em produção, prefira o gerenciador de segredos da plataforma.

Erros comuns

Subir .env para o Git; esquecer load_dotenv(); misturar configuração de teste e produção.

Pydantic · problema

Um arquivo pode abrir e ainda conter dados inválidos

idade

"dezesseis"
esperado: inteiro ≥ 18

email

"ana@dominio"
esperado: endereço válido

cpf

"123"
esperado: 11 dígitos

01Entrada

dict, JSON ou linha.

02Modelo

Tipos e regras.

03Validação

Aceitar ou rejeitar.

04Saída

Dado confiável.

Pydantic cria um contrato explícito na fronteira do sistema.

Pydantic · código comentado

O modelo transforma regra de negócio em validação executável

# importa tipos de validação
from pydantic import (
    BaseModel,
    Field, field_validator
)

class Cliente(BaseModel):
    # converte texto numérico para inteiro
    idade: int = Field(ge=18)
    email: str = Field(
        pattern=r"^[^@]+@[^@]+\.[^@]+$"
    )
    cpf: str

    @field_validator("cpf")
    @classmethod
    def validar_cpf(cls, valor):
        # mantém somente números
        digitos = "".join(
            c for c in valor if c.isdigit()
        )
        if len(digitos) != 11:
            raise ValueError("CPF inválido")
        return digitos

Resultado

Dados válidos seguem para o banco. Registros inválidos produzem erros por campo e podem ir para uma área de quarentena.

Mercado · ★★★★☆

Muito usado em APIs, serviços de dados, configurações e contratos entre sistemas.

Erros comuns

Confiar apenas em conversão automática; validar tarde demais; esconder o motivo da rejeição.

SQLAlchemy · persistência

O DataFrame precisa de uma ponte segura até o banco

Python

regra do fluxo

Engine

conexão SQLAlchemy

PostgreSQL

persistência real

SQL

consulta no banco

DataFrame

resultado tabular

BI

consumo final

Sem configuração

O exemplo usa SQLite porque não exige servidor e funciona imediatamente.

Com DATABASE_URL

O mesmo arquivo conecta ao PostgreSQL, MySQL ou SQL Server com o driver correspondente.

SQLAlchemy · código comentado

Uma engine centraliza como o Python conversa com o banco

# lê a URL do .env; vazio mantém SQLite
import os
from dotenv import load_dotenv
from sqlalchemy import create_engine

load_dotenv(".env")
url = os.getenv("DATABASE_URL") or (
    "sqlite:///saida/vendas.db"
)
engine = create_engine(url)

# grava em uma tabela exclusiva da aula
vendas.to_sql(
    "vendas_aula06", engine,
    if_exists="replace", index=False
)
# define uma consulta SQL explícita
from sqlalchemy import text
consulta = text("""
    SELECT canal,
           SUM(quantidade) AS itens
    FROM vendas
    GROUP BY canal
""")

# lê o resultado como DataFrame
resumo = pd.read_sql(
    consulta,
    engine
)

Mercado · ★★★★☆

Base de muitas integrações Python com bancos. Aprenda engine, transação e SQL parametrizado.

Erros comuns

Driver ausente; URL incorreta; conexão não fechada; usar replace em produção sem intenção.

Requests · APIs

Nem toda fonte chega em CSV: muitas chegam por HTTP

01URL

Endereço do recurso.

02GET

Solicitação HTTP.

03Status

200, 404, 500...

04JSON

Objetos e listas.

05DataFrame

Tabela normalizada.

API pública

JSONPlaceholder fornece dados de teste para a demonstração.

Fallback local

api.json mantém o exemplo funcional sem internet.

A resposta HTTP pode chegar; ainda assim, você precisa verificar status, formato e campos.

Requests · código comentado

Timeout e raise_for_status evitam silêncios perigosos

# importa cliente HTTP e Pandas
import requests
import pandas as pd

try:
    # limita o tempo de espera
    resposta = requests.get(
        "https://jsonplaceholder.typicode.com/users",
        timeout=10
    )
    # transforma 4xx e 5xx em erro
    resposta.raise_for_status()
    dados = resposta.json()
except requests.RequestException:
    # usa cópia local sem internet
    dados = pd.read_json(
        "dados/api.json"
    ).to_dict("records")

# abre campos aninhados
usuarios = pd.json_normalize(dados)

Mercado · ★★★★★

Essencial para integrações simples. Em pipelines reais, acrescente autenticação, paginação, retry e logs.

Erros comuns

Sem timeout; ignorar status; token exposto; assumir que todos os objetos possuem os mesmos campos.

Streamlit · evolução

O mesmo dado pode evoluir de saída técnica para interface

01print()

Texto no terminal.

02DataFrame

Tabela tratada.

03st.dataframe

Tabela interativa.

04st.bar_chart

Comparação visual.

05Dashboard

Filtro + KPI + ação.

Bom para

Protótipos, ferramentas internas, portfólios, exploração compartilhada e pequenos produtos de dados.

Atenção

Um dashboard não corrige dados ruins. Ele torna a qualidade — ou a falta dela — mais visível.

Streamlit · código comentado

Com poucas chamadas, o script vira uma aplicação local

# importa interface e dados
import streamlit as st
import pandas as pd

# lê o mesmo CSV da aula
vendas = pd.read_csv(
    "dados/vendas.csv"
)

# cria um filtro lateral
canal = st.sidebar.selectbox(
    "Canal",
    ["Todos", *sorted(vendas["canal"].unique())]
)

# mostra tabela e gráfico
st.dataframe(vendas)
st.bar_chart(
    vendas.groupby("canal")[
        "quantidade"
    ].sum()
)

Execute

streamlit run exemplos/08_streamlit.py

Mercado · ★★★★☆

Excelente para demonstrar valor rapidamente; avalie autenticação e arquitetura antes de produção crítica.

Erros comuns

Rodar com python em vez de streamlit run; recalcular tudo a cada clique; não usar cache.

Prefect · fluxo observável

Um pipeline precisa explicar o que aconteceu quando falha

# transforma funções em tarefas observáveis
from prefect import flow, task

@task(retries=2, retry_delay_seconds=2)
def extrair():
    # uma falha transitória pode ser repetida
    return pd.read_csv("dados/vendas.csv")

@flow(name="pipeline-vendas")
def pipeline():
    # estados e duração ficam registrados
    dados = extrair()
    transformar(dados)

pipeline()

O que o fluxo ganha

  • Pipeline: funções rastreáveis.
  • Retry: novas tentativas.
  • Monitoramento: estados, tempo e logs.

Mercado · ★★★☆☆

Boa escolha para equipes Python que querem adotar orquestração gradualmente.

Erro comum

Uma única task torna o retry caro e o erro pouco localizado.

Prefect · interface local

A execução vira uma linha do tempo que a equipe consegue investigar

Interface do Prefect mostrando uma execução e suas tarefas

1. Inicie a interface

prefect server start

2. Conecte o cliente

prefect config set PREFECT_API_URL="http://127.0.0.1:4200/api"

3. Execute e acompanhe

python exemplos/09_prefect.py

Abra 127.0.0.1:4200 e mostre tarefas, duração, estados e logs.

Demonstração sugerida: abra a execução mais recente, entre na task transformar e compare o estado visual com a mensagem registrada no log.

Airflow · DAG

Dependências formam um grafo que o scheduler acompanha

01
Scheduler

decide quando uma execução nasce

02
DAG

define tarefas e dependências

03
Executor

envia tarefas prontas para execução

# API do Airflow 3
from airflow.sdk import dag, task

@dag(
    schedule="@daily",
    start_date=datetime(2026, 1, 1),
    catchup=False
)
def pipeline_vendas():
    @task
    def extrair():
        return "vendas.csv"

    @task
    def transformar(arquivo):
        return "vendas_tratadas.csv"

    @task
    def carregar(arquivo):
        print(arquivo)

    carregar(transformar(extrair()))

dag = pipeline_vendas()

Mercado · ★★★★☆

Muito presente em plataformas de dados maduras, com várias DAGs, equipes e integrações.

Erros comuns

Confundir data lógica com horário de execução; criar DAG cíclica; fazer trabalho pesado ao importar o arquivo.

Comparação

Prefect e Airflow resolvem orquestração com experiências diferentes

CritérioPrefectAirflowEscolhaPergunta
Entradafunções PythonDAGs e plataformaPrefectadoção gradual?
Ecossistemamoderno e flexívelamplo e consolidadoAirflowmuitas integrações?
Operaçãolocal, cloud ou self-hostserviços persistentesdependequem opera?
Escala da equipepequena a grandemédia a grandedependequal governança?
Comece pelo problema operacional. Orquestrador não corrige uma função de transformação frágil.

PySpark · limite local

Quando um computador deixa de ser suficiente, distribua o trabalho

Planilha
MB
Pandas / Polars
GB
Spark
TB+

Memória

A base não cabe com segurança em uma máquina.

Tempo

O processamento local não termina na janela disponível.

Infraestrutura

Os dados já vivem em um lake e um cluster está disponível.

Não use Spark para um CSV de 30 linhas. O custo de distribuição só faz sentido quando o problema exige.

PySpark · arquitetura

O driver coordena; os executors processam partições

Driver

Cria o plano e distribui tarefas.

Cluster manager

Aloca CPU e memória para a aplicação.

Executor A

Processa partições 1 e 2.

Executor B

Processa partições 3 e 4.

Partição

Fatia do conjunto de dados.

Task

Unidade enviada ao executor.

Shuffle

Movimento de dados entre partições; pode custar caro.

Fonte conceitual: Apache Spark Cluster Mode Overview.

PySpark · código comentado

A intenção é parecida; a execução ocorre em um cluster

Pandas · uma máquina
# lê localmente
vendas = pd.read_csv(
    "dados/vendas.csv"
)

# agrega em memória
resumo = (
    vendas.groupby("canal")[
        "quantidade"
    ].sum()
)
PySpark · execução distribuída
# cria a sessão Spark
spark = SparkSession.builder.getOrCreate()

# lê e distribui o DataFrame
vendas = spark.read.csv(
    "dados/vendas.csv",
    header=True,
    inferSchema=True
)

# cria um plano distribuído
resumo = vendas.groupBy("canal").sum(
    "quantidade"
)
resumo.show()

Mercado · ★★★★☆

Relevante em engenharia de dados, lakes e grandes volumes. Aprenda depois de SQL e DataFrames locais.

Avisos no Windows

winutils.exe e native-hadoop são informativos nesta leitura local. O aviso do pandas desaparece com pandas<3. Falhas reais: Java ausente, JAVA_HOME incorreto, excesso de shuffle ou uso indiscriminado de toPandas().

Scikit-learn · primeiro modelo

Machine learning aprende uma relação para estimar novos casos

01Dados

linhas históricas

02Características

X: quantidade e preço

03Treino

fit(X, y)

04Modelo

relação aprendida

05Predição

predict(novo X)

Treino

Exemplos usados para ajustar o modelo.

Teste

Exemplos separados para medir se o modelo generaliza.

Previsão não é certeza. Sem avaliação, o modelo é apenas uma função que produz números.

Scikit-learn · código comentado

Separar treino e teste evita avaliar o modelo com a própria prova

# escolhe características e alvo
X = vendas[[
    "quantidade",
    "preco_unitario"
]]
y = vendas["valor_total"]

# reserva 25% para avaliação
X_treino, X_teste, y_treino, y_teste = (
    train_test_split(
        X, y,
        test_size=0.25,
        random_state=42
    )
)

# aprende com o treino
modelo = LinearRegression()
modelo.fit(X_treino, y_treino)

# prevê e mede o erro no teste
previsoes = modelo.predict(X_teste)
erro = mean_absolute_error(
    y_teste,
    previsoes
)

Mercado · ★★★☆☆

Base sólida para ML clássico. Aprenda depois de dominar limpeza, variáveis e avaliação.

Erros comuns

Vazamento entre treino e teste; base pequena; alvo mal definido; comemorar acurácia sem referência.

Escopo da aula

Entender o fluxo fit → predict → avaliar, sem aprofundar algoritmos.

Decisão

Escolha a biblioteca pelo problema observável

ProblemaPrimeira escolhaAlternativaSinal de trocaImportância
Tabela localPandasPolarstempo/memória★★★★★
ContratoPydanticregras manuaismuitas bordas★★★★☆
BancoSQLAlchemydriver diretomais bancos★★★★☆
InterfaceStreamlitPower BI/webproduto crítico★★★★☆
OrquestraçãoPrefectAirflowgovernança★★★☆☆
Grande volumeSparkPolars/SQLcluster real★★★★☆

Projeto final

Do CSV ao dashboard com validação no meio

CSV

clientes, produtos e vendas

Pandas

filtro, cálculo e merge

Pydantic

contrato por registro

SQLAlchemy

tabela fato_vendas

Streamlit

filtro, KPI e gráfico

Decisão

receita por região e categoria

Entrada controlada

Pathlib encontra arquivos; dotenv protege configurações.

Fluxo observável

Prefect ou Airflow agenda, registra e repete.

Evolução

Spark entra quando a escala local deixa de atender.

Projeto final

O esqueleto combina extração, qualidade e persistência

# 1. encontra as fontes do projeto
ROOT = Path(__file__).resolve().parent.parent
vendas = pd.read_csv(ROOT / "dados" / "vendas.csv")

# 2. valida cada registro antes do tratamento
validas = []
for registro in vendas.to_dict("records"):
    try:
        Venda.model_validate(registro)
        validas.append(registro)
    except ValidationError as erro:
        print("Registro rejeitado:", erro.error_count())

# 3. transforma e calcula a receita
base = pd.DataFrame(validas)
base = base.loc[base["status"] == "Concluida"].copy()
base["valor_total"] = base["quantidade"] * base["preco_unitario"]

# 4. grava a camada analítica no banco
engine = create_engine("sqlite:///saida/projeto_final.db")
base.to_sql("fato_vendas", engine, if_exists="replace", index=False)
O arquivo completo está em exemplos/13_projeto_final.py.

Onde as demais ferramentas entram

O projeto cresce substituindo capacidades, não reescrevendo a história

Requests

Troca o CSV externo por uma API paginada.

Polars

Acelera transformações locais maiores.

Prefect

Adiciona estados, retry e agenda com pouco atrito.

Airflow

Organiza muitas DAGs e dependências de plataforma.

Spark

Distribui volume que excede uma máquina.

Scikit-learn

Acrescenta previsão depois que a base é confiável.

Power BI

Entrega análise governada a mais públicos.

Testes

Protegem regras antes de cada publicação.

Demonstração para chamar atenção

O Radar Econômico conecta fonte oficial, previsão e operação visível

BCB SGS

câmbio e Meta Selic

Prefect

retry, estados e logs

Pandas

tipos, lags e média móvel

sklearn

regressão e MAE

SQLAlchemy

camada analítica SQLite

Streamlit

KPI, série e projeção

1. Mostre a fonte

A API do Banco Central entrega dados oficiais; uma amostra versionada mantém a aula offline.

2. Provoque a pergunta

“Como transformar uma cotação em um processo confiável, observável e reutilizável?”

3. Revele o fluxo

Execute o Prefect, acompanhe as tasks e termine no dashboard com o próximo ponto estimado.

Arquivos: projeto_bcb/pipeline.py e projeto_bcb/dashboard.py. A projeção é didática, não uma recomendação financeira.

Exercício

Construa uma análise de vendas reproduzível

Trabalho em dupla · 30 minutos
01Ler

vendas.csv

02Filtrar

somente concluídas

03Calcular

valor_total

04Agrupar

receita por canal

05Salvar

resumo.csv

06Mostrar

Streamlit

Obrigatório

Pathlib, comentários, tratamento de status e saída sem índice.

Bônus

Filtro por canal, ticket médio e validação de quantidade positiva.

Entrega

Script + CSV gerado + captura do dashboard.

Solução esperada

O código está pronto quando outra pessoa consegue reproduzir

Correto

Vendas canceladas não entram na receita.

Legível

Nomes e comentários explicam a intenção.

Portátil

Nenhum caminho depende do seu computador.

Seguro

Nenhuma senha aparece no arquivo.

Observável

Erros informam arquivo, coluna ou regra.

Repetível

Executar novamente produz o mesmo resultado.

Compare sua solução com 01_pandas.py, 08_streamlit.py e 13_projeto_final.py.

Reprodução

Tudo que apareceu na aula está no pacote da Aula 06

aula06/
├─ aula-06-python-para-dados.html
├─ python-3.12.7-amd64.exe
├─ dados/ · 3 CSVs + JSON
├─ exemplos/ · 13 scripts
├─ projeto_bcb/ · pipeline + dashboard
├─ requirements.txt
├─ .env.example
└─ README.md

1. Instale

Crie .venv e instale requirements.

2. Execute

Comece por 01_pandas.py.

3. Compare

Rode o mesmo fluxo em Polars e Spark.

4. Entregue

Abra o dashboard Streamlit.

Fechamento

Python conecta o fluxo; seu raciocínio escolhe as peças

Comece com dados pequenos, contratos claros e um resultado reproduzível. Escale somente quando o problema exigir.