Functional Weave
Code in TypeScript

retail.sku-generate@1.0.0

impl/python.py

1,447 bytes · the Python implementation · view raw

from typing import Sequence


def _clean(part: str) -> str:
    # Keep ASCII letters and digits only, then uppercase. Filtering first
    # matters: "ß".upper() is "SS", which would make the SKU depend on how each
    # language's Unicode tables treat one letter.
    return "".join(c for c in part if ("A" <= c <= "Z") or ("a" <= c <= "z") or ("0" <= c <= "9")).upper()


def generate_sku(prefix: str, attributes: Sequence[str], segment_length: int) -> str:
    """A deterministic SKU: the cleaned prefix and attributes, joined by hyphens.

    Each attribute is cut to ``segment_length`` characters (0 keeps it whole).
    """
    if isinstance(segment_length, bool) or not isinstance(segment_length, int) or segment_length < 0:
        raise ValueError("segmentLength must be 0 or more, received %r" % (segment_length,))
    if len(attributes) == 0:
        raise ValueError("a SKU needs at least one attribute")
    parts = []
    if prefix != "":
        cleaned = _clean(prefix)
        if cleaned == "":
            raise ValueError('prefix ("%s") has no letters or digits' % prefix)
        parts.append(cleaned)
    for index, attribute in enumerate(attributes):
        cleaned = _clean(attribute)
        if cleaned == "":
            raise ValueError('attribute %d ("%s") has no letters or digits' % (index + 1, attribute))
        parts.append(cleaned if segment_length == 0 else cleaned[:segment_length])
    return "-".join(parts)