CSIT-1110: Prepare for migrating the new detection
[csit.git] / resources / tools / presentation / new / jumpavg / BitCountingGroupList.py
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:
5 #
6 #     http://www.apache.org/licenses/LICENSE-2.0
7 #
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.
13
14 """Module holding BitCountingGroupList class."""
15
16 from BitCountingGroup import BitCountingGroup
17 from BitCountingMetadataFactory import BitCountingMetadataFactory
18
19
20 class BitCountingGroupList(list):
21     """List of BitCountingGroup which tracks overall bit count.
22
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.
27
28     Method with_value_added_to_last_group() delegates to BitCountingGroup,
29     with_group_appended() adds new group with recalculated bits.
30
31     TODO: last_group.metadata_factory.max_value in with_group_appended()
32     is ugly, find a more natural class design.
33     """
34
35     def __init__(self, group_list=[], bits=None):
36         """Create a group list from given list of groups.
37
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
42         """
43         super(BitCountingGroupList, self).__init__(group_list)
44         if bits is not None:
45             self.bits = bits
46             return
47         bits = 0.0
48         for group in group_list:
49             bits += group.metadata.bits
50         self.bits = bits
51
52     def with_group_appended(self, group):
53         """Create and return new group list with given group more than self.
54
55         The group argument object is updated with derivative metadata.
56
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
61         """
62         group_list = list(self)
63         if group_list:
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)
72
73     def with_value_added_to_last_group(self, value):
74         """Create and return new group list with value added to last group.
75
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
80         """
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)