Writing Effective Comments and Prompts
The quality of Copilot's suggestions depends heavily on the context you provide. Learning to write effective comments and structure your code for Copilot is the key to getting useful, accurate suggestions.
The Comment-Driven Development Approach
Copilot excels when you describe what you want before writing code. This "comment-driven development" approach helps Copilot understand your intent:
// Function that validates an email address using regex
// Returns true if valid, false otherwise
function validateEmail(email) {
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return regex.test(email);
}
By writing the comment first, Copilot has clear guidance on what to generate.
Principles of Effective Prompts
1. Be Specific About Inputs and Outputs
Vague prompts produce vague code. Compare these examples:
Vague (less effective):
# Sort the list
Specific (more effective):
# Sort a list of dictionaries by the 'price' key in descending order
# Input: list of dicts with 'name' and 'price' keys
# Output: sorted list with highest price first
def sort_products_by_price(products):
return sorted(products, key=lambda x: x['price'], reverse=True)
2. Mention Edge Cases
Help Copilot handle special situations:
// Parse a date string in format "YYYY-MM-DD"
// Handle invalid formats by returning null
// Handle empty strings by returning null
function parseDate(dateString) {
if (!dateString || typeof dateString !== 'string') {
return null;
}
const regex = /^\d{4}-\d{2}-\d{2}$/;
if (!regex.test(dateString)) {
return null;
}
const date = new Date(dateString);
return isNaN(date.getTime()) ? null : date;
}
3. Specify the Technology or Library
When using specific libraries, mention them:
# Using pandas, read a CSV file and return rows where 'status' column equals 'active'
import pandas as pd
def get_active_records(filepath):
df = pd.read_csv(filepath)
return df[df['status'] == 'active']
4. Include Example Data
Examples help Copilot understand the expected format:
// Convert a camelCase string to kebab-case
// Example: "backgroundColor" -> "background-color"
// Example: "fontSize" -> "font-size"
function camelToKebab(str: string): string {
return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
}
Structuring Your Code for Better Suggestions
Use Descriptive Function Names
Copilot uses your function name as a major hint:
# Good: Clear function name tells Copilot what to generate
def calculate_compound_interest(principal, rate, years):
return principal * (1 + rate) ** years
# Less effective: Generic name provides little context
def calc(p, r, y):
# Copilot has to guess what this does
Provide Type Hints
Type annotations give Copilot valuable information:
// TypeScript types help Copilot generate accurate code
interface User {
id: number;
name: string;
email: string;
createdAt: Date;
}
// Copilot now knows exactly what to work with
function formatUserForDisplay(user: User): string {
return `${user.name} (${user.email})`;
}
Use Consistent Patterns
If your codebase follows patterns, Copilot learns from them:
// If you consistently use this error handling pattern
async function fetchUser(id) {
try {
const response = await api.get(`/users/${id}`);
return { data: response.data, error: null };
} catch (error) {
return { data: null, error: error.message };
}
}
// Copilot will suggest similar patterns for new functions
async function fetchProducts(category) {
// Copilot suggests the same try/catch pattern
}
Comment Patterns That Work Well
The "Requirements List" Pattern
# Create a function that:
# 1. Takes a list of numbers
# 2. Filters out negative numbers
# 3. Squares each remaining number
# 4. Returns the sum of the squares
def sum_of_positive_squares(numbers):
positive = [n for n in numbers if n >= 0]
squares = [n ** 2 for n in positive]
return sum(squares)
The "API Documentation" Pattern
/**
* Fetches weather data for a given city
* @param {string} city - The city name to look up
* @param {string} units - Temperature units: 'celsius' or 'fahrenheit'
* @returns {Promise<Object>} Weather data including temp, humidity, conditions
* @throws {Error} If city is not found or API is unavailable
*/
async function getWeather(city, units = 'celsius') {
// Copilot generates appropriate implementation
}
The "Step-by-Step" Pattern
# Implementation steps:
# 1. Validate the input is a non-empty string
# 2. Convert to lowercase
# 3. Remove all non-alphanumeric characters
# 4. Check if the string equals its reverse
def is_palindrome(text):
if not text or not isinstance(text, str):
return False
cleaned = ''.join(c.lower() for c in text if c.isalnum())
return cleaned == cleaned[::-1]
Context Matters: Open Related Files
Copilot considers open files in your editor. For better suggestions:
- Open related files - If writing a service, open the model/type definitions
- Keep imports visible - Copilot uses import statements as context
- Open test files - When writing implementations, have corresponding tests open
Iterating on Suggestions
Don't accept the first suggestion blindly. Refine your prompt:
// First attempt - too generic
// Sort users
// Refined - added specifics
// Sort users by lastName, then firstName, case-insensitive
// Final - added all requirements
// Sort users by lastName then firstName (case-insensitive)
// Handle null/undefined names by placing them at the end
function sortUsers(users) {
return users.sort((a, b) => {
const lastA = (a.lastName || '').toLowerCase();
const lastB = (b.lastName || '').toLowerCase();
if (lastA !== lastB) return lastA.localeCompare(lastB);
const firstA = (a.firstName || '').toLowerCase();
const firstB = (b.firstName || '').toLowerCase();
return firstA.localeCompare(firstB);
});
}
Common Prompting Mistakes
Mistake 1: Too Much at Once
# Bad: Asking for too much in one comment
# Create a complete user authentication system with login, logout,
# password reset, email verification, and session management
# Better: Break it into smaller pieces
# Validate user credentials against the database
# Returns user object if valid, None if invalid
def authenticate_user(email, password):
# Copilot can focus on this specific task
Mistake 2: Assuming Context
// Bad: Assumes Copilot knows your data structure
// Update the user's settings
// Better: Explicit about the structure
// Update user settings in the database
// settings is an object with theme, notifications, and language keys
// userId is the user's unique identifier
async function updateUserSettings(userId, settings) {
// Clear context for Copilot
}
Mistake 3: Not Specifying Error Handling
# Bad: No mention of errors
# Read a file and return its contents
# Better: Specify error handling
# Read a file and return its contents as a string
# If file doesn't exist, return an empty string
# If file can't be read, raise an IOError with a descriptive message
def read_file_contents(filepath):
# Copilot knows how to handle errors
Summary
Writing effective prompts for Copilot is a skill that improves with practice. Key principles:
- Be specific about inputs, outputs, and edge cases
- Mention libraries and technologies you're using
- Include examples when format matters
- Use descriptive names for functions and variables
- Add type hints to provide more context
- Break complex tasks into smaller, focused pieces
- Iterate on prompts if initial suggestions aren't right
In the next lesson, you'll learn the keyboard shortcuts and techniques for efficiently managing Copilot's suggestions.

