feat(task-8): ISO fastener and ISO 15 bearing tables, transcribed and pinned
engineering/mech/standards/fasteners.py carries ISO 4014:2011 / ISO 4017:2014 head dimensions (s, k), ISO 4032:2012 nut heights, ISO 7089:2000 washer d1/d2/h and ISO 4762:2004 socket head cap screws, plus the ISO 261:1998 coarse pitch column. bearings.py carries the ISO 15:2017 deep groove boundary dimensions for 6000-6010, 6200-6210 and 6300-6310. Only the ISO 261 first-choice sizes ship. M14/M18/M22/M27/M33, everything above M36 (above M24 for ISO 4762), the 618x/619x/16xx bearing series, bore numbers above 10 and every suffixed bearing variant are refused by name rather than interpolated: a narrow table is merely narrow, a wrong row ships a wrong workshop drawing. Across-corners e is derived geometry (2s/sqrt(3)), so no e column had to be transcribed at all, and the ISO 8826-1 cross and ISO 8826-2 element-symbol fractions are declared drawing conventions, not table values. No ActiveX member is called by this task, so no live AutoCAD probe was needed; the two modules are pure tables and pure arithmetic. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FKFStjEFzpGyLq5bMpWxTd
This commit is contained in:
co-authored by
Claude Opus 5
parent
2bb8044144
commit
49b972f007
@@ -0,0 +1,136 @@
|
||||
"""ISO 15 deep groove ball bearings, plus the ISO 8826 representation rules.
|
||||
|
||||
SOURCE
|
||||
------
|
||||
* ``DEEP_GROOVE`` - ISO 15:2017 Table 4: boundary dimensions ``d`` (bore),
|
||||
``D`` (outside diameter) and ``B`` (width) for the radial bearings of
|
||||
dimension series 10 (600x), 02 (620x) and 03 (630x).
|
||||
* ``SOURCE_ISO_8826_1`` - ISO 8826-1:1989, general simplified representation:
|
||||
the bearing is drawn as its envelope outline with an upright cross inside
|
||||
that does not touch the outline.
|
||||
* ``SOURCE_ISO_8826_2`` - ISO 8826-2:1994, particular simplified
|
||||
representation: the envelope outline plus a symbol for the rolling element.
|
||||
|
||||
COVERAGE
|
||||
--------
|
||||
600x, 620x and 630x, bore numbers 00..10 (d = 10..50 mm) - 33 rows. Bore
|
||||
numbers 00/01/02/03 are 10/12/15/17 mm by the ISO 15 rule; 04 and up are
|
||||
``5 x bore number``. Deliberately **not** transcribed, and refused by name:
|
||||
bore numbers above 10, the wide series 622x/623x, the light series 618x/619x
|
||||
and 16xx, the inch series, and every suffixed variant (``6205-2RS``,
|
||||
``6205-Z``) - a suffix changes width and sealing, not a number this module may
|
||||
guess.
|
||||
|
||||
The chamfer dimensions ``r_s`` are not transcribed either: neither simplified
|
||||
representation needs them, so no row carries a value nobody checked.
|
||||
|
||||
CROSS_FRACTION and BALL_SYMBOL_FRACTION are **declared drawing conventions**,
|
||||
not transcribed dimensions. ISO 8826-1 fixes the *form* of the cross and
|
||||
requires only that it not touch the outline; ISO 15 carries no ball diameter
|
||||
at all, so the element symbol is sized as a fraction of the ring gap rather
|
||||
than invented as a real ball.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from . import Coverage, register
|
||||
|
||||
SOURCE_ISO_15 = (
|
||||
"ISO 15:2017 Table 4 - rolling bearings, radial bearings, boundary dimensions "
|
||||
"(dimension series 10, 02, 03)"
|
||||
)
|
||||
SOURCE_ISO_8826_1 = (
|
||||
"ISO 8826-1:1989 - technical drawings, rolling bearings, general simplified representation"
|
||||
)
|
||||
SOURCE_ISO_8826_2 = (
|
||||
"ISO 8826-2:1994 - technical drawings, rolling bearings, particular simplified representation"
|
||||
)
|
||||
|
||||
#: Fraction of the half-width / half-gap used by the ISO 8826-1 upright cross.
|
||||
#: A declared convention (see the module docstring), never a table value.
|
||||
CROSS_FRACTION = 0.6
|
||||
|
||||
#: Fraction of the half-gap used by the ISO 8826-2 rolling-element symbol.
|
||||
#: A declared convention, never a ball diameter.
|
||||
BALL_SYMBOL_FRACTION = 0.6
|
||||
|
||||
BEARING_SERIES = ("600x", "620x", "630x")
|
||||
_SERIES_PREFIX = {"60": "600x", "62": "620x", "63": "630x"}
|
||||
|
||||
#: ISO 15:2017 Table 4 - d, D, B in millimetres.
|
||||
DEEP_GROOVE: dict[str, dict[str, float]] = {
|
||||
# dimension series 10 (600x)
|
||||
"6000": {"d": 10.0, "D": 26.0, "B": 8.0},
|
||||
"6001": {"d": 12.0, "D": 28.0, "B": 8.0},
|
||||
"6002": {"d": 15.0, "D": 32.0, "B": 9.0},
|
||||
"6003": {"d": 17.0, "D": 35.0, "B": 10.0},
|
||||
"6004": {"d": 20.0, "D": 42.0, "B": 12.0},
|
||||
"6005": {"d": 25.0, "D": 47.0, "B": 12.0},
|
||||
"6006": {"d": 30.0, "D": 55.0, "B": 13.0},
|
||||
"6007": {"d": 35.0, "D": 62.0, "B": 14.0},
|
||||
"6008": {"d": 40.0, "D": 68.0, "B": 15.0},
|
||||
"6009": {"d": 45.0, "D": 75.0, "B": 16.0},
|
||||
"6010": {"d": 50.0, "D": 80.0, "B": 16.0},
|
||||
# dimension series 02 (620x)
|
||||
"6200": {"d": 10.0, "D": 30.0, "B": 9.0},
|
||||
"6201": {"d": 12.0, "D": 32.0, "B": 10.0},
|
||||
"6202": {"d": 15.0, "D": 35.0, "B": 11.0},
|
||||
"6203": {"d": 17.0, "D": 40.0, "B": 12.0},
|
||||
"6204": {"d": 20.0, "D": 47.0, "B": 14.0},
|
||||
"6205": {"d": 25.0, "D": 52.0, "B": 15.0},
|
||||
"6206": {"d": 30.0, "D": 62.0, "B": 16.0},
|
||||
"6207": {"d": 35.0, "D": 72.0, "B": 17.0},
|
||||
"6208": {"d": 40.0, "D": 80.0, "B": 18.0},
|
||||
"6209": {"d": 45.0, "D": 85.0, "B": 19.0},
|
||||
"6210": {"d": 50.0, "D": 90.0, "B": 20.0},
|
||||
# dimension series 03 (630x)
|
||||
"6300": {"d": 10.0, "D": 35.0, "B": 11.0},
|
||||
"6301": {"d": 12.0, "D": 37.0, "B": 12.0},
|
||||
"6302": {"d": 15.0, "D": 42.0, "B": 13.0},
|
||||
"6303": {"d": 17.0, "D": 47.0, "B": 14.0},
|
||||
"6304": {"d": 20.0, "D": 52.0, "B": 15.0},
|
||||
"6305": {"d": 25.0, "D": 62.0, "B": 17.0},
|
||||
"6306": {"d": 30.0, "D": 72.0, "B": 19.0},
|
||||
"6307": {"d": 35.0, "D": 80.0, "B": 21.0},
|
||||
"6308": {"d": 40.0, "D": 90.0, "B": 23.0},
|
||||
"6309": {"d": 45.0, "D": 100.0, "B": 25.0},
|
||||
"6310": {"d": 50.0, "D": 110.0, "B": 27.0},
|
||||
}
|
||||
|
||||
|
||||
def bearing(designation) -> dict:
|
||||
"""Boundary dimensions of one deep groove ball bearing.
|
||||
|
||||
Returns ``{"designation", "series", "source", "d", "D", "B"}``. A
|
||||
designation outside the transcribed table is refused by name; nothing is
|
||||
interpolated between series or bore numbers.
|
||||
"""
|
||||
key = " ".join(str(designation).split()).upper()
|
||||
if key not in DEEP_GROOVE:
|
||||
raise ValueError(
|
||||
"ISO 15 deep groove ball bearings are transcribed here for the 600x, 620x "
|
||||
f"and 630x series, bore numbers 00-10 (d = 10-50 mm); {key!r} is outside "
|
||||
f"that table and is never interpolated ({SOURCE_ISO_15})."
|
||||
)
|
||||
return {
|
||||
"designation": key,
|
||||
"series": _SERIES_PREFIX[key[:2]],
|
||||
"source": SOURCE_ISO_15,
|
||||
**DEEP_GROOVE[key],
|
||||
}
|
||||
|
||||
|
||||
def list_bearings(series: str | None = None) -> tuple[dict, ...]:
|
||||
"""Every transcribed bearing, optionally restricted to one series."""
|
||||
rows = tuple(bearing(name) for name in DEEP_GROOVE)
|
||||
if series is None:
|
||||
return rows
|
||||
name = " ".join(str(series).split()).lower()
|
||||
if name not in BEARING_SERIES:
|
||||
raise ValueError(
|
||||
f"list_bearings: series must be one of {', '.join(BEARING_SERIES)}, got {series!r}."
|
||||
)
|
||||
return tuple(row for row in rows if row["series"] == name)
|
||||
|
||||
|
||||
register("ISO 15", DEEP_GROOVE, Coverage(10.0, 50.0), SOURCE_ISO_15)
|
||||
@@ -0,0 +1,269 @@
|
||||
"""ISO metric fastener tables - transcribed from the standards, never derived.
|
||||
|
||||
SOURCE
|
||||
------
|
||||
* ``HEX_HEAD`` ISO 4014:2011 Table 1 (hexagon head bolts, product grades A
|
||||
and B) and ISO 4017:2014 Table 1 (hexagon head screws, fully threaded). The
|
||||
two standards carry the same width across flats ``s`` and head height ``k``
|
||||
for every size shipped here, so one table serves both and the standard is a
|
||||
property of the *part*, not a second copy of the table.
|
||||
* ``HEX_NUT`` ISO 4032:2012 Table 1 (hexagon regular nuts, style 1):
|
||||
width across flats ``s``, nut height ``m`` (max).
|
||||
* ``WASHER`` ISO 7089:2000 Table 1 (plain washers, normal series, product
|
||||
grade A): inside diameter ``d1``, outside diameter ``d2``, thickness ``h``.
|
||||
* ``SOCKET_HEAD`` ISO 4762:2004 Table 1 (hexagon socket head cap screws): head
|
||||
diameter ``dk`` (max), head height ``k`` (max), hexagon socket width across
|
||||
flats ``s``, thread length ``b``.
|
||||
* ``COARSE_PITCH`` ISO 261:1998, coarse pitch series.
|
||||
|
||||
COVERAGE (deliberately narrow - the table rule of the mech spec, section 5)
|
||||
---------------------------------------------------------------------------
|
||||
Only ISO 261 **first-choice** sizes are shipped:
|
||||
|
||||
* ISO 4014 / 4017 / 4032 / 7089 : M5 M6 M8 M10 M12 M16 M20 M24 M30 M36
|
||||
* ISO 4762 : M3 M4 M5 M6 M8 M10 M12 M16 M20 M24
|
||||
|
||||
Second-choice sizes (M14, M18, M22, M27, M33) and everything beyond those
|
||||
ranges are **not** shipped and are refused by name. A narrow table is merely
|
||||
narrow; a wrong across-flats ships a wrong workshop drawing.
|
||||
|
||||
Two columns are deliberately absent:
|
||||
|
||||
* across-corners ``e`` - :func:`across_corners` returns the *nominal*
|
||||
hexagon's ``2s/sqrt(3)`` instead. The standards' own ``e`` is a minimum
|
||||
computed from ``s`` min and is product-grade dependent; a drawing of the
|
||||
nominal part wants the nominal hexagon, so no ``e`` column is transcribed.
|
||||
* the per-size nominal length ranges of ISO 4014 Table 1 - ``l`` is validated
|
||||
as a finite positive number and the useful thread length comes from the
|
||||
standard's own ``b`` rule in :func:`thread_length`.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import math
|
||||
|
||||
from . import Coverage, register
|
||||
|
||||
SOURCE_ISO_4014 = "ISO 4014:2011 Table 1 - hexagon head bolts, product grades A and B"
|
||||
SOURCE_ISO_4017 = "ISO 4017:2014 Table 1 - hexagon head screws, fully threaded"
|
||||
SOURCE_ISO_4032 = "ISO 4032:2012 Table 1 - hexagon regular nuts, style 1"
|
||||
SOURCE_ISO_7089 = "ISO 7089:2000 Table 1 - plain washers, normal series, product grade A"
|
||||
SOURCE_ISO_4762 = "ISO 4762:2004 Table 1 - hexagon socket head cap screws"
|
||||
SOURCE_ISO_261 = "ISO 261:1998 - ISO general purpose metric screw threads, coarse pitch series"
|
||||
|
||||
#: ISO 261:1998 coarse pitch, one entry per size any table below carries.
|
||||
COARSE_PITCH: dict[str, float] = {
|
||||
"M3": 0.5,
|
||||
"M4": 0.7,
|
||||
"M5": 0.8,
|
||||
"M6": 1.0,
|
||||
"M8": 1.25,
|
||||
"M10": 1.5,
|
||||
"M12": 1.75,
|
||||
"M16": 2.0,
|
||||
"M20": 2.5,
|
||||
"M24": 3.0,
|
||||
"M30": 3.5,
|
||||
"M36": 4.0,
|
||||
}
|
||||
|
||||
#: ISO 4014:2011 / ISO 4017:2014 Table 1 - s = across flats, k = head height.
|
||||
HEX_HEAD: dict[str, dict[str, float]] = {
|
||||
"M5": {"s": 8.0, "k": 3.5},
|
||||
"M6": {"s": 10.0, "k": 4.0},
|
||||
"M8": {"s": 13.0, "k": 5.3},
|
||||
"M10": {"s": 16.0, "k": 6.4},
|
||||
"M12": {"s": 18.0, "k": 7.5},
|
||||
"M16": {"s": 24.0, "k": 10.0},
|
||||
"M20": {"s": 30.0, "k": 12.5},
|
||||
"M24": {"s": 36.0, "k": 15.0},
|
||||
"M30": {"s": 46.0, "k": 18.7},
|
||||
"M36": {"s": 55.0, "k": 22.5},
|
||||
}
|
||||
|
||||
#: ISO 4032:2012 Table 1 - s = across flats, m = nut height (max).
|
||||
HEX_NUT: dict[str, dict[str, float]] = {
|
||||
"M5": {"s": 8.0, "m": 4.7},
|
||||
"M6": {"s": 10.0, "m": 5.2},
|
||||
"M8": {"s": 13.0, "m": 6.8},
|
||||
"M10": {"s": 16.0, "m": 8.4},
|
||||
"M12": {"s": 18.0, "m": 10.8},
|
||||
"M16": {"s": 24.0, "m": 14.8},
|
||||
"M20": {"s": 30.0, "m": 18.0},
|
||||
"M24": {"s": 36.0, "m": 21.5},
|
||||
"M30": {"s": 46.0, "m": 25.6},
|
||||
"M36": {"s": 55.0, "m": 31.0},
|
||||
}
|
||||
|
||||
#: ISO 7089:2000 Table 1 - d1 = bore, d2 = outside diameter, h = thickness.
|
||||
WASHER: dict[str, dict[str, float]] = {
|
||||
"M5": {"d1": 5.3, "d2": 10.0, "h": 1.0},
|
||||
"M6": {"d1": 6.4, "d2": 12.0, "h": 1.6},
|
||||
"M8": {"d1": 8.4, "d2": 16.0, "h": 1.6},
|
||||
"M10": {"d1": 10.5, "d2": 20.0, "h": 2.0},
|
||||
"M12": {"d1": 13.0, "d2": 24.0, "h": 2.5},
|
||||
"M16": {"d1": 17.0, "d2": 30.0, "h": 3.0},
|
||||
"M20": {"d1": 21.0, "d2": 37.0, "h": 3.0},
|
||||
"M24": {"d1": 25.0, "d2": 44.0, "h": 4.0},
|
||||
"M30": {"d1": 31.0, "d2": 56.0, "h": 4.0},
|
||||
"M36": {"d1": 37.0, "d2": 66.0, "h": 5.0},
|
||||
}
|
||||
|
||||
#: ISO 4762:2004 Table 1 - dk = head diameter (max), k = head height (max),
|
||||
#: s = hexagon socket across flats, b = thread length.
|
||||
SOCKET_HEAD: dict[str, dict[str, float]] = {
|
||||
"M3": {"dk": 5.5, "k": 3.0, "s": 2.5, "b": 18.0},
|
||||
"M4": {"dk": 7.0, "k": 4.0, "s": 3.0, "b": 20.0},
|
||||
"M5": {"dk": 8.5, "k": 5.0, "s": 4.0, "b": 22.0},
|
||||
"M6": {"dk": 10.0, "k": 6.0, "s": 5.0, "b": 24.0},
|
||||
"M8": {"dk": 13.0, "k": 8.0, "s": 6.0, "b": 28.0},
|
||||
"M10": {"dk": 16.0, "k": 10.0, "s": 8.0, "b": 32.0},
|
||||
"M12": {"dk": 18.0, "k": 12.0, "s": 10.0, "b": 36.0},
|
||||
"M16": {"dk": 24.0, "k": 16.0, "s": 14.0, "b": 44.0},
|
||||
"M20": {"dk": 30.0, "k": 20.0, "s": 17.0, "b": 52.0},
|
||||
"M24": {"dk": 36.0, "k": 24.0, "s": 19.0, "b": 60.0},
|
||||
}
|
||||
|
||||
_TABLES: dict[str, tuple[dict[str, dict[str, float]], str]] = {
|
||||
"ISO 4014": (HEX_HEAD, SOURCE_ISO_4014),
|
||||
"ISO 4017": (HEX_HEAD, SOURCE_ISO_4017),
|
||||
"ISO 4032": (HEX_NUT, SOURCE_ISO_4032),
|
||||
"ISO 7089": (WASHER, SOURCE_ISO_7089),
|
||||
"ISO 4762": (SOCKET_HEAD, SOURCE_ISO_4762),
|
||||
}
|
||||
|
||||
THREAD_LENGTH_STANDARDS = ("ISO 4014", "ISO 4017", "ISO 4762")
|
||||
|
||||
|
||||
def _key(size) -> str:
|
||||
key = str(size).strip().upper()
|
||||
if not key:
|
||||
raise ValueError("fastener size must be a non-empty string such as 'M12'")
|
||||
return key
|
||||
|
||||
|
||||
def _row(table: dict, standard: str, source: str, key: str) -> dict:
|
||||
if key not in table:
|
||||
raise ValueError(
|
||||
f"{standard} is transcribed here for {', '.join(table)} only; {key!r} is "
|
||||
f"outside that table and is never interpolated ({source})."
|
||||
)
|
||||
return dict(table[key])
|
||||
|
||||
|
||||
def nominal_diameter(size) -> float:
|
||||
"""Nominal thread diameter in mm, e.g. ``'M12' -> 12.0``."""
|
||||
key = _key(size)
|
||||
if key not in COARSE_PITCH:
|
||||
raise ValueError(
|
||||
f"{SOURCE_ISO_261} is transcribed here for {', '.join(COARSE_PITCH)}; "
|
||||
f"{key!r} is outside it."
|
||||
)
|
||||
return float(key[1:])
|
||||
|
||||
|
||||
def thread_pitch(size) -> float:
|
||||
"""ISO 261 coarse pitch in mm."""
|
||||
key = _key(size)
|
||||
if key not in COARSE_PITCH:
|
||||
raise ValueError(
|
||||
f"{SOURCE_ISO_261} is transcribed here for {', '.join(COARSE_PITCH)}; "
|
||||
f"{key!r} is outside it."
|
||||
)
|
||||
return COARSE_PITCH[key]
|
||||
|
||||
|
||||
def hex_head(size) -> dict:
|
||||
"""ISO 4014 / ISO 4017 head row plus the nominal diameter and pitch."""
|
||||
key = _key(size)
|
||||
row = _row(HEX_HEAD, "ISO 4014 / ISO 4017", SOURCE_ISO_4014, key)
|
||||
return {"size": key, "d": nominal_diameter(key), "p": thread_pitch(key), **row}
|
||||
|
||||
|
||||
def hex_nut(size) -> dict:
|
||||
"""ISO 4032 nut row plus the nominal diameter and pitch."""
|
||||
key = _key(size)
|
||||
row = _row(HEX_NUT, "ISO 4032", SOURCE_ISO_4032, key)
|
||||
return {"size": key, "d": nominal_diameter(key), "p": thread_pitch(key), **row}
|
||||
|
||||
|
||||
def washer(size) -> dict:
|
||||
"""ISO 7089 washer row plus the mating thread's nominal diameter and pitch."""
|
||||
key = _key(size)
|
||||
row = _row(WASHER, "ISO 7089", SOURCE_ISO_7089, key)
|
||||
return {"size": key, "d": nominal_diameter(key), "p": thread_pitch(key), **row}
|
||||
|
||||
|
||||
def socket_head(size) -> dict:
|
||||
"""ISO 4762 socket head cap screw row plus the nominal diameter and pitch."""
|
||||
key = _key(size)
|
||||
row = _row(SOCKET_HEAD, "ISO 4762", SOURCE_ISO_4762, key)
|
||||
return {"size": key, "d": nominal_diameter(key), "p": thread_pitch(key), **row}
|
||||
|
||||
|
||||
def thread_length(size, length: float, standard: str = "ISO 4014") -> float:
|
||||
"""Useful thread length ``b`` for a nominal length ``l``, per the part standard.
|
||||
|
||||
ISO 4014 fixes ``b`` by rule rather than by table: ``2d + 6`` for
|
||||
``l <= 125``, ``2d + 12`` for ``125 < l <= 200`` and ``2d + 25`` for
|
||||
``l > 200``. ISO 4017 screws are threaded over their whole length. ISO 4762
|
||||
tabulates ``b`` per size. In every case a screw shorter than its own ``b``
|
||||
is threaded to the head, so the result is capped at ``l``.
|
||||
"""
|
||||
key = _key(size)
|
||||
name = " ".join(str(standard).split())
|
||||
if name not in THREAD_LENGTH_STANDARDS:
|
||||
raise ValueError(
|
||||
f"thread_length: standard must be one of {', '.join(THREAD_LENGTH_STANDARDS)}, "
|
||||
f"got {standard!r}."
|
||||
)
|
||||
if isinstance(length, bool) or not isinstance(length, (int, float)):
|
||||
raise ValueError(f"thread_length: length must be a number, got {length!r}")
|
||||
l_mm = float(length)
|
||||
if not math.isfinite(l_mm) or l_mm <= 0.0:
|
||||
raise ValueError(f"thread_length: length must be finite and > 0, got {length!r}")
|
||||
if name == "ISO 4017":
|
||||
hex_head(key)
|
||||
return l_mm
|
||||
if name == "ISO 4762":
|
||||
return min(socket_head(key)["b"], l_mm)
|
||||
diameter = nominal_diameter(key)
|
||||
hex_head(key) # ISO 4014 coverage: refuse a size the head table does not carry
|
||||
if l_mm <= 125.0:
|
||||
b = 2.0 * diameter + 6.0
|
||||
elif l_mm <= 200.0:
|
||||
b = 2.0 * diameter + 12.0
|
||||
else:
|
||||
b = 2.0 * diameter + 25.0
|
||||
return min(b, l_mm)
|
||||
|
||||
|
||||
def across_corners(s: float) -> float:
|
||||
"""Across-corners width of the *nominal* hexagon: ``2s/sqrt(3)``.
|
||||
|
||||
Derived geometry, not a transcribed column - see the module docstring.
|
||||
"""
|
||||
if isinstance(s, bool) or not isinstance(s, (int, float)):
|
||||
raise ValueError(f"across_corners: s must be a number, got {s!r}")
|
||||
width = float(s)
|
||||
if not math.isfinite(width) or width <= 0.0:
|
||||
raise ValueError(f"across_corners: s must be finite and > 0, got {s!r}")
|
||||
return 2.0 * width / math.sqrt(3.0)
|
||||
|
||||
|
||||
def sizes(standard: str) -> tuple[str, ...]:
|
||||
"""The transcribed sizes of one fastener standard, in table order."""
|
||||
name = " ".join(str(standard).split()).upper()
|
||||
if name not in _TABLES:
|
||||
raise ValueError(
|
||||
f"sizes: {standard!r} is not a fastener standard in this module; "
|
||||
f"have {', '.join(_TABLES)}."
|
||||
)
|
||||
return tuple(_TABLES[name][0])
|
||||
|
||||
|
||||
register("ISO 4014", HEX_HEAD, Coverage(5.0, 36.0), SOURCE_ISO_4014)
|
||||
register("ISO 4017", HEX_HEAD, Coverage(5.0, 36.0), SOURCE_ISO_4017)
|
||||
register("ISO 4032", HEX_NUT, Coverage(5.0, 36.0), SOURCE_ISO_4032)
|
||||
register("ISO 7089", WASHER, Coverage(5.0, 36.0), SOURCE_ISO_7089)
|
||||
register("ISO 4762", SOCKET_HEAD, Coverage(3.0, 24.0), SOURCE_ISO_4762)
|
||||
Reference in New Issue
Block a user