Pular para o conteúdo

    Capítulo 3, Ambiente

    Notebooks, scripts e o fluxo de trabalho

    Análise de dados é exploração: você testa uma ideia, olha o resultado e decide o próximo passo. Os notebooks existem para esse ciclo, e têm uma armadilha que todo mundo cai uma vez.

    Código deste capítulo: ambiente/cap03_notebooks.py

    Script ou notebook

    Um script roda de cima para baixo, do começo ao fim, toda vez. Isso é ótimo para um programa que você vai executar no servidor, mas ruim para explorar dados, porque reprocessar tudo para olhar uma coluna é lento. Um notebook é dividido em células que você executa uma de cada vez, e o resultado fica visível logo abaixo, como em um caderno de laboratório.

    OpçãoQuando eu uso
    JupyterLabExploração local, o padrão da área
    Jupyter no VS CodeNotebook dentro do mesmo editor onde escrevo o resto do código
    Google ColabQuando não quero instalar nada, ou preciso de GPU
    Script comumQuando o código vai virar rotina, teste ou serviço

    Para usar o JupyterLab em um projeto com uv, instale-o como dependência de desenvolvimento e abra:

    Terminal
    uv add --dev jupyterlab ipykernel
    uv run jupyter lab
    

    O kernel e a armadilha do estado escondido

    Cada notebook é ligado a um kernel, o processo Python que lembra de todas as variáveis que você criou. As células não precisam rodar em ordem: você pode executar a quinta, voltar e reexecutar a segunda. É exatamente isso que causa o problema. O notebook pode mostrar um resultado que só existe por causa de uma célula que você editou depois, e o texto que você lê na tela não reproduz mais o resultado:

    ambiente/cap03_notebooks.pylinhas 10 a 23
    celulas = ["total = 10", "dobro = total * 2"]
    
    kernel = {}
    for celula in celulas:
        exec(celula, kernel)
    
    celulas[0] = "total = 99"
    exec(celulas[0], kernel)
    print("o que a tela mostra:", kernel["dobro"])
    
    novo_kernel = {}
    for celula in celulas:
        exec(celula, novo_kernel)
    print("depois de reiniciar e rodar tudo:", novo_kernel["dobro"])
    
    Saída
    o que a tela mostra: 20
    depois de reiniciar e rodar tudo: 198
    

    Eu editei a primeira célula para 99 e reexecutei só ela. O dobro na tela continuou 20, um valor que não corresponde mais ao código visível. Só ao reiniciar o kernel e rodar tudo em ordem aparece o valor verdadeiro, 198.

    A regra antes de chamar um notebook de pronto

    Reinicie o kernel e execute todas as células, em ordem. Se algo quebrar ou mudar, o notebook dependia de um estado escondido. Eu faço isso antes de compartilhar qualquer notebook.

    O melhor dos dois mundos: células em um arquivo `.py`

    O VS Code e o JupyterLab (com a extensão jupytext) entendem um arquivo Python comum com marcadores # %%: cada marcador abre uma célula. O arquivo continua sendo um script que roda inteiro, com a vantagem de diferenças legíveis no Git, o que o formato .ipynb (um JSON gigante com saídas embutidas) não dá:

    exemplos/celulas.py
    # %% [markdown]
    # # Notas de vendas
    # Cada bloco `# %%` é uma célula no VS Code e no JupyterLab (com jupytext).
    
    # %%
    import numpy as np
    
    vendas = np.array([120.0, 80.5, 99.9, 150.0])
    
    # %%
    print(vendas.mean().round(2))
    
    # %%
    print(vendas.max())
    

    Medir tempo no notebook

    No Jupyter, a "mágica" %timeit roda o código várias vezes e devolve uma média confiável, muito melhor do que um time.time() isolado. Em um script comum, o equivalente é o módulo timeit, que o capítulo 18 usa.