Instructing Claude
I’m taking a brief break from tech employment but things are changing fast enough in our industry that I’m keeping current with personal projects. One spreadsheet I update monthly really needed a Sankey diagram, but Google Sheets doesn’t offer one. I wrote a trivial python script to process the data into the text input format for the online Sankeymatic tool.
The script worked fine, but copy/pasting the data from a spreadsheet into the script and then copy/pasting the output of the script into Sankeymatic was a silly hassle. I wanted to add to my script so that it could generate the diagrams directly and pull the data in automatically too. I decided to use those simple changes to compare my own coding output with what Anthropic’s Claude (Claude Code v2.1.141, Sonnet 4.6) would do. I also wanted to test two different levels of instruction with Claude: one where I told it what changes to make with a high degree of specificity and one where I gave it only the general goals of the features I wanted added with no implementation details.
I forked the project and now have three different versions of the script. The sabbatical-sankey script is 100% hand rolled python with network loading and local image generation added how I would normally do it. The sabbatical-sankey-claude script is Claude’s modifications when told explicitly what libraries to use and options to add. The sabbatical-sankey-extra-claude script is Claude’s modifications when given only plan-level descriptions of the features to add.
All in all the three are pretty similar. I used the requests HTTP client
because I know it well, and had the instructed Claude use it too. The plan-only
Claude used the built-in urllib, which is arguably the better choice since it
keeps requirements down, but no one actually likes using it. Claude did
a better job of keeping the command line arguments clean and giving them help
text.
The less specifically instructed Claude added a required header and then command line options to select columns by name. That’s a fine idea if the script is going to grow, but felt a little YAGNI to me.
I also noticed that both Claude implementations did some clumsy handling of
list comprehensions and dicts to get the awkward list of integer indexes that
plotly wants for source and target when creating links in the link and
labels keys of an input dict:
The low-specificity Claude did it this way:
|
|
The high-specificity Claude did it this way:
|
|
Whereas I did this when hand coding:
|
|
My way does does require knowing that since python 3.7 insertion order of dicts is maintained and that casting a dict to a list gets you the keys in insertion order, but it also just reads and looks like python instead of janky list comprehensions with opaque positional indexes.
I think Claude’s results were better when it wasn’t given implementation instructions, only general goals, so I’ll go with a less hands-on approach in the future when I do use a coding agent. Mostly though I’ll continue to prefer hand-rolling code.
On my way out the door I asked the plan-only Claude what improvements it would suggest for the script. None of them are things I wanted, but they weren’t unreasonable:
Final suggestions:
- Auto-open the output file — right now you generate sankey.png and then have to navigate to it separately. A –open flag (or always-open behavior) with xdg-open/open would save a step every run.
- Save the –url to a local config file — typing or pasting that long Google Sheets URL every time is friction. A –save-url flag could persist it to a .tsv2sankey file in the project dir so subsequent runs just work without the flag.
- –title flag — add a title to the diagram, useful when generating multiple variants.
Which of these (if any) would you like to pursue?