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']
37 def __init__(self
, data
, get_value
, get_value_str
, title
, unit
):
39 self
._get
_value
= get_value
43 self
._max
_value
_len
= 0
45 if get_value_str
is not None:
46 self
._get
_value
_str
_cb
= get_value_str
48 self
._get
_value
_str
_cb
= Graph
._get
_value
_str
_default
50 def _transform_data(self
, data
):
54 graph_datum
= self
._get
_graph
_datum
(datum
)
56 if graph_datum
.value
> self
._max
_value
:
57 self
._max
_value
= graph_datum
.value
58 if len(graph_datum
.value_str
) > self
._max
_value
_len
:
59 self
._max
_value
_len
= len(graph_datum
.value_str
)
61 graph_data
.append(graph_datum
)
65 def _get_value_str(self
, value
):
66 return self
._get
_value
_str
_cb
(value
)
68 def _get_graph_datum(self
, datum
):
69 value
= self
._get
_value
(datum
)
70 value_str
= self
._get
_value
_str
(value
)
72 return GraphDatum(value
, value_str
)
74 def _print_header(self
):
78 def _print_separator(self
):
79 print(self
.HR_CHAR
* self
.MAX_GRAPH_WIDTH
)
81 def _print_body(self
):
82 raise NotImplementedError()
84 def print_graph(self
):
89 self
._print
_separator
()
94 def _get_value_str_default(value
):
95 if isinstance(value
, float):
96 value_str
= '{:0.02f}'.format(value
)
98 value_str
= str(value
)
103 class BarGraph(Graph
):
104 def __init__(self
, data
, get_value
, get_label
, get_value_str
=None,
105 title
=None, label_header
=None, unit
=None):
106 super().__init
__(data
, get_value
, get_value_str
, title
, unit
)
108 self
._get
_label
= get_label
109 self
._label
_header
= label_header
110 self
._data
= self
._transform
_data
(self
._data
)
112 def _get_graph_datum(self
, datum
):
113 value
= self
._get
_value
(datum
)
114 value_str
= self
._get
_value
_str
(value
)
115 label
= self
._get
_label
(datum
)
117 return BarGraphDatum(value
, value_str
, label
)
119 def _get_value_str(self
, value
):
120 value_str
= super()._get
_value
_str
(value
)
122 value_str
+= ' ' + self
._unit
126 def _get_graph_header(self
):
127 if not self
._label
_header
:
130 title_len
= len(self
._title
)
131 space_width
= (self
.MAX_GRAPH_WIDTH
- title_len
) + \
132 1 + self
._max
_value
_len
+ 1
134 return self
._title
+ ' ' * space_width
+ self
._label
_header
136 def _print_header(self
):
137 header
= self
._get
_graph
_header
()
140 def _get_bar_str(self
, datum
):
141 if self
._max
_value
== 0:
144 bar_width
= int(self
.MAX_GRAPH_WIDTH
* datum
.value
/
146 space_width
= self
.MAX_GRAPH_WIDTH
- bar_width
147 bar_str
= self
.BAR_CHAR
* bar_width
+ ' ' * space_width
151 def _print_body(self
):
152 for datum
in self
._data
:
153 bar_str
= self
._get
_bar
_str
(datum
)
154 value_padding
= ' ' * (self
._max
_value
_len
- len(datum
.value_str
))
155 print(bar_str
, value_padding
+ datum
.value_str
, datum
.label
)
158 class FreqGraph(Graph
):
159 LOWER_BOUND_WIDTH
= 8
161 def __init__(self
, data
, get_value
, get_lower_bound
,
162 get_value_str
=None, title
=None, unit
=None):
163 super().__init
__(data
, get_value
, get_value_str
, title
, unit
)
165 self
._get
_lower
_bound
= get_lower_bound
166 self
._data
= self
._transform
_data
(self
._data
)
168 def _get_graph_datum(self
, datum
):
169 value
= self
._get
_value
(datum
)
170 value_str
= self
._get
_value
_str
(value
)
171 lower_bound
= self
._get
_lower
_bound
(datum
)
173 return FreqGraphDatum(value
, value_str
, lower_bound
)
175 def _print_header(self
):
178 header
+= ' ({})'.format(self
._unit
)
182 def _get_bar_str(self
, datum
):
183 max_width
= self
.MAX_GRAPH_WIDTH
- self
.LOWER_BOUND_WIDTH
184 if self
._max
_value
== 0:
187 bar_width
= int(max_width
* datum
.value
/ self
._max
_value
)
188 space_width
= max_width
- bar_width
189 bar_str
= self
.BAR_CHAR
* bar_width
+ ' ' * space_width
193 def _print_body(self
):
194 for datum
in self
._data
:
195 bound_str
= FreqGraph
._get
_bound
_str
(datum
)
196 bar_str
= self
._get
_bar
_str
(datum
)
197 value_padding
= ' ' * (self
._max
_value
_len
- len(datum
.value_str
))
198 print(bound_str
, bar_str
, value_padding
+ datum
.value_str
)
201 def _get_bound_str(datum
):
202 return '{:>7.03f}'.format(datum
.lower_bound
)
This page took 0.038651 seconds and 5 git commands to generate.