Ir para o conteúdo

Lab 010: GitHub Copilot — Primeiros Passos

Nível: L100 Trilha: 🤖 GitHub Copilot Tempo: ~45 min 💰 Custo: GitHub Free — Plano gratuito (2.000 completações + 50 chats/mês)

O Que Você Vai Aprender

  • Usar completação de código inline para escrever código a partir de comentários
  • Usar Copilot Chat /fix para encontrar e entender bugs reais
  • Usar Copilot Edits para refatorar um arquivo inteiro com linguagem natural
  • Usar chat inline para estender código sem sair do editor
  • Escrever prompts que geram melhores resultados

Este laboratório usa exercícios práticos — você abrirá arquivos com bugs reais e código incompleto, e então usará o Copilot para corrigir e estendê-los.


Pré-requisitos

1. Ativar o GitHub Copilot Free

  1. Acesse github.com/features/copilot"Start for free"
  2. Faça login e siga o assistente de configuração

Estudantes recebem o Copilot Pro gratuitamente

GitHub Student Developer Pack

2. Instalar o VS Code + extensão do Copilot

  1. Instale o VS Code
  2. Extensões (Ctrl+Shift+X) → pesquise "GitHub Copilot" → Instale ambos:
  3. GitHub Copilot (completações)
  4. GitHub Copilot Chat (painel de chat)
  5. Faça login quando solicitado — você verá o ícone do Copilot na barra de status

3. Baixar os arquivos de exercício

Clone ou baixe os arquivos de exercício para este laboratório:

git clone https://github.com/lcarli/AI-LearningHub.git
cd AI-LearningHub/docs/docs/en/labs/lab-010

Ou copie cada arquivo diretamente das seções abaixo.


Início Rápido com GitHub Codespaces

Open in GitHub Codespaces

Todas as dependências estão pré-instaladas no devcontainer.

📦 Arquivos de Apoio

Baixe estes arquivos antes de iniciar o laboratório

Salve todos os arquivos em uma pasta lab-010/ no seu diretório de trabalho.

Arquivo Descrição Download
exercise1_fibonacci.py Script de exercício interativo 📥 Download
exercise2_shopping_cart.py Script de exercício interativo 📥 Download
exercise3_product_search.py Script de exercício interativo 📥 Download
exercise4_refactor_me.py Script de exercício interativo 📥 Download

Exercício 1 — Completação Inline: Escreva Código a Partir de Comentários

Objetivo: Aprender como o Copilot completa código enquanto você digita.

Crie um novo arquivo practice.py e digite cada comentário abaixo. Após cada comentário, pare de digitar e aguarde a sugestão do Copilot. Pressione Tab para aceitar, você pode continuar pressionando tab até o Copilot parar de sugerir mais completações.

Não vamos executar este código, então não se preocupe com erros de sintaxe ou imports faltando — apenas foque nas sugestões que o Copilot oferece com base nos comentários.

# Function that takes a list of prices and returns the average:

# Function that reads a CSV file and returns rows as a list of dicts:

# Async function that fetches JSON from a URL using httpx:

# Class OutdoorProduct with name, price, category attributes and a discount() method:

Atalhos de teclado

Tecla Ação
Tab Aceitar sugestão
Esc Descartar
Alt+] / Alt+[ Próxima / sugestão anterior
Ctrl+Enter Abrir painel com todas as sugestões

Experimente prompts melhores e piores:

❌ Vago ✅ Específico
# sort this # Sort list of dicts by 'price' descending, then 'name' ascending
# connect to db # Connect to PostgreSQL using asyncpg, return a connection pool
# handle error # Retry 3 times with exponential backoff if requests.Timeout is raised

Exercício 2 — Copilot /fix: Caça aos Bugs 🐛

Objetivo: Usar o Copilot Chat para encontrar, entender e corrigir bugs reais.

Arquivo: 📥 exercise1_fibonacci.py

exercise1_fibonacci.py — 3 bugs escondidos
# exercise1_fibonacci.py
# 🐛 BUG HUNT — This file has 3 bugs. Can you find them all using Copilot /fix?
#
# TASK: The fibonacci() function should return a list of the first n
#       Fibonacci numbers: [0, 1, 1, 2, 3, 5, 8, 13, ...]
#
# EXPECTED OUTPUT (for n=8):
#   fibonacci(8)  → [0, 1, 1, 2, 3, 5, 8, 13]
#   fibonacci(1)  → [0]
#   fibonacci(0)  → []
#
# HOW TO USE THIS EXERCISE:
#   1. Open this file in VS Code
#   2. Select ALL the code (Ctrl+A)
#   3. Open Copilot Chat → type: /fix
#   4. Read Copilot's explanation of each bug
#   5. Accept the fix and run the tests below to verify

def fibonacci(n):
    """Return a list of the first n Fibonacci numbers."""
    if n = 0:           # BUG 1: syntax error
        return []

    sequence = [0, 1]

    for i in range(2, n):
        next_val = sequence[i-1] + sequence[i-2]
        sequence.append(next_val)

    return sequence[n]  # BUG 2: should return a slice, not a single element
                        # BUG 3: what happens when n=1? sequence has 2 elements but we only want 1


# --- Tests (run after fixing) ---
if __name__ == "__main__":
    assert fibonacci(0) == [], f"Expected [], got {fibonacci(0)}"
    assert fibonacci(1) == [0], f"Expected [0], got {fibonacci(1)}"
    assert fibonacci(8) == [0, 1, 1, 2, 3, 5, 8, 13], f"Got {fibonacci(8)}"
    print("✅ All tests passed!")

Passos:

  1. Copie o código acima em um novo arquivo (ou abra-o dos exercícios baixados)
  2. Abra o Copilot Chat (Ctrl+Shift+I)
  3. Selecione todo o código (Ctrl+A)
  4. Digite: /fix

O Copilot deve identificar todos os 3 bugs e explicar cada um. Antes de aceitar, leia a explicação — entender por que o código estava errado é o objetivo.

Saída esperada após a correção:

fibonacci(0)  # → []
fibonacci(1)  # → [0]
fibonacci(8)  # → [0, 1, 1, 2, 3, 5, 8, 13]

Execute python exercise1_fibonacci.py — você deverá ver: ✅ All tests passed!


Arquivo: 📥 exercise2_shopping_cart.py

exercise2_shopping_cart.py — 4 bugs escondidos
# exercise2_shopping_cart.py
# 🐛 BUG HUNT — This file has 4 bugs. Use Copilot Chat to find and fix them.
#
# SCENARIO: OutdoorGear Inc. shopping cart logic.
# The cart should:
#   - Add items with a quantity
#   - Calculate total price (sum of price × quantity)
#   - Apply a 10% discount on orders over $200
#   - Count unique items (not total quantity)
#
# EXPECTED OUTPUT:
#   Cart with 2x TrailBlazer ($189.99) + 1x Summit Tent ($349):
#   total before discount = $728.98
#   total after 10% discount = $656.08
#   unique_items = 2
#
# HOW TO USE:
#   1. Copy this file into VS Code
#   2. Try to run it: python exercise2_shopping_cart.py
#   3. Read the errors — but DON'T fix manually yet!
#   4. Select all code → Copilot Chat → /fix
#   5. Ask Copilot to explain EACH bug before fixing
#   6. Verify with the tests at the bottom

class ShoppingCart:
    def __init__(self):
        self.items = {}  # {product_name: {"price": float, "quantity": int}}

    def add_item(self, name: str, price: float, quantity: int = 1):
        if name in self.items:
            self.items[name]["quantity"] += quantity
        else:
            self.items[name] = {"price": price, "quantity": quantity}

    def get_total(self) -> float:
        """Calculate total price, applying 10% discount if over $200."""
        total = 0
        for item in self.items:            # BUG 1: iterating over keys only, not values
            total += item["price"] * item["quantity"]

        if total > 200:
            total = total * 0.90           # BUG 2: discount calculation correct, but...
                                           # should return rounded to 2 decimal places
        return total

    def count_unique_items(self) -> int:
        """Return the number of unique products (not total quantity)."""
        return sum(self.items.values())    # BUG 3: wrong — should be len(), not sum()

    def get_receipt(self) -> str:
        lines = []
        for name, details in self.items.items():
            subtotal = details["price"] + details["quantity"]  # BUG 4: + instead of *
            lines.append(f"  {name} x{details['quantity']} @ ${details['price']:.2f} = ${subtotal:.2f}")
        total = self.get_total()
        lines.append(f"\nTotal: ${total:.2f}")
        return "\n".join(lines)


# --- Tests ---
if __name__ == "__main__":
    cart = ShoppingCart()
    cart.add_item("TrailBlazer X200", 189.99, 2)
    cart.add_item("Summit Pro Tent", 349.00, 1)

    total = cart.get_total()
    unique = cart.count_unique_items()

    print(cart.get_receipt())
    print(f"\nUnique items: {unique}")

    assert unique == 2, f"Expected 2 unique items, got {unique}"
    assert abs(total - 656.08) < 0.01, f"Expected $656.08, got ${total}"
    print("\n✅ All tests passed!")

Este arquivo tem 4 bugs na classe ShoppingCart. Desta vez, antes de usar /fix:

  1. Tente identificar os bugs primeiro — gaste 2 minutos lendo o código
  2. Depois use o Copilot Chat: selecione tudo → /fix
  3. O Copilot encontrou bugs que você não percebeu?

Peça ao Copilot para explicar um bug em detalhes:

Why is iterating with "for item in self.items" wrong here? What does it actually iterate over?

Saída esperada após a correção:

TrailBlazer X200 x2 @ $189.99 = $379.98
Summit Pro Tent x1 @ $349.00 = $349.00

Total: $656.08
Unique items: 2
✅ All tests passed!


Exercício 3 — Chat Inline: Corrigir + Estender

Objetivo: Corrigir bugs E adicionar uma nova funcionalidade usando o chat inline (Ctrl+I).

Arquivo: 📥 exercise3_product_search.py

exercise3_product_search.py — 2 bugs + 1 funcionalidade faltando
# exercise3_product_search.py
# 🐛 BUG HUNT + EXTEND — This file has 2 bugs AND is missing a feature.
#
# SCENARIO: OutdoorGear product search with filtering.
#
# TASK A (Fix): Find and fix the 2 bugs using Copilot /fix
# TASK B (Extend): Ask Copilot to add a sort_by_price() function
#   Prompt to use: "Add a sort_by_price(products, ascending=True) function
#                   that sorts the search results by price"
#
# EXPECTED OUTPUT after fixing:
#   search("boot")   → [{"name": "TrailBlazer X200", "price": 189.99, "category": "footwear"}]
#   search("tent")   → [{"name": "Summit Pro Tent",  "price": 349.00, "category": "camping"}]
#   search("xyz")    → []
#   search("")       → all 5 products
#
# HOW TO USE:
#   Step 1 — Fix bugs:  Select all → Copilot Chat → /fix
#   Step 2 — Extend:    Ctrl+I (inline chat) → type the prompt above
#   Step 3 — Test:      Run the tests at the bottom

CATALOG = [
    {"name": "TrailBlazer X200",      "price": 189.99, "category": "footwear"},
    {"name": "Summit Pro Tent",        "price": 349.00, "category": "camping"},
    {"name": "ClimbTech Pro Harness", "price": 129.99, "category": "climbing"},
    {"name": "OmniPack 45L",          "price": 279.99, "category": "packs"},
    {"name": "StormShell Jacket",      "price": 349.00, "category": "clothing"},
]

def search_products(query: str) -> list[dict]:
    """Return products matching query in name or category (case-insensitive)."""
    if not query:
        return CATALOG

    query_lower = query.lower()
    results = []
    for product in CATALOG:
        if query_lower in product["name"].lower or \   # BUG 1: missing () on .lower
           query_lower in product["category"].lower():
            result.append(product)                      # BUG 2: wrong variable name (result vs results)
    return results


def format_results(products: list[dict]) -> str:
    """Format search results for display."""
    if not products:
        return "No products found."
    lines = [f"Found {len(products)} product(s):"]
    for p in products:
        lines.append(f"  • {p['name']} — ${p['price']:.2f} ({p['category']})")
    return "\n".join(lines)


# --- Tests ---
if __name__ == "__main__":
    print("Test 1: search for 'boot'")
    r1 = search_products("boot")
    print(format_results(r1))
    assert len(r1) == 1 and r1[0]["name"] == "TrailBlazer X200"

    print("\nTest 2: search for 'tent'")
    r2 = search_products("tent")
    print(format_results(r2))
    assert len(r2) == 1 and r2[0]["name"] == "Summit Pro Tent"

    print("\nTest 3: empty search returns all")
    r3 = search_products("")
    assert len(r3) == 5

    print("\nTest 4: search 'xyz' returns empty")
    r4 = search_products("xyz")
    assert r4 == []

    # Test the sort function Copilot should have added:
    print("\nTest 5: sort by price ascending")
    sorted_asc = sort_by_price(CATALOG, ascending=True)
    assert sorted_asc[0]["name"] == "ClimbTech Pro Harness"  # cheapest first
    assert sorted_asc[-1]["price"] == 349.00

    print("\n✅ All tests passed!")

Parte A — Corrigir (2 bugs):

  1. Abra o arquivo no VS Code
  2. Selecione tudo (Ctrl+A) → Copilot Chat → /fix
  3. Verifique: python exercise3_product_search.py — os testes 1–4 devem passar

Parte B — Estender (1 funcionalidade faltando):

O arquivo menciona uma função sort_by_price() que ainda não existe.

  1. Posicione o cursor no final do arquivo (antes da seção de testes)
  2. Pressione Ctrl+I (chat inline)
  3. Digite exatamente:
    Add a sort_by_price(products, ascending=True) function that returns
    the products list sorted by price
    
  4. Revise a sugestão e pressione Aceitar (Ctrl+Enter)
  5. Execute os testes novamente — todos os 5 devem passar agora

Exercício 4 — Copilot Edits: Refatorar um Arquivo Inteiro

Objetivo: Usar o Copilot Edits para melhorar a qualidade do código com instruções em linguagem natural — sem alterar o comportamento.

Arquivo: 📥 exercise4_refactor_me.py

exercise4_refactor_me.py — funciona, mas precisa de melhorias
# exercise4_refactor_me.py
# ✏️  REFACTORING CHALLENGE — No bugs here, but the code is terrible.
#
# TASK: Use Copilot Edits to improve this code WITHOUT changing its behavior.
#
# TRY THESE COPILOT EDITS PROMPTS (one at a time):
#   1. "Add type hints to all function parameters and return values"
#   2. "Add docstrings following Google style to every function"  
#   3. "Replace the magic numbers with named constants at the top of the file"
#   4. "Refactor calculate_shipping to use early return instead of nested ifs"
#   5. "Add input validation: raise ValueError for negative prices or quantities"
#
# After each prompt, review what Copilot changed. Accept or reject with Ctrl+Enter / Ctrl+Backspace.
#
# GOAL: By the end, this code should be production-ready.

STANDARD_SHIPPING = 5.99
EXPRESS_SHIPPING = 14.99
FREE_SHIPPING_THRESHOLD = 75.0
DISCOUNT_THRESHOLD = 200.0
DISCOUNT_RATE = 0.10

def calculate_price(p, q):
    return p * q

def calculate_shipping(t):
    if t >= 75:
        return 0
    else:
        if t > 50:
            return 5.99
        else:
            return 14.99

def apply_discount(t):
    if t > 200:
        d = t * 0.10
        t = t - d
    return round(t, 2)

def order_summary(items):
    t = 0
    for i in items:
        t = t + calculate_price(i[0], i[1])
    s = calculate_shipping(t)
    t_with_shipping = t + s
    final = apply_discount(t_with_shipping)
    return {"subtotal": round(t, 2), "shipping": s, "discount_applied": t > 200, "total": final}


# Test — this should still pass after all refactoring
if __name__ == "__main__":
    items = [(189.99, 1), (349.00, 1)]   # (price, quantity)
    result = order_summary(items)
    print(result)
    assert result["total"] == 489.59, f"Got {result['total']}"
    print("✅ Refactoring complete — behavior unchanged!")

Este código funciona corretamente mas é difícil de ler e manter. Use o Copilot Edits para melhorá-lo passo a passo:

  1. Abra o painel do Copilot Edits: Ctrl+Shift+I → clique em "Open Copilot Edits" (ícone de lápis)
  2. Clique em "Add Files" e adicione exercise4_refactor_me.py
  3. Execute cada um destes prompts um de cada vez, revisando as alterações antes de prosseguir:

Prompt 1:

Add type hints to all function parameters and return values

Prompt 2:

Add docstrings following Google style to every function

Prompt 3:

Refactor calculate_shipping to use early return instead of nested if/else

Prompt 4:

Add input validation: raise ValueError if price or quantity is negative

Após cada prompt, verifique se o teste no final ainda passa:

python exercise4_refactor_me.py
# Deve continuar exibindo: ✅ Refactoring complete — behavior unchanged!

Não aceite tudo cegamente

Às vezes o Copilot adiciona complexidade extra. Se uma sugestão tornar o código mais difícil de ler, pressione Descartar (Ctrl+Backspace) e reformule.


Bônus: Peça ao Copilot para explicar, não apenas corrigir

Use estes prompts em qualquer um dos arquivos de exercício para aprofundar seu entendimento:

/explain
What tests should I write for this function? Generate them.
What edge cases does this code not handle?
Is there a more Pythonic way to write this?


O Que Você Praticou

Funcionalidade do Copilot Exercício Caso de uso
Completação inline Exercício 1 Escrever código novo a partir de comentários
Chat /fix Exercício 2 Entender e corrigir bugs
Chat inline Ctrl+I Exercício 3 Corrigir + estender no local
Copilot Edits Exercício 4 Refatorar arquivos inteiros

Próximos Passos