Lesson 1: Set up Cursor, install the FlyPython Skill, fetch the course
Objective
By the end of this lesson Cursor is running, the FlyPython Skill is
installed in it (with network access approved), and the agent has fetched
this course’s files into your working folder — you downloaded nothing by
hand. With the folder in place you run the course’s objective check and
explain what “the starter fails” means in test names. No code is changed
in this lesson.
Step 1 — Get Cursor running
Install Cursor, then File → Open Folder
on an empty working folder.
Step 2 — (Optional) Pre-install the FlyPython Skill
Optional: Step 3’s entry sentence reads the Skill straight from its
URL, so the course works without this step — pre-installing just saves a
permission round-trip on tools that keep skills between sessions.
Save the Skill as a project rule:
mkdir -p .cursor/rules
curl -s https://flypython.com/skills/flypython/SKILL.md -o .cursor/rules/flypython.mdc
Open a chat in Agent mode — that mode reads files and runs commands.
Agent mode fetches URLs with approval; approve when it asks. If your
setup blocks the network, run the curl yourself and paste the file.
The Skill is one file, the same in every tool: it tells the agent how to
authorize you, fetch course files, verify, and submit claim codes.
Step 3 — Let the agent fetch this course (you download nothing)
Start a new session/chat/thread in the working folder and paste this one
sentence:
Read https://flypython.com/skills/flypython/SKILL.md and start the FlyPython course hands-on-with-cursor.
The agent gives you an authorization link with a short code. Open it, log
in, make sure the code matches what the agent showed you, and click
Allow — then tell the agent “done”. It takes a token once and writes this
course’s files to courses/hands-on-with-cursor/.
Prerequisite: these courses need a coding agent that can run commands
and reach the network. A chat-only web AI cannot do them.
Why this lesson exists
Most AI-written Python dies the same way: the demo input works, the real
input arrives, and the script crashes on row 3 — or worse, quietly produces
a wrong number. The fix does not start with a better prompt. It starts with
turning “it’s broken” into a command that anyone can run and get the same
answer. In Cursor, Agent mode runs that command right next to the code it
verifies.
Warm-up (2 minutes)
Open starter/report_tool.py in the editor and read it top to bottom. It
looks reasonable: functions with docstrings, type hints, a CLI. This is
exactly what AI-generated code looks like — clean surface, missing
behavior. Now open TASK.md and keep it next to you.
The lesson
The course files are in courses/hands-on-with-cursor/ now — no download happened on
your side. Ask the agent to survey them without changing anything:
“Read COURSE.md — it is the teaching contract for this folder. Then read
TASK.md and starter/report_tool.py. Do not change any file. Tell me which
behaviors the tests expect that the starter does not have.”
While it reads, run the learner’s command — your single check for the
rest of the course:
python verify.py
You should see the starter reproduce five real-world failure classes
plus two end-to-end consequences — seven named failing tests in all —
mapped to test names:
| Failing test | Real-world meaning |
|---|
test_load_json_records_returns_list_of_dicts | the tool only handles CSV; the API scenario crashes |
test_unsupported_suffix_raises_value_error | an .xlsx upload becomes a confusing crash instead of a clear rejection |
test_invalid_records_are_isolated_with_reasons | one empty cell aborts the entire run — no partial report, no reason |
test_group_totals_are_rounded_to_two_decimals | 0.1 + 0.2 prints as 0.30000000000000004 in your report |
test_write_report_creates_missing_parent_directories | the tool cannot write into a fresh output directory |
test_run_scenario_writes_report_file, test_main_prints_summary_and_returns_zero | end-to-end consequences of the above |
If you want the missing behaviors as exact failing test names, the
maintainer command prints them:
python verify.py starter --expect-failure
(The reference solution/ exists so maintainers can prove the target is
reachable. You never need to run it, and it is never the completion
standard — your implementation in starter/ is.)
Exercise
Pick the scenario skin you most identify with (excel-report,
data-monitor, or api-tool), open its data file, and find the rows that
will be rejected. Write down, before running anything, which test each bad
row will trigger. Then check yourself against the table above — and ask the
agent to confirm, not to fix.
Checkpoint
Run python verify.py in the course folder. You pass this lesson when you
can answer, without looking:
- Which five behaviors separate starter from solution, and which two
failing tests are their end-to-end consequences?
- Why does
python verify.py exit non-zero on purpose — what state is
it reporting, and why is that a success condition rather than an error?
- What does the row you found in the exercise do to the starter — crash,
isolate, or silently pass?
This checkpoint’s claim code is already in the default command’s output —
submit it only once you can answer the questions.
Expected evidence
The transcript of the default command, and your three answers. Keep them;
Lesson 4 will ask for them again.