T08-L02 · Write code · Level 2 Power user · 13-minute read, plus 75 minutes of doing

The script only one person could run

A PhD student wrote a small script with an AI assistant last spring. It turns the plate reader's export into the group's weekly summary: blank-corrected means, a check on replicate spread, one table for the lab meeting. Then she goes to a conference for two weeks. Her colleague finds the script on the shared drive, double-clicks it, gets a wall of red text, and does the summary by hand. Worse, the next week he gets it running, but on an export saved with German settings, so every value with a decimal comma is read as text and silently skipped. The table looks fine. Three samples are missing.

In a company it's the quality team at a medical-device maker. Once a month someone exports the returns from the ERP system, the company's business software for orders and stock, and builds a table of returns per product and reason. A colleague automated it with a script. It works on his laptop. On anyone else's, it needs a package, an add-on library for Python, that nobody has installed, and it writes its output over last month's file, so a failed run destroys the only copy.

The script was never the problem: only its author could run it and check it. This book shows you how to get a working script from an AI coding assistant, and then make it something a colleague can rerun and trust without you in the room. You are at Level 2 Power user: the table goes to your team, so a silent error spreads into their work.

After this you can

  • Describe a script by its input, steps, output and a known answer you worked out by hand, before you ask for any code.
  • Have OpenCode plan the script first, then build it, and read the diff to see which files it touched.
  • Make the script refuse bad input with the line number, and never overwrite an earlier result.
  • Hand the script to a colleague with a README and a test file, and watch them rerun it on their own computer.

Before you start

  • Books: T01-L01 for the four-quadrant method. T08-L01: one change in OpenCode Desktop, read in the diff and undone.
  • OpenCode Desktop with a working model (see T08-L01), and Git, the program that keeps every version of the files in a folder. Use the model your lab or company has set up. If there is none, the free models are enough for this book, provided you use made-up numbers only in the chat.
  • Python 3, the programming language the script is written in. Set up below installs it, on your computer and on your colleague's.
  • One real export your team processes by hand every week or month, and a place to share code: your group's Git server (such as Gitea or GitHub, websites that store Git folders), or a shared folder if there's none yet.
  • One colleague who'll rerun the script without you.
  • About 110 minutes: 13 to read, 20 to set up, about 75 to do.

Last verified 23 September 2026. OpenCode Desktop is free. Its free models are hosted in the US; during their free period some may use your prompts to improve the model, so keep real data out. The latest Python is 3.14.7. Details for experts at the end of this book.

Set up (20 minutes, once per computer)

Do this on your computer and on your colleague's. You'll use a terminal, a window where you type a command and press Enter instead of clicking, to run the script.

Open a terminal in a folder. On Windows 11, open the folder in File Explorer, right-click an empty space in it and choose Open in Terminal. On a Mac, click the magnifying glass in the menu bar, type Terminal and click it; then type cd and a space, drag the folder from Finder into the window, and press Return. Either way, the terminal now works "in" that folder.

Install Python. Go to python.org/downloads. On Windows, click Download Python install manager, double-click the downloaded file and choose Install; you don't need administrator rights, and the first time you type python, it fetches the current Python by itself. On a Mac, click the download button, open the file and follow the installer.

On a Mac, type python3 wherever this book says python. To check the install, type python --version and press Enter (Mac: python3 --version). You should see a number starting with 3.

Install Git. On Windows, go to git-scm.com/install/windows, click Click here to download, run the file and accept the suggested settings. On a Mac, type xcode-select --install in the terminal and confirm; Apple's developer tools include Git. Check with git --version.

The idea in one page

Describe the job before the code. A coding assistant turns a clear description into a working script in minutes. A vague one ("clean my export") gets you a script that does something. Write five lines first:

Input:   the file, its columns, one real example row
Steps:   what happens to each row, in order
Output:  the new file(s), their columns, where they go
Refuse:  what counts as a bad row, and what the script says then
Answer:  a tiny test file and the output you worked out by hand

The known answer is the whole trick. Take five or six rows of your export, copy them into test_input.csv, a CSV file (a plain-text table that any spreadsheet opens), and work out the result on paper or in a spreadsheet. Save that as expected_output.csv. A script that gives confident wrong numbers looks exactly like one that gives right numbers. Your hand-worked answer is the only difference, and later it lets a colleague check the script in thirty seconds.

Plan first, then build. In OpenCode, click in the message box and press Tab to switch to Plan mode, then paste your description. The assistant explains what it will write, and it can't change anything yet. Correct the plan: no extra packages, one file, don't touch the input. Then Tab back to Build.

Read the diff, not the reply. The assistant's closing message says what it meant to do. The Review panel shows what it did. For a one-script request, you should see one new file. If you see five, ask why.

Three rules make a script safe to share:

  1. Standard library only, meaning the tools that come with Python itself, unless your team already has a package installed everywhere. Every extra package is one more thing that fails on a colleague's laptop.
  2. Refuse, don't skip. A bad row stops the run with the line number and the reason. A script that quietly skips bad rows produces a table that looks complete and isn't.
  3. Never overwrite. Each run writes to a new folder named with the date. If the folder exists, the script stops. An earlier result is never lost to a failed run.

Share it where colleagues look. Put it in a Git repository on your group's server: a project folder whose every version Git keeps, so a colleague can see what changed and when. Add a README.md, a short instruction file next to the code. In five lines, it says how to run the script and how to check it. If your team has no Git server yet, a shared folder with dated copies is a start.

Worked example: a weekly script, handed over

The method comes from T01-L01. First the plate reader, then the returns report.

Lab: the weekly plate-reader summary

Structure it. Mira, the PhD student, decides to fix it properly when she's back. "Every week our plate reader exports a CSV. I subtract the blank, average the triplicates, and flag any sample whose replicates spread by more than 15%. A good result: a script anyone in the group can run on the export, which gives the same table I make by hand and refuses anything it can't read."

Understand it. She asks Paul, the colleague who covered for her, what went wrong. Two things. He works on Windows and has no admin rights, so he can't install packages. And the export he used came from the plate reader PC, which is set to German: semicolons between columns and decimal commas. Hers comes from her own laptop's re-save, with commas and decimal points. She checks the plate reader software: it always writes the German format.

That changes her problem. Back to Structure it: "The input is the raw export exactly as the plate reader writes it: semicolon-separated, decimal comma. Standard Python only. A value the script can't read as a number stops the run with the line number. It never skips."

She writes the description and works out the answer by hand for a seven-row test file: two samples in triplicate, one blank. Sample A: 0,512, 0,498, 0,505, blank 0,050, so corrected mean 0,455, spread well under 15%. Sample B: 0,310, 0,420, 0,300, corrected mean 0,293, spread over 15%, flagged.

Choose tools. OpenCode Desktop, because it shows the diff and /undo gives her a way back. The model is the one the institute provides through the group's account; the test file uses real numbers from a public demo plate, nothing unpublished. The alternative is Claude Code, which works the same way from a terminal or the Claude desktop app. For sharing: the group already runs a Gitea server on the institute's own computers for the lab wiki, so the script gets its own repository there.

Build it. She makes a new folder, platereader-summary, puts her two test files in it and opens it in OpenCode as in T08-L01. In the Review panel she clicks Create Git repository, which starts Git's version history for the folder.

Then she types in the message box: "Commit the two test files with the message 'Test file and hand-worked answer'." A commit saves the files as a named version; this one exists before any code does. If OpenCode asks permission to run Git, she chooses Allow once. Then she presses Tab for Plan mode and pastes:

Write summarise.py, using only the Python standard library.
Input: a plate reader CSV, semicolon-separated, decimal comma,
columns well;sample;od. The blank rows have sample "blank".
Steps: subtract the mean blank from every value; group by sample;
mean and coefficient of variation (standard deviation / mean);
flag CV above 15%.
Output: a new folder results-YYYY-MM-DD next to the input, with
summary.csv (sample;mean;cv_percent;flag), decimal comma.
If that folder exists, stop with a message. Never overwrite.
Refuse: a value that isn't a number, a missing column or no blank:
stop with the line number and the reason. Never skip a row.
Usage: python summarise.py export.csv
Show me your plan first. Don't create any other files.

The plan comes back with one surprise: it proposes pandas, a popular add-on package for tables, "for easier CSV handling". She answers: "Standard library only: Paul can't install packages." The revised plan uses Python's built-in csv module, the part of Python that reads tables, set to split columns at semicolons. She presses Tab for Build.

In the Review panel she sees one new file, summarise.py. She asks OpenCode to point to three places: where the file is read, where a bad value stops the run, and where the output is written. She reads those three spots. The output line uses mode "x", which fails if the file exists; that's her never-overwrite rule.

Check it. She opens a terminal in the folder, as in Set up, and types this command, which runs the script on the test file:

python summarise.py test_input.csv

She compares summary.csv with her hand-worked file, value by value. Sample A matches. Sample B's CV (coefficient of variation, the spread as a percentage of the mean) says 22,7; she had 23,0. She reruns her own arithmetic and finds she rounded the mean too early. The script was right. Then she breaks the test on purpose: she changes one value to n.d. and runs it again. "Line 5: can't read 'n.d.' as a number." No output folder is created. She restores the value, runs it twice more, and the second run stops: results folder already exists.

She asks OpenCode to run /init, which writes an AGENTS.md file describing the project for the assistant. She reads it, then writes the README herself:

# Plate reader summary
Run:   python summarise.py <export.csv>   (the raw export, unchanged)
Check: python summarise.py test_input.csv, then compare
       results-*/summary.csv with expected_output.csv. Must match.
Stops: on any value that isn't a number, with the line number.
Ask:   Mira; deputy: Paul

She asks OpenCode to commit everything. Then she shares it through the browser. On the group's Gitea she creates a new, empty repository. Its page offers an Upload File button: she uploads the two test files first, then the script, AGENTS.md and the README, so the history there also shows the test before the code. Developers send commits with git push instead; that's in T08-L04.

Team side. On the repository's page Paul clicks Code, then Download ZIP, and unpacks the file on his Windows laptop. He reads only the README, opens a terminal in the folder and runs the check. It matches. He runs it on this week's real export. It stops at line 41: an overflow value OVRFLW from a well that saturated. That's exactly the silent loss from before, now caught. They agree that saturated wells need a person to decide, and Mira adds that line to the README.

Company: the monthly returns report

Structure it. Leonie, in the quality team, takes over the script from the colleague who wrote it. "Every month: the ERP returns export in, a table of returns per product and reason code out, and a flag for any product with more than five returns. Anyone in the team can run it."

Understand it. She tries the old script on her laptop and it fails on a missing package. She reads what it does with OpenCode in Plan mode: "explain this script; don't change anything." It turns out the package is used only to read the CSV, and the script drops any row with an empty reason code. Last month that was nine returns. Back to Structure it: "Standard library. An empty reason code counts as 'not coded', and those go on their own line in the table: the team wants to see them, not lose them."

Choose tools. The same OpenCode route. The export contains customer numbers but no names; she uses a test file with made-up customer numbers in the chat, and the real export only on her own computer. The script goes into the quality team's repository on the company's GitHub.

Build it. A seven-row test file with the answer worked out by hand, including one empty reason code. Plan mode, correct the plan, Build, read the diff: one file. The new script writes to returns-YYYY-MM, refuses to overwrite, and stops on a malformed date with the line number.

Team side. A colleague runs the README check from her own laptop, then this month's export. The not coded line shows 14 returns, which starts a conversation with customer service about why reason codes go missing.

In both cases the assistant wrote the code in minutes. What made it a team script was the hand-worked answer, the refusal, the README and a colleague's run.

What goes wrong

It works on your laptop only. Symptom: a colleague gets an error about a missing module. Fix: standard library only, and have a colleague run the README check on their own computer before anyone relies on it.

Rows quietly disappear. Symptom: the summary has fewer samples or products than the input. Fix: refuse, don't skip. Print the number of rows read and rows used at the end of every run.

The format changed under you. Symptom: decimal commas read as text, or a new column shifts everything. Fix: describe the raw export exactly, check the header, and stop on anything unexpected.

Last month's result is gone. Symptom: a failed run overwrote the only good copy. Fix: a new dated folder per run, opened in a mode that fails if it exists.

The assistant widens the job. Symptom: a request for one script adds packages and extra files you didn't ask for. Fix: Plan mode first, "don't create any other files" in the request, and one file in the diff.

No way back. Symptom: after five changes, yesterday's working version is gone. Fix: commit after every check that passes. /undo helps inside a session; Git helps after it.

Do it yourself (75 minutes)

  1. Structure it (10 min). Write the five lines: input, steps, output, refuse, answer. Use one real row as the example.
  2. Understand it (15 min). Ask the colleague who'll rerun it what computer they use and what they may install. Open the raw export in a text editor, not a spreadsheet: check separators and decimals. Rewrite your description.
  3. Choose tools (5 min). OpenCode with your organisation's model; made-up or public numbers in the chat. Decide where the repository lives.
  4. Build it (45 min). Test file and hand-worked answer first, committed. Plan mode, correct the plan, Build. Read the diff and find the three places. Run the check, break it once, run it twice. README, commit, upload. Watch your colleague download it and run the check from the README alone.

Exit check

What you hand in: a shared repository with:

  • the script, standard library only;
  • test_input.csv and expected_output.csv, worked out by hand;
  • a README.md with the run command, the check, what makes it stop, and who to ask;
  • a commit history that shows the test file before the script.

It passes when your colleague, on their own computer and using only the README, gets exactly the expected output, and gets a refusal with a line number from one broken row.

Rule to remember

A script is ready for the team when someone else can check it without you.

Details for experts

Checked on 23 September 2026. You don't need this to follow the book; it's for setting things up or answering a colleague.

WhatDetailsWhat it means for you
OpenCode Desktop downloadFree from opencode.ai/download for macOS (Apple Silicon and Intel), Windows (x64) and Linux (.deb and .rpm, the two common Linux install formats).Pick the file that matches your computer. On a managed work laptop, ask IT.
Free modelsThey run through OpenCode Zen, OpenCode's own model service, hosted in the US. During their free period, some free models may use your prompts and answers to improve the model.Made-up or public numbers only in the chat. For real exports, use the model your lab or company has set up (T12-L01).
Plan and Build modesPress Tab to switch to Plan mode, where OpenCode suggests how it will make a change but can't edit files. Tab again returns to Build, where it can.Plan first on every new script, so you can strike extra packages before any file is written.
Review tabLists the files a session changed. In a folder without Git it offers Create Git repository.Create it before the first edit, or you can't see the diff.
/undo and /redoTyped in the message box. /undo reverts the last change and can be repeated; /redo brings it back.A way back inside one session. After the session, your Git commits are the way back.
/initWrites an AGENTS.md file describing the project, which OpenCode reads in later sessions. OpenCode recommends committing it to Git.Commit it with the script, so the next person's assistant starts with the same picture.
PythonThe latest stable version is 3.14.7, released 5 August 2026. On Windows, python.org offers the Python install manager, which installs per user without administrator rights; the standalone installer is the alternative. The Mac installer adds the python3 command.A computer without Python gets the current version from python.org.
GitGit for Windows 2.55.0 (20 August 2026) from git-scm.com. On a Mac, Git comes with Apple's Command Line Tools (xcode-select --install); Homebrew is the alternative.On a managed work computer, ask IT to install both.
Uploading in the browserGitea: Add File → Upload File; GitHub: Add file → Upload files. Each upload is one commit. Downloading: Code → Download ZIP on both.No sign-in from the terminal needed. The ZIP has no history; that's fine for running the check.

The app in depth, including models and permissions: T08-L04.

Further reading and tools

Next books

Tools

  • OpenCode: Taught. Plan mode, Build mode, the Review tab and /init.
  • Git: Taught. Commits and the shared repository.
  • Gitea, GitHub: Catalogued. Where the team's repository can live.
  • Claude Code: Catalogued. The same loop from a terminal or the Claude desktop app.