College AI Track

Module 4 of 12

Module 04: Coding with AI — GitHub Copilot, Cursor, Claude & Critical Acceptance

15 min read2,906 words

"The compiler does not care how confident the autocomplete looked. Your tests, your types, and your code review are the only ground truth."
— Common distillation of senior-engineering mentoring (paraphrased)

Duration: 6–8 hours · Difficulty: Intermediate · Prerequisites: Basic programming in one language (this module uses Python examples), comfort with files and folders, and Git at the level of clone, commit, branch, diff. Install VS Code or Cursor; access to GitHub Copilot (or institution-approved equivalent) and optionally Claude (web or desktop) per your syllabus and license.

Learning Objectives

By the end of this module, you will be able to:

  1. Configure IDE-integrated assistants (GitHub Copilot, Cursor, JetBrains AI) for navigation, boilerplate, tests, and debugging without abdicating understanding.
  2. Apply a read–predict–verify loop for every non-trivial suggestion: trace data flow, check edge cases, run tests.
  3. Author prompt patterns for code: spec-first, test-first, small-scope refactors, debugging traces, and “explain this diff” requests suited to coursework and internships.
  4. Compare Copilot, Cursor, and Claude-style assistants across context window, repo awareness, and risk profile—and choose the right tool for each task.
  5. Explain common failure modes: hallucinated APIs, subtle logic bugs, security anti-patterns, dependency drift, and license ambiguity in generated snippets.
  6. Use Git to isolate experiments, review AI-generated diffs line-by-line, and bisect when something breaks after a broad “agent” edit.
  7. Conduct AI-assisted code review: request structured feedback, then validate every claim with execution and static analysis.
  8. Communicate your workflow in a README suitable for a TA, open-source contributor, or internship mentor, including AI disclosure and ethical use of third-party code.

Concept 1: Copilots as Accelerators, Not Oracles

Modern coding assistants predict likely continuations from context: open files, cursor position, linter diagnostics, and sometimes repository-wide indexing (Cursor, Copilot Workspace-style features). They are trained on public code; they do not know your private assignment spec, your runtime environment, or your university’s data-handling rules unless you state them.

Productive mental model: the assistant is a pair programmer who types fast but sometimes confidently wrong. Your job is to supply intent, constraints, and verification.

MindsetRisk
“It compiled, so it’s fine.”Logic bugs, wrong library version, silent data loss.
“The model used fancy syntax.”Unreadable code you cannot defend in office hours.
“I’ll paste my whole repo into chat.”Secret leakage, license issues, policy violations.

Real-world example: A CS student uses Copilot to implement a CSV parser for a sociology group project. The suggestion uses pandas.read_csv with default dtypes; student IDs lose leading zeros. Grades import wrong. Verify with sample rows that mirror real data quirks (leading zeros, mixed encodings, stray commas in text fields).

Comparison: Where each tool shines (high level)

DimensionGitHub Copilot (IDE)CursorClaude (chat / API / integrations)
Primary winFast inline completions in familiar editorsRepo-wide context, multi-file edits, “agent” flowsLong context, careful explanations, refactoring dialogue
Typical riskAccepting slick one-liners without testsBroad refactors that break imports globallyOver-trusting narrative explanations of code you have not run
Best forBoilerplate, tests from signatures, docstrings“Change pattern X across these files”Architecture discussion, long file review, policy-safe prompting when allowed
Verify withpytest, ruff, local runSame + smaller scoped tasksSame; paste minimal excerpts if policy allows

Vendor features change frequently—treat this table as a thinking scaffold, not a product spec.

Concept 2: GitHub Copilot — Deep Dive

What Copilot sees: Usually the current file, nearby tabs, and sometimes related files—depending on editor integration and your settings. It does not magically know your autograder; put assignment constraints in comments or chat when permitted.

Inline completions: Tab to accept; partial accepts in many setups. Practice: before you hit Tab, say aloud the next line you expect; if the suggestion diverges, slow down.

Copilot Chat (VS Code): Useful for “explain this error,” “generate tests for this function,” “rewrite with type hints.” Risk: chat may encourage pasting large blobs—redact secrets and personal data.

Commit messages and PR text: Copilot can draft summaries from git diff. You must ensure the message matches what you actually changed—misleading messages erode trust in team projects.

Licensing and training: Read your institution’s agreement and GitHub’s current documentation on data retention and code suggestions. Policies evolve; re-check each term.

Configuration habits that pay off:

  • Enable format-on-save and a linter so bad suggestions get visible immediately.
  • Pin Python version in pyproject.toml or .python-version so suggestions match your environment.
  • Use .github/copilot-instructions.md or editor-level guidance (if available) for team style: “prefer explicit loops,” “no eval,” etc.

Concept 3: Cursor — Repo-Aware Assistance

Cursor emphasizes whole-repository context and agent flows (multi-step edits across files). Useful for: “add error handling across these three modules,” “generate tests matching this interface,” “rename this concept consistently.”

Composer / multi-file edits: Treat like a junior developer with a wide paintbrush. Always:

  1. Work on a branch.
  2. Run tests after each coherent chunk of changes.
  3. Review the full diff before commit—agent flows can “fix” one file while breaking another.

@ symbols and context: Learn how your build of Cursor attaches files, folders, and docs. Prefer narrow folders (e.g., src/parser/) over the entire monorepo for first attempts.

Rules files: Project .cursorrules or team rules can encode style and forbidden patterns. Align them with course style guides so the assistant nudges toward gradable code.

Real-world scenario: Team member uses Cursor to “modernize” imports. CI fails on the campus cluster with older Python. Lock environment in pyproject.toml or environment.yml and run CI locally before push.

Concept 4: Claude for Coding (and When to Prefer It)

Claude (Anthropic) is often used via browser chat, API, or integrations. Strengths:

  • Long-context sessions for reading a large module you paste in slices (respect copyright and syllabus).
  • Explanations that decompose logic step-by-step—useful when learning algorithms.
  • Refactoring dialogue when you describe constraints in natural language.

Cautions:

  • Same hallucination risks as any LLM for library APIs—verify against docs.
  • Paste discipline: Never upload confidential lab code, student PII, or proprietary internship code without written permission.
  • For graded work, follow AI disclosure rules; some courses allow IDE tools but forbid external chat—compliance first.

Sample prompt (spec-first, Claude-friendly):

text
Role: coding tutor constrained to Python 3.11 stdlib only.
Task: Implement merge_sorted(a: list[int], b: list[int]) -> list[int]
Requirements: O(n) time, O(n) extra space, no imports.
Output: function + 3 doctest examples in docstring. No prose outside the code block.

Expected shape of a good response: A single code block with def merge_sorted and doctests you can copy into a .py file and run with python -m doctest file.py.

Concept 5: The Read–Predict–Verify Loop

This loop is the professional backbone of working with any assistant.

  1. Read the problem and existing code until you can state invariants (what must always be true) and inputs/outputs.
  2. Predict what a good change would look like before you accept a suggestion—shape of function, edge cases.
  3. Verify with execution: unit tests, pytest, mypy, print debugging, minimal repro scripts.
  4. Review the diff line-by-line; reject cleverness you cannot explain to a TA in five sentences.

Table: Verification tools by ecosystem (examples)

EcosystemFast checks
Pythonpytest, ruff, mypy
JavaScript/TSeslint, tsc, jest
Javajavac, JUnit, SpotBugs (optional)
C/C++-Wall, Valgrind or sanitizers

Real-world scenario (internship): You accept a snippet that calls requests.get without timeout=. In production, hung connections freeze workers. Always set timeouts on network calls; add that to your mental checklist before accepting HTTP code.

Pro Tips — IDE copilots

  • Comment-driven completion: Write a 2-line docstring with inputs, outputs, and errors before asking for implementation—Copilot uses comments as strong priors.
  • Shrink the blast radius: After any agent edit, run git diff --stat—if more than N files changed, revert and retry with a narrower prompt.
  • Pin the “source of truth”: Link the assistant to README.md or CONTRIBUTING.md when your course publishes style rules; reduces drift between teammates.
  • Rubber-duck with tests: If you cannot write a failing test, you do not yet understand the bug—avoid asking the model to “fix everything.”

Common mistakes — Module 04

  • Accepting imports you have not installed—especially optional extras ([dev], gpu) that break CI.
  • Blind trust of type hints generated without mypy; annotations can lie while code runs.
  • Mega-prompting entire assignments into chat instead of incremental functions with tests between steps.
  • Forgetting license headers when mixing AI snippets with third-party Stack Overflow–style code in one file.

Comparison table: When to use inline completion vs. chat vs. agent

SituationInline (Tab)Chat / ComposerExternal long chat
Boilerplate / docstringsStrongOverkillOK if policy allows
Rename across filesWeakStrongPaste paths carefully
Debug stack traceOK for hintsStrong with @fileStrong for long logs
Architecture debateWeakMediumOften strongest
Exam-style restrictionsCheck syllabusOften bannedOften banned

Hands-On A: Prompt Patterns That Survive Review

Vague prompts yield vague code. Use structure.

A.1 Spec-first pattern

text
You are helping with a homework module. Constraints:
- Language: Python 3.11
- No external deps beyond stdlib
- Function signature must be: def normalize_email(s: str) -> str:
Behavior: strip, lowercase, reject strings without exactly one '@' by raising ValueError.
Do not write main(); provide the function and docstring only.

You write the signature and failing tests; the assistant fills implementation you then refine.

python
[object Object],
,[object Object], ,[object Object],(,[object Object],) -> ,[object Object],:
    ,[object Object],
    ,[object Object], NotImplementedError
python
[object Object],
,[object Object], pytest
,[object Object], gpa ,[object Object], gpa_from_letter_grades

,[object Object], ,[object Object],():
    ,[object Object], gpa_from_letter_grades([,[object Object],, ,[object Object],]) == pytest.approx(,[object Object],)

,[object Object], ,[object Object],():
    ,[object Object], gpa_from_letter_grades([,[object Object],, ,[object Object],]) > ,[object Object],

,[object Object], ,[object Object],():
    ,[object Object], pytest.raises(ValueError):
        gpa_from_letter_grades([])

,[object Object], ,[object Object],():
    ,[object Object], pytest.raises(ValueError):
        gpa_from_letter_grades([,[object Object],, ,[object Object],])

Walkthrough: Ask your assistant: “Implement gpa_from_letter_grades to pass these tests; use explicit mapping dict.” Then run pytest -v.

Expected output (excerpt): test_gpa.py::test_simple PASSED … all green. If one fails, read the failure, fix your understanding first, then adjust code.

A.3 Refactor prompts

  • “Extract validation into _parse_grade(token: str) -> float without changing behavior; show diff only for gpa.py.”
  • “Rename variable df1 to enrollment_by_term across this file; no logic changes.”

A.4 Debugging with AI

Paste stack trace + minimal file excerpt (not entire assignment).

text
Hypothesis: off-by-one in loop over CSV rows.
Here is the traceback: [paste]
Here is the function read_rows (40 lines max): [paste]
Suggest two candidate fixes. I will run tests before choosing.

Expected assistant behavior: Points to boundary conditions (header row, empty file, final newline). You run pytest on each suggested fix—do not merge both.

A.5 Code review with AI

text
Review this diff for: (1) logic bugs, (2) security issues, (3) readability.
For each issue, cite file:function and suggest a concrete patch.
If uncertain, say "verify with test" instead of guessing.

Mandatory next step: For every claimed bug, either write a failing test that proves it or reject the claim. Models false-positive on review like everyone else.

A.6 “Explain this diff” for learning

After merging AI help:

text
Explain in plain English what changed and list one edge case I should still test.

Use the answer as a comment block or README note if your course encourages learning journals.

Hands-On B: Property-Style Test (Optional Stretch)

Install: pip install hypothesis

python
[object Object], hypothesis ,[object Object], given, strategies ,[object Object], st
,[object Object], gpa ,[object Object], gpa_from_letter_grades

VALID = st.sampled_from([,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],])

,[object Object],
,[object Object], ,[object Object],(,[object Object],):
    g = gpa_from_letter_grades(grades)
    ,[object Object], ,[object Object], <= g <= ,[object Object],

Expected outcome: Test runs; if it fails, you have discovered a normalization bug that unit tests missed.

Hands-On D: Building a Small Project with AI Assistance (End-to-End)

Scenario: A “study hours logger” CLI that appends dated entries to a CSV.

  1. You write test_logger.py with tests for: create file if missing, append row, reject negative hours, reject future dates.
  2. AI implements logger.py to pass tests; you reject any use of eval or shell string formatting with user input.
  3. You add README.md with install, usage, and AI disclosure.
  4. Verify: pytest -v and manual run python logger.py add --hours 2 --note "reading".

Expected output (pytest): all tests passed. Expected CSV row: consistent column order and UTF-8 encoding.

Reflection prompt: Which step would have taken longest without AI? Where did AI steer you wrong?

Hands-On C: Git Workflow for AI Collaboration

bash
git checkout -b feature/ai-assisted-refactor
,[object Object],
pytest
git add -p
git commit -m ,[object Object],

When things break: git bisect between last good commit and HEAD finds the offending change—useful after a large agentic edit.

Hands-On E: Python — ast guardrail (reject eval / exec in suggestions)

When reviewing AI-generated code programmatically (or building a course autograder), you can scan the AST for dangerous calls. This does not replace human review but catches obvious foot-guns.

python
[object Object], ast


,[object Object], ,[object Object],(ast.NodeVisitor):
    ,[object Object], ,[object Object],(,[object Object],) -> ,[object Object],:
        ,[object Object],.forbidden: ,[object Object],[,[object Object],] = []

    ,[object Object], ,[object Object],(,[object Object],) -> ,[object Object],:
        ,[object Object], ,[object Object],(node.func, ast.Name) ,[object Object], node.func.,[object Object], ,[object Object], {,[object Object],, ,[object Object],}:
            ,[object Object],.forbidden.append(node.func.,[object Object],)
        ,[object Object],.generic_visit(node)


,[object Object], ,[object Object],(,[object Object],) -> ,[object Object],[,[object Object],]:
    tree = ast.parse(code)
    v = ForbiddenCallVisitor()
    v.visit(tree)
    ,[object Object], v.forbidden


sample = ,[object Object],
,[object Object],(,[object Object],, scan_source(sample))
,[object Object],

Expected use: Run on pasted snippets before merge; extend the visitor with subprocess, os.system, etc., if your threat model requires it.

Hands-On F: Python — Minimal diff summary for study logs

After each coding session, a tiny script helps you document what changed for AI-disclosure appendices (pairs with Module 01 logging).

python
[object Object], subprocess
,[object Object], sys


,[object Object], ,[object Object],() -> ,[object Object],:
    ,[object Object], subprocess.check_output(
        [,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],],
        text=,[object Object],,
        stderr=subprocess.STDOUT,
    )


,[object Object], __name__ == ,[object Object],:
    ,[object Object],:
        ,[object Object],(last_commit_stat())
    ,[object Object], subprocess.CalledProcessError ,[object Object], e:
        ,[object Object],(,[object Object],, e.output, file=sys.stderr)
        sys.exit(,[object Object],)

Expected output: git diff --stat lines suitable to paste into a lab notebook “session summary.”

Security, Ethics, and Academic Honesty

Secrets and .env

python
[object Object], os
api_key = os.environ.get(,[object Object],)
,[object Object], ,[object Object], api_key:
    ,[object Object], RuntimeError(,[object Object],)

Add .env to .gitignore. Check whether chat content is retained or used for training (vendor docs change—re-read each term).

Intellectual property and licenses

Generated code may resemble training data snippets. For commercial release or patent-sensitive work, run legal review. Prefer permissive dependencies and document provenance.

Security anti-patterns to reject

Bad patternWhy
eval(user_input)Remote code execution
SQL string concat with user dataInjection
shell=True with untrusted stringsCommand injection
Disabling TLS verificationMan-in-the-middle risk

Code review checklist (every AI-assisted PR)

  • I can explain each new function’s preconditions and postconditions.
  • Tests cover happy path, empty input, and one weird input.
  • No new dependencies without README note and license check.
  • Logging does not print PII or tokens.

OWASP awareness

If your project has login forms or cookies, skim OWASP Top 10. AI often generates demo auth that is not production-safe—label it in README.

Try This Now

  1. Tab discipline: Open a small Python file. For five completions, predict the suggestion before it appears; log how many you would have accepted blindly vs after prediction.
  2. Minimal repro: Take one failing test. Strip the production code to the smallest snippet that still fails; use AI only after you can state the failure in one sentence.
  3. Tool rotation: Solve the same 20-line task with Copilot inline only, then with Cursor chat only, then with Claude—compare time-to-green and number of bad suggestions accepted.
  4. Review drill: Paste a diff you wrote (not AI) and ask the model to find bugs—fact-check every claim with a test or grep.
  5. Disclosure draft: Write a 5-sentence AI disclosure paragraph suitable for your course’s honor code; include what you verified manually.

Discussion Prompts / Reflection Questions

  • When is accepting AI-generated code more risky than writing code slowly by hand—and why?
  • How would you explain to a non-technical stakeholder why “it passed the autograder once” is insufficient for production?
  • If your team disagrees on whether AI assistance is allowed for a class project, what process would you propose to align with syllabus and fairness?
  • Where should long-term learning live—in your head, in tests, in docs, or in the model—and how do those options trade off?

Practice Exercises

Exercise 1 — Bug garden (20 pts)
Start from intentionally buggy code. Use AI to propose fixes; you select and justify the correct fix in comments or 150 words. Rubric: correct fix (8), justification cites behavior/tests (8), honesty about AI role (4).

Exercise 2 — API hallucination drill (20 pts)
Ask for sample code using a library you know well (e.g., pathlib). Compare against official docs; list every discrepancy. Rubric: completeness (10), accuracy (10).

Exercise 3 — Diff review (20 pts)
Generate a 30-line patch with AI. Without running, predict behavior on three inputs; then run and reconcile mismatches in a short log. Rubric: predictions (8), reconciliation (8), insight (4).

Exercise 4 — Explainer (20 pts)
After accepting help, write five sentences for a non-programmer TA: what changed, why, one residual risk. Rubric: clarity (10), technical correctness (10).

Exercise 5 — No-assistant hour (20 pts)
Implement a small function without tools; repeat with assistance. Reflect in 200 words on time, correctness, and depth of understanding. Rubric: reflection depth (12), specific examples (8).

Mini-Project

CLI Utility with README, Tests, and AI Disclosure

Build a small command-line tool in Python (or your course language) that solves a real campus-adjacent problem you can ethically access: parse a schedule export, summarize club expense CSV, normalize survey codes, or validate bibliography snippets. Avoid identifiable private data about other students.

Requirements

  • CLI with argparse (or equivalent): at least one subcommand or two flags.
  • ≥8 automated tests including edge cases (empty file, malformed row, wrong encoding).
  • Clear error messages for user-fixable mistakes (file not found, bad column name).

Documentation

  • README.md: purpose, install (venv, pip install -r requirements.txt), usage examples, limitations, AI disclosure (which tools, which files/commits, how you verified).

Process

  • Git history: ≥5 meaningful commits; avoid single “dump” commits.
  • Self-review paragraph: Describe one AI-generated hunk you rejected and why.

Approach (suggested)

  1. Spec in plain English → 2. tests → 3. minimal implementation → 4. refactor with AI in small steps → 5. README + disclosure.

Mini-project extensions (depth)

  • Error catalog: Document three user errors your CLI catches with helpful messages (file not found, bad encoding, wrong column)—and one error you deliberately do not catch with a rationale.
  • Performance note: If your tool reads large CSVs, time one run on a synthetic 10k-row file; state Big-O intuition in plain language (O(n) scan vs. accidental O(n²) nested loops).
  • Pair interview prep: Write five flash-card answers explaining your design choices without opening the repo—mirrors internship code walkthroughs.

Deliverables

  • Source tree with tests passing in clean venv.
  • README + disclosure.
  • Optional: pre-commit with ruff; pyproject.toml entry point.

Evaluation hint: TAs grade whether you can explain the tool under questions, not line count. Prefer boring explicit logic over clever one-liners unless you fully own them.

Key Takeaways

  • Tests and types are your ground truth—not model confidence or fluent comments.
  • Small commits and hunk staging make AI collaboration auditable and reversible.
  • Read–predict–verify scales from first-year labs to industry code review.
  • Prompt with constraints (language version, deps, error behavior) to reduce garbage suggestions.
  • Copilot, Cursor, and Claude differ in context and workflow—match tool to task, then verify the same way.
  • Security and policy (secrets, FERPA-adjacent data, honor code) limit what you paste into cloud assistants.
  • The goal is understanding that survives a whiteboard interview or a senior engineer’s “why this line?”

Resources