@@ -582,6 +582,11 @@ def mathify(*args, **kwargs):
582582 return m (gfunc (* args , ** kwargs ))
583583 return mathify
584584
585+ # -----------------------------------------------------------------------------
586+ # We expose the full set of "m" operators also as functions à la the ``operator`` module.
587+ # Prefix "s", short for "mathematical Sequence".
588+ # https://docs.python.org/3/library/operator.html
589+
585590# The *settings mechanism is used by round and pow.
586591# These are recursive to support iterables containing iterables (e.g. an iterable of math sequences).
587592def _make_termwise_stream_unop (op , * settings ):
@@ -606,49 +611,20 @@ def stream_op(a, b):
606611 return op (a , b , * settings )
607612 return stream_op
608613
609- # We expose the full set of "m" operators also as functions à la the ``operator`` module.
610- _add = _make_termwise_stream_binop (primitive_add )
611- _sub = _make_termwise_stream_binop (primitive_sub )
612- _abs = _make_termwise_stream_unop (abs )
613- _pos = _make_termwise_stream_unop (primitive_pos )
614- _neg = _make_termwise_stream_unop (primitive_neg )
615- _mul = _make_termwise_stream_binop (primitive_mul )
614+ sadd = _make_termwise_stream_binop (primitive_add )
615+ sadd .__doc__ = """Termwise a + b when one or both are iterables."""
616+ ssub = _make_termwise_stream_binop (primitive_sub )
617+ ssub .__doc__ = """Termwise a - b when one or both are iterables."""
618+ sabs = _make_termwise_stream_unop (abs )
619+ sabs .__doc__ = """Termwise abs(a) for an iterable."""
620+ spos = _make_termwise_stream_unop (primitive_pos )
621+ spos .__doc__ = """Termwise +a for an iterable."""
622+ sneg = _make_termwise_stream_unop (primitive_neg )
623+ sneg .__doc__ = """Termwise -a for an iterable."""
624+ smul = _make_termwise_stream_binop (primitive_mul )
625+ smul .__doc__ = """Termwise a * b when one or both are iterables."""
626+
616627_pow = _make_termwise_stream_binop (primitive_pow ) # 2-arg form
617- _truediv = _make_termwise_stream_binop (primitive_truediv )
618- _floordiv = _make_termwise_stream_binop (primitive_floordiv )
619- _mod = _make_termwise_stream_binop (primitive_mod )
620- _divmod = _make_termwise_stream_binop (divmod )
621- _round = _make_termwise_stream_unop (round ) # 1-arg form
622- _trunc = _make_termwise_stream_unop (trunc )
623- _floor = _make_termwise_stream_unop (floor )
624- _ceil = _make_termwise_stream_unop (ceil )
625- _lshift = _make_termwise_stream_binop (primitive_lshift )
626- _rshift = _make_termwise_stream_binop (primitive_rshift )
627- _and = _make_termwise_stream_binop (primitive_and )
628- _xor = _make_termwise_stream_binop (primitive_xor )
629- _or = _make_termwise_stream_binop (primitive_or )
630- _invert = _make_termwise_stream_unop (primitive_invert )
631- def sadd (a , b ):
632- """Termwise a + b when one or both are iterables."""
633- return _add (a , b )
634- def ssub (a , b ):
635- """Termwise a - b when one or both are iterables."""
636- return _sub (a , b )
637- def sabs (a ):
638- """Termwise abs(a) for an iterable."""
639- return _abs (a )
640- def spos (a ):
641- """Termwise +a for an iterable."""
642- return _pos (a )
643- def sneg (a ):
644- """Termwise -a for an iterable."""
645- return _neg (a )
646- def sinvert (a ):
647- """Termwise ~a for an iterable."""
648- return _invert (a )
649- def smul (a , b ):
650- """Termwise a * b when one or both are iterables."""
651- return _mul (a , b )
652628def spow (a , b , * mod ):
653629 """Termwise a ** b when one or both are iterables.
654630
@@ -657,50 +633,61 @@ def spow(a, b, *mod):
657633 """
658634 op = _make_termwise_stream_binop (pow , mod [0 ]) if mod else _pow
659635 return op (a , b )
660- def struediv (a , b ):
661- """Termwise a / b when one or both are iterables."""
662- return _truediv (a , b )
663- def sfloordiv (a , b ):
664- """Termwise a // b when one or both are iterables."""
665- return _floordiv (a , b )
666- def smod (a , b ):
667- """Termwise a % b when one or both are iterables."""
668- return _mod (a , b )
669- def sdivmod (a , b ):
670- """Termwise (a // b, a % b) when one or both are iterables."""
671- return _divmod (a , b )
636+
637+ struediv = _make_termwise_stream_binop (primitive_truediv )
638+ struediv .__doc__ = """Termwise a / b when one or both are iterables."""
639+ sfloordiv = _make_termwise_stream_binop (primitive_floordiv )
640+ sfloordiv .__doc__ = """Termwise a // b when one or both are iterables."""
641+ smod = _make_termwise_stream_binop (primitive_mod )
642+ smod .__doc__ = """Termwise a % b when one or both are iterables."""
643+ sdivmod = _make_termwise_stream_binop (divmod )
644+ sdivmod .__doc__ = """Termwise (a // b, a % b) when one or both are iterables."""
645+
646+ _round = _make_termwise_stream_unop (round ) # 1-arg form
672647def sround (a , * ndigits ):
673648 """Termwise round(a) for an iterable.
674649
675650 An optional second argument is supported, and passed through to the
676651 built-in ``round`` function.
652+
653+ As with the built-in, rounding is correct taking into account the float
654+ representation, which is base-2.
655+
656+ https://docs.python.org/3/library/functions.html#round
677657 """
678658 op = _make_termwise_stream_unop (round , ndigits [0 ]) if ndigits else _round
679659 return op (a )
680- def strunc (a ):
681- """Termwise math.trunc(a) for an iterable."""
682- return _trunc (a )
683- def sfloor (a ):
684- """Termwise math.floor(a) for an iterable."""
685- return _floor (a )
686- def sceil (a ):
687- """Termwise math.ceil(a) for an iterable."""
688- return _ceil (a )
689- def slshift (a , b ):
690- """Termwise a << b when one or both are iterables."""
691- return _lshift (a , b )
692- def srshift (a , b ):
693- """Termwise a >> b when one or both are iterables."""
694- return _rshift (a , b )
695- def sand (a , b ):
696- """Termwise a & b when one or both are iterables."""
697- return _and (a , b )
698- def sxor (a , b ):
699- """Termwise a ^ b when one or both are iterables."""
700- return _xor (a , b )
701- def sor (a , b ):
702- """Termwise a | b when one or both are iterables."""
703- return _or (a , b )
660+
661+ strunc = _make_termwise_stream_unop (trunc )
662+ strunc .__doc__ = """Termwise math.trunc(a) for an iterable."""
663+ sfloor = _make_termwise_stream_unop (floor )
664+ sfloor .__doc__ = """Termwise math.floor(a) for an iterable."""
665+ sceil = _make_termwise_stream_unop (ceil )
666+ sceil .__doc__ = """Termwise math.ceil(a) for an iterable."""
667+
668+ # bit twiddling operations
669+ slshift = _make_termwise_stream_binop (primitive_lshift )
670+ slshift .__doc__ = """Termwise a << b when one or both are iterables."""
671+ srshift = _make_termwise_stream_binop (primitive_rshift )
672+ srshift .__doc__ = """Termwise a >> b when one or both are iterables."""
673+ sand = _make_termwise_stream_binop (primitive_and )
674+ sand .__doc__ = """Termwise a & b when one or both are iterables."""
675+ sxor = _make_termwise_stream_binop (primitive_xor )
676+ sxor .__doc__ = """Termwise a ^ b when one or both are iterables."""
677+ sor = _make_termwise_stream_binop (primitive_or )
678+ sor .__doc__ = """Termwise a | b when one or both are iterables."""
679+ sinvert = _make_termwise_stream_unop (primitive_invert )
680+ sinvert .__doc__ = """Termwise ~a for an iterable.
681+
682+ Note this is a bitwise invert, which is usually not what you want.
683+
684+ However, there is no ``__not__`` method for object instances,
685+ only the interpreter core defines that operation.
686+
687+ See:
688+ https://docs.python.org/3/library/operator.html#operator.not_
689+ """
690+
704691
705692# -----------------------------------------------------------------------------
706693
0 commit comments