Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
aos
GitHub Repository: aos/firecracker
Path: blob/main/tests/framework/stats/function.py
1956 views
1
# Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
# SPDX-License-Identifier: Apache-2.0
3
4
"""Module for statistical functions."""
5
6
from abc import ABC, abstractmethod
7
from typing import Any, List
8
# pylint: disable=E0611
9
from statistics import mean, stdev
10
from pydoc import locate
11
12
13
# pylint: disable=R0903
14
class FunctionFactory:
15
"""Function factory class."""
16
17
@classmethod
18
def get(cls, func_cls_name) -> 'Function':
19
"""`func_cls_name` must be a valid function class name."""
20
return locate(f"framework.stats.function.{func_cls_name}")
21
22
23
# pylint: disable=R0903
24
class Function(ABC):
25
"""Statistic function abstract class."""
26
27
def __init__(self, name):
28
"""Initialize the statistic function."""
29
self._name = name
30
31
@abstractmethod
32
def __call__(self, result: Any) -> Any:
33
"""Builtin function needs to be implemented."""
34
35
@property
36
def name(self) -> str:
37
"""Return the a name identifier for the class."""
38
return self._name
39
40
41
# pylint: disable=R0903
42
class ValuePlaceholder(Function):
43
"""This function can be used as a placeholder for results consumption.
44
45
When used, it will simply provide a no-op over the result passed to it.
46
The data will be forwarded to the final statistics view as it is received.
47
48
If used for each iteration of a statistical exercise, the function will
49
retain only the result corresponding to the last iteration.
50
"""
51
52
def __init__(self, name="result"):
53
"""Initialize the statistic function."""
54
super().__init__(name)
55
56
def __call__(self, result: Any) -> Any:
57
"""Get the value."""
58
return result
59
60
61
# pylint: disable=R0903
62
class Min(Function):
63
"""A function which computes the minimum observation from a list of...
64
65
...observations.
66
"""
67
68
def __init__(self, name="Min"):
69
"""Initialize the statistic function."""
70
super().__init__(name)
71
72
def __call__(self, result: Any) -> Any:
73
"""Get the minimum observation."""
74
assert isinstance(result, list)
75
return min(result)
76
77
78
# pylint: disable=R0903
79
class Max(Function):
80
"""A function which computes the maximum observation from a list of...
81
82
...observations.
83
"""
84
85
def __init__(self, name="Max"):
86
"""Initialize the statistic function."""
87
super().__init__(name)
88
89
def __call__(self, result: Any) -> Any:
90
"""Get the maximum observation."""
91
assert isinstance(result, list)
92
return max(result)
93
94
95
# pylint: disable=R0903
96
class Avg(Function):
97
"""A function which computes the average of a list of observations."""
98
99
def __init__(self, name="Avg"):
100
"""Initialize the statistic function."""
101
super().__init__(name)
102
103
def __call__(self, result: Any) -> Any:
104
"""Get the average."""
105
assert isinstance(result, list)
106
return mean(result)
107
108
109
# pylint: disable=R0903
110
class Sum(Function):
111
"""A function which computes the sum for a list of observations."""
112
113
def __init__(self, name="Sum"):
114
"""Initialize the statistic function."""
115
super().__init__(name)
116
117
def __call__(self, result: Any) -> Any:
118
"""Get the sum."""
119
assert isinstance(result, list)
120
return sum(result)
121
122
123
# pylint: disable=R0903
124
class Stddev(Function):
125
"""A function which computes the standard deviation of a list of...
126
127
...observations.
128
"""
129
130
def __init__(self, name="Stddev"):
131
"""Initialize the statistic function."""
132
super().__init__(name)
133
134
def __call__(self, result: Any) -> Any:
135
"""Get the stddev."""
136
assert isinstance(result, list)
137
assert len(result) > 0
138
# pylint: disable=R0123
139
if len(result) is 1:
140
return 0
141
return stdev(result)
142
143
144
# pylint: disable=R0903
145
class Percentile(Function, ABC):
146
"""A function which computes the kth percentile of a list of...
147
148
...observations.
149
"""
150
151
def __init__(self, k: int, name: str):
152
"""Initialize the function."""
153
super().__init__(name)
154
self.k = k
155
156
def __call__(self, result: List) -> Any:
157
"""Get the kth percentile of the statistical exercise."""
158
# pylint: disable=R0123
159
assert isinstance(result, list)
160
if len(result) is 1:
161
return result[0]
162
163
length = len(result)
164
result.sort()
165
idx = length * self.k / 100
166
if not idx.is_integer():
167
return (result[int(idx)] + result[min((int(idx) + 1),
168
length - 1)]) / 2
169
170
return result[int(idx)]
171
172
173
class Percentile50(Percentile):
174
"""A function which computes the 50th percentile of a list of...
175
176
...observations.
177
"""
178
179
def __init__(self, name="P50"):
180
"""Initialize the function."""
181
super().__init__(50, name)
182
183
184
class Percentile90(Percentile):
185
"""A function which computes the 90th percentile of a list of...
186
187
...observations.
188
"""
189
190
def __init__(self, name="P90"):
191
"""Initialize the statistic function."""
192
super().__init__(90, name)
193
194
195
class Percentile99(Percentile):
196
"""A function which computes the 99th percentile of a list of...
197
198
...observations.
199
"""
200
201
def __init__(self, name="P99"):
202
"""Initialize the statistic function."""
203
super().__init__(99, name)
204
205