Hi Hugh,
> It started off just getting Claude to generate these directly from the
> csv, but by the time I’d done a couple of them it made sense to get it
> into a simple program. All told it’s about half a day of work. Claude
> did all the program architecture, wrote all the code, wrote the docs,
> managed the repo and pushed to my GitHub.
Thanks for making that available. I was curious so here's some
comments.
When looking at the HTML produced for the example, I was puzzled why
clicking each of the ‘Bootlace ferrule’ wires in turn switched the
highlight to them except for ‘TL-GND (power meter’ which cancelled the
highlight.
It's because clicking the text doesn't ‘pick’; clicking the rectangle
the text sits in is needed. ‘TL-GND (power meter’ is the longest piece
of text so when I ran the mouse down vertically, it happened to be over
text for just that one wire.
I think the text should pick too, e.g. ‘13 Mode change’.
I looked just at the start of wd/parser.py:
5 # Flexible column name aliases (all lowercase, spaces normalised)
6 COLUMN_ALIASES: dict[str, list[str]] = {
7 "signal": ["signal", "signal name", "name", "wire", "wire
name"],
8 "left_conn": ["left connector", "left conn", "from connector",
"from",
9 "source connector", "source"],
10 "left_pin": ["left pin", "from pin", "source pin", "pin (left)",
"left pin no"],
11 "right_conn": ["right connector", "right conn", "to connector",
"to",
12 "dest connector", "destination connector",
"destination",
13 "termination", "termination type"],
14 "right_pin": ["right pin", "to pin", "dest pin", "destination
pin",
15 "pin (right)", "right pin no"],
16 "colour": ["wire colour", "wire color", "colour", "color",
"wire col"],
17 "warning": ["warning", "note", "notes", "annotation", "remark"],
18 "pair": ["pair", "twisted pair", "tp", "pair group", "cable
group"],
19 "length": ["length", "wire length", "len"],
20 }
COLUMN_ALIASES is only currently used by parser.py so perhaps it could
be better hidden from importers.
That the value is a list suggests to me, trying to understand its
purpose, that it may be modified, but it isn't. A tuple avoids this.
It would be nice if the first string in the list of values was
consistently the same as the key. Then I wouldn't need to hunt to see
if that was true each time, as it is.
23 def _norm(h: str) -> str:
24 return h.strip().lower().replace("_", " ").replace("-", " ")
This smells wrong: stripping spaces only to then turn some characters
into spaces.
27 def _map_headers(headers: list[str]) -> dict[str, int]:
28 norm = {_norm(h): i for i, h in enumerate(headers)}
29 result: dict[str, int] = {}
30 for field, aliases in COLUMN_ALIASES.items():
31 for alias in aliases:
32 if alias in norm:
33 result[field] = norm[alias]
34 break
35 return result
I haven't looked at the calls of this so it might not be possible, and
if it is possible it may not matter, but headers[] may be mapped onto
a norm{} which has fewer keys than len(headers). The last one wins,
having its index, ‘i’, stored. This might confuse the user.
And if a normalised header element isn't found in the aliases, which
include the key itself, then it is silently dropped by not appearing in
result[].
The example CSV could show that blank lines and comments are allowed,
that spaces can be used within fields to create columns, and notes may
be given.
--
Cheers, Ralph.
--
Next meeting: Online, Jitsi, Tuesday, 2026-06-02 20:00
Check to whom you are replying
Meetings, mailing list, IRC, ... https://dorset.lug.org.uk
New thread, don't hijack: mailto:[email protected]