diff --git a/HISTORY.rst b/HISTORY.rst index 43a8cda..95b9328 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -1,11 +1,12 @@ History ------- -0.9.3 (2010-11-2?) +0.9.3 (2011-01-31) ++++++++++++++++++ * Databook duplication leak fix. * HTML Table output. +* Added column sorting. 0.9.2 (2010-11-17) diff --git a/NOTICE b/NOTICE index 88d5d2d..c8428e8 100644 --- a/NOTICE +++ b/NOTICE @@ -1,6 +1,12 @@ Tablib includes some vendorized python libraries: ordereddict, pyyaml, simplejson, and xlwt. +Markup License +============== + +Markup is in the public domain. + + OrderedDict License =================== diff --git a/README.rst b/README.rst index 00b6345..f974248 100644 --- a/README.rst +++ b/README.rst @@ -18,6 +18,7 @@ Output formats supported: - Excel (Sets + Books) - JSON (Sets + Books) - YAML (Sets + Books) +- HTML (Sets) - TSV (Sets) - CSV (Sets) diff --git a/fabfile.py b/fabfile.py index 6e72092..391bf92 100644 --- a/fabfile.py +++ b/fabfile.py @@ -1,7 +1,7 @@ import os from fabric.api import * -os.f + def scrub(): """ Death to the bytecode! """ local('rm -fr dist build') diff --git a/setup.py b/setup.py index e779457..c851751 100644 --- a/setup.py +++ b/setup.py @@ -19,7 +19,7 @@ required = [] setup( name='tablib', - version='0.9.2', + version='0.9.3', description='Format agnostic tabular data library (XLS, JSON, YAML, CSV)', long_description=open('README.rst').read() + '\n\n' + open('HISTORY.rst').read(), diff --git a/tablib/core.py b/tablib/core.py index c7e9dd5..9d36970 100644 --- a/tablib/core.py +++ b/tablib/core.py @@ -10,13 +10,14 @@ """ from copy import copy +from operator import itemgetter from tablib import formats __title__ = 'tablib' -__version__ = '0.9.2' -__build__ = 0x000902 +__version__ = '0.9.3' +__build__ = 0x000903 __author__ = 'Kenneth Reitz' __license__ = 'MIT' __copyright__ = 'Copyright 2011 Kenneth Reitz' @@ -519,6 +520,7 @@ class Dataset(object): 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 `. @@ -528,6 +530,43 @@ class Dataset(object): return _dset + + def sort(self, col, reverse=False): + """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.""" + + if isinstance(col, basestring): + + if not self.headers: + raise HeadersNeeded + + _sorted = sorted(self.dict, key=itemgetter(col), reverse=reverse) + _dset = Dataset(headers=self.headers) + + for item in _sorted: + row = [item[key] for key in self.headers] + _dset.append(row=row) + + else: + if self.headers: + col = self.headers[col] + + _sorted = sorted(self.dict, key=itemgetter(col), reverse=reverse) + _dset = Dataset(headers=self.headers) + + for item in _sorted: + if self.headers: + row = [item[key] for key in self.headers] + else: + row = item + _dset.append(row=row) + + + return _dset + def transpose(self): """Transpose a :class:`Dataset`, turning rows into columns and vice versa, returning a new ``Dataset`` instance. The first row of the diff --git a/test_tablib.py b/test_tablib.py index 2d1f6b4..15630f2 100755 --- a/test_tablib.py +++ b/test_tablib.py @@ -425,7 +425,22 @@ class TablibTestCase(unittest.TestCase): self.assertEqual(column_stacked[0], ("John", "Adams", 90, "John", "Adams", 90)) + def test_sorting(self): + """Sort columns.""" + + sorted_data = self.founders.sort(col="first_name") + + first_row = sorted_data[0] + second_row = sorted_data[2] + third_row = sorted_data[1] + expected_first = self.founders[1] + expected_second = self.founders[2] + expected_third = self.founders[0] + + self.assertEqual(first_row, expected_first) + self.assertEqual(second_row, expected_second) + self.assertEqual(third_row, expected_third) def test_wipe(self): """Purge a dataset."""