dyce.h
package reference
HableOpsMixin
A “mix-in” class providing arithmetic operations for implementers of the
HableT
protocol. The P
class derives from this
class.
Info
See HableT
for notes on pronunciation.
__slots__: Union[str, Iterable[str]]
special
__abs__(self: HableT) -> H
special
Shorthand for operator.__abs__(self.h())
. See the
h
method.
Source code in dyce/h.py
@beartype
def __abs__(self: HableT) -> H:
r"""
Shorthand for ``#!python operator.__abs__(self.h())``. See the
[``h`` method][dyce.h.HableT.h].
"""
return __abs__(self.h())
__add__(self: HableT, other: _OperandT) -> H
special
Shorthand for operator.__add__(self.h(), other)
. See the
h
method.
Source code in dyce/h.py
@beartype
def __add__(self: HableT, other: _OperandT) -> H:
r"""
Shorthand for ``#!python operator.__add__(self.h(), other)``. See the
[``h`` method][dyce.h.HableT.h].
"""
return __add__(self.h(), other)
__and__(self: HableT, other: Union[SupportsIntSCU, H, HableT]) -> H
special
Shorthand for operator.__and__(self.h(), other)
. See the
h
method.
Source code in dyce/h.py
@beartype
def __and__(self: HableT, other: Union[SupportsIntSCU, H, HableT]) -> H:
r"""
Shorthand for ``#!python operator.__and__(self.h(), other)``. See the
[``h`` method][dyce.h.HableT.h].
"""
return __and__(self.h(), other)
__floordiv__(self: HableT, other: _OperandT) -> H
special
Shorthand for operator.__floordiv__(self.h(), other)
. See the
h
method.
Source code in dyce/h.py
@beartype
def __floordiv__(self: HableT, other: _OperandT) -> H:
r"""
Shorthand for ``#!python operator.__floordiv__(self.h(), other)``. See the
[``h`` method][dyce.h.HableT.h].
"""
return __floordiv__(self.h(), other)
__invert__(self: HableT) -> H
special
Shorthand for operator.__invert__(self.h())
. See the
h
method.
Source code in dyce/h.py
@beartype
def __invert__(self: HableT) -> H:
r"""
Shorthand for ``#!python operator.__invert__(self.h())``. See the
[``h`` method][dyce.h.HableT.h].
"""
return __invert__(self.h())
__mod__(self: HableT, other: _OperandT) -> H
special
Shorthand for operator.__mod__(self.h(), other)
. See the
h
method.
Source code in dyce/h.py
@beartype
def __mod__(self: HableT, other: _OperandT) -> H:
r"""
Shorthand for ``#!python operator.__mod__(self.h(), other)``. See the
[``h`` method][dyce.h.HableT.h].
"""
return __mod__(self.h(), other)
__mul__(self: HableT, other: _OperandT) -> H
special
Shorthand for operator.__mul__(self.h(), other)
. See the
h
method.
Source code in dyce/h.py
@beartype
def __mul__(self: HableT, other: _OperandT) -> H:
r"""
Shorthand for ``#!python operator.__mul__(self.h(), other)``. See the
[``h`` method][dyce.h.HableT.h].
"""
return __mul__(self.h(), other)
__neg__(self: HableT) -> H
special
Shorthand for operator.__neg__(self.h())
. See the
h
method.
Source code in dyce/h.py
@beartype
def __neg__(self: HableT) -> H:
r"""
Shorthand for ``#!python operator.__neg__(self.h())``. See the
[``h`` method][dyce.h.HableT.h].
"""
return __neg__(self.h())
__or__(self: HableT, other: Union[SupportsIntSCU, H, HableT]) -> H
special
Shorthand for operator.__or__(self.h(), other)
. See the
h
method.
Source code in dyce/h.py
@beartype
def __or__(self: HableT, other: Union[SupportsIntSCU, H, HableT]) -> H:
r"""
Shorthand for ``#!python operator.__or__(self.h(), other)``. See the
[``h`` method][dyce.h.HableT.h].
"""
return __or__(self.h(), other)
__pos__(self: HableT) -> H
special
Shorthand for operator.__pos__(self.h())
. See the
h
method.
Source code in dyce/h.py
@beartype
def __pos__(self: HableT) -> H:
r"""
Shorthand for ``#!python operator.__pos__(self.h())``. See the
[``h`` method][dyce.h.HableT.h].
"""
return __pos__(self.h())
__pow__(self: HableT, other: _OperandT) -> H
special
Shorthand for operator.__pow__(self.h(), other)
. See the
h
method.
Source code in dyce/h.py
@beartype
def __pow__(self: HableT, other: _OperandT) -> H:
r"""
Shorthand for ``#!python operator.__pow__(self.h(), other)``. See the
[``h`` method][dyce.h.HableT.h].
"""
return __pow__(self.h(), other)
__radd__(self: HableT, other: RealLikeSCU) -> H
special
Shorthand for operator.__add__(other, self.h())
. See the
h
method.
Source code in dyce/h.py
@beartype
def __radd__(self: HableT, other: RealLikeSCU) -> H:
r"""
Shorthand for ``#!python operator.__add__(other, self.h())``. See the
[``h`` method][dyce.h.HableT.h].
"""
return __add__(other, self.h())
__rand__(self: HableT, other: SupportsIntSCU) -> H
special
Shorthand for operator.__and__(other, self.h())
. See the
h
method.
Source code in dyce/h.py
@beartype
def __rand__(self: HableT, other: SupportsIntSCU) -> H:
r"""
Shorthand for ``#!python operator.__and__(other, self.h())``. See the
[``h`` method][dyce.h.HableT.h].
"""
return __and__(other, self.h())
__rfloordiv__(self: HableT, other: RealLikeSCU) -> H
special
Shorthand for operator.__floordiv__(other, self.h())
. See the
h
method.
Source code in dyce/h.py
@beartype
def __rfloordiv__(self: HableT, other: RealLikeSCU) -> H: # type: ignore [misc]
r"""
Shorthand for ``#!python operator.__floordiv__(other, self.h())``. See the
[``h`` method][dyce.h.HableT.h].
"""
return __floordiv__(other, self.h())
__rmod__(self: HableT, other: RealLikeSCU) -> H
special
Shorthand for operator.__mod__(other, self.h())
. See the
h
method.
Source code in dyce/h.py
@beartype
def __rmod__(self: HableT, other: RealLikeSCU) -> H:
r"""
Shorthand for ``#!python operator.__mod__(other, self.h())``. See the
[``h`` method][dyce.h.HableT.h].
"""
return __mod__(other, self.h())
__rmul__(self: HableT, other: RealLikeSCU) -> H
special
Shorthand for operator.__mul__(other, self.h())
. See the
h
method.
Source code in dyce/h.py
@beartype
def __rmul__(self: HableT, other: RealLikeSCU) -> H:
r"""
Shorthand for ``#!python operator.__mul__(other, self.h())``. See the
[``h`` method][dyce.h.HableT.h].
"""
return __mul__(other, self.h())
__ror__(self: HableT, other: SupportsIntSCU) -> H
special
Shorthand for operator.__or__(other, self.h())
. See the
h
method.
Source code in dyce/h.py
@beartype
def __ror__(self: HableT, other: SupportsIntSCU) -> H:
r"""
Shorthand for ``#!python operator.__or__(other, self.h())``. See the
[``h`` method][dyce.h.HableT.h].
"""
return __or__(other, self.h())
__rpow__(self: HableT, other: RealLikeSCU) -> H
special
Shorthand for operator.__pow__(other, self.h())
. See the
h
method.
Source code in dyce/h.py
@beartype
def __rpow__(self: HableT, other: RealLikeSCU) -> H:
r"""
Shorthand for ``#!python operator.__pow__(other, self.h())``. See the
[``h`` method][dyce.h.HableT.h].
"""
return __pow__(other, self.h())
__rsub__(self: HableT, other: RealLikeSCU) -> H
special
Shorthand for operator.__sub__(other, self.h())
. See the
h
method.
Source code in dyce/h.py
@beartype
def __rsub__(self: HableT, other: RealLikeSCU) -> H:
r"""
Shorthand for ``#!python operator.__sub__(other, self.h())``. See the
[``h`` method][dyce.h.HableT.h].
"""
return __sub__(other, self.h())
__rtruediv__(self: HableT, other: RealLikeSCU) -> H
special
Shorthand for operator.__truediv__(other, self.h())
. See the
h
method.
Source code in dyce/h.py
@beartype
def __rtruediv__(self: HableT, other: RealLikeSCU) -> H:
r"""
Shorthand for ``#!python operator.__truediv__(other, self.h())``. See the
[``h`` method][dyce.h.HableT.h].
"""
return __truediv__(other, self.h())
__rxor__(self: HableT, other: SupportsIntSCU) -> H
special
Shorthand for operator.__xor__(other, self.h())
. See the
h
method.
Source code in dyce/h.py
@beartype
def __rxor__(self: HableT, other: SupportsIntSCU) -> H:
r"""
Shorthand for ``#!python operator.__xor__(other, self.h())``. See the
[``h`` method][dyce.h.HableT.h].
"""
return __xor__(other, self.h())
__sub__(self: HableT, other: _OperandT) -> H
special
Shorthand for operator.__sub__(self.h(), other)
. See the
h
method.
Source code in dyce/h.py
@beartype
def __sub__(self: HableT, other: _OperandT) -> H:
r"""
Shorthand for ``#!python operator.__sub__(self.h(), other)``. See the
[``h`` method][dyce.h.HableT.h].
"""
return __sub__(self.h(), other)
__truediv__(self: HableT, other: _OperandT) -> H
special
Shorthand for operator.__truediv__(self.h(), other)
. See the
h
method.
Source code in dyce/h.py
@beartype
def __truediv__(self: HableT, other: _OperandT) -> H:
r"""
Shorthand for ``#!python operator.__truediv__(self.h(), other)``. See the
[``h`` method][dyce.h.HableT.h].
"""
return __truediv__(self.h(), other)
__xor__(self: HableT, other: Union[SupportsIntSCU, H, HableT]) -> H
special
Shorthand for operator.__xor__(self.h(), other)
. See the
h
method.
Source code in dyce/h.py
@beartype
def __xor__(self: HableT, other: Union[SupportsIntSCU, H, HableT]) -> H:
r"""
Shorthand for ``#!python operator.__xor__(self.h(), other)``. See the
[``h`` method][dyce.h.HableT.h].
"""
return __xor__(self.h(), other)
eq(self: HableT, other: _OperandT) -> H
explode(self: HableT, max_depth: SupportsIntSCU = 1) -> H
Shorthand for self.h().explode(max_depth)
. See the
h
method and H.explode
.
Source code in dyce/h.py
@beartype
def explode(self: HableT, max_depth: SupportsIntSCU = 1) -> H:
r"""
Shorthand for ``#!python self.h().explode(max_depth)``. See the
[``h`` method][dyce.h.HableT.h] and [``H.explode``][dyce.h.H.explode].
"""
return self.h().explode(max_depth)
ge(self: HableT, other: _OperandT) -> H
gt(self: HableT, other: _OperandT) -> H
is_even(self: HableT) -> H
is_odd(self: HableT) -> H
le(self: HableT, other: _OperandT) -> H
lt(self: HableT, other: _OperandT) -> H
ne(self: HableT, other: _OperandT) -> H
substitute(self: HableT, expand: _ExpandT, coalesce: _CoalesceT = <function coalesce_replace at 0x10d423040>, max_depth: SupportsIntSCU = 1) -> H
Shorthand for self.h().substitute(expand, coalesce, max_depth)
. See the
h
method and H.substitute
.
Source code in dyce/h.py
@beartype
def substitute(
self: HableT,
expand: _ExpandT,
coalesce: _CoalesceT = coalesce_replace,
max_depth: SupportsIntSCU = 1,
) -> H:
r"""
Shorthand for ``#!python self.h().substitute(expand, coalesce, max_depth)``. See the
[``h`` method][dyce.h.HableT.h] and [``H.substitute``][dyce.h.H.substitute].
"""
return self.h().substitute(expand, coalesce, max_depth)
within(self: HableT, lo: RealLikeSCU, hi: RealLikeSCU, other: _OperandT = 0) -> H
Shorthand for self.h().within(lo, hi, other)
. See the
h
method and H.within
.
Source code in dyce/h.py
@beartype
def within(
self: HableT, lo: RealLikeSCU, hi: RealLikeSCU, other: _OperandT = 0
) -> H:
r"""
Shorthand for ``#!python self.h().within(lo, hi, other)``. See the
[``h`` method][dyce.h.HableT.h] and [``H.within``][dyce.h.H.within].
"""
return self.h().within(lo, hi, other)
HableT (Protocol)
A protocol whose implementer can be expressed as (or reduced to) an
H
object by calling its h
method. Currently,
only the P
class implements this protocol, but this affords an
integration point for dyce
users.
Info
The intended pronunciation of Hable
is AYCH-uh-bul1 (i.e.,
H
-able). Yes, that is a clumsy attempt at
verbing. (You could
totally H
that, dude!) However, if you prefer something else
(e.g. HAY-bul or AYCH-AY-bul), no one is going to judge you. (Well, they
might, but they shouldn’t.) We all know what you mean.
-
World Book Online (WBO) style pronunciation respelling. ↩
__slots__: Union[str, Iterable[str]]
special
__init__(self, *args, **kwargs)
special
Source code in dyce/h.py
def _no_init(self, *args, **kwargs):
raise TypeError('Protocols cannot be instantiated')
__subclasshook__(other)
special
Source code in dyce/h.py
def _proto_hook(other):
if not cls.__dict__.get('_is_protocol', False):
return NotImplemented
# First, perform various sanity checks.
if not getattr(cls, '_is_runtime_protocol', False):
if _allow_reckless_class_cheks():
return NotImplemented
raise TypeError("Instance and class checks can only be used with"
" @runtime_checkable protocols")
if not _is_callable_members_only(cls):
if _allow_reckless_class_cheks():
return NotImplemented
raise TypeError("Protocols with non-method members"
" don't support issubclass()")
if not isinstance(other, type):
# Same error message as for issubclass(1, int).
raise TypeError('issubclass() arg 1 must be a class')
# Second, perform the actual structural compatibility check.
for attr in _get_protocol_attrs(cls):
for base in other.__mro__:
# Check if the members appears in the class dictionary...
if attr in base.__dict__:
if base.__dict__[attr] is None:
return NotImplemented
break
# ...or in annotations, if it is a sub-protocol.
annotations = getattr(base, '__annotations__', {})
if (isinstance(annotations, collections.abc.Mapping) and
attr in annotations and
issubclass(other, Generic) and other._is_protocol):
break
else:
return NotImplemented
return True
h(self) -> H
Express its implementer as an H
object.
Source code in dyce/h.py
def h(self) -> H:
r"""
Express its implementer as an [``H`` object][dyce.h.H].
"""
...
coalesce_replace(h: H, outcome: RealLikeSCU) -> H
Default behavior for H.substitute
. Returns h unmodified
(outcome is ignored).
Source code in dyce/h.py
def coalesce_replace(h: H, outcome: RealLikeSCU) -> H:
r"""
Default behavior for [``H.substitute``][dyce.h.H.substitute]. Returns *h* unmodified
(*outcome* is ignored).
"""
return h
resolve_dependent_probability(dependent_term: Callable[..., H], **independent_sources: _SourceT) -> H
Experimental
This method should be considered experimental and may change or disappear in future versions.
Calls dependent_term
for each set of outcomes from the product of
independent_sources
and accumulates the results. This is useful for resolving
dependent probabilities and is semantically equivalent to nesting substitution
functions.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
|
This function imposes a modest overhead when compared to the nesting approach. In most cases, the improved readability is worth it.
1 2 3 4 5 |
|
Source: perf_resolve_dependent_probability.ipy
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
|
Source code in dyce/h.py
@beartype
def resolve_dependent_probability(
dependent_term: Callable[..., H],
**independent_sources: _SourceT,
) -> H:
r"""
!!! warning "Experimental"
This method should be considered experimental and may change or disappear in
future versions.
Calls ``#!python dependent_term`` for each set of outcomes from the product of
``independent_sources`` and accumulates the results. This is useful for resolving
dependent probabilities and is semantically equivalent to nesting substitution
functions.
``` python
>>> def dependent_term(
... outcome_1,
... outcome_2,
... outcome_3,
... # ...
... outcome_n,
... ):
... return (
... (outcome_1 == outcome_2) +
... (outcome_2 == outcome_3) +
... (outcome_1 == outcome_3) +
... (
... outcome_n > outcome_1
... and outcome_n > outcome_2
... and outcome_n > outcome_3
... # ...
... )
... )
>>> source_1 = H(6)
>>> source_2 = H(8)
>>> source_3 = H(10)
>>> # ...
>>> source_n = H(20)
>>> def sub_source_1(__, outcome_1):
... def sub_source_2(__, outcome_2):
... def sub_source_3(__, outcome_3):
... # ...
... def sub_source_n(__, outcome_n):
... return dependent_term(
... outcome_1,
... outcome_2,
... outcome_3,
... # ...
... outcome_n,
... )
... return source_n.substitute(sub_source_n)
... # ...
... return source_3.substitute(sub_source_3)
... return source_2.substitute(sub_source_2)
>>> from dyce.h import resolve_dependent_probability
>>> h = resolve_dependent_probability(
... dependent_term,
... outcome_1=source_1,
... outcome_2=source_2,
... outcome_3=source_3,
... # ...
... outcome_n=source_n,
... ) ; h
H({0: 808, 1: 1700, 2: 652, 3: 7, 4: 33})
>>> source_1.substitute(sub_source_1) == h
True
```
This function imposes a modest overhead when compared to the nesting approach. In
most cases, the improved readability is worth it.
``` python
--8<-- "docs/assets/perf_resolve_dependent_probability.txt"
```
<details>
<summary>Source: <a href="https://github.com/posita/dyce/blob/latest/docs/assets/perf_resolve_dependent_probability.ipy"><code>perf_resolve_dependent_probability.ipy</code></a></summary>
``` python
--8<-- "docs/assets/perf_resolve_dependent_probability.ipy"
```
</details>
"""
independent_variables_by_name: Dict[str, H] = {}
for key, value in independent_sources.items():
if isinstance(value, H):
independent_variables_by_name[key] = value
else:
independent_variables_by_name[key] = H(value)
captured_values_by_name: Dict[str, RealLikeSCU] = {}
uncaptured_value_names = set(independent_variables_by_name)
def _resolve() -> Union[H, RealLikeSCU]:
def _capture_dependent_value(
h: H, outcome: RealLikeSCU
) -> Union[RealLikeSCU, H]:
expanded: Union[RealLikeSCU, H]
captured_values_by_name[name_to_be_captured] = outcome
expanded = _resolve()
del captured_values_by_name[name_to_be_captured]
return expanded
if uncaptured_value_names:
# Used in _capture_dependent_value
name_to_be_captured = uncaptured_value_names.pop()
expanded = independent_variables_by_name[name_to_be_captured].substitute(
_capture_dependent_value
)
uncaptured_value_names.add(name_to_be_captured)
else:
return dependent_term(**captured_values_by_name)
return expanded
resolved = _resolve()
if not isinstance(resolved, H):
resolved = H({resolved: 1})
return resolved
sum_h(hs: Iterable[H])
Shorthand for H({}) if h_sum == 0 else sum(hs)
.
This is to ensure that summing zero or more histograms always returns a histograms.
Source code in dyce/h.py
@beartype
def sum_h(hs: Iterable[H]):
"""
Shorthand for ``#!python H({}) if h_sum == 0 else sum(hs)``.
This is to ensure that summing zero or more histograms always returns a histograms.
"""
h_sum = sum(hs)
return H({}) if h_sum == 0 else h_sum