Você já estudou Python, conhece os fundamentos, mas agora bate aquela dúvida: "E agora? Como provar que sei programar?"
A resposta é simples: construindo projetos. Não importa se você está buscando seu primeiro emprego ou quer consolidar conhecimento — um portfólio com projetos reais vale mais que 10 certificados.
Neste guia, vou te mostrar 5 projetos Python completos, do mais simples ao intermediário, com código passo a passo. Todos são perfeitos para iniciantes e vão impressionar recrutadores.
🎯 Por Que Você Precisa de um Portfólio de Projetos?
Antes de mergulhar nos projetos, entenda: o mercado não contrata quem sabe teoria. Empresas querem ver se você consegue transformar conhecimento em soluções reais.
Um portfólio forte mostra:
- Capacidade de resolver problemas: Você sai do "print('Olá, mundo!')" e cria algo útil
- Domínio de ferramentas: APIs, manipulação de arquivos, automação
- Organização de código: Funções, estrutura limpa, comentários
- Pensamento lógico: Como você estrutura a solução do começo ao fim
Vamos aos projetos!
📋 Projeto 1: Gerador de Senhas Forte e Seguro
🎯 O que você vai aprender
- Manipulação de strings
- Biblioteca
random - Validação de entrada do usuário
- Concatenação e formatação
💡 Por que este projeto é importante
Todo mundo precisa de senhas fortes. Este projeto mostra que você entende segurança digital e consegue criar ferramentas úteis.
📝 Código Completo
import random
import string
def gerar_senha(tamanho=12, incluir_especiais=True):
"""
Gera uma senha aleatória forte
Parâmetros:
- tamanho: comprimento da senha (padrão: 12)
- incluir_especiais: se deve incluir caracteres especiais
"""
# Define os caracteres disponíveis
caracteres = string.ascii_letters + string.digits
if incluir_especiais:
caracteres += string.punctuation
# Gera a senha aleatória
senha = ''.join(random.choice(caracteres) for _ in range(tamanho))
return senha
def validar_forca_senha(senha):
"""Valida se a senha é forte"""
tem_maiuscula = any(c.isupper() for c in senha)
tem_minuscula = any(c.islower() for c in senha)
tem_numero = any(c.isdigit() for c in senha)
tem_especial = any(c in string.punctuation for c in senha)
if len(senha) >= 12 and tem_maiuscula and tem_minuscula and tem_numero and tem_especial:
return "🟢 Senha FORTE"
elif len(senha) >= 8:
return "🟡 Senha MÉDIA"
else:
return "🔴 Senha FRACA"
# Menu principal
print("🔐 GERADOR DE SENHAS SEGURAS")
print("-" * 40)
tamanho = int(input("Tamanho da senha (mínimo 8): "))
especiais = input("Incluir caracteres especiais? (s/n): ").lower() == 's'
senha_gerada = gerar_senha(tamanho, especiais)
print(f"\n✅ Senha gerada: {senha_gerada}")
print(f"📊 Força: {validar_forca_senha(senha_gerada)}")
🚀 Como melhorar este projeto
- Adicione opção de salvar senhas em arquivo criptografado
- Crie interface gráfica com Tkinter
- Permita gerar múltiplas senhas de uma vez
- Adicione verificação de senhas comprometidas via API
🎲 Projeto 2: Jogo da Adivinhação com Níveis de Dificuldade
🎯 O que você vai aprender
- Estruturas condicionais (if/elif/else)
- Loops (while)
- Lógica de programação
- Interação com usuário
💡 Por que este projeto é importante
Jogos ensinam lógica pura. Este projeto demonstra que você domina condicionais, loops e sabe criar experiências interativas.
📝 Código Completo
import random
def jogar_adivinhacao():
print("🎮 JOGO DA ADIVINHAÇÃO")
print("=" * 50)
# Escolhe nível de dificuldade
print("\nEscolha a dificuldade:")
print("1 - Fácil (1-50, 10 tentativas)")
print("2 - Médio (1-100, 7 tentativas)")
print("3 - Difícil (1-500, 5 tentativas)")
nivel = int(input("\nNível: "))
# Define configurações por nível
configuracoes = {
1: {'max': 50, 'tentativas': 10},
2: {'max': 100, 'tentativas': 7},
3: {'max': 500, 'tentativas': 5}
}
config = configuracoes.get(nivel, configuracoes[1])
numero_secreto = random.randint(1, config['max'])
tentativas_restantes = config['tentativas']
print(f"\n🎯 Adivinhe o número entre 1 e {config['max']}")
print(f"⏱️ Você tem {tentativas_restantes} tentativas\n")
# Loop do jogo
while tentativas_restantes > 0:
try:
palpite = int(input(f"Tentativa {config['tentativas'] - tentativas_restantes + 1}: "))
if palpite < 1 or palpite > config['max']:
print(f"❌ Digite um número entre 1 e {config['max']}!")
continue
tentativas_restantes -= 1
if palpite == numero_secreto:
print(f"\n🎉 PARABÉNS! Você acertou em {config['tentativas'] - tentativas_restantes} tentativas!")
return
elif palpite < numero_secreto:
print(f"📈 Muito baixo! Restam {tentativas_restantes} tentativas")
else:
print(f"📉 Muito alto! Restam {tentativas_restantes} tentativas")
except ValueError:
print("❌ Digite apenas números!")
print(f"\n😔 Game Over! O número era {numero_secreto}")
# Executar jogo
jogar_adivinhacao()
# Opção de jogar novamente
while input("\nJogar novamente? (s/n): ").lower() == 's':
jogar_adivinhacao()
🚀 Como melhorar este projeto
- Adicione sistema de pontuação baseado em tentativas
- Crie ranking dos melhores jogadores (salvando em arquivo)
- Adicione dicas mais inteligentes (quente/frio)
- Implemente modo multiplayer
📊 Projeto 3: Analisador de Gastos Pessoais
🎯 O que você vai aprender
- Manipulação de listas e dicionários
- Leitura e escrita de arquivos CSV
- Cálculos e estatísticas básicas
- Formatação de dados
💡 Por que este projeto é importante
Trabalhar com dados é essencial em qualquer área. Este projeto mostra que você sabe manipular, analisar e apresentar informações de forma organizada.
📝 Código Completo
import csv
from datetime import datetime
from collections import defaultdict
class AnalisadorGastos:
def __init__(self):
self.gastos = []
self.arquivo = 'gastos.csv'
self.carregar_gastos()
def carregar_gastos(self):
"""Carrega gastos do arquivo CSV"""
try:
with open(self.arquivo, 'r', encoding='utf-8') as arquivo:
leitor = csv.DictReader(arquivo)
self.gastos = list(leitor)
# Converte valores para float
for gasto in self.gastos:
gasto['valor'] = float(gasto['valor'])
except FileNotFoundError:
print("📁 Arquivo não encontrado. Criando novo...")
self.criar_arquivo()
def criar_arquivo(self):
"""Cria arquivo CSV se não existir"""
with open(self.arquivo, 'w', newline='', encoding='utf-8') as arquivo:
campos = ['data', 'categoria', 'descricao', 'valor']
escritor = csv.DictWriter(arquivo, fieldnames=campos)
escritor.writeheader()
def adicionar_gasto(self, categoria, descricao, valor):
"""Adiciona novo gasto"""
gasto = {
'data': datetime.now().strftime('%Y-%m-%d'),
'categoria': categoria,
'descricao': descricao,
'valor': float(valor)
}
self.gastos.append(gasto)
# Salva no CSV
with open(self.arquivo, 'a', newline='', encoding='utf-8') as arquivo:
campos = ['data', 'categoria', 'descricao', 'valor']
escritor = csv.DictWriter(arquivo, fieldnames=campos)
escritor.writerow(gasto)
print(f"✅ Gasto de R$ {valor:.2f} adicionado!")
def relatorio_por_categoria(self):
"""Mostra relatório agrupado por categoria"""
if not self.gastos:
print("❌ Nenhum gasto registrado!")
return
categorias = defaultdict(float)
for gasto in self.gastos:
categorias[gasto['categoria']] += gasto['valor']
print("\n📊 RELATÓRIO POR CATEGORIA")
print("-" * 50)
total_geral = sum(categorias.values())
for categoria, valor in sorted(categorias.items(), key=lambda x: x[1], reverse=True):
percentual = (valor / total_geral) * 100
print(f"{categoria:20} R$ {valor:>10.2f} ({percentual:.1f}%)")
print("-" * 50)
print(f"{'TOTAL':20} R$ {total_geral:>10.2f}")
def relatorio_mensal(self):
"""Mostra gastos do mês atual"""
mes_atual = datetime.now().strftime('%Y-%m')
gastos_mes = [g for g in self.gastos if g['data'].startswith(mes_atual)]
if not gastos_mes:
print(f"❌ Nenhum gasto em {mes_atual}")
return
total = sum(g['valor'] for g in gastos_mes)
print(f"\n📅 GASTOS DE {mes_atual}")
print("-" * 70)
print(f"{'Data':<12} {'Categoria':<15} {'Descrição':<25} {'Valor':>10}")
print("-" * 70)
for gasto in sorted(gastos_mes, key=lambda x: x['data']):
print(f"{gasto['data']:<12} {gasto['categoria']:<15} "
f"{gasto['descricao']:<25} R$ {gasto['valor']:>8.2f}")
print("-" * 70)
print(f"{'TOTAL DO MÊS':>52} R$ {total:>8.2f}")
# Menu principal
def menu():
analisador = AnalisadorGastos()
while True:
print("\n💰 ANALISADOR DE GASTOS PESSOAIS")
print("1 - Adicionar gasto")
print("2 - Relatório por categoria")
print("3 - Relatório mensal")
print("4 - Sair")
opcao = input("\nEscolha uma opção: ")
if opcao == '1':
categoria = input("Categoria (ex: Alimentação, Transporte): ")
descricao = input("Descrição: ")
valor = float(input("Valor (R$): "))
analisador.adicionar_gasto(categoria, descricao, valor)
elif opcao == '2':
analisador.relatorio_por_categoria()
elif opcao == '3':
analisador.relatorio_mensal()
elif opcao == '4':
print("👋 Até logo!")
break
if __name__ == "__main__":
menu()
🚀 Como melhorar este projeto
- Adicione gráficos com matplotlib
- Crie metas de gastos por categoria
- Implemente filtros por período personalizado
- Adicione exportação para Excel/PDF
🌐 Projeto 4: Web Scraper de Notícias
🎯 O que você vai aprender
- Biblioteca BeautifulSoup para web scraping
- Requisições HTTP com requests
- Manipulação de HTML
- Tratamento de exceções
💡 Por que este projeto é importante
Web scraping é uma habilidade valiosa no mercado. Este projeto demonstra que você consegue extrair dados da web de forma automatizada.
📝 Código Completo
import requests
from bs4 import BeautifulSoup
from datetime import datetime
import json
class ScraperNoticias:
def __init__(self):
self.headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
def buscar_noticias_python(self):
"""Busca notícias sobre Python no site Python.org"""
url = 'https://www.python.org/blogs/'
try:
print("🔍 Buscando notícias sobre Python...")
resposta = requests.get(url, headers=self.headers, timeout=10)
resposta.raise_for_status()
soup = BeautifulSoup(resposta.content, 'html.parser')
# Encontra artigos (ajuste o seletor conforme o site)
artigos = soup.find_all('article', class_='blog-widget', limit=5)
noticias = []
for artigo in artigos:
try:
titulo_tag = artigo.find('h2', class_='widget-title')
titulo = titulo_tag.get_text(strip=True) if titulo_tag else 'Sem título'
link_tag = titulo_tag.find('a') if titulo_tag else None
link = link_tag['href'] if link_tag else '#'
# Monta link completo
if link.startswith('/'):
link = f'https://www.python.org{link}'
resumo_tag = artigo.find('p')
resumo = resumo_tag.get_text(strip=True)[:200] if resumo_tag else 'Sem descrição'
noticia = {
'titulo': titulo,
'link': link,
'resumo': resumo,
'data_coleta': datetime.now().strftime('%Y-%m-%d %H:%M')
}
noticias.append(noticia)
except Exception as e:
print(f"❌ Erro ao processar artigo: {e}")
continue
return noticias
except requests.exceptions.RequestException as e:
print(f"❌ Erro ao acessar o site: {e}")
return []
def exibir_noticias(self, noticias):
"""Exibe as notícias formatadas"""
if not noticias:
print("❌ Nenhuma notícia encontrada!")
return
print(f"\n📰 {len(noticias)} NOTÍCIAS ENCONTRADAS")
print("=" * 80)
for i, noticia in enumerate(noticias, 1):
print(f"\n{i}. {noticia['titulo']}")
print(f" {noticia['resumo']}...")
print(f" 🔗 {noticia['link']}")
print(f" 📅 Coletado em: {noticia['data_coleta']}")
print("-" * 80)
def salvar_json(self, noticias, arquivo='noticias.json'):
"""Salva notícias em arquivo JSON"""
try:
with open(arquivo, 'w', encoding='utf-8') as f:
json.dump(noticias, f, ensure_ascii=False, indent=4)
print(f"✅ Notícias salvas em {arquivo}")
except Exception as e:
print(f"❌ Erro ao salvar arquivo: {e}")
# Executar scraper
def main():
scraper = ScraperNoticias()
print("🌐 WEB SCRAPER DE NOTÍCIAS PYTHON")
print("=" * 80)
noticias = scraper.buscar_noticias_python()
scraper.exibir_noticias(noticias)
if noticias:
salvar = input("\n💾 Deseja salvar em JSON? (s/n): ")
if salvar.lower() == 's':
scraper.salvar_json(noticias)
if __name__ == "__main__":
# Primeiro, instale as bibliotecas:
# pip install requests beautifulsoup4
main()
🚀 Como melhorar este projeto
- Adicione scraping de múltiplos sites
- Implemente agendamento automático (cron/schedule)
- Crie sistema de notificações por email
- Adicione análise de sentimento nas notícias
🤖 Projeto 5: Automatizador de Tarefas Diárias
🎯 O que você vai aprender
- Automação de arquivos e pastas
- Biblioteca os e shutil
- Agendamento de tarefas
- Organização de código em módulos
💡 Por que este projeto é importante
Automação economiza tempo e mostra que você resolve problemas reais. Este projeto impressiona porque tem aplicação prática imediata.
📝 Código Completo
import os
import shutil
from datetime import datetime
from pathlib import Path
class AutomatizadorArquivos:
def __init__(self, pasta_origem):
self.pasta_origem = Path(pasta_origem)
self.extensoes = {
'Imagens': ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.svg'],
'Documentos': ['.pdf', '.doc', '.docx', '.txt', '.xlsx', '.pptx'],
'Videos': ['.mp4', '.avi', '.mkv', '.mov', '.flv'],
'Musicas': ['.mp3', '.wav', '.flac', '.aac'],
'Compactados': ['.zip', '.rar', '.7z', '.tar', '.gz'],
'Codigo': ['.py', '.js', '.html', '.css', '.java', '.cpp']
}
def organizar_downloads(self):
"""Organiza arquivos por tipo em pastas"""
if not self.pasta_origem.exists():
print(f"❌ Pasta {self.pasta_origem} não existe!")
return
print(f"🗂️ Organizando arquivos em {self.pasta_origem}")
arquivos_movidos = 0
for arquivo in self.pasta_origem.iterdir():
if arquivo.is_file():
extensao = arquivo.suffix.lower()
# Determina categoria do arquivo
categoria = self.obter_categoria(extensao)
if categoria:
# Cria pasta da categoria se não existir
pasta_destino = self.pasta_origem / categoria
pasta_destino.mkdir(exist_ok=True)
# Move arquivo
try:
destino = pasta_destino / arquivo.name
# Se arquivo já existe, adiciona timestamp
if destino.exists():
nome_base = arquivo.stem
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
destino = pasta_destino / f"{nome_base}_{timestamp}{extensao}"
shutil.move(str(arquivo), str(destino))
arquivos_movidos += 1
print(f"✅ {arquivo.name} → {categoria}/")
except Exception as e:
print(f"❌ Erro ao mover {arquivo.name}: {e}")
print(f"\n🎉 {arquivos_movidos} arquivos organizados!")
def obter_categoria(self, extensao):
"""Retorna categoria baseada na extensão"""
for categoria, extensoes in self.extensoes.items():
if extensao in extensoes:
return categoria
return None
def limpar_arquivos_antigos(self, dias=30):
"""Remove arquivos mais antigos que X dias"""
agora = datetime.now().timestamp()
limite = dias * 24 * 60 * 60 # Converte dias para segundos
removidos = 0
for arquivo in self.pasta_origem.rglob('*'):
if arquivo.is_file():
idade = agora - arquivo.stat().st_mtime
if idade > limite:
try:
arquivo.unlink()
print(f"🗑️ Removido: {arquivo.name}")
removidos += 1
except Exception as e:
print(f"❌ Erro ao remover {arquivo.name}: {e}")
print(f"\n🎉 {removidos} arquivos antigos removidos!")
def gerar_relatorio(self):
"""Gera relatório de arquivos por categoria"""
print("\n📊 RELATÓRIO DE ARQUIVOS")
print("=" * 60)
categorias_count = {}
total_tamanho = 0
for arquivo in self.pasta_origem.rglob('*'):
if arquivo.is_file():
extensao = arquivo.suffix.lower()
categoria = self.obter_categoria(extensao) or 'Outros'
tamanho = arquivo.stat().st_size
if categoria not in categorias_count:
categorias_count[categoria] = {'count': 0, 'size': 0}
categorias_count[categoria]['count'] += 1
categorias_count[categoria]['size'] += tamanho
total_tamanho += tamanho
for categoria, dados in sorted(categorias_count.items()):
tamanho_mb = dados['size'] / (1024 * 1024)
print(f"{categoria:15} {dados['count']:>5} arquivos {tamanho_mb:>10.2f} MB")
print("=" * 60)
print(f"{'TOTAL':15} {sum(d['count'] for d in categorias_count.values()):>5} arquivos "
f"{total_tamanho / (1024 * 1024):>10.2f} MB")
# Menu principal
def menu():
pasta = input("📁 Digite o caminho da pasta (ou Enter para Downloads): ").strip()
if not pasta:
# Pasta padrão de Downloads
pasta = str(Path.home() / "Downloads")
automatizador = AutomatizadorArquivos(pasta)
while True:
print(f"\n🤖 AUTOMATIZADOR DE ARQUIVOS")
print(f"📂 Pasta: {pasta}")
print("\n1 - Organizar arquivos por tipo")
print("2 - Gerar relatório")
print("3 - Limpar arquivos antigos (30+ dias)")
print("4 - Sair")
opcao = input("\nEscolha: ")
if opcao == '1':
automatizador.organizar_downloads()
elif opcao == '2':
automatizador.gerar_relatorio()
elif opcao == '3':
confirma = input("⚠️ Remover arquivos com 30+ dias? (s/n): ")
if confirma.lower() == 's':
automatizador.limpar_arquivos_antigos(30)
elif opcao == '4':
print("👋 Até logo!")
break
if __name__ == "__main__":
menu()
🚀 Como melhorar este projeto
- Adicione agendamento automático (executar todo dia às 8h)
- Crie regras personalizadas de organização
- Implemente backup automático na nuvem
- Adicione interface gráfica com PyQt ou Tkinter
🎓 Como Publicar Seus Projetos no GitHub
Ter os projetos prontos é só metade do caminho. Você precisa mostrá-los ao mundo. Veja o passo a passo:
1. Crie uma conta no GitHub
Acesse github.com e crie sua conta gratuita.
2. Crie um repositório para cada projeto
- Clique em "New Repository"
- Nome: "gerador-senhas-python" (use nomes descritivos)
- Adicione descrição clara do que o projeto faz
- Marque "Add a README file"
3. Escreva um README.md profissional
# 🔐 Gerador de Senhas Seguras
Ferramenta Python para criar senhas fortes e validar sua segurança.
## 🚀 Funcionalidades
- Gera senhas aleatórias personalizáveis
- Valida força da senha (fraca/média/forte)
- Permite escolher tamanho e caracteres especiais
## 📦 Como usar
```bash
python gerador_senhas.py
```
## 🛠️ Tecnologias
- Python 3.x
- Bibliotecas: random, string
## 📸 Screenshot
[Adicione uma imagem do seu projeto rodando]
4. Faça commits organizados
# No terminal/cmd:
git init
git add .
git commit -m "Adiciona gerador de senhas com validação"
git branch -M main
git remote add origin https://github.com/seu-usuario/gerador-senhas-python.git
git push -u origin main
💼 Como Usar Estes Projetos em Entrevistas
Quando um recrutador perguntar "Quais projetos você já fez?", você pode responder:
"Desenvolvi 5 projetos Python que demonstram diferentes habilidades:
- Gerador de Senhas: Mostra domínio de strings, random e validação de dados
- Jogo de Adivinhação: Demonstra lógica com loops e condicionais
- Analisador de Gastos: Trabalha com CSV, manipulação de dados e relatórios
- Web Scraper: Extrai dados automaticamente de sites usando BeautifulSoup
- Automatizador: Organiza arquivos e elimina tarefas repetitivas
Todos estão no meu GitHub com código documentado e README profissional."
🎯 Próximos Passos
Agora que você tem 5 projetos no portfólio, é hora de:
- Adicionar testes: Aprenda pytest e adicione testes aos projetos
- Melhorar o código: Refatore seguindo PEP 8 e boas práticas
- Adicionar complexidade: Implemente as melhorias sugeridas em cada projeto
- Criar projetos maiores: API REST, dashboard com dados reais, bot de Telegram
- Contribuir em open source: Procure projetos Python no GitHub e contribua
🚀 Conclusão
Você não precisa de 50 projetos para conseguir seu primeiro emprego. Você precisa de 5 projetos bem feitos que demonstrem:
- ✅ Capacidade de resolver problemas reais
- ✅ Código limpo e organizado
- ✅ Documentação clara
- ✅ Variedade de habilidades
Pegue estes 5 projetos, publique no GitHub, melhore-os continuamente e use em entrevistas. Isso vai te destacar de 90% dos candidatos que só têm certificados.
Agora é com você. Escolha o primeiro projeto, abra seu editor de código e comece a construir seu portfólio hoje!
Boa sorte, futuro programador Python! 🐍🚀