summaryrefslogtreecommitdiff
path: root/tablib
diff options
context:
space:
mode:
authorKenneth Reitz <me@kennethreitz.com>2011-06-21 19:42:56 -0400
committerKenneth Reitz <me@kennethreitz.com>2011-06-21 19:42:56 -0400
commit004b3da680b821d0dcedbe52ee6fb5a2a45c9ad5 (patch)
tree20065c575a7349e0806a21f3312973eb975338f5 /tablib
parentd4923533eb3091cd4dddbe74cbddf50b158f74fe (diff)
downloadtablib-004b3da680b821d0dcedbe52ee6fb5a2a45c9ad5.tar.gz
Major API Changes
Related #21
Diffstat (limited to 'tablib')
-rw-r--r--tablib/core.py308
1 files changed, 198 insertions, 110 deletions
diff --git a/tablib/core.py b/tablib/core.py
index 16b3dff..9c561fd 100644
--- a/tablib/core.py
+++ b/tablib/core.py
@@ -62,8 +62,14 @@ class Row(object):
def __setstate__(self, state):
for (k, v) in list(state.items()): setattr(self, k, v)
+ def rpush(self, value):
+ self.insert(0, value)
+
+ def lpush(self, value):
+ self.insert(len(value), value)
+
def append(self, value):
- self._row.append(value)
+ self.rpush(value)
def insert(self, index, value):
self._row.insert(index, value)
@@ -200,6 +206,10 @@ class Dataset(object):
return '<dataset object>'
+ # ---------
+ # Internals
+ # ---------
+
@classmethod
def _register_formats(cls):
"""Adds format properties."""
@@ -236,6 +246,7 @@ class Dataset(object):
def _package(self, dicts=True, ordered=True):
"""Packages Dataset into lists of dictionaries for transmission."""
+ # TODO: Dicts default to false?
_data = list(self._data)
@@ -269,46 +280,6 @@ class Dataset(object):
return data
- def _clean_col(self, col):
- """Prepares the given column for insert/append."""
-
- col = list(col)
-
- if self.headers:
- header = [col.pop(0)]
- else:
- header = []
-
- if len(col) == 1 and hasattr(col[0], '__call__'):
-
- col = list(map(col[0], self._data))
- col = tuple(header + col)
-
- return col
-
-
- @property
- def height(self):
- """The number of rows currently in the :class:`Dataset`.
- Cannot be directly modified.
- """
- return len(self._data)
-
-
- @property
- def width(self):
- """The number of columns currently in the :class:`Dataset`.
- Cannot be directly modified.
- """
-
- try:
- return len(self._data[0])
- except IndexError:
- try:
- return len(self.headers)
- except TypeError:
- return 0
-
def _get_headers(self):
"""An *optional* list of strings to be used for header rows and attribute names.
@@ -332,6 +303,7 @@ class Dataset(object):
headers = property(_get_headers, _set_headers)
+
def _get_dict(self):
"""A native Python representation of the :class:`Dataset` object. If headers have
been set, a list of Python dictionaries will be returned. If no headers have been set,
@@ -379,6 +351,52 @@ class Dataset(object):
dict = property(_get_dict, _set_dict)
+ def _clean_col(self, col):
+ """Prepares the given column for insert/append."""
+
+ col = list(col)
+
+ if self.headers:
+ header = [col.pop(0)]
+ else:
+ header = []
+
+ if len(col) == 1 and hasattr(col[0], '__call__'):
+
+ col = list(map(col[0], self._data))
+ col = tuple(header + col)
+
+ return col
+
+
+ @property
+ def height(self):
+ """The number of rows currently in the :class:`Dataset`.
+ Cannot be directly modified.
+ """
+ return len(self._data)
+
+
+ @property
+ def width(self):
+ """The number of columns currently in the :class:`Dataset`.
+ Cannot be directly modified.
+ """
+
+ try:
+ return len(self._data[0])
+ except IndexError:
+ try:
+ return len(self.headers)
+ except TypeError:
+ return 0
+
+
+ # -------
+ # Formats
+ # -------
+
+
@property
def xls():
"""A Legacy Excel Spreadsheet representation of the :class:`Dataset` object, with :ref:`separators`. Cannot be set.
@@ -493,15 +511,128 @@ class Dataset(object):
pass
- def append(self, row=None, col=None, header=None, tags=list()):
- """Adds a row or column to the :class:`Dataset`.
- Usage is :class:`Dataset.insert` for documentation.
+ # ----
+ # Rows
+ # ----
+
+ def insert(self, index, row, tags=list()):
+ """Inserts a row to the :class:`Dataset` at the given index.
+
+ Rows and columns inserted must be the correct size (height or width).
+
+ The default behaviour is to insert the given row to the :class:`Dataset`
+ object at the given index. If the ``col`` parameter is given, however,
+ a new column will be insert to the :class:`Dataset` object instead.
+
+ You can also insert a column of a single callable object, which will
+ add a new column with the return values of the callable each as an
+ item in the column. ::
+
+ data.append(col=random.randint)
+
+ See :ref:`dyncols` for an in-depth example.
+
+ .. versionchanged:: 0.9.0
+ If inserting a column, and :class:`Dataset.headers` is set, the
+ header attribute must be set, and will be considered the header for
+ that row.
+
+ .. versionadded:: 0.9.0
+ If inserting a row, you can add :ref:`tags <tags>` to the row you are inserting.
+ This gives you the ability to :class:`filter <Dataset.filter>` your
+ :class:`Dataset` later.
+ """
+
+ self._validate(row)
+ self._data.insert(index, Row(row, tags=tags))
+
+
+ def rpush(self, row, tags=list()):
+ """Adds a row to the end of the :class:`Dataset`.
+ See :class:`Dataset.insert` for additional documentation.
+ """
+
+ self.insert(self.height, row=row, tags=tags)
+
+
+ def lpush(self, row, tags=list()):
+ """Adds a row to the top of the :class:`Dataset`.
+ See :class:`Dataset.insert` for additional documentation.
+ """
+
+ self.insert(0, row=row, tags=tags)
+
+
+ def append(self, row, tags=list()):
+ """Adds a row to the :class:`Dataset`.
+ See :class:`Dataset.insert` for additional documentation.
+ """
+
+ self.rpush(row, tags)
+
+
+ # -------
+ # Columns
+ # -------
+
+ def insert_col(self, index, col=None, header=None):
+ """Inserts a column to the :class:`Dataset` at the given index.
+
+ Columns inserted must be the correct height.
+
+ You can also insert a column of a single callable object, which will
+ add a new column with the return values of the callable each as an
+ item in the column. ::
+
+ data.append_col(col=random.randint)
+
+ If inserting a column, and :class:`Dataset.headers` is set, the
+ header attribute must be set, and will be considered the header for
+ that row.
+
+ See :ref:`dyncols` for an in-depth example.
+ """
+
+ col = list(col)
+
+ # Callable Columns...
+ if len(col) == 1 and hasattr(col[0], '__call__'):
+ col = list(map(col[0], self._data))
+
+ col = self._clean_col(col)
+ self._validate(col=col)
+
+ if self.headers:
+ # pop the first item off, add to headers
+ if not header:
+ raise HeadersNeeded()
+ self.headers.insert(index, header)
+
+ if self.height and self.width:
+
+ for i, row in enumerate(self._data):
+
+ row.insert(index, col[i])
+ self._data[i] = row
+ else:
+ self._data = [Row([row]) for row in col]
+
+
+
+ def rpush_col(self, col, header=None):
+ """Adds a column to the end of the :class:`Dataset`.
+ See :class:`Dataset.insert` for additional documentation.
"""
- if row is not None:
- self.insert(self.height, row=row, tags=tags)
- elif col is not None:
- self.insert(self.width, col=col, header=header)
+ self.insert_col(self.width, col, header=header)
+
+
+ def lpush_col(self, col, header=None):
+ """Adds a column to the top of the :class:`Dataset`.
+ See :class:`Dataset.insert` for additional documentation.
+ """
+
+ self.insert_col(0, col, header=header)
def insert_separator(self, index, text='-'):
@@ -523,6 +654,18 @@ class Dataset(object):
self.insert_separator(index, text)
+ def append_col(self, col, header=None):
+ """Adds a column to the :class:`Dataset`.
+ See :class:`Dataset.insert_col` for additional documentation.
+ """
+
+ self.rpush_col(col, header)
+
+
+ # ----
+ # Misc
+ # ----
+
def add_formatter(self, col, handler):
"""Adds a :ref:`formatter` to the :class:`Dataset`.
@@ -546,63 +689,6 @@ class Dataset(object):
return True
- def insert(self, index, row=None, col=None, header=None, tags=list()):
- """Inserts a row or column to the :class:`Dataset` at the given index.
-
- Rows and columns inserted must be the correct size (height or width).
-
- The default behaviour is to insert the given row to the :class:`Dataset`
- object at the given index. If the ``col`` parameter is given, however,
- a new column will be insert to the :class:`Dataset` object instead.
-
- You can also insert a column of a single callable object, which will
- add a new column with the return values of the callable each as an
- item in the column. ::
-
- data.append(col=random.randint)
-
- See :ref:`dyncols` for an in-depth example.
-
- .. versionchanged:: 0.9.0
- If inserting a column, and :class:`Dataset.headers` is set, the
- header attribute must be set, and will be considered the header for
- that row.
-
- .. versionadded:: 0.9.0
- If inserting a row, you can add :ref:`tags <tags>` to the row you are inserting.
- This gives you the ability to :class:`filter <Dataset.filter>` your
- :class:`Dataset` later.
-
- """
- if row:
- self._validate(row)
- self._data.insert(index, Row(row, tags=tags))
- elif col:
- col = list(col)
-
- # Callable Columns...
- if len(col) == 1 and hasattr(col[0], '__call__'):
- col = list(map(col[0], self._data))
-
- col = self._clean_col(col)
- self._validate(col=col)
-
- if self.headers:
- # pop the first item off, add to headers
- if not header:
- raise HeadersNeeded()
- self.headers.insert(index, header)
-
- if self.height and self.width:
-
- for i, row in enumerate(self._data):
-
- row.insert(index, col[i])
- self._data[i] = row
- else:
- self._data = [Row([row]) for row in col]
-
-
def filter(self, tag):
"""Returns a new instance of the :class:`Dataset`, excluding any rows
that do not contain the given :ref:`tags <tags>`.
@@ -617,8 +703,10 @@ class Dataset(object):
"""Sort a :class:`Dataset` by a specific column, given string (for
header) or integer (for column index). The order can be reversed by
setting ``reverse`` to ``True``.
+
Returns a new :class:`Dataset` instance where columns have been
- sorted."""
+ sorted.
+ """
if isinstance(col, str):
@@ -679,7 +767,7 @@ class Dataset(object):
return _dset
- def stack_rows(self, other):
+ def stack(self, other):
"""Stack two :class:`Dataset` instances together by
joining at the row level, and return new combined
``Dataset`` instance."""
@@ -702,7 +790,7 @@ class Dataset(object):
return _dset
- def stack_columns(self, other):
+ def stack_cols(self, other):
"""Stack two :class:`Dataset` instances together by
joining at the column level, and return a new
combined ``Dataset`` instance. If either ``Dataset``
@@ -726,10 +814,10 @@ class Dataset(object):
_dset = Dataset()
for column in self.headers:
- _dset.append(col=self[column])
+ _dset.append_col(col=self[column])
for column in other.headers:
- _dset.append(col=other[column])
+ _dset.append_col(col=other[column])
_dset.headers = new_headers