Fase 1 — Fundamentos | Pré-requisitos: Aulas 0 e 1 | Duração estimada: 60 minutos


Introdução

Jupyter Notebook é o ambiente de trabalho padrão para análise de dados em Python. Não é a única opção — você pode usar VS Code, PyCharm ou qualquer editor de texto com um terminal — mas é o ambiente mais usado no mercado e na academia por razões práticas: ele mistura código, resultados e texto explicativo numa sequência linear que facilita tanto o trabalho exploratório quanto a comunicação de resultados.

Esta aula cobre o que você precisa saber para usar o Jupyter de forma produtiva: como ele funciona por dentro, como navegar sem depender do mouse, como organizar notebooks de forma que outros (e você mesmo no futuro) consigam entender, e quais armadilhas evitar.


O que é o Jupyter Notebook

Jupyter Notebook é uma aplicação web que roda localmente no seu computador. Quando você executa o comando jupyter notebook no terminal, ele inicia um servidor local e abre uma interface no navegador. Seus arquivos ficam no seu disco — nada vai para a nuvem por padrão.

Um notebook é um arquivo com extensão .ipynb (IPython Notebook). Por dentro, é um arquivo JSON que armazena células de código, células de texto (markdown) e os outputs gerados pela execução do código.

A unidade básica do Jupyter é a célula. Há três tipos principais:

Célula de código: contém Python. Quando executada, o output aparece logo abaixo.

Célula de markdown: contém texto formatado com sintaxe markdown. Útil para explicações, títulos, fórmulas matemáticas e documentação.

Célula raw: conteúdo bruto, sem processamento. Raramente usada em análise de dados.

O kernel é o processo Python que executa o seu código. Cada notebook tem um kernel próprio. Quando você reinicia o kernel, todas as variáveis são apagadas da memória — o código volta ao estado inicial.


Iniciando o Jupyter

Para abrir o Jupyter Notebook, abra um terminal, navegue até o diretório onde quer trabalhar e execute:

jupyter notebook

Isso abre o painel de controle (dashboard) no navegador, na porta 8888 por padrão. Para criar um novo notebook, clique em "New" e escolha "Python 3".

Se você usa JupyterLab, a interface mais moderna que substitui gradualmente o Notebook clássico, o comando é:

jupyter lab

JupyterLab tem mais recursos (abas, explorador de arquivos lateral, suporte a extensões), mas o comportamento das células é idêntico. Tudo nesta aula se aplica a ambos.


Modos de operação

O Jupyter tem dois modos distintos, e entender a diferença é essencial para usar atalhos de teclado com eficiência.

Modo de comando (azul): você está navegando entre células. Pressione Esc para entrar neste modo. Atalhos de teclado aqui afetam a estrutura do notebook.

Modo de edição (verde): você está editando o conteúdo de uma célula. Clique dentro de uma célula ou pressione Enter para entrar neste modo.


Atalhos essenciais

Aprender os atalhos do Jupyter é um dos investimentos de maior retorno em produtividade. Com eles, você nunca precisa tirar as mãos do teclado durante uma análise.

Atalhos que funcionam em ambos os modos:

Shift + Enter — executa a célula atual e move para a próxima (ou cria uma nova se for a última). Ctrl + Enter — executa a célula atual e permanece nela. Alt + Enter — executa a célula atual e insere uma nova célula abaixo.

Atalhos no modo de comando (pressione Esc primeiro):

A — insere uma célula acima da atual. B — insere uma célula abaixo da atual. D D (dois D em sequência) — deleta a célula atual. Z — desfaz a deleção da última célula. M — converte a célula para markdown. Y — converte a célula para código. L — mostra ou esconde os números de linha da célula. Shift + Up ou Shift + Down — seleciona múltiplas células. Shift + M — combina as células selecionadas. 0 0 (dois zeros) — reinicia o kernel (pede confirmação). H — abre o painel de ajuda com todos os atalhos.

Atalhos no modo de edição:

Tab — autocomplete. Após digitar o início de um nome de variável ou função, Tab completa ou mostra opções. Shift + Tab — mostra a documentação inline da função onde o cursor está. Pressionar duas vezes expande a documentação. Essencial para não precisar sair do notebook para consultar a documentação. Ctrl + Z — desfaz dentro da célula. Ctrl + / — comenta ou descomenta a linha atual.


Como o estado funciona no Jupyter

Este é o ponto que mais confunde quem está começando, então vale atenção especial.

No Jupyter, o estado do kernel é global e persistente enquanto o kernel estiver rodando. Isso significa que uma variável definida na célula 1 está disponível na célula 10, independente da ordem em que você executa as células.

O problema começa quando você executa células fora de ordem. Veja este exemplo:

# Célula 1
x = 10
# Célula 2
x = x + 5
print(x)

Se você executar a célula 1, depois a célula 2, o resultado é 15. Correto. Mas se você executar a célula 2 de novo sem re-executar a célula 1, o resultado é 20. Execute mais uma vez: 25. O valor de x está acumulando porque a célula 2 modifica x no estado atual do kernel, não em algum estado "inicial".

Isso cria um problema sutil mas sério: seu notebook pode parecer funcionar quando na verdade depende de um estado que não está documentado no código, porque você executou células em alguma ordem específica durante a exploração.

A solução é desenvolver o hábito de usar "Kernel → Restart & Run All" periodicamente para verificar que o notebook funciona do início ao fim, na ordem das células, sem depender de estado acumulado. Todo notebook que você entrega ou compartilha deve passar por esse teste.

O número entre colchetes ao lado de cada célula, como [7], indica a ordem em que as células foram executadas. Se você vê números fora de sequência (1, 5, 3, 2), isso é um sinal de que o notebook foi executado fora de ordem.


Markdown nas células de texto

Células de markdown permitem documentar sua análise com formatação. A sintaxe é simples.

# Título principal (H1)
## Título de seção (H2)
### Título de subseção (H3)

Texto normal com **negrito** e *itálico*.

- Item de lista
- Outro item

1. Item numerado
2. Outro item numerado

`código inline`

[Texto do link](https://url.com)

Para fórmulas matemáticas, Jupyter suporta LaTeX via MathJax. Fórmulas inline ficam entre cifrões simples e fórmulas em bloco entre cifrões duplos:

A média é $\bar{x} = \frac{1}{n}\sum_{i=1}^{n} x_i$

$$\sigma = \sqrt{\frac{1}{n}\sum_{i=1}^{n}(x_i - \bar{x})^2}$$

Recursos úteis do Jupyter

Comandos mágicos são instruções especiais prefixadas com % ou %% que controlam o comportamento do kernel ou fornecem funcionalidades extras.

# Medir o tempo de execução de uma linha
%timeit sum(range(1000))

# Medir o tempo de execução de uma célula inteira
%%timeit
total = 0
for i in range(1000):
    total += i

# Listar variáveis no escopo atual
%who

# Listar variáveis com detalhes de tipo e tamanho
%whos

# Executar um arquivo Python externo
%run meu_script.py

# Carregar o conteúdo de um arquivo numa célula
%load meu_script.py

O comando %matplotlib inline era necessário em versões antigas para exibir gráficos dentro do notebook. Em versões modernas do Jupyter e matplotlib, isso não é mais necessário, mas você ainda verá em muito código legado.

Exibir documentação de uma função sem sair do notebook:

# Adicione ? após o nome para ver a documentação
pd.read_csv?

# Adicione ?? para ver o código-fonte
pd.read_csv??

Boas práticas de organização

Um notebook mal organizado é praticamente ilegível depois de uma semana, mesmo para quem o escreveu. As práticas a seguir fazem a diferença entre um notebook profissional e um rascunho descartável.

Use uma célula de markdown no topo com título, data, autor e uma frase descrevendo o objetivo do notebook. Isso parece redundante mas poupa tempo quando você tem dezenas de notebooks numa pasta.

# Análise de vendas por categoria — 2024
**Autor:** Seu nome
**Data:** 2024-11-15
**Objetivo:** Comparar a receita por categoria de produto nos dois semestres de 2024 e identificar tendências.

Organize o notebook em seções com títulos markdown. Uma estrutura típica para análise de dados:

  1. Imports e configuração
  2. Carregamento dos dados
  3. Inspeção inicial
  4. Limpeza
  5. Análise
  6. Visualizações
  7. Conclusões

Agrupe todos os imports numa única célula no topo do notebook. Nunca espalhe imports ao longo do notebook — isso torna impossível saber quais dependências o código tem sem ler tudo.

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

Mantenha células curtas e focadas. Uma célula deve fazer uma coisa. Se uma célula tem mais de 20 linhas, considere dividir.

Comente o raciocínio, não o código óbvio. O comentário # soma os valores numa linha total = sum(valores) não acrescenta nada. O comentário útil explica por quê você fez algo, não o quê: # remove outliers acima do percentil 99 para não distorcer a média.

Limpe células vazias e outputs desnecessários antes de compartilhar. Um notebook com 40 células vazias no meio ou outputs de debug esquecidos passa uma impressão de descuido.


Quando não usar Jupyter

Jupyter é excelente para exploração e comunicação, mas tem limitações que você precisa conhecer.

Ele não é bom para código de produção. Se você está escrevendo uma função que vai ser chamada por um sistema em produção, coloque em um arquivo .py, não num notebook.

Ele tem controle de versão ruim. O formato .ipynb é JSON com outputs incluídos, o que gera diffs enormes e pouco legíveis no git. Para código de longa duração em equipe, prefira arquivos .py ou use ferramentas como nbstripout para limpar os outputs antes de commitar.

Ele incentiva execução fora de ordem. Como discutido, o estado global e a liberdade de executar células em qualquer ordem é uma faca de dois gumes. Em projetos grandes, scripts Python lineares são mais confiáveis.


Resumo

Jupyter Notebook é um ambiente de código, texto e output integrados, organizado em células. O estado do kernel é global e persistente, o que exige disciplina na ordem de execução. Atalhos de teclado eliminam a necessidade do mouse e aumentam muito a produtividade. Boas práticas de organização — imports no topo, seções com markdown, células curtas, comentários de raciocínio — fazem a diferença entre um notebook útil e um ilegível. Use "Restart & Run All" para validar que seu notebook funciona de ponta a ponta antes de compartilhar.

Exercícios

  1. Explique com suas próprias palavras o problema do estado acumulado no Jupyter. Por que executar células fora de ordem pode levar a resultados incorretos que parecem corretos?

    ✓ Resposta:

    O kernel do Jupyter mantém um estado global único enquanto está rodando. Cada vez que você executa uma célula, ela modifica esse estado — cria variáveis, altera valores existentes, importa módulos. O problema é que esse estado depende da história de execução, não da posição das células no notebook.

    Se você executa a célula 5 antes da célula 3, a variável criada na célula 5 já existe quando a célula 3 rodar. Isso pode mascarar erros: a célula 3 pode funcionar aparentemente bem porque encontrou a variável que precisava, mas na verdade ela dependia de algo que só existia porque você tinha executado a célula 5 antes — uma ordem que não está documentada no código.

    O resultado é um notebook que funciona na sua máquina, na sessão que você tem aberta, mas falha quando outra pessoa tenta executar do início ou quando você reinicia o kernel. "Restart & Run All" é o teste que expõe esses problemas.

  2. Qual a diferença prática entre Shift + Enter e Ctrl + Enter? Em que situação cada um é mais útil?

    ✓ Resposta:

    Shift + Enter executa a célula atual e move o foco para a próxima célula, criando uma nova se a atual for a última. É o atalho mais usado durante o fluxo normal de trabalho: você escreve uma célula, executa, e já está posicionado na próxima para continuar.

    Ctrl + Enter executa a célula e mantém o foco nela. É mais útil quando você está ajustando e re-executando a mesma célula repetidamente — por exemplo, quando está refinando um gráfico ou testando diferentes parâmetros numa função. Você não quer avançar para a próxima célula; quer ver o resultado da modificação e talvez modificar de novo.

  3. O trecho de código abaixo tem um problema relacionado ao estado do Jupyter. Identifique o problema e explique como corrigir.

    # Célula 1
    dados = [10, 20, 30, 40, 50]
    
    # Célula 2
    dados.append(60)
    
    # Célula 3
    print(f"Total de itens: {len(dados)}")
    print(f"Média: {sum(dados)/len(dados)}")
    

    ✓ Resposta:

    O problema é que a célula 2 modifica a lista dados com append. Se você executar a sequência completa uma vez, o resultado é correto: 6 itens, média 35. Mas se você executar a célula 2 uma segunda vez (sem re-executar a célula 1 antes), a lista terá 7 itens com dois 60s. Execute a célula 2 três vezes e terá 8 itens. A célula 3 sempre mostrará o estado atual da lista, que depende de quantas vezes a célula 2 foi executada.

    A correção é garantir que a célula 2 não seja idempotente de forma acidental. Uma abordagem é sempre partir do dado original e criar um novo objeto:

    # Célula 2 corrigida
    dados_completos = dados + [60]
    
    # Célula 3 corrigida
    print(f"Total de itens: {len(dados_completos)}")
    print(f"Média: {sum(dados_completos)/len(dados_completos)}")
    

    Assim dados nunca é modificado, e re-executar a célula 2 quantas vezes quiser sempre produz o mesmo resultado.

  4. Reescreva o comentário abaixo para que ele explique o raciocínio em vez de repetir o código:

    # filtra as linhas onde a coluna 'idade' é maior que 18
    adultos = df[df['idade'] > 18]
    

    ✓ Resposta:

    O comentário original é redundante — qualquer pessoa que sabe Python entende o código sem ele. Um comentário útil explicaria por que o filtro foi feito:

    # menores de idade foram excluídos da análise por não terem
    # consentimento registrado no formulário de coleta
    adultos = df[df['idade'] > 18]
    

    Ou, se o motivo for analítico:

    # análise restrita a adultos conforme definição do estudo (idade >= 18)
    adultos = df[df['idade'] >= 18]
    

    Note que a segunda versão também corrige um possível erro: o enunciado diz "maior que 18" mas a intenção provavelmente é "18 anos ou mais", o que seria >= 18. Comentar o raciocínio frequentemente revela inconsistências no código.

  5. Por que todos os imports devem ficar numa única célula no topo do notebook? O que acontece de problemático se você espalha imports ao longo do notebook?

    ✓ Resposta:

    Concentrar imports no topo serve a dois propósitos. Primeiro, deixa explícitas todas as dependências do notebook antes de qualquer execução: quem abre o arquivo vê imediatamente de quais bibliotecas ele depende. Segundo, garante que todas as bibliotecas estejam disponíveis antes de qualquer código que as usa.

    Quando imports estão espalhados, surgem dois problemas. O problema técnico: se alguém executa as células fora de ordem ou pula células, pode chegar numa célula que usa sns.barplot() antes de ter executado a célula que contém import seaborn as sns, gerando um NameError. O problema de legibilidade: para saber se o notebook usa pandas, você precisa ler todas as células em vez de olhar para os primeiros 10 linhas.

    Há uma exceção aceitável: imports de bibliotecas pesadas usadas apenas numa seção específica (como TensorFlow num notebook que faz análise e depois treina um modelo) podem ficar na seção relevante com um comentário explicando o motivo. Mas isso é exceção, não regra.

Referências

  • Documentação oficial do Jupyter Notebook: jupyter-notebook.readthedocs.io. Referência completa para instalação, uso e configuração.
  • JupyterLab Documentation: jupyterlab.readthedocs.io. Documentação da interface moderna que está substituindo o Notebook clássico.
  • Kluyver, Thomas et al. "Jupyter Notebooks — a publishing format for reproducible computational workflows". Positioning and Power in Academic Publishing, 2016. O artigo original descrevendo o projeto Jupyter e seus objetivos de reprodutibilidade.
  • Rule, Adam et al. "Ten Simple Rules for Reproducible Research in Jupyter Notebooks". PLOS Computational Biology, 2019. Artigo prático com dez recomendações concretas para notebooks reproduzíveis. Disponível em journals.plos.org.
  • Shen, Helen. "Interactive notebooks: Sharing the code". Nature, 2014. Artigo acessível sobre como os notebooks transformaram a ciência computacional.