emrevarol.com

Materiais da Aula

Melhores Práticas de Programação e Revisão Eficaz de Código

A2SV - University of Rwanda

Ver Apresentação

Checklist de Revisão de Código A2SV

O padrão ouro. Dez categorias para avaliar cada pull request que você revisar.

1 Clareza e Legibilidade
Pergunte
  • Os nomes de funções e variáveis são claros?
  • Consigo entender o código sem adivinhar?
  • A intenção é óbvia?
  • A lógica é fácil de seguir?
Sinais de Alerta
Nomes como x, tmp, data, calc, process; lógica profundamente aninhada; funções grandes e pouco claras
2 Qualidade de Funções e Design
Pergunte
  • Cada função faz uma coisa clara?
  • A lógica de negócios está separada dos efeitos colaterais?
  • O design é fácil de testar?
  • Alguma função está fazendo coisas demais?
Sinais de Alerta
Validação + salvamento + e-mail + logging em uma única função; print dentro de funções de lógica; comportamento hardcoded espalhado pelo arquivo
3 Correção
Pergunte
  • O código realmente resolve o problema corretamente?
  • As suposições são explícitas?
  • Todos os casos são tratados?
Sinais de Alerta
Validação de entrada ausente; suposições sobre chaves de dicionário; valores mágicos; falha silenciosa
4 Casos Limite
Pergunte
  • O que acontece com entrada vazia?
  • O que acontece com entrada inválida?
  • O que acontece com chaves ausentes?
  • O que acontece com valores zero ou negativos?
Sinais de Alerta
Apenas o caminho feliz considerado; nenhuma verificação defensiva onde necessário
5 Testes
Pergunte
  • Os testes estão incluídos?
  • Os testes verificam resultados exatos?
  • Os casos limite estão cobertos?
  • Esses testes detectariam regressões?
Sinais de Alerta
Apenas um teste; asserções fracas como > 0; nenhum caso de entrada inválida; nenhum teste para lógica alterada
6 Duplicação
Pergunte
  • A lógica está repetida?
  • A lógica compartilhada pode ser extraída?
  • As regras de negócio estão duplicadas em vários lugares?
Sinais de Alerta
Fórmulas repetidas; blocos de condição repetidos; valores hardcoded repetidos
7 Tratamento de Erros
Pergunte
  • Os erros são tratados de forma clara?
  • O código falha de maneira compreensível?
  • Os estados inválidos são visíveis?
Sinais de Alerta
Retornar None sem explicação; exceções engolidas; modos de falha ocultos
8 Manutenibilidade
Pergunte
  • Será fácil estender isso depois?
  • Outro engenheiro conseguirá modificar isso com segurança?
  • Isso torna o código mais limpo ou mais confuso?
Sinais de Alerta
Regras hardcoded; PR muito grande; lógica fortemente acoplada
9 Qualidade do Repositório
Pergunte
  • A estrutura do repositório é clara?
  • O README é útil?
  • Um novo engenheiro consegue rodar o projeto facilmente?
  • As dependências estão visíveis?
Sinais de Alerta
Sem instruções de configuração; README fraco; layout confuso; diretório de testes ausente
10 Qualidade do PR
Pergunte
  • O PR é focado?
  • O título é descritivo?
  • A descrição é útil?
  • O tamanho da mudança é razoável?
Sinais de Alerta
Títulos vagos; sem explicação; mudanças não relacionadas misturadas; PRs gigantes

Modelos de Comentários de Revisão

Frases profissionais para cenários comuns de revisão. Use como ponto de partida.

Nomenclatura
"Poderíamos renomear esta função para refletir melhor seu propósito?"
"Este nome de variável parece muito genérico. Podemos torná-lo mais descritivo?"
Lógica
"Poderíamos simplificar esta condição para melhorar a legibilidade?"
"Faria sentido extrair esta lógica para uma função auxiliar?"
Testes
"Podemos adicionar um teste para o caso de entrada vazia?"
"Poderíamos verificar o valor esperado exato aqui em vez de usar uma verificação ampla?"
Estrutura
"Esta função parece estar fazendo várias coisas. Podemos separar as responsabilidades?"
"Dividir isso em funções menores tornaria mais fácil de testar e revisar?"
Casos Limite
"O que acontece se esta chave estiver ausente?"
"Devemos validar a entrada antes de processá-la?"
Qualidade do PR
"Você poderia adicionar uma breve descrição ao PR explicando a mudança e como ela deve ser testada?"

Demo ao Vivo: Revise Este Pull Request

Um PR deliberadamente com falhas para prática. Você consegue encontrar os problemas?

Branch: feature/cart-total-update
Título: "Update cart calculation logic"
Descrição: "Updated the cart calculation logic and added support for discount."
src/cart.py
def calc(items, user, d=False): t = 0 for i in items: if i["type"] == "book": t += i["price"] * 0.9 else: t += i["price"] if d: t = t - t * 0.1 if user is not None: if "is_premium" in user: if user["is_premium"] == True: t = t - t * 0.05 return t def process_cart(items, user): total = calc(items, user, True) print("cart processed") return total
tests/test_cart.py
from src.cart import calc def test_calc(): items = [{"type": "book", "price": 100}] user = {"is_premium": True} assert calc(items, user, True) > 0
README.md
# Cart Project cart logic
Guia de Revisão - Problemas para Encontrar
Problemas no Nível do PR
  • Título vago do PR: "Update cart calculation logic" não descreve o que mudou
  • A descrição é genérica e não ajuda
  • Sem plano de testes ou instruções para revisores
Problemas no Nível do Código
  • Nome da função calc é muito genérico - deveria ser calculate_cart_total
  • Parâmetro d é obscuro - deveria ser discount_enabled
  • Variáveis t e i não são descritivas
  • Números mágicos: 0.9, 0.1, 0.05 deveriam ser constantes nomeadas
  • Blocos if profundamente aninhados para verificação premium - use .get()
  • process_cart tem efeito colateral (print) misturado com lógica de negócio
  • Sem validação de entrada para items ou user
  • Parâmetro booleano d=False passado posicionalmente como True é confuso
Problemas no Nível dos Testes
  • Apenas um caso de teste para o módulo inteiro
  • Asserção fraca: > 0 não verifica a correção
  • Sem testes de casos limite (lista vazia, chaves ausentes, usuário não premium)
  • Não testa process_cart
Problemas no Nível do Repositório
  • README está essencialmente vazio - sem instruções de configuração, sem descrição
  • Sem informação sobre como rodar os testes
Versão Melhorada - cart_improved.py
src/cart_improved.py
BOOK_DISCOUNT_RATE = 0.10 GENERAL_DISCOUNT_RATE = 0.10 PREMIUM_DISCOUNT_RATE = 0.05 def calculate_item_price(item): item_type = item["type"] price = item["price"] if item_type == "book": return price * (1 - BOOK_DISCOUNT_RATE) return price def apply_general_discount(total_price, discount_enabled): if not discount_enabled: return total_price return total_price * (1 - GENERAL_DISCOUNT_RATE) def apply_premium_discount(total_price, user): if not user or not user.get("is_premium", False): return total_price return total_price * (1 - PREMIUM_DISCOUNT_RATE) def calculate_cart_total(items, user, discount_enabled=False): total_price = 0 for item in items: total_price += calculate_item_price(item) total_price = apply_general_discount(total_price, discount_enabled) total_price = apply_premium_discount(total_price, user) return total_price def process_cart(items, user): total_price = calculate_cart_total(items, user, discount_enabled=True) return total_price

Tarefa de Casa

Tarefa de Revisão de PR: Revise Como um Engenheiro Profissional

Sua submissão deve incluir:

  • 10 total Mínimo de comentários de revisão
  • 3 mín Comentários sobre nomenclatura
  • 2 mín Comentários sobre testes
  • 2 mín Comentários sobre design ou responsabilidade de funções
  • 1 mín Comentário sobre qualidade do repositório
  • 1 mín Sugestão de refatoração

Formato de Submissão

File: src/orders.py
Line/Area: calc function
Comment: The function name is too generic. Could we rename
it to calculate_order_total for clarity?

File: tests/test_orders.py
Line/Area: test_calc
Comment: This test only checks that the result is greater
than zero. Could we assert the exact expected value instead?

Revise os seguintes arquivos:

src/orders.py
def calc(items, vip=False): total = 0 for i in items: if i["type"] == "book": total += i["price"] * 0.9 elif i["type"] == "electronics": total += i["price"] else: total += i["price"] if vip == True: total = total - total * 0.05 return total def checkout(items, user): total = calc(items, user["vip"]) print("checking out order...") print("total is", total) return {"ok": True, "total": total}
src/utils.py
def f(x): if x == None: return False return True
tests/test_orders.py
from src.orders import calc def test_calc(): items = [{"type": "book", "price": 100}] assert calc(items, False) > 0
README.md
# Orders Run it with python.
Grandes engenheiros não apenas fazem o código funcionar. Eles tornam o código compreensível, testável, revisável e confiável.
Citação do Dia
"O código que você está ocupado demais para limpar hoje se torna o problema que domina sua equipe amanhã."