From f81dc41a57e19926868efa036bdb9e862cd3bbbb Mon Sep 17 00:00:00 2001 From: Luca Beltrame Date: Tue, 11 Jan 2011 20:53:59 +0100 Subject: [PATCH 1/7] Support for sorting. Unit-tested. --- tablib/core.py | 20 ++++++++++++++++++++ test_tablib.py | 15 +++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/tablib/core.py b/tablib/core.py index c7e9dd5..5727a69 100644 --- a/tablib/core.py +++ b/tablib/core.py @@ -10,6 +10,7 @@ """ from copy import copy +from operator import itemgetter from tablib import formats @@ -528,6 +529,25 @@ class Dataset(object): return _dset + def sort(self, col, reverse=False): + + """Sort a :class:`Dataset` by a specific column. The order can be + reversed by setting ``reverse`` to ``True``. Requires headers to be + set. Returns a new :class:`Dataset` instance where columns have been + sorted.""" + + 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) + + 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.""" From 0797ec67d4a4c6c145d86d0b7dca9d3b03c6d8e6 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Mon, 31 Jan 2011 00:58:16 -0500 Subject: [PATCH 2/7] Prepping for new release (0.9.3) --- HISTORY.rst | 3 ++- README.rst | 1 + tablib/core.py | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) 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/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/tablib/core.py b/tablib/core.py index c7e9dd5..6eb57db 100644 --- a/tablib/core.py +++ b/tablib/core.py @@ -15,8 +15,8 @@ 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' From 89b431213bc74f219da48489fbaabdd02bcfe56a Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Mon, 31 Jan 2011 01:28:10 -0500 Subject: [PATCH 3/7] Sorting update for headerless datasets. --- tablib/core.py | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/tablib/core.py b/tablib/core.py index 19eec3e..0de2b28 100644 --- a/tablib/core.py +++ b/tablib/core.py @@ -535,16 +535,32 @@ class Dataset(object): reversed by setting ``reverse`` to ``True``. Requires headers to be set. Returns a new :class:`Dataset` instance where columns have been sorted.""" + if isinstance(col, basestring): - if not self.headers: - raise HeadersNeeded + if not self.headers: + raise HeadersNeeded - _sorted = sorted(self.dict, key=itemgetter(col), reverse=reverse) - _dset = Dataset(headers=self.headers) + _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) - for item in _sorted: - row = [item[key] for key in self.headers] - _dset.append(row=row) return _dset From a0822bc9b091ca6b613aac71afc39acf0665a1e1 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Mon, 31 Jan 2011 01:29:41 -0500 Subject: [PATCH 4/7] sorting update. --- tablib/core.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tablib/core.py b/tablib/core.py index 0de2b28..9d36970 100644 --- a/tablib/core.py +++ b/tablib/core.py @@ -520,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 `. @@ -529,12 +530,14 @@ class Dataset(object): return _dset - def sort(self, col, reverse=False): - """Sort a :class:`Dataset` by a specific column. The order can be - reversed by setting ``reverse`` to ``True``. Requires headers to be - set. Returns a new :class:`Dataset` instance where columns have been + 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: From e8b44b57779b6374fbee3e5dc2b7dc1091e1cf5c Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Mon, 31 Jan 2011 01:33:00 -0500 Subject: [PATCH 5/7] Version bump. --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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(), From 5379c5683d9cb7c07f7619e544c0c2fc4efa80b1 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Mon, 31 Jan 2011 01:33:12 -0500 Subject: [PATCH 6/7] Markup license notice. PD? Really? --- NOTICE | 6 ++++++ 1 file changed, 6 insertions(+) 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 =================== From 140736ff332ff164f18821ec150488b1a2092898 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Mon, 31 Jan 2011 01:34:40 -0500 Subject: [PATCH 7/7] fabfile typo. --- fabfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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')