コード例 #1
0
def histogram_differences(adapters: List[int]) -> HistogramOfDeltas:
    """Compute the histogram of jolt differences in ``adapters``."""
    histo = collections.defaultdict(lambda: 0)  # type: MutableMapping[int, int]

    for prev, current in common.pairwise(sorted([0] + adapters + [max(adapters) + 3])):
        delta = current - prev
        histo[delta] += 1

    return HistogramOfDeltas(histo)
コード例 #2
0
class BinRanges(DBC):
    """Represent the ranges of the histogram bins."""

    # fmt: off
    @require(
        lambda lower_bound, upper_bound:
        lower_bound < upper_bound
    )
    @require(
        lambda upper_bound:
        not math.isnan(upper_bound) and not math.isinf(upper_bound)
    )
    @require(
        lambda lower_bound:
        not math.isnan(lower_bound) and not math.isinf(lower_bound)
    )
    @require(
        lambda lower_bound, upper_bound, bin_count:
        (
                bin_width := (upper_bound - lower_bound) / bin_count,
                bin_width != 0
        )[1],
        "Bin width not numerically zero"
    )
    @ensure(
        lambda result:
        all(
            previous.end == current.start
            for previous, current in common.pairwise(result)
        ),
        "Bin ranges without a hole"
    )
    @ensure(
        lambda bin_count, include_minus_inf, result:
        not (include_minus_inf ^ math.isinf(result[0].start)),
        "include_min_inf <=> lower bound of the first bin is -inf"
    )
    @ensure(
        lambda bin_count, include_inf, result:
        not (include_inf ^ math.isinf(result[-1].end)),
        "include_inf <=> upper bound of the last bin is +inf"
    )
    @ensure(
        lambda bin_count, include_inf, include_minus_inf, result:
        not (not include_inf and not include_minus_inf) or len(result) == bin_count,
        "bin_count does not refer to +/- inf bins"
    )
    @ensure(
        lambda bin_count, include_inf, include_minus_inf, result:
        not (include_inf and not include_minus_inf) or len(result) == bin_count + 1,
        "bin_count does not refer to +/- inf bins"
    )
    @ensure(
        lambda bin_count, include_inf, include_minus_inf, result:
        not (not include_inf and include_minus_inf) or len(result) == bin_count + 1,
        "bin_count does not refer to +/- inf bins"
    )
    @ensure(
        lambda bin_count, include_inf, include_minus_inf, result:
        not (include_inf and include_minus_inf) or len(result) == bin_count + 2,
        "bin_count does not refer to +/- inf bins"
    )
    # fmt: on
    def __new__(
        cls,
        bin_count: int,
        lower_bound: float,
        upper_bound: float,
        include_minus_inf: bool,
        include_inf: bool,
    ) -> "BinRanges":
        """
        Construct ``bin_count`` number of histogram bins between ``lower_bound``
        and ``upper_bound``.

        If ``include_inf``, include -∞ and +∞ in the spanned total range of histogram.
        """
        ranges = []  # type: List[Range]

        if include_minus_inf:
            ranges.append(Range(start=-math.inf, end=lower_bound))

        bin_width = (upper_bound - lower_bound) / bin_count
        start = lower_bound
        for i in range(bin_count):
            end = start + bin_width

            # We need to account for numerical imprecision with summation
            # so that the last bin indeed matches the exact upper bound.
            if i < bin_count - 1:
                ranges.append(Range(start=start, end=end))
            else:
                ranges.append(Range(start=start, end=upper_bound))

            start = end

        if include_inf:
            ranges.append(Range(start=upper_bound, end=math.inf))

        return cast(BinRanges, ranges)

    @overload
    def __getitem__(self, index: int) -> Range:
        """Get the bin range at the given integer index."""
        pass

    @overload
    def __getitem__(self, index: slice) -> "BinRanges":
        """Get the slice of the bin ranges."""
        pass

    def __getitem__(self, index: Union[int, slice]) -> Union[Range, "BinRanges"]:
        """Get the bin range at the given index."""
        raise NotImplementedError("Only for type annotations")

    def __len__(self) -> int:
        """Return the number of the bin ranges."""
        raise NotImplementedError("Only for type annotations")

    def __iter__(self) -> Iterator[Range]:
        """Iterate over the bin ranges."""
        raise NotImplementedError("Only for type annotations")
コード例 #3
0
        return object.__eq__(self, other)

    def __repr__(self) -> str:
        """Represent the instance as a string for debugging."""
        return (
            f"{self.__class__.__name__}("
            f"{self.value!r}, {self.start}, {self.end}, {self.kind.value!r})")


# fmt: off
@ensure(lambda text, result: tokens_to_text(result) == text  # type: ignore
        )
@ensure(lambda text, result: all(token.value == text[token.start:token.end]
                                 for token in result), "Token values correct")
@ensure(lambda result: all(token1.end == token2.start
                           for token1, token2 in common.pairwise(result)),
        "Tokens consecutive")
@ensure(
    lambda text, result: not (len(result) > 0) or result[-1].end == len(text),
    "Text tokenized till the end")
@ensure(lambda result: not (len(result) > 0) or result[0].start == 0,
        "Text tokenized from the start")
# fmt: on
def tokenize(text: str) -> List[Token]:
    """Tokenize the given ``text``."""
    if len(text) == 0:
        return []

    result = []  # type: List[Token]

    cursor = 0