1 # The MIT License (MIT)
3 # Copyright (C) 2016 - Antoine Busque <abusque@efficios.com>
5 # Permission is hereby granted, free of charge, to any person obtaining a copy
6 # of this software and associated documentation files (the "Software"), to deal
7 # in the Software without restriction, including without limitation the rights
8 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 # copies of the Software, and to permit persons to whom the Software is
10 # furnished to do so, subject to the following conditions:
12 # The above copyright notice and this permission notice shall be included in
13 # all copies or substantial portions of the Software.
15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 from collections
import namedtuple
26 GraphDatum
= namedtuple('GraphDatum', ['value', 'value_str'])
27 BarGraphDatum
= namedtuple('BarGraphDatum', ['value', 'value_str', 'label'])
28 FreqGraphDatum
= namedtuple(
29 'FreqGraphDatum', ['value', 'value_str', 'lower_bound']
38 def __init__(self
, data
, get_value
, get_value_str
, title
, unit
):
40 self
._get
_value
= get_value
44 self
._max
_value
_len
= 0
46 if get_value_str
is not None:
47 self
._get
_value
_str
_cb
= get_value_str
49 self
._get
_value
_str
_cb
= Graph
._get
_value
_str
_default
51 def _transform_data(self
, data
):
55 graph_datum
= self
._get
_graph
_datum
(datum
)
57 if graph_datum
.value
> self
._max
_value
:
58 self
._max
_value
= graph_datum
.value
59 if len(graph_datum
.value_str
) > self
._max
_value
_len
:
60 self
._max
_value
_len
= len(graph_datum
.value_str
)
62 graph_data
.append(graph_datum
)
66 def _get_value_str(self
, value
):
67 return self
._get
_value
_str
_cb
(value
)
69 def _get_graph_datum(self
, datum
):
70 value
= self
._get
_value
(datum
)
71 value_str
= self
._get
_value
_str
(value
)
73 return GraphDatum(value
, value_str
)
75 def _print_header(self
):
79 def _print_separator(self
):
80 print(self
.HR_CHAR
* self
.MAX_GRAPH_WIDTH
)
82 def _print_body(self
):
83 raise NotImplementedError()
85 def print_graph(self
):
90 self
._print
_separator
()
95 def _get_value_str_default(value
):
96 if isinstance(value
, float):
97 value_str
= '{:0.02f}'.format(value
)
99 value_str
= str(value
)
104 class BarGraph(Graph
):
105 def __init__(self
, data
, get_value
, get_label
, get_value_str
=None,
106 title
=None, label_header
=None, unit
=None):
107 super().__init
__(data
, get_value
, get_value_str
, title
, unit
)
109 self
._get
_label
= get_label
110 self
._label
_header
= label_header
111 self
._data
= self
._transform
_data
(self
._data
)
113 def _get_graph_datum(self
, datum
):
114 value
= self
._get
_value
(datum
)
115 value_str
= self
._get
_value
_str
(value
)
116 label
= self
._get
_label
(datum
)
118 return BarGraphDatum(value
, value_str
, label
)
120 def _get_value_str(self
, value
):
121 value_str
= super()._get
_value
_str
(value
)
123 value_str
+= ' ' + self
._unit
127 def _get_graph_header(self
):
128 if not self
._label
_header
:
131 title_len
= len(self
._title
)
133 self
.MAX_GRAPH_WIDTH
- title_len
+ 1 + self
._max
_value
_len
+ 1
136 return self
._title
+ ' ' * space_width
+ self
._label
_header
138 def _print_header(self
):
139 header
= self
._get
_graph
_header
()
142 def _get_bar_str(self
, datum
):
143 if self
._max
_value
== 0:
146 bar_width
= int(self
.MAX_GRAPH_WIDTH
* datum
.value
/
148 space_width
= self
.MAX_GRAPH_WIDTH
- bar_width
149 bar_str
= self
.BAR_CHAR
* bar_width
+ ' ' * space_width
153 def _print_body(self
):
154 for datum
in self
._data
:
155 bar_str
= self
._get
_bar
_str
(datum
)
156 value_padding
= ' ' * (self
._max
_value
_len
- len(datum
.value_str
))
157 print(bar_str
, value_padding
+ datum
.value_str
, datum
.label
)
160 class FreqGraph(Graph
):
161 LOWER_BOUND_WIDTH
= 8
163 def __init__(self
, data
, get_value
, get_lower_bound
,
164 get_value_str
=None, title
=None, unit
=None):
165 super().__init
__(data
, get_value
, get_value_str
, title
, unit
)
167 self
._get
_lower
_bound
= get_lower_bound
168 self
._data
= self
._transform
_data
(self
._data
)
170 def _get_graph_datum(self
, datum
):
171 value
= self
._get
_value
(datum
)
172 value_str
= self
._get
_value
_str
(value
)
173 lower_bound
= self
._get
_lower
_bound
(datum
)
175 return FreqGraphDatum(value
, value_str
, lower_bound
)
177 def _print_header(self
):
180 header
+= ' ({})'.format(self
._unit
)
184 def _get_bar_str(self
, datum
):
185 max_width
= self
.MAX_GRAPH_WIDTH
- self
.LOWER_BOUND_WIDTH
186 if self
._max
_value
== 0:
189 bar_width
= int(max_width
* datum
.value
/ self
._max
_value
)
190 space_width
= max_width
- bar_width
191 bar_str
= self
.BAR_CHAR
* bar_width
+ ' ' * space_width
195 def _print_body(self
):
196 for datum
in self
._data
:
197 bound_str
= FreqGraph
._get
_bound
_str
(datum
)
198 bar_str
= self
._get
_bar
_str
(datum
)
199 value_padding
= ' ' * (self
._max
_value
_len
- len(datum
.value_str
))
200 print(bound_str
, bar_str
, value_padding
+ datum
.value_str
)
203 def _get_bound_str(datum
):
204 return '{:>7.03f}'.format(datum
.lower_bound
)
This page took 0.034391 seconds and 5 git commands to generate.