From 627cddca1d64edb8475407a1524efb2a22249a25 Mon Sep 17 00:00:00 2001 From: Vratko Polak Date: Mon, 2 Dec 2019 18:38:44 +0100 Subject: Refactor jumpavg to be more readable and usable This is the python3 change, the python2 is still used for testing bisect. + New version is 0.2.0 due to amount o API changes. + Jumpavg is now part of CSIT resource package tree. + Perpatch migrated to new jumpavg. - PAL NOT updated (the update moved to a different Change). Change-Id: I7d7a8bf8a411196c20c2a40a8c64478d6709bc07 Signed-off-by: Vratko Polak --- PyPI/jumpavg/jumpavg | 1 + PyPI/jumpavg/jumpavg/AbstractGroupClassifier.py | 40 -------- PyPI/jumpavg/jumpavg/AbstractGroupMetadata.py | 42 -------- PyPI/jumpavg/jumpavg/AvgStdevMetadata.py | 54 ---------- PyPI/jumpavg/jumpavg/AvgStdevMetadataFactory.py | 54 ---------- PyPI/jumpavg/jumpavg/BitCountingClassifier.py | 70 ------------- PyPI/jumpavg/jumpavg/BitCountingGroup.py | 50 ---------- PyPI/jumpavg/jumpavg/BitCountingGroupList.py | 87 ---------------- PyPI/jumpavg/jumpavg/BitCountingMetadata.py | 109 --------------------- PyPI/jumpavg/jumpavg/BitCountingMetadataFactory.py | 85 ---------------- .../jumpavg/ClassifiedBitCountingMetadata.py | 73 -------------- PyPI/jumpavg/jumpavg/ClassifiedMetadataFactory.py | 42 -------- PyPI/jumpavg/jumpavg/RunGroup.py | 34 ------- PyPI/jumpavg/jumpavg/__init__.py | 16 --- PyPI/jumpavg/setup.py | 50 ++++++---- 15 files changed, 31 insertions(+), 776 deletions(-) create mode 120000 PyPI/jumpavg/jumpavg delete mode 100644 PyPI/jumpavg/jumpavg/AbstractGroupClassifier.py delete mode 100644 PyPI/jumpavg/jumpavg/AbstractGroupMetadata.py delete mode 100644 PyPI/jumpavg/jumpavg/AvgStdevMetadata.py delete mode 100644 PyPI/jumpavg/jumpavg/AvgStdevMetadataFactory.py delete mode 100644 PyPI/jumpavg/jumpavg/BitCountingClassifier.py delete mode 100644 PyPI/jumpavg/jumpavg/BitCountingGroup.py delete mode 100644 PyPI/jumpavg/jumpavg/BitCountingGroupList.py delete mode 100644 PyPI/jumpavg/jumpavg/BitCountingMetadata.py delete mode 100644 PyPI/jumpavg/jumpavg/BitCountingMetadataFactory.py delete mode 100644 PyPI/jumpavg/jumpavg/ClassifiedBitCountingMetadata.py delete mode 100644 PyPI/jumpavg/jumpavg/ClassifiedMetadataFactory.py delete mode 100644 PyPI/jumpavg/jumpavg/RunGroup.py delete mode 100644 PyPI/jumpavg/jumpavg/__init__.py (limited to 'PyPI/jumpavg') diff --git a/PyPI/jumpavg/jumpavg b/PyPI/jumpavg/jumpavg new file mode 120000 index 0000000000..df32002d6b --- /dev/null +++ b/PyPI/jumpavg/jumpavg @@ -0,0 +1 @@ +../../resources/libraries/python/jumpavg \ No newline at end of file diff --git a/PyPI/jumpavg/jumpavg/AbstractGroupClassifier.py b/PyPI/jumpavg/jumpavg/AbstractGroupClassifier.py deleted file mode 100644 index 2612b009da..0000000000 --- a/PyPI/jumpavg/jumpavg/AbstractGroupClassifier.py +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright (c) 2018 Cisco and/or its affiliates. -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Module holding AbstractGroupClassifier class.""" - -from abc import ABCMeta, abstractmethod - - -class AbstractGroupClassifier(object): - """Abstract class defining API for classifier. - - The classifier is an object with classify() method - which divides data into groups containing metadata. - """ - - __metaclass__ = ABCMeta - - @abstractmethod - def classify(self, values): - """Divide values into consecutive groups with metadata. - - The metadata does not need to follow any specific rules, - although progression/regression/outlier description would be fine. - - :param values: Sequence of runs to classify. - :type values: Iterable of float or of AvgStdevMetadata - :returns: Classified groups - :rtype: Iterable of RunGroup - """ - pass diff --git a/PyPI/jumpavg/jumpavg/AbstractGroupMetadata.py b/PyPI/jumpavg/jumpavg/AbstractGroupMetadata.py deleted file mode 100644 index 3235dbd485..0000000000 --- a/PyPI/jumpavg/jumpavg/AbstractGroupMetadata.py +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright (c) 2018 Cisco and/or its affiliates. -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Module holding AbstractGroupMetadata class.""" - -from abc import ABCMeta, abstractmethod - - -class AbstractGroupMetadata(object): - """Abstract classdefining API for metadata. - - At this level, only __str__() and __repr() methods are required.""" - - __metaclass__ = ABCMeta - - @abstractmethod - def __str__(self): - """Return string with human readable description of the group. - - :returns: Readable description. - :rtype: str - """ - pass - - @abstractmethod - def __repr__(self): - """Return string executable as Python constructor call. - - :returns: Executable constructor call. - :rtype: str - """ - pass diff --git a/PyPI/jumpavg/jumpavg/AvgStdevMetadata.py b/PyPI/jumpavg/jumpavg/AvgStdevMetadata.py deleted file mode 100644 index efc1a90cd4..0000000000 --- a/PyPI/jumpavg/jumpavg/AvgStdevMetadata.py +++ /dev/null @@ -1,54 +0,0 @@ -# Copyright (c) 2018 Cisco and/or its affiliates. -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Module for holding AvgStdevMetadata class.""" - -from AbstractGroupMetadata import AbstractGroupMetadata - - -class AvgStdevMetadata(AbstractGroupMetadata): - """Class for metadata specifying the average and standard deviation.""" - - def __init__(self, size=0, avg=0.0, stdev=0.0): - """Construct the metadata by setting the values needed. - - The values are sanitized, so faulty callers to not cause math errors. - - :param size: Number of values participating in this group. - :param avg: Population average of the participating sample values. - :param stdev: Population standard deviation of the sample values. - :type size: int - :type avg: float - :type stdev: float - """ - self.size = size if size >= 0 else 0 - self.avg = avg if size >= 1 else 0.0 - self.stdev = stdev if size >= 2 else 0.0 - - def __str__(self): - """Return string with human readable description of the group. - - :returns: Readable description. - :rtype: str - """ - return "size={size} avg={avg} stdev={stdev}".format( - size=self.size, avg=self.avg, stdev=self.stdev) - - def __repr__(self): - """Return string executable as Python constructor call. - - :returns: Executable constructor call. - :rtype: str - """ - return "AvgStdevMetadata(size={size},avg={avg},stdev={stdev})".format( - size=self.size, avg=self.avg, stdev=self.stdev) diff --git a/PyPI/jumpavg/jumpavg/AvgStdevMetadataFactory.py b/PyPI/jumpavg/jumpavg/AvgStdevMetadataFactory.py deleted file mode 100644 index 25bc600aeb..0000000000 --- a/PyPI/jumpavg/jumpavg/AvgStdevMetadataFactory.py +++ /dev/null @@ -1,54 +0,0 @@ -# Copyright (c) 2018 Cisco and/or its affiliates. -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Module holding AvgStdevMetadataFactory class.""" - -import math - -from AvgStdevMetadata import AvgStdevMetadata - - -class AvgStdevMetadataFactory(object): - """Class factory which creates avg,stdev metadata from data.""" - - @staticmethod - def from_data(values): - """Return new metadata object fitting the values. - - :param values: Run values to be processed. - :type values: Iterable of float or of AvgStdevMetadata - :returns: The metadata matching the values. - :rtype: AvgStdevMetadata - """ - # Using Welford method to be more resistant to rounding errors. - # Adapted from code for sample standard deviation at: - # https://www.johndcook.com/blog/standard_deviation/ - # The logic of plus operator is taken from - # https://www.johndcook.com/blog/skewness_kurtosis/ - size = 0 - avg = 0.0 - moment_2 = 0.0 - for value in values: - if not isinstance(value, AvgStdevMetadata): - value = AvgStdevMetadata(size=1, avg=value) - old_size = size - delta = value.avg - avg - size += value.size - avg += delta * value.size / size - moment_2 += value.stdev * value.stdev * value.size - moment_2 += delta * delta * old_size * value.size / size - if size < 1: - return AvgStdevMetadata() - stdev = math.sqrt(moment_2 / size) - ret_obj = AvgStdevMetadata(size=size, avg=avg, stdev=stdev) - return ret_obj diff --git a/PyPI/jumpavg/jumpavg/BitCountingClassifier.py b/PyPI/jumpavg/jumpavg/BitCountingClassifier.py deleted file mode 100644 index 9a723199d2..0000000000 --- a/PyPI/jumpavg/jumpavg/BitCountingClassifier.py +++ /dev/null @@ -1,70 +0,0 @@ -# Copyright (c) 2018 Cisco and/or its affiliates. -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Module holding BitCountingClassifier class. - -This is the main class to be used by callers.""" - -from AbstractGroupClassifier import AbstractGroupClassifier -from BitCountingGroup import BitCountingGroup -from BitCountingGroupList import BitCountingGroupList -from BitCountingMetadataFactory import BitCountingMetadataFactory -from ClassifiedMetadataFactory import ClassifiedMetadataFactory - - -class BitCountingClassifier(AbstractGroupClassifier): - """Classifier using Minimal Description Length principle.""" - - def classify(self, values): - """Return the values in groups of optimal bit count. - - The current implementation could be a static method, - but we might support options in later versions, - for example for chosing encodings. - - :param values: Sequence of runs to classify. - :type values: Iterable of float or of AvgStdevMetadata - :returns: Classified group list. - :rtype: BitCountingGroupList - """ - max_value = BitCountingMetadataFactory.find_max_value(values) - factory = BitCountingMetadataFactory(max_value) - opened_at = [] - closed_before = [BitCountingGroupList()] - for index, value in enumerate(values): - singleton = BitCountingGroup(factory, [value]) - newly_opened = closed_before[index].with_group_appended(singleton) - opened_at.append(newly_opened) - record_group_list = newly_opened - for previous in range(index): - previous_opened_list = opened_at[previous] - still_opened = ( - previous_opened_list.with_value_added_to_last_group(value)) - opened_at[previous] = still_opened - if still_opened.bits < record_group_list.bits: - record_group_list = still_opened - closed_before.append(record_group_list) - partition = closed_before[-1] - previous_average = partition[0].metadata.avg - for group in partition: - if group.metadata.avg == previous_average: - group.metadata = ClassifiedMetadataFactory.with_classification( - group.metadata, "normal") - elif group.metadata.avg < previous_average: - group.metadata = ClassifiedMetadataFactory.with_classification( - group.metadata, "regression") - elif group.metadata.avg > previous_average: - group.metadata = ClassifiedMetadataFactory.with_classification( - group.metadata, "progression") - previous_average = group.metadata.avg - return partition diff --git a/PyPI/jumpavg/jumpavg/BitCountingGroup.py b/PyPI/jumpavg/jumpavg/BitCountingGroup.py deleted file mode 100644 index 2071c061ea..0000000000 --- a/PyPI/jumpavg/jumpavg/BitCountingGroup.py +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright (c) 2018 Cisco and/or its affiliates. -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Module holding BitCountingGroup class.""" - -from RunGroup import RunGroup - - -class BitCountingGroup(RunGroup): - """RunGroup with BitCountingMetadata. - - Support with_run_added() method to simplify extending the group. - As bit content has to be re-counted, metadata factory is stored. - """ - - def __init__(self, metadata_factory, values=[]): - """Create the group from metadata factory and values. - - :param metadata_factory: Factory object to create metadata with. - :param values: The runs belonging to this group. - :type metadata_factory: BitCountingMetadataFactory - :type values: Iterable of float or of AvgStdevMetadata - """ - self.metadata_factory = metadata_factory - metadata = metadata_factory.from_data(values) - super(BitCountingGroup, self).__init__(metadata, values) - - def with_run_added(self, value): - """Create and return a new group with one more run that self. - - :param value: The run value to add to the group. - :type value: float or od AvgStdevMetadata - :returns: New group with the run added. - :rtype: BitCountingGroup - """ - values = list(self.values) - values.append(value) - return BitCountingGroup(self.metadata_factory, values) - # TODO: Is there a good way to save some computation - # by copy&updating the metadata incrementally? diff --git a/PyPI/jumpavg/jumpavg/BitCountingGroupList.py b/PyPI/jumpavg/jumpavg/BitCountingGroupList.py deleted file mode 100644 index 1f69c0635d..0000000000 --- a/PyPI/jumpavg/jumpavg/BitCountingGroupList.py +++ /dev/null @@ -1,87 +0,0 @@ -# Copyright (c) 2018 Cisco and/or its affiliates. -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Module holding BitCountingGroupList class.""" - -from BitCountingGroup import BitCountingGroup -from BitCountingMetadataFactory import BitCountingMetadataFactory - - -class BitCountingGroupList(list): - """List of BitCountingGroup which tracks overall bit count. - - This is useful, as bit count of a subsequent group - depends on average of the previous group. - Having the logic encapsulated here spares the caller - the effort to pass averages around. - - Method with_value_added_to_last_group() delegates to BitCountingGroup, - with_group_appended() adds new group with recalculated bits. - - TODO: last_group.metadata_factory.max_value in with_group_appended() - is ugly, find a more natural class design. - """ - - def __init__(self, group_list=[], bits=None): - """Create a group list from given list of groups. - - :param group_list: List of groups to compose this group. - :param bits: Bit count if known, else None. - :type group_list: list of BitCountingGroup - :type bits: float or None - """ - super(BitCountingGroupList, self).__init__(group_list) - if bits is not None: - self.bits = bits - return - bits = 0.0 - for group in group_list: - bits += group.metadata.bits - self.bits = bits - - def with_group_appended(self, group): - """Create and return new group list with given group more than self. - - The group argument object is updated with derivative metadata. - - :param group: Next group to be appended to the group list. - :type group: BitCountingGroup - :returns: New group list with added group. - :rtype: BitCountingGroupList - """ - group_list = list(self) - if group_list: - last_group = group_list[-1] - factory = BitCountingMetadataFactory( - last_group.metadata_factory.max_value, last_group.metadata.avg) - group.metadata_factory = factory - group.metadata = factory.from_data(group.values) - group_list.append(group) - bits = self.bits + group.metadata.bits - return BitCountingGroupList(group_list, bits) - - def with_value_added_to_last_group(self, value): - """Create and return new group list with value added to last group. - - :param value: The run value to add to the last group. - :type value: float or od AvgStdevMetadata - :returns: New group list with the last group updated. - :rtype: BitCountingGroupList - """ - group_list = list(self) - last_group = group_list[-1] - bits_before = last_group.metadata.bits - last_group = last_group.with_run_added(value) - group_list[-1] = last_group - bits = self.bits - bits_before + last_group.metadata.bits - return BitCountingGroupList(group_list, bits) diff --git a/PyPI/jumpavg/jumpavg/BitCountingMetadata.py b/PyPI/jumpavg/jumpavg/BitCountingMetadata.py deleted file mode 100644 index d25d355cab..0000000000 --- a/PyPI/jumpavg/jumpavg/BitCountingMetadata.py +++ /dev/null @@ -1,109 +0,0 @@ -# Copyright (c) 2018 Cisco and/or its affiliates. -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Module holding BitCountingMetadata class.""" - -import math - -from AvgStdevMetadata import AvgStdevMetadata - - -class BitCountingMetadata(AvgStdevMetadata): - """Class for metadata which includes information content of a group. - - The information content is based on an assumption - that the data consists of independent random values - from a normal distribution. - """ - - def __init__(self, max_value, size=0, avg=0.0, stdev=0.0, prev_avg=None): - """Construct the metadata by computing from the values needed. - - The bit count is not real, as that would depend on numeric precision - (number of significant bits in values). - The difference is assumed to be constant per value, - which is consistent with Gauss distribution - (but not with floating point mechanic). - The hope is the difference will have - no real impact on the classification procedure. - - :param max_value: Maximal expected value. - TODO: This might be more optimal, - but max-invariant algorithm will be nicer. - :param size: Number of values participating in this group. - :param avg: Population average of the participating sample values. - :param stdev: Population standard deviation of the sample values. - :param prev_avg: Population average of the previous group. - If None, no previous average is taken into account. - If not None, the given previous average is used to discourage - consecutive groups with similar averages - (opposite triangle distribution is assumed). - :type max_value: float - :type size: int - :type avg: float - :type stdev: float - :type prev_avg: float or None - """ - super(BitCountingMetadata, self).__init__(size, avg, stdev) - self.max_value = max_value - self.prev_avg = prev_avg - self.bits = 0.0 - if self.size < 1: - return - # Length of the sequence must be also counted in bits, - # otherwise the message would not be decodable. - # Model: probability of k samples is 1/k - 1/(k+1) - # == 1/k/(k+1) - self.bits += math.log(size * (size + 1), 2) - if prev_avg is None: - # Avg is considered to be uniformly distributed - # from zero to max_value. - self.bits += math.log(max_value + 1.0, 2) - else: - # Opposite triangle distribution with minimum. - self.bits += math.log( - max_value * (max_value + 1) / (abs(avg - prev_avg) + 1), 2) - if self.size < 2: - return - # Stdev is considered to be uniformly distributed - # from zero to max_value. That is quite a bad expectation, - # but resilient to negative samples etc. - self.bits += math.log(max_value + 1.0, 2) - # Now we know the samples lie on sphere in size-1 dimensions. - # So it is (size-2)-sphere, with radius^2 == stdev^2 * size. - # https://en.wikipedia.org/wiki/N-sphere - sphere_area_ln = math.log(2) + math.log(math.pi) * ((size - 1) / 2.0) - sphere_area_ln -= math.lgamma((size - 1) / 2.0) - sphere_area_ln += math.log(stdev + 1.0) * (size - 2) - sphere_area_ln += math.log(size) * ((size - 2) / 2.0) - self.bits += sphere_area_ln / math.log(2) - - def __str__(self): - """Return string with human readable description of the group. - - :returns: Readable description. - :rtype: str - """ - return "size={size} avg={avg} stdev={stdev} bits={bits}".format( - size=self.size, avg=self.avg, stdev=self.stdev, bits=self.bits) - - def __repr__(self): - """Return string executable as Python constructor call. - - :returns: Executable constructor call. - :rtype: str - """ - return ("BitCountingMetadata(max_value={max_value},size={size}," + - "avg={avg},stdev={stdev},prev_avg={prev_avg})").format( - max_value=self.max_value, size=self.size, avg=self.avg, - stdev=self.stdev, prev_avg=self.prev_avg) diff --git a/PyPI/jumpavg/jumpavg/BitCountingMetadataFactory.py b/PyPI/jumpavg/jumpavg/BitCountingMetadataFactory.py deleted file mode 100644 index 567c3d4fe6..0000000000 --- a/PyPI/jumpavg/jumpavg/BitCountingMetadataFactory.py +++ /dev/null @@ -1,85 +0,0 @@ -# Copyright (c) 2018 Cisco and/or its affiliates. -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Module holding BitCountingMetadataFactory class.""" - -import math - -from AvgStdevMetadata import AvgStdevMetadata -from AvgStdevMetadataFactory import AvgStdevMetadataFactory -from BitCountingMetadata import BitCountingMetadata - - -class BitCountingMetadataFactory(object): - """Class for factory which creates bit counting metadata from data. - - TODO: Summarize the methods? - """ - - @staticmethod - def find_max_value(values): - """Return the max value. - - This is a separate helper method, - because the whole set of values is usually larger than in from_data(). - - :param values: Run values to be processed. - :type values: Iterable of float - :returns: 0.0 or the biggest value found. - :rtype: float - """ - max_value = 0.0 - for value in values: - if isinstance(value, AvgStdevMetadata): - value = value.avg - if value > max_value: - max_value = value - return max_value - - def __init__(self, max_value, prev_avg=None): - """Construct the factory instance with given arguments. - - :param max_value: Maximal expected value. - :param prev_avg: Population average of the previous group. - If None, no previous average is taken into account. - If not None, the given previous average is used to discourage - consecutive groups with similar averages - (opposite triangle distribution is assumed). - :type max_value: float - :type prev_avg: float or None - """ - self.max_value = max_value - self.prev_avg = prev_avg - - def from_avg_stdev_metadata(self, metadata): - """Return new metadata object by adding bits to existing metadata. - - :param metadata: Metadata to count bits for. - :type metadata: AvgStdevMetadata - :returns: The metadata with bits counted. - :rtype: BitCountingMetadata - """ - return BitCountingMetadata( - max_value=self.max_value, size=metadata.size, - avg=metadata.avg, stdev=metadata.stdev, prev_avg=self.prev_avg) - - def from_data(self, values): - """Return new metadata object fitting the values. - - :param values: Run values to be processed. - :type values: Iterable of float or of AvgStdevMetadata - :returns: The metadata matching the values. - :rtype: BitCountingMetadata - """ - metadata = AvgStdevMetadataFactory.from_data(values) - return self.from_avg_stdev_metadata(metadata) diff --git a/PyPI/jumpavg/jumpavg/ClassifiedBitCountingMetadata.py b/PyPI/jumpavg/jumpavg/ClassifiedBitCountingMetadata.py deleted file mode 100644 index 29359f0908..0000000000 --- a/PyPI/jumpavg/jumpavg/ClassifiedBitCountingMetadata.py +++ /dev/null @@ -1,73 +0,0 @@ -# Copyright (c) 2018 Cisco and/or its affiliates. -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Module holding ClassifiedBitCountingMetadata class.""" - -from BitCountingMetadata import BitCountingMetadata - - -class ClassifiedBitCountingMetadata(BitCountingMetadata): - """Class for metadata which includes classification. - - TODO: Can we create ClassifiedMetadata and inherit (also) from that? - """ - - def __init__( - self, max_value, size=0, avg=0.0, stdev=0.0, prev_avg=None, - classification=None): - """Delegate to ancestor constructors and set classification. - - :param max_value: Maximal expected value. - :param size: Number of values participating in this group. - :param avg: Population average of the participating sample values. - :param stdev: Population standard deviation of the sample values. - :param prev_avg: Population average of the previous group. - If None, no previous average is taken into account. - If not None, the given previous average is used to discourage - consecutive groups with similar averages - (opposite triangle distribution is assumed). - :param classification: Arbitrary object classifying this group. - :type max_value: float - :type size: int - :type avg: float - :type stdev: float - :type prev_avg: float - :type classification: object - """ - super(ClassifiedBitCountingMetadata, self).__init__( - max_value, size, avg, stdev, prev_avg) - self.classification = classification - - def __str__(self): - """Return string with human readable description of the group. - - :returns: Readable description. - :rtype: str - """ - # str(super(...)) describes the proxy, not the proxied object. - super_str = super(ClassifiedBitCountingMetadata, self).__str__() - return super_str + " classification={classification}".format( - classification=self.classification) - - def __repr__(self): - """Return string executable as Python constructor call. - - :returns: Executable constructor call. - :rtype: str - """ - return ("ClassifiedBitCountingMetadata(max_value={max_value}," + - "size={size},avg={avg},stdev={stdev},prev_avg={prev_avg}," + - "classification={cls})").format( - max_value=self.max_value, size=self.size, avg=self.avg, - stdev=self.stdev, prev_avg=self.prev_avg, - cls=self.classification) diff --git a/PyPI/jumpavg/jumpavg/ClassifiedMetadataFactory.py b/PyPI/jumpavg/jumpavg/ClassifiedMetadataFactory.py deleted file mode 100644 index 7fdea7c162..0000000000 --- a/PyPI/jumpavg/jumpavg/ClassifiedMetadataFactory.py +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright (c) 2018 Cisco and/or its affiliates. -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Module holding ClassifiedBitCountingMetadata class.""" - -from ClassifiedBitCountingMetadata import ClassifiedBitCountingMetadata - - -class ClassifiedMetadataFactory(object): - """Class for factory which adds classification to bit counting metadata.""" - - @staticmethod - def with_classification(metadata, classification): - """Return new metadata object with added classification. - - TODO: Is there a way to add classification to any metadata, - without messing up constructors and __repr__()? - - FIXME: Factories take raw resources. Find a name for the thing - which takes semi-finished products. Transformer? - - :param metadata: Existing metadata without classification. - :param classification: Arbitrary object classifying this group. - :type metadata: BitCountingMetadata - :type classification: object - :returns: The metadata with added classification. - :rtype: ClassifiedBitCountingMetadata - """ - return ClassifiedBitCountingMetadata( - max_value=metadata.max_value, size=metadata.size, avg=metadata.avg, - stdev=metadata.stdev, prev_avg=metadata.prev_avg, - classification=classification) diff --git a/PyPI/jumpavg/jumpavg/RunGroup.py b/PyPI/jumpavg/jumpavg/RunGroup.py deleted file mode 100644 index 9de8ae8919..0000000000 --- a/PyPI/jumpavg/jumpavg/RunGroup.py +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright (c) 2018 Cisco and/or its affiliates. -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Module holding RunGroup class.""" - - -class RunGroup(object): - """Effectively a named touple of data and metadata. - - TODO: This feels like an abstract class. - Most uses assume restrictions on metadata type. - Can this be defined similarly to C++ templates? - """ - - def __init__(self, metadata, values): - """Create the group from metadata and values. - - :param metadata: Metadata object to associate with the group. - :param values: The runs belonging to this group. - :type metadata: AbstractGroupMetadata - :type values: Iterable of float or od AvgStdevMetadata - """ - self.metadata = metadata - self.values = values diff --git a/PyPI/jumpavg/jumpavg/__init__.py b/PyPI/jumpavg/jumpavg/__init__.py deleted file mode 100644 index 8e41ed9fe2..0000000000 --- a/PyPI/jumpavg/jumpavg/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (c) 2018 Cisco and/or its affiliates. -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -__init__ file for "jumpavg" Python package. -""" diff --git a/PyPI/jumpavg/setup.py b/PyPI/jumpavg/setup.py index 206373ac47..c80e38f069 100644 --- a/PyPI/jumpavg/setup.py +++ b/PyPI/jumpavg/setup.py @@ -1,40 +1,47 @@ +#!/usr/bin/env python3 + """A setup module for setuptools. See: https://packaging.python.org/en/latest/distributing.html """ -from setuptools import setup, find_packages +from setuptools import (setup, find_packages) from os import path from io import open here = path.abspath(path.dirname(__file__)) -with open(path.join(here, "README.rst"), encoding="utf-8") as f: +with open(path.join(here, u"README.rst"), encoding=u"utf-8") as f: long_description = f.read() setup( - name="jumpavg", - version="0.1.4", # This is currently the only place listing the version. - description="Library for finding changes in time series by grouping results.", + name=u"jumpavg", + version=u"0.2.0", # This is currently the only place listing the version. + description=( + u"Library for locating changes in time series by grouping results." + ), long_description=long_description, - long_description_content_type="text/x-rst", + long_description_content_type=u"text/x-rst", # TODO: Create a separate webpage for jumpavg library. - url="https://gerrit.fd.io/r/gitweb?p=csit.git;a=tree;f=PyPI/jumpavg;hb=refs/heads/master", - author="Cisco Systems Inc. and/or its affiliates", - author_email="csit-dev@lists.fd.io", + url=( + u"https://gerrit.fd.io/r/gitweb?p=csit.git;a=tree;f=PyPI/jumpavg" + u";hb=refs/heads/master" + ), + author=u"Cisco Systems Inc. and/or its affiliates", + author_email=u"csit-dev@lists.fd.io", classifiers=[ - "Development Status :: 3 - Alpha", - "Intended Audience :: Science/Research", + u"Development Status :: 3 - Alpha", + u"Intended Audience :: Science/Research", # Pick your license as you wish - "License :: OSI Approved :: Apache Software License", - "Natural Language :: English", + u"License :: OSI Approved :: Apache Software License", + u"Natural Language :: English", # TODO: Test which Python versions is the code compatible with. - "Programming Language :: Python :: 2.7", - "Topic :: Scientific/Engineering :: Information Analysis" + u"Programming Language :: Python :: 2.7", + u"Topic :: Scientific/Engineering :: Information Analysis" ], - keywords="progression regression anomaly detection", + keywords=u"progression regression anomaly detection statistics bits", packages=find_packages(exclude=[]), - # TODO: python_requires="~=2.7" + python_requires="~=3.6" install_requires=[], # TODO: Include simulator and tests. extras_require={ @@ -42,11 +49,14 @@ setup( package_data={ }, entry_points={ - "console_scripts": [ + u"console_scripts": [ ], }, project_urls={ - "Bug Reports": "https://jira.fd.io/projects/CSIT/issues", - "Source": "https://gerrit.fd.io/r/gitweb?p=csit.git;a=tree;f=PyPI/jumpavg;hb=refs/heads/master", + u"Bug Reports": u"https://jira.fd.io/projects/CSIT/issues", + u"Source": ( + u"https://gerrit.fd.io/r/gitweb?p=csit.git;a=tree;f=PyPI/jumpavg" + u";hb=refs/heads/master" + ), }, ) -- cgit 1.2.3-korg