/usr/lib/python3/dist-packages/leather/series/base.py is in python3-leather 0.3.3-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | #!/usr/bin/env python
from collections import Iterable, Sequence, Mapping
from functools import partial
import six
from leather.data_types import DataType
from leather.utils import DIMENSION_NAMES, X, Y, Datum
class Series(object):
"""
A series of data and its associated metadata.
Series object does not modify the data it is passed.
:param data:
A sequence (rows) of sequences (columns), a.k.a. :func:`csv.reader`
format. If the :code:`x` and :code:`y` are not specified then the first
column is used as the X values and the second column is used for Y.
Or, a sequence of (rows) of dicts (columns), a.k.a.
:class:`csv.DictReader` format. If this format is used then :code:`x`
and :code:`y` arguments must specify the columns to be charted.
Or, a custom data format, in which case :code:`x` and :code:`y` must
specify :func:`.key_function`.
:param x:
If using sequence row data, then this may be either an integer index
identifying the X column, or a :func:`.key_function`.
If using dict row data, then this may be either a key name identifying
the X column, or a :func:`.key_function`.
If using a custom data format, then this must be a
:func:`.key_function`.`
:param y:
See :code:`x`.
:param name:
An optional name to be used in labeling this series. This will be
used as the chart title if rendered in a :class:`.Lattice`.
"""
def __init__(self, data, x=None, y=None, name=None):
self._data = data
self._name = name
self._keys = [
self._make_key(x if x is not None else X),
self._make_key(y if y is not None else Y)
]
self._types = [
self._infer_type(X),
self._infer_type(Y)
]
def _make_key(self, key):
"""
Process a user-specified data key and convert to a function if needed.
"""
if callable(key):
return key
else:
return lambda row, index: row[key]
def _infer_type(self, dimension):
"""
Infer the datatype of this column by sampling the data.
"""
key = self._keys[dimension]
for i, row in enumerate(self._data):
v = key(row, i)
if v is not None:
break
if v is None:
raise ValueError('All values in %s dimension are null.' % DIMENSION_NAMES[dimension])
return DataType.infer(v)
@property
def name(self):
return self._name
def data_type(self, dimension):
"""
Return the data type for a dimension of this series.
"""
return self._types[dimension]
def data(self):
"""
Return data for this series.
"""
x = self._keys[X]
y = self._keys[Y]
for i, row in enumerate(self._data):
yield Datum(i, x(row, i), y(row, i), None, row)
def values(self, dimension):
"""
Get a flattened list of values for a given dimension of the data.
"""
key = self._keys[dimension]
return [key(row, i) for i, row in enumerate(self._data)]
def min(self, dimension):
"""
Compute the minimum value of a given dimension.
"""
return min(v for v in self.values(dimension) if v is not None)
def max(self, dimension):
"""
Compute the minimum value of a given dimension.
"""
return max(v for v in self.values(dimension) if v is not None)
def key_function(row, index):
"""
This example shows how to define a function to extract X and Y values
from custom data.
:param row:
The function will be called with the row data, in whatever format it
was provided to the :class:`.Series`.
:param index:
The row index in the series data will also be provided.
:returns:
The function must return a chartable value.
"""
pass
|