Exam domains exercised
- Master five prompting techniques: zero-shot, few-shot, comment-driven, context crafting, and iterative refinement
- Experience the difference between vague and specific prompts firsthand
- Apply the 4S Framework (Single, Specific, Short, Surround) to every prompt
The 4S Framework (Reference)
- 🎯 Single — One task per prompt. Break complex goals into discrete steps.
- 🔍 Specific — Name technologies, specify types, mention edge cases.
- ✂️ Short — Concise beats verbose. Get to the point.
- 🔄 Surround — Provide context: open relevant files, add type annotations, use meaningful names.
Exercises
Zero-Shot Prompting — Luhn Algorithm
Zero-shot means giving the model a task with no examples — just a clear description of what you want.
Part A: The Vague Prompt (Anti-Pattern)
- Create a new file:
lab2-prompts.ts - Open Copilot Chat and type this deliberately vague prompt:
write a credit card validator - Record what you get. Note:
- Does it specify the algorithm?
- Does it handle edge cases (empty string, non-numeric input, wrong length)?
- Does it include types?
- What language did it choose?
Part B: The 4S Prompt (Best Practice)
- Now rewrite the prompt using the 4S Framework:
Write a TypeScript function called validateCreditCard that takes a string of digits and returns a boolean. Use the Luhn algorithm. Handle edge cases: empty string, non-numeric characters, and strings shorter than 13 or longer than 19 digits. Include JSDoc. - Compare the two results side-by-side:
Ambiguous language, no type info, no edge cases specified, model guesses everything.
Single task, specific algorithm + types + edge cases, short and direct, language context provided.
Few-Shot Prompting — Date Format Conversion
Few-shot prompting gives the model examples of input → output to establish a pattern. The model then follows the pattern for new inputs.
Instructions
- In
lab2-prompts.ts, type the following pattern of examples. Type them manually — don't paste — so Copilot sees you building the pattern:// Date format conversions: US → ISO // "01/15/2025" → "2025-01-15" // "12/31/2024" → "2024-12-31" // "03/07/2026" → "2026-03-07" // // Now convert: "06/19/2026" → - Copilot should auto-complete with
"2026-06-19"— demonstrating it learned the pattern. - Now below that, write a function using the pattern:
// Convert US date (MM/DD/YYYY) to ISO format (YYYY-MM-DD) // Examples: // convertDate("01/15/2025") → "2025-01-15" // convertDate("12/31/2024") → "2024-12-31" function convertDate(usDate: string): string { - Let Copilot generate the implementation. Verify it follows the pattern correctly.
- Test it mentally: does the generated code handle invalid dates? Single-digit months/days?
Comment-Driven Development — Binary Search Tree
Write a complete specification as comments/JSDoc first, then let Copilot implement from your spec. This is the recommended best practice for getting high-quality suggestions.
Instructions
- Create a new file:
lab2-bst.ts - Write the following JSDoc specification (type it, don't paste):
/** * Binary Search Tree implementation * * @class BinarySearchTree * @template T - The type of values stored in the tree * * Methods: * - insert(value: T): void — Insert a value maintaining BST property * - search(value: T): boolean — Return true if value exists * - inOrderTraversal(): T[] — Return sorted array of all values * - delete(value: T): void — Remove value, maintaining BST property * - min(): T | undefined — Return minimum value * - max(): T | undefined — Return maximum value * * Properties: * - root: TreeNode<T> | null * - size: number (readonly) * * Edge cases: * - Duplicate values should be ignored (no duplicates) * - Operations on empty tree should not throw */ - Press Enter after the closing
*/and type:interface TreeNode<T> { - Let Copilot generate the interface. It should create
value,left, andrightfields based on your spec. - Then type:
class BinarySearchTree<T> { - Let Copilot generate the entire class. Because your JSDoc was thorough, the implementation should include all specified methods.
- Review the generated code:
- Does it implement all 6 methods from your spec?
- Does it handle duplicates as specified?
- Does it handle empty tree operations?
Context Crafting — Repository Pattern from Types
Context crafting means opening relevant files in your editor so Copilot can see types, interfaces, and patterns to follow.
Instructions
- Create a type definitions file:
lab2-types.tsexport interface User { id: string; name: string; email: string; role: 'admin' | 'editor' | 'viewer'; createdAt: Date; updatedAt: Date; }export interface CreateUserInput {
name: string;
email: string;
role: ‘admin’ | ’editor’ | ‘viewer’;
}export interface UpdateUserInput {
name?: string;
email?: string;
role?: ‘admin’ | ’editor’ | ‘viewer’;
}export interface UserRepository {
findById(id: string): Promise<User | null>;
findByEmail(email: string): Promise<User | null>;
findAll(filter?: { role?: string }): Promise<User[]>;
create(input: CreateUserInput): Promise<User>;
update(id: string, input: UpdateUserInput): Promise<User>;
delete(id: string): Promise<void>;
} - Keep this file open in a tab. This is the key — Copilot uses open files as context.
- Create a new file:
lab2-user-repo.ts - Type at the top:
import { User, CreateUserInput, UpdateUserInput, UserRepository } from './lab2-types'; // In-memory implementation of UserRepository for testing</li> <li>Then type:export class InMemoryUserRepository implements UserRepository {</li> <li>Let Copilot generate the implementation. Because the type file is open, Copilot knows exactly what methods to implement and their signatures.</li> <li>Verify that every method from the <code>UserRepository</code> interface is implemented correctly.</li>
Iterative Refinement — Sort, Validate, Optimize
Real-world Copilot usage is iterative: generate, review, refine, improve. This exercise simulates that workflow.
Instructions
- Open Copilot Chat. Start with a basic request:
Write a TypeScript function called smartSort that sorts an array of numbers. Use quicksort algorithm. - Review the output. Insert it into a new file
lab2-sort.ts. - Now iterate. In Chat, type:
Add input validation: handle empty arrays, single-element arrays, and arrays with non-finite numbers (NaN, Infinity). Throw a descriptive TypeError for invalid inputs. - Apply the updated version. Then iterate again:
Optimize for large arrays (100k+ elements): add insertion sort fallback for partitions smaller than 10 elements. Add a comparison counter parameter for benchmarking. - Apply the optimized version. One more iteration:
Add comprehensive JSDoc with @param, @returns, @throws, @example tags. Include time and space complexity analysis in the docs. - Compare your final version to the first version. The iterative approach produced code that is validated, optimized, and documented — far better than any single prompt could achieve.
Bonus: Create a Custom Instructions File
Lock in your team's standards so every Copilot interaction follows your conventions automatically.
Instructions
- Create the file
.github/copilot-instructions.mdin your project root:# Copilot InstructionsLanguage & Style #
- Use TypeScript strict mode for all code
- Prefer
constoverlet; never usevar - Use async/await, never raw Promises or callbacks
Documentation #
- All exported functions must have JSDoc with @param and @returns
- Include @example for public API functions
Error Handling #
- Use custom error classes extending Error
- Never catch and silently ignore errors
- Save the file. Now go back to Chat and ask:
Write a function that fetches user data from an API endpoint</li>
<li>Verify that Copilot follows your instructions: TypeScript, const, async/await, JSDoc, proper error handling.</li>
<li>Try violating one rule — ask for callback-style code. Copilot should still prefer async/await if your instructions are active.</li>
.github/copilot-instructions.md. It applies to all contributors who use Copilot in that repository.✅ Completion Checklist
- Compared a vague prompt vs. a 4S-framework prompt — saw the quality difference
- Used few-shot prompting to teach Copilot a date format pattern
- Wrote JSDoc spec first, then let Copilot implement a full BST class
- Used context crafting (open type file) to generate a repository implementation
- Iteratively refined a sort function through 4 rounds of improvement
- Created a .github/copilot-instructions.md and verified Copilot follows it
🎯 Key Takeaways for the Exam
- 4S Framework: Single, Specific, Short, Surround
- Zero-shot: No examples, just a clear task description
- Few-shot: Provide input/output examples to establish a pattern
- Comment-driven: Write specs first, let Copilot implement
- Context references:
#project= entire project,#file= specific file,#selection= selected code - .github/copilot-instructions.md applies repo-wide custom instructions
