1 # Copyright (c) 2018 Cisco and/or its affiliates.
2 # Licensed under the Apache License, Version 2.0 (the "License");
3 # you may not use this file except in compliance with the License.
4 # You may obtain a copy of the License at:
6 # http://www.apache.org/licenses/LICENSE-2.0
8 # Unless required by applicable law or agreed to in writing, software
9 # distributed under the License is distributed on an "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 # See the License for the specific language governing permissions and
12 # limitations under the License.
14 """Module holding BitCountingGroupList class."""
16 from BitCountingGroup import BitCountingGroup
17 from BitCountingMetadataFactory import BitCountingMetadataFactory
20 class BitCountingGroupList(list):
21 """List of BitCountingGroup which tracks overall bit count.
23 This is useful, as bit count of a subsequent group
24 depends on average of the previous group.
25 Having the logic encapsulated here spares the caller
26 the effort to pass averages around.
28 Method with_value_added_to_last_group() delegates to BitCountingGroup,
29 with_group_appended() adds new group with recalculated bits.
31 TODO: last_group.metadata_factory.max_value in with_group_appended()
32 is ugly, find a more natural class design.
35 def __init__(self, group_list=[], bits=None):
36 """Create a group list from given list of groups.
38 :param group_list: List of groups to compose this group.
39 :param bits: Bit count if known, else None.
40 :type group_list: list of BitCountingGroup
41 :type bits: float or None
43 super(BitCountingGroupList, self).__init__(group_list)
48 for group in group_list:
49 bits += group.metadata.bits
52 def with_group_appended(self, group):
53 """Create and return new group list with given group more than self.
55 The group argument object is updated with derivative metadata.
57 :param group: Next group to be appended to the group list.
58 :type group: BitCountingGroup
59 :returns: New group list with added group.
60 :rtype: BitCountingGroupList
62 group_list = list(self)
64 last_group = group_list[-1]
65 factory = BitCountingMetadataFactory(
66 last_group.metadata_factory.max_value, last_group.metadata.avg)
67 group.metadata_factory = factory
68 group.metadata = factory.from_data(group.values)
69 group_list.append(group)
70 bits = self.bits + group.metadata.bits
71 return BitCountingGroupList(group_list, bits)
73 def with_value_added_to_last_group(self, value):
74 """Create and return new group list with value added to last group.
76 :param value: The run value to add to the last group.
77 :type value: float or od AvgStdevMetadata
78 :returns: New group list with the last group updated.
79 :rtype: BitCountingGroupList
81 group_list = list(self)
82 last_group = group_list[-1]
83 bits_before = last_group.metadata.bits
84 last_group = last_group.with_run_added(value)
85 group_list[-1] = last_group
86 bits = self.bits - bits_before + last_group.metadata.bits
87 return BitCountingGroupList(group_list, bits)