Aula 1 - Ferramentas, Ambiente e Versionamento

Data de Publicação

14 de setembro de 2026

Motivação

Imagine a seguinte cena, porque ela vai acontecer com você mais cedo ou mais tarde.

Você passou duas semanas construindo uma análise excelente. O notebook roda perfeitamente na sua máquina. Você envia o arquivo para um colega e recebe de volta a mensagem mais temida da computação:

“Aqui não funcionou.”

Ou pior: você mesmo, três meses depois, abre o próprio projeto e ele não roda mais. Alguma biblioteca foi atualizada, algo quebrou, e você não faz ideia de qual versão usava na época. O código está lá, intacto, mas o resultado sumiu.

Esse tipo de situação não é um acidente raro. Ela é a consequência natural de trabalhar sem três práticas fundamentais: versionamento de código, isolamento de ambientes e registro de dependências. São exatamente essas três práticas que vamos construir nesta aula.

Ciência de Dados é, antes de tudo, ciência. E ciência precisa ser reprodutível: outra pessoa, com acesso aos mesmos dados e ao mesmo procedimento, deve conseguir chegar aos mesmos resultados. Um resultado que só existe na sua máquina, em um estado que você não consegue recriar, não é um resultado científico. É um acidente feliz.

Há ainda um argumento profissional. Quando você entrar em uma equipe de dados, ninguém vai perguntar se você sabe usar Git e ambientes virtuais. Isso é assumido como pré-requisito, da mesma forma que se assume que um cirurgião sabe lavar as mãos. As ferramentas desta aula são a infraestrutura invisível de todo projeto sério de dados: elas não aparecem no resultado final, mas sem elas o resultado final não se sustenta.

A aula de hoje tem um formato diferente do usual. Em vez de estudar cada ferramenta em uma seção separada, vamos fazer o que um cientista de dados faz no primeiro dia de um projeto real: criar a pasta, iniciar o repositório, montar o ambiente e instalar as primeiras dependências, nessa ordem. Cada ferramenta será apresentada no momento exato em que o projeto precisar dela. Ao final, o próprio histórico do projeto contará a história da aula.

Objetivos de aprendizagem

Ao final deste roteiro, você será capaz de:

  1. Descrever o ecossistema de ferramentas do cientista de dados que trabalha com Python e o papel de cada componente;
  2. Conhecer as principais IDEs usadas em ciência de dados, em Python e em outras linguagens;
  3. Criar a estrutura de um projeto de dados pelo terminal;
  4. Explicar a importância do versionamento de código e executar o ciclo essencial do Git (init, status, add, commit, log), sabendo que também existem tecnologias para versionamento de dados e de modelos;
  5. Comparar os gerenciadores de pacotes e ambientes mais comuns (pip, venv, conda e uv) e escolher o adequado para cada situação;
  6. Criar e usar ambientes virtuais isolados, explicando por que o isolamento e o registro de dependências são essenciais para a reprodutibilidade.
Como usar este roteiro

Leia as células de contexto com calma e execute as células de código na ordem em que aparecem. A ordem importa mais do que de costume: estamos construindo um projeto passo a passo, e cada etapa depende da anterior. Ao final do roteiro, três perguntas ajudam a consolidar o que foi aprendido. Tente respondê-las antes de expandir as explicações.

1. O mapa do território: o ecossistema do cientista de dados

Antes de colocar a mão na massa, vale abrir o mapa. Quando alguém diz que trabalha com ciência de dados em Python, na verdade está falando de um conjunto de ferramentas que operam juntas, cada uma resolvendo um problema específico:

Camada Ferramenta Para que serve
Linguagem Python A língua em que escrevemos análises e modelos
Bibliotecas NumPy, pandas, Matplotlib, scikit-learn Funcionalidades prontas: tabelas, gráficos, modelos
Gerenciador de pacotes pip, conda, uv Instala e organiza as bibliotecas
Ambiente virtual venv, conda env, uv venv Isola as bibliotecas de cada projeto
Ambiente de trabalho Jupyter, VS Code, IDEs Onde escrevemos e executamos o código
Terminal bash, PowerShell O painel de controle de todas as camadas
Versionamento Git e GitHub Histórico e colaboração no código

Uma analogia ajuda a fixar. Se o Python é o fogão, as bibliotecas são os ingredientes, o gerenciador de pacotes é o mercado onde você compra esses ingredientes, o ambiente virtual é uma cozinha separada para cada receita, a IDE é a sua bancada de trabalho, e o Git é o caderno de receitas que guarda todas as versões que você já testou, incluindo as que deram errado.

Não tente memorizar a tabela agora. Ela é um mapa de referência: ao longo da aula, vamos visitar cada linha no momento em que o nosso projeto precisar dela, e ao final a tabela fará sentido por experiência própria, não por decoreba.

Duas notas rápidas antes de seguir. Primeiro, sobre o terminal: ele é a interface de texto do sistema operacional, em que você digita comandos em vez de clicar em botões. Parece antiquado, mas é o padrão da área por um motivo prático: comandos de texto são precisos, automatizáveis e idênticos em qualquer máquina. Praticamente todas as ferramentas desta aula são operadas por ele. Segundo, sobre o Python: ele não é a linguagem mais rápida nem a mais elegante, mas venceu na área de dados pela sintaxe legível, pelo ecossistema científico construído ao longo de duas décadas e pelo efeito de rede: a maioria dos tutoriais, cursos e vagas da área usa Python. A linguagem R continua relevante em estatística e na academia, como veremos a seguir.

Vamos conferir o fogão. Execute a célula abaixo:

import sys

print(f"Versão do Python: {sys.version}")
print(f"Executável em uso: {sys.executable}")
Versão do Python: 3.10.12 (main, Mar  3 2026, 11:56:32) [GCC 11.4.0]
Executável em uso: /usr/bin/python3

Guarde um detalhe da saída: o caminho do executável. É comum ter vários interpretadores Python instalados na mesma máquina, cada um com o seu próprio conjunto de bibliotecas, e boa parte dos erros de iniciante (o famoso ModuleNotFoundError logo após instalar um pacote) vem de instalar a biblioteca em um Python e rodar o código em outro. Saber qual executável está em uso é o primeiro passo de qualquer diagnóstico, e os ambientes virtuais, que criaremos daqui a pouco, existem justamente para eliminar essa ambiguidade.

2. A bancada de trabalho: IDEs para ciência de dados

Antes de começar a obra, escolhemos a bancada. IDE, sigla em inglês para Integrated Development Environment, é o programa em que você escreve, executa e depura o seu código. Em ciência de dados, a escolha tem uma particularidade: trabalhamos intensamente com notebooks, documentos que misturam texto, código executável e resultados na mesma página, o que é excelente para exploração de dados e comunicação de resultados.

Ferramenta Linguagem principal Perfil
Jupyter Notebook / JupyterLab Python (e outras, via kernels) O ambiente clássico de notebooks. Ideal para exploração e ensino.
VS Code Todas O canivete suíço: leve, gratuito, com extensões para Python, notebooks, Git integrado e assistentes de IA. A escolha mais popular da atualidade.
PyCharm Python IDE robusta e completa, muito usada em engenharia de software com Python. Depurador excelente.
Spyder Python Interface no estilo MATLAB e RStudio, com explorador de variáveis. Amigável para quem vem das ciências exatas.
RStudio / Positron R (Positron: R e Python) A casa da comunidade R. O Positron é o sucessor moderno, poliglota, criado para ciência de dados.
Google Colab Python Notebooks na nuvem, sem instalar nada, com acesso gratuito a GPU. Excelente plano B e ótimo para estudar.

Para este curso, a recomendação é simples: JupyterLab para explorar e VS Code como base de operações, já que ele reúne notebooks, terminal e Git em uma única janela. Mas a mensagem mais importante é outra: os conceitos desta aula funcionam de forma idêntica em qualquer IDE. Ferramenta é meio, não fim. Não gaste energia em debates sobre qual editor é superior; gaste energia dominando os conceitos, que são transferíveis.

Um aviso prático sobre notebooks, já que vamos usá-los o semestre inteiro: as células podem ser executadas fora de ordem, e isso é uma armadilha para a reprodutibilidade. Se você executa a célula 10, volta e roda a 3, depois a 7, o estado da memória vira uma colcha de retalhos que a leitura de cima para baixo não explica. A proteção é um hábito: antes de considerar um notebook pronto, use a opção Restart Kernel and Run All e confira se ele roda inteiro, na ordem, sem erros. Guarde a regra: notebook bom é notebook que roda de cima a baixo depois de um restart.

Bancada escolhida. Hora de começar o projeto.

3. Nasce o projeto: terminal e estrutura de pastas

Todo projeto começa do mesmo jeito: uma pasta com um bom nome e uma estrutura mínima que separa as coisas. Vamos criar o nosso pelo terminal.

Uma nota sobre o formato: como este roteiro será executado no Jupyter, os comandos de terminal permanecem em células Python e começam com !. Esse prefixo instrui o notebook a enviar a linha ao shell, em vez de interpretá-la como Python. Repetimos o cd em cada célula porque cada comando abre uma sessão nova; no terminal de verdade, você entra na pasta uma vez e trabalha dentro dela.

!mkdir -p ./projeto-vendas/{data,notebooks,src}

!ls ./projeto-vendas
data  notebooks  README.md  requirements.txt  src

Simples assim: o projeto existe. Ele ainda não tem memória (qualquer mudança é irreversível) nem cozinha própria (nenhuma biblioteca isolada). São exatamente as duas próximas etapas, e a ordem entre elas não é por acaso: primeiro a memória, porque queremos que tudo o que acontecer a partir de agora já fique registrado.

4. Nasce a memória do projeto: Git e o primeiro commit

Você já criou arquivos com nomes assim?

analise_final.ipynb
analise_final_v2.ipynb
analise_final_v2_AGORA_VAI.ipynb
analise_final_v2_AGORA_VAI_revisado_prof.ipynb

Todos nós já criamos. Isso é um sistema de versionamento, só que um sistema péssimo: não há como saber o que mudou de uma versão para outra, quem mudou, quando, nem por quê. O Git resolve esse problema de forma elegante. Ele é um sistema de controle de versão: um programa que registra fotografias do estado do projeto ao longo do tempo. Cada fotografia, chamada de commit, guarda o conteúdo dos arquivos naquele momento, além do autor, da data e de uma mensagem explicando a mudança. Com esse histórico, você pode voltar no tempo para qualquer versão, ver exatamente o que mudou entre duas fotografias e, mais adiante, colaborar com outras pessoas sem sobrescrever o trabalho de ninguém.

Um esclarecimento que evita confusão: Git e GitHub não são a mesma coisa. O Git é o programa de versionamento, que roda na sua máquina e funciona inteiramente offline. O GitHub é um serviço na internet que hospeda repositórios Git e adiciona recursos de colaboração. A relação é parecida com a das suas fotos com um álbum online: as fotos existem sem o álbum, mas o álbum facilita o compartilhamento. Hoje trabalhamos com o Git local; a publicação no GitHub é o tema da próxima aula.

O modelo mental do Git tem três áreas, e entender essa separação evita a maior parte das confusões:

Diretorio de trabalho --(git add)--> Staging Area --(git commit)--> Repositorio
(seus arquivos,        (a bancada:                  (o historico
 a bagunca do          o que vai entrar             permanente de
 dia a dia)            na proxima foto)             fotografias)

Ou seja: editar e salvar um arquivo não o coloca no histórico. Primeiro você escolhe o que entra na próxima fotografia (git add), depois tira a fotografia (git commit). Essa etapa intermediária parece burocrática, mas é ela que permite montar commits organizados: você pode ter alterado cinco arquivos e decidir fotografar apenas dois agora, deixando os outros para um commit separado, com outra mensagem.

Nesta aula usaremos cinco comandos, que são o núcleo de todo o resto:

Comando O que faz
git init Transforma uma pasta comum em repositório Git
git status Mostra o estado atual: o que mudou, o que está na staging
git add arquivo Coloca mudanças na staging area, preparando a próxima foto
git commit -m “mensagem” Tira a foto: registra a versão no histórico
git log Mostra o histórico de commits

Comandos como git diff, git branch e git merge existem e são importantes, mas ficam para a próxima aula. Hoje o objetivo é transformar o ciclo status, add, commit em reflexo.

Vamos dar memória ao projeto:

# Transformamos a pasta em repositorio Git
!cd ./projeto-vendas && git init

# Configuracao de identidade: troque pelos SEUS dados.
# Essa informacao sera gravada em cada commit que voce fizer.
!cd ./projeto-vendas && git config user.name  "Seu Nome"
!cd ./projeto-vendas && git config user.email "seu.email@exemplo.com"

O git init criou uma pasta oculta chamada .git, onde todo o histórico ficará guardado. A partir de agora, o Git observa o projeto, mas nunca registra nada sem um comando explícito seu. Vamos criar o primeiro arquivo e perguntar ao Git o que ele está vendo:

# Criamos o README, o cartao de visitas de qualquer projeto
!cd ./projeto-vendas && echo "# Projeto Vendas" > README.md
!cd ./projeto-vendas && echo "Analise desenvolvida na disciplina de Ciencia de Dados." >> README.md

# O que o Git acha disso?
!cd ./projeto-vendas && git status

Observe a saída com atenção: o Git enxergou o README.md, mas o classificou como untracked, ou seja, não rastreado. Ele está avisando que existe um arquivo novo, mas que você ainda não disse se ele deve entrar na próxima fotografia. O Git nunca decide isso por você. Vamos decidir:

# Colocamos o arquivo na staging area, a bancada da foto...
!cd ./projeto-vendas && git add README.md

# ...e tiramos a foto, com uma mensagem descritiva.
!cd ./projeto-vendas && git commit -m "Adiciona README com a descricao do projeto"

# O historico agora tem a sua primeira fotografia:
!cd ./projeto-vendas && git log --oneline

Você acabou de fazer o seu primeiro commit. O código alfanumérico no início da linha é o identificador único daquela fotografia. Esse ciclo, modificar, add, commit, é o batimento cardíaco do trabalho com Git, e vamos repeti-lo mais algumas vezes ainda hoje, a cada etapa do projeto. Uma boa prática desde já: commits pequenos e frequentes, com mensagens que descrevem a mudança. Mensagens vagas como “ajustes” tornam o histórico inútil, porque ninguém localiza nada nele depois.

Uma última ideia antes de seguir: em ciência de dados, não é só o código que muda com o tempo. Os dados mudam (chegam registros novos, erros são corrigidos) e os modelos treinados também (novos hiperparâmetros, novos dados de treino). O Git não foi projetado para arquivos grandes e binários, mas o ecossistema tem ferramentas dedicadas: DVC e Git LFS versionam datasets ao lado do Git, e MLflow e Weights and Biases registram experimentos e versões de modelos. Guarde apenas a ideia central: em um projeto profissional, código, dados e modelos são versionados. Começamos pelo código porque ele é a base.

5. Nasce o ambiente: isolamento e o incidente do git status

O projeto tem memória. Agora ele precisa de uma cozinha própria: um lugar isolado para instalar bibliotecas sem interferir em nenhum outro projeto da máquina. Antes do comando, o motivo, contado em três atos:

  • Em março, você desenvolveu o Projeto A, que utiliza pandas na versão 1.5.
  • Em agosto, você começou o Projeto B e atualizou o pandas para a versão 2.2.
  • Em setembro, você reabriu o Projeto A e ele quebrou: a atualização mudou comportamentos dos quais o código antigo dependia.

O que aconteceu? Os dois projetos compartilhavam uma única instalação de Python e, portanto, uma única versão de cada biblioteca. Ao atualizar o pandas para um projeto, você alterou, sem perceber, o ambiente do outro. A solução é o ambiente virtual: uma pasta isolada com uma cópia do interpretador Python e um conjunto próprio de bibliotecas, nas versões exatas de que aquele projeto precisa. Um esclarecimento: ambiente virtual não é máquina virtual. Ele não emula um sistema operacional; é apenas uma pasta, criada em segundos e apagada com um simples delete. A regra prática da área é: um projeto, um ambiente, sem exceções.

Criar o ambiente com o quê?

Aqui surge a primeira decisão de ferramenta da aula, e ela merece uma comparação honesta, porque o ecossistema Python tem várias opções com sobreposição parcial:

Ferramenta O que é Pontos fortes Pontos fracos
pip O instalador de pacotes oficial do Python. Baixa pacotes do repositório PyPI. Vem junto com o Python; funciona em qualquer lugar; é o denominador comum do ecossistema. Só instala, não isola: precisa do venv como parceiro. Resolução de dependências lenta.
venv Módulo da biblioteca padrão que cria ambientes virtuais. Nativo, simples, sem instalar nada extra. Só cria o ambiente: não instala pacotes nem gerencia versões do Python.
conda Gerenciador de pacotes e de ambientes, do ecossistema Anaconda. Instala também dependências que não são Python (CUDA, bibliotecas C, R). Por isso domina a computação científica e o deep learning. Mais pesado e mais lento; usa um ecossistema de pacotes paralelo ao PyPI.
uv Ferramenta moderna escrita em Rust, criada pela Astral. Entre 10 e 100 vezes mais rápido que o pip; unifica pacotes, ambientes, versões do Python e arquivos de lock em uma única ferramenta. Mais recente: algumas empresas ainda estão migrando; não substitui o conda para dependências nativas.

E qual é a mais usada atualmente? A resposta exige uma distinção. O pip ainda é a ferramenta mais onipresente: vem instalado com o Python e todo o ecossistema é compatível com ele. O uv, porém, tornou-se o padrão recomendado para projetos novos: a comunidade migrou rapidamente para ele pela velocidade e por resolver sozinho o que antes exigia quatro ferramentas combinadas. Em projetos novos, é a ferramenta dominante da atualidade, e será o padrão deste curso. O conda continua sendo a escolha correta quando o projeto precisa de dependências fora do mundo Python, como drivers CUDA para deep learning com GPU. Em resumo: aprenda pip e venv porque são o fundamento; use uv no dia a dia; e saiba que o conda existe para quando o problema for maior do que o Python.

Decisão tomada. Vamos criar o ambiente do nosso projeto com o uv:

# Criamos o ambiente virtual: uma pasta .venv dentro do projeto
!cd ./projeto-vendas && uv venv --clear

# O ambiente existe. Vamos conferir a pasta do projeto:
!ls -a ./projeto-vendas

Nos comandos do dia a dia, no terminal, você ativaria o ambiente com source .venv/bin/activate (Linux e Mac) ou .venv\Scripts\Activate.ps1 (Windows), e o nome do ambiente apareceria entre parênteses no início da linha, como (.venv). Esse é o sinal de que você está na cozinha certa. Com o uv há um atalho ainda melhor, que veremos já já: o uv run executa qualquer comando dentro do ambiente sem precisar ativar nada.

O incidente

Agora pergunte ao Git como ele está se sentindo a respeito:

!cd ./projeto-vendas && git status

O Git está apontando para a pasta .venv como conteúdo novo, não rastreado. E se você fizesse um git add nela, centenas de arquivos de bibliotecas entrariam no histórico do projeto: arquivos que não são seus, que mudam a cada instalação e que qualquer pessoa recria em segundos. O repositório ficaria inchado e o histórico, poluído.

Esse pequeno incidente ensina uma distinção importante: nem tudo o que está na pasta do projeto pertence ao histórico do projeto. Três categorias devem ficar de fora. Primeiro, artefatos recriáveis, como o próprio .venv e os caches da pasta pycache: são gerados a partir do código e não carregam informação própria. Segundo, credenciais e segredos, como senhas e chaves de API: uma vez commitados, ficam no histórico para sempre, mesmo que você apague o arquivo depois, e existem robôs varrendo o GitHub continuamente em busca de chaves vazadas. Terceiro, dados brutos grandes: incham o repositório e frequentemente contêm informação pessoal ou sensível, o que envolve questões legais como a LGPD; para eles existem as ferramentas de versionamento de dados que mencionamos, como o DVC.

A solução formal é o arquivo .gitignore: uma lista de padrões de nomes que o Git deve ignorar por completo. Vamos criar o nosso e resolver o incidente:

# Criamos o .gitignore com as exclusoes classicas de projetos de dados
!cd ./projeto-vendas && printf ".venv/\n__pycache__/\ndata/\n*.env\n.ipynb_checkpoints/\n" > .gitignore

# O incidente foi resolvido? So o .gitignore deve aparecer como novo:
!cd ./projeto-vendas && git status
# O .gitignore faz parte do projeto e deve ser versionado. Novo ciclo:
!cd ./projeto-vendas && git add .gitignore
!cd ./projeto-vendas && git commit -m "Adiciona .gitignore para ambiente, dados e segredos"
!cd ./projeto-vendas && git log --oneline

Repare no hábito se formando: cada etapa do projeto termina com um commit. É o segundo do dia, e não será o último.

6. O projeto ganha dependências: instalação e registro de versões

Cozinha montada, hora de comprar os ingredientes. Vamos instalar o pandas, a biblioteca central da próxima aula, dentro do ambiente do projeto:

# O uv detecta o .venv da pasta e instala DENTRO dele
!cd ./projeto-vendas && uv pip install pandas

# Quais bibliotecas o ambiente tem agora? Observe as colunas: nome e versao.
!cd ./projeto-vendas && uv pip list

Observe a saída do uv pip list: cada biblioteca aparece acompanhada de um número de versão exato, por exemplo pandas 2.2.3, além das dependências que vieram junto, como o numpy. Esse detalhe é o coração da reprodutibilidade, porque bibliotecas mudam de comportamento entre versões: uma função pode ser renomeada, um parâmetro pode mudar de valor padrão, um bug pode ser corrigido, alterando o resultado numérico, ou introduzido. O mesmo código com pandas 1.5 e com pandas 2.2 pode produzir resultados diferentes, ou simplesmente não rodar. Dizer “usei pandas” não basta; é preciso registrar “usei pandas 2.2.3”.

E onde se registra isso? Em um arquivo dentro do repositório:

# Congelamos as versoes exatas do ambiente em um arquivo
!cd ./projeto-vendas && uv pip freeze > requirements.txt

# O que ficou registrado?
!cd ./projeto-vendas && cat requirements.txt

Esse arquivo é a lista de ingredientes com as quantidades exatas da sua receita. Com ele no repositório, qualquer pessoa, incluindo o seu eu do futuro, recria o ambiente idêntico com um único comando (uv pip install -r requirements.txt) e obtém os mesmos resultados. Essa é a fórmula central da aula, agora materializada em arquivos concretos:

Isolamento (a pasta .venv) + registro de versões (o requirements.txt) = reprodutibilidade.

Note a divisão de papéis, que resolve o incidente da seção anterior de forma definitiva: o ambiente em si fica fora do histórico, porque é recriável; a receita para recriá-lo fica dentro do histórico, porque é ela que carrega a informação. Versionamos a receita, não a cozinha.

E claro, etapa concluída, commit:

!cd ./projeto-vendas && git add requirements.txt
!cd ./projeto-vendas && git commit -m "Adiciona pandas e registra dependencias em requirements.txt"
!cd ./projeto-vendas && git log --oneline

Uma confissão para fechar a seção: fizemos cada passo manualmente, de propósito, para que você entendesse cada peça. No dia a dia, o uv automatiza boa parte disso: o comando uv init cria a pasta, o pyproject.toml (a descrição moderna do projeto) e o ambiente de uma vez, e o uv add pandas instala a biblioteca já registrando a versão exata em um arquivo de lock (uv.lock), mais preciso que o requirements.txt. A lógica, porém, é idêntica: criar, isolar, instalar, registrar. Você aprendeu o mecanismo; a automação agora é um atalho consciente, não uma caixa-preta. Experimente o uv init no exercício para casa.

7. Fechamento: o histórico conta a história

Vamos encerrar pedindo ao projeto que conte a própria história:

!cd ./projeto-vendas && git log --oneline

Leia as três linhas de baixo para cima. Elas são a ata desta aula:

  1. “Adiciona README com a descricao do projeto”: o projeto nasceu e ganhou memória;
  2. “Adiciona .gitignore para ambiente, dados e segredos”: o ambiente virtual chegou, causou o incidente do git status e ensinou a diferença entre o que se versiona e o que se ignora;
  3. “Adiciona pandas e registra dependencias em requirements.txt”: o projeto ganhou a sua primeira dependência, com a versão devidamente registrada.

Cada commit corresponde a uma etapa que você viveu. É assim que um repositório bem cuidado funciona: o git log de um bom projeto é legível como uma narrativa, e qualquer pessoa que chegue depois consegue reconstituir as decisões tomadas.

Recapitulando o que você conquistou:

  • Conheceu o mapa do ecossistema do cientista de dados e as principais IDEs da área, em Python e em outras linguagens;
  • Criou um projeto do zero pelo terminal, com estrutura de pastas;
  • Deu memória ao projeto com o Git e praticou o ciclo essencial (init, status, add, commit, log) três vezes, uma a cada etapa;
  • Comparou pip, venv, conda e uv, e sabe que o uv é o padrão atual para projetos novos, que o pip é o fundamento universal e que o conda é a escolha para dependências científicas nativas;
  • Criou um ambiente virtual isolado, viveu o incidente do .venv no git status e o resolveu com o .gitignore;
  • Materializou a fórmula da reprodutibilidade: isolamento mais registro de versões, com o requirements.txt versionado no repositório;
  • Descobriu que dados e modelos também são versionados, com ferramentas como DVC e MLflow, e que branch, merge e GitHub são os próximos capítulos.

Perguntas para consolidar

Agora que o projeto está de pé, três perguntas para exercitar o que foi aprendido. Tente responder cada uma antes de expandir a explicação: o aprendizado acontece na tentativa, não na leitura da solução.

Pergunta 1: o colega cético

Um colega afirma: “Ambiente virtual é exagero. Eu instalo tudo no Python global e nunca tive problema.” Ele trabalha sozinho e mantém um único projeto. Ele está errado? E o que muda quando ele tiver dois projetos, ou um colega de equipe?

Com um único projeto e trabalhando sozinho, ele de fato pode viver sem sentir dor por algum tempo. O problema é invisível até o dia em que deixa de ser. Considere três cenários:

Dois projetos: no momento em que dois projetos precisarem de versões diferentes da mesma biblioteca, um deles quebra. Pior: atualizar uma biblioteca para o projeto novo pode quebrar silenciosamente o projeto antigo, e ele só vai descobrir semanas depois, quando reabrir o código.

Um colega de equipe: sem um ambiente isolado e um arquivo de versões, o novo colega não tem como saber o que instalar. Ele vai instalar as versões mais recentes de tudo, que provavelmente não são as que o projeto usa, e o famoso “aqui não funcionou” está garantido.

O futuro: mesmo sem colegas, o eu de daqui a seis meses é, na prática, outra pessoa, que não lembra de nada e precisará recriar o ambiente do zero.

Ou seja: não é exagero, é um seguro contra um acidente que vai acontecer. E com ferramentas como o uv, criar um ambiente custa segundos. O seguro ficou barato demais para ser recusado.

Pergunta 2: ignorar não é proteger

No nosso projeto, o .gitignore exclui a pasta data/ do versionamento. Suponha que você coloque um arquivo valioso, digamos data/vendas.csv, nessa pasta, e meses depois o apague por acidente. O Git consegue recuperá-lo, como recuperaria o README.md? O que isso ensina sobre a diferença entre ignorar e versionar, e qual seria a estratégia correta para proteger esse arquivo?

Não, o Git não consegue recuperar o vendas.csv. O README.md está no histórico: um simples git restore README.md o traz de volta, porque há fotografias dele guardadas. Já a pasta data/ está sendo ignorada: para o Git, o que está nela não existe, e nenhuma fotografia jamais a incluiu. Ignorar um arquivo significa abrir mão, para aquele arquivo, de toda a proteção que o versionamento oferece.

Por isso a decisão sobre o que entra no .gitignore é uma decisão de engenharia, e não um detalhe burocrático. Segredos devem ficar de fora por proteção (uma chave commitada fica no histórico para sempre). Artefatos recriáveis, como o .venv, podem ficar de fora porque o requirements.txt permite regenerá-los. Mas dados valiosos não são nem segredo a esconder, nem artefato recriável: eles precisam de uma estratégia própria de proteção, que é backup e, em projetos maduros, versionamento de dados com ferramentas dedicadas, como o DVC e o Git LFS, que guardam os dados fora do repositório e mantêm no Git apenas referências leves.

A síntese: versionamos a receita, ignoramos o que a receita recria, e protegemos os dados por outros meios.

Pergunta 3: o teste definitivo da aula

Sua colega clonou o repositório do projeto-vendas na máquina dela. Ela recebeu o README.md, o .gitignore e o requirements.txt, mas não recebeu a pasta .venv, que está no .gitignore. Descreva, passo a passo, o que ela precisa fazer para executar o projeto com exatamente as mesmas versões de bibliotecas que você usou. Em seguida, responda: por que o fato de o .venv não viajar junto não é um defeito, e sim o próprio desenho da reprodutibilidade?

O caminho dela tem três passos, todos já vistos na aula:

  1. Entrar na pasta do projeto clonado pelo terminal;
  2. Criar um ambiente virtual novo, com uv venv;
  3. Instalar as dependências registradas, com uv pip install -r requirements.txt.

Pronto: o ambiente dela agora contém exatamente as mesmas bibliotecas, nas mesmas versões, que o seu, porque o requirements.txt registrou tudo com precisão. O código rodará sobre a mesma fundação nas duas máquinas.

E por que o .venv não viajar junto é o desenho correto? Porque o ambiente é um artefato local e recriável: ele contém arquivos compilados para o sistema operacional de cada máquina (um .venv criado no Windows não funciona no Linux) e pode ser regenerado em segundos a partir da receita. O que precisa viajar é a informação, não o artefato: a receita (requirements.txt) é leve, universal e suficiente. Transportar a cozinha inteira seria pesado, frágil e desnecessário, quando a receita reconstrói a cozinha em qualquer lugar.

Se você respondeu essa pergunta com segurança, você entendeu a aula inteira: o repositório carrega o código e as receitas; cada máquina reconstrói o resto. É exatamente assim que equipes de dados profissionais trabalham todos os dias.

Para casa

  1. Refaça o projeto do zero, em uma pasta nova e sem consultar o roteiro, digitando os comandos diretamente no terminal, sem o ponto de exclamação. Se errar, ótimo: errar aqui é barato e pedagógico. Use o git status como bússola sempre que se perder.
  2. Experimente a automação: crie um segundo projeto com uv init, adicione o pandas com uv add pandas e compare os arquivos gerados (pyproject.toml e uv.lock) com o que fizemos manualmente. Tente identificar o que cada arquivo registra.
  3. Crie uma conta no GitHub, caso ainda não tenha. Na próxima aula vamos publicar o projeto-vendas lá e conhecer clone, push, pull, branch e merge.

Ferramentas não fazem um bom cientista de dados, mas nenhum bom cientista de dados trabalha sem elas.

Até a próxima aula, quando os dados finalmente entram em cena: Introdução aos Dados Tabulares.