WillTools 2026-09-09 -- clean snapshot of the development repo for review
ci / test (push) Successful in 6m18s

History-free snapshot of the private development repository at cbe45c5
(2026-09-09). Code, docs and public catalogue only; no plant or job
knowledge layers, no client or job names (tools/scrub.py clean). The
intro deck is left out of this snapshot because its slide images could
not be checked for job drawings.
This commit is contained in:
2026-09-09 08:32:15 -05:00
commit 8e6ee31596
406 changed files with 223435 additions and 0 deletions
+67
View File
@@ -0,0 +1,67 @@
# -*- coding: utf-8 -*-
"""Panel Analysis: decimal feet -> feet-inches display text, shared.
Owner ruling (`CLAUDE.md` / the pagespec docs): every length this tool
displays is feet-inches to 1/8" (`8'-4 1/2"`), never decimal feet -- the same
rule `tools/pa_web/static/units.js`'s `Units.fmtFtIn` enforces client-side for
plain editable fields. A `kv` block or a read-only table CELL built server-
side (Panel Weight & Centroid, the lifter/dunnage summary tables) is plain
text by the time it reaches the page -- the client never reformats it -- so
the same rounding has to happen here, in CPython/IronPython, before the text
is ever sent.
Split out of `vibe.pa_extents._feet_str` (2026-09-05) once a second module
(`vibe.pa_handling`) needed the identical formatting for its own kv/table
cells -- one algorithm, not two copies that can drift on a rounding edge.
Standard library only, both Pythons: no f-strings, no `pathlib`, no
`dataclasses`/typing/`enum`.
"""
# Eighths-of-an-inch -> the fraction word this module prints. A precast
# dimension finer than 1/8" is not meaningful, so `feet_str` rounds to it
# rather than pretending to more precision than the field carries.
EIGHTHS = {0: '', 1: '1/8', 2: '1/4', 3: '3/8', 4: '1/2',
5: '5/8', 6: '3/4', 7: '7/8'}
def feet_str(value):
"""Decimal feet -> an architectural dimension string, e.g. 8'-4 1/2".
Internal units are decimal feet throughout this codebase (`CLAUDE.md`
SS3), so a bare number is read as feet and converted here to the
feet-inches form the owner requires everywhere a length is displayed.
A value that is already a string is left to the CALLER to decide
whether to pass through unreformatted (a sibling module may hand this a
value that is already formatted correctly, and reformatting a string
that already reads right is how a "2'-11.5\"" becomes a wrong
"2'-11 1/2\"" glued onto a stray decimal) -- this function itself always
tries to read `value` as a plain number.
Returns `None` only when `value` cannot be read as a number at all --
never a fabricated dimension.
"""
try:
feet = float(value)
except (TypeError, ValueError):
return None
negative = feet < 0.0
feet = abs(feet)
whole_ft = int(feet)
inches = (feet - whole_ft) * 12.0
eighths_total = int(round(inches * 8.0))
whole_in, eighths = divmod(eighths_total, 8)
if whole_in >= 12:
whole_ft += whole_in // 12
whole_in = whole_in % 12
frac = EIGHTHS[eighths]
if frac and whole_in:
in_part = '{0} {1}'.format(whole_in, frac)
elif frac:
in_part = frac
else:
in_part = str(whole_in)
if whole_ft > 0:
text = u'{0}\'-{1}"'.format(whole_ft, in_part)
else:
text = u'{0}"'.format(in_part)
return u'-' + text if negative else text