From 8d6e75ad20a2ae56ae7270ff7f4f8943af69e8db Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 4 Nov 2010 04:49:31 -0400 Subject: [PATCH 1/6] Fixes for 0.9.0. --- setup.py | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/setup.py b/setup.py index 50159a5..a5c5588 100644 --- a/setup.py +++ b/setup.py @@ -17,12 +17,9 @@ if sys.argv[-1] == "publish": required = [] -# if sys.version_info < (2, 6): -# required.append('simplejson') - setup( name='tablib', - version='0.8.5', + version='0.9.0', description='Format agnostic tabular data library (XLS, JSON, YAML, CSV)', long_description=open('README.rst').read() + '\n\n' + open('HISTORY.rst').read(), @@ -50,9 +47,4 @@ setup( # 'Programming Language :: Python :: 3.0', # 'Programming Language :: Python :: 3.1', ), - # entry_points={ - # 'console_scripts': [ - # 'tabbed = tablib.cli:start', - # ], - # } ) From f6964bba8f16d588836b6491e61ba7278c06f514 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 4 Nov 2010 04:49:37 -0400 Subject: [PATCH 2/6] Version bump. --- tablib/core.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tablib/core.py b/tablib/core.py index 7388370..07397c1 100644 --- a/tablib/core.py +++ b/tablib/core.py @@ -15,8 +15,8 @@ from tablib import formats __title__ = 'tablib' -__version__ = '0.8.5' -__build__ = 0x000805 +__version__ = '0.9.0' +__build__ = 0x000900 __author__ = 'Kenneth Reitz' __license__ = 'MIT' __copyright__ = 'Copyright 2010 Kenneth Reitz' From 642b1d8deffbc619f749a7d2685bc1dfb81f2c5f Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 4 Nov 2010 05:43:00 -0400 Subject: [PATCH 3/6] Exception documentation update. --- docs/api.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/api.rst b/docs/api.rst index 4a0ff52..942b69d 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -48,17 +48,17 @@ Exceptions .. class:: InvalidDatasetType - Raised when shit goes down. + You're trying to add something that doesn't quite look right. .. class:: InvalidDimensions - Raised when shit goes down. + You're trying to add something that doesn't quite fit right. .. class:: UnsupportedFormat - Raised when shit goes down. + You're trying to add something that doesn't quite taste right. Now, go start some :ref:`Tablib Development `. \ No newline at end of file From 49f098ee22f707050783ca0e991de9c563f4aae9 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 4 Nov 2010 05:43:23 -0400 Subject: [PATCH 4/6] Verb-age update for documentation. --- docs/index.rst | 4 +--- docs/intro.rst | 17 ++------------ docs/tutorial.rst | 60 ++++++++++++++++++++++++++++++----------------- 3 files changed, 41 insertions(+), 40 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index 87a8d3b..4a4de40 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -6,8 +6,6 @@ Tablib: Pythonic Tabular Data ============================= -Welcome to Tablib's documentation. - .. Contents: .. .. .. toctree:: @@ -22,7 +20,7 @@ Welcome to Tablib's documentation. .. * :ref:`search` -Tablib is a format-agnostic tabular dataset library, written in Python. It allows you to import, export, and manipulate tabular data sets. Oh, and it's :ref:`MIT Lisenced `. +Tablib is an :ref:`MIT Lisenced ` format-agnostic tabular dataset library, written in Python. It allows you to import, export, and manipulate tabular data sets. Advanced features include, segregation, dynamic columns, tags & filtering, and seamless format import & exmport. I recommend you start with :ref:`Installation `. diff --git a/docs/intro.rst b/docs/intro.rst index 616b3e1..a327d28 100644 --- a/docs/intro.rst +++ b/docs/intro.rst @@ -4,17 +4,7 @@ Introduction ============ This part of the documentation covers all the interfaces of Tablib. -Tablib is a format-agnostic tabular dataset library, written in Python. It allows you to Pythonically import, export, and manipulate tabular data sets. - - -Inception ---------- - -Tablib was build by `Kenneth Reitz`_ to fufill a specfic need. - -Tablib was born. - -.. _`Kenneth Reitz`: http://kennethreitz.com +Tablib is a format-agnostic tabular dataset library, written in Python. It allows you to Pythonically import, export, and manipulate tabular data sets. Advanced features include, segregation, dynamic columns, tags / filtering, and seamless format import/exmport. Philosphy @@ -29,10 +19,7 @@ Tablib was developed with a few :pep:`20` idioms in mind. #. Complex is better than complicated. #. Readability counts. -Besides, Why not? - -:ref:`seperators` - +All contributions to Tablib should keep these important rules in mind. .. _mit: diff --git a/docs/tutorial.rst b/docs/tutorial.rst index 0aa0f80..774158d 100644 --- a/docs/tutorial.rst +++ b/docs/tutorial.rst @@ -158,7 +158,7 @@ Let's find the average age. :: Removing Rows & Columns ----------------------- -:: +It's easier than you could imagine. :: >>> del data['Col Name'] @@ -166,9 +166,6 @@ Removing Rows & Columns >>> del data[0:12] -Fucking easy. - - ============== Advanced Usage @@ -180,6 +177,8 @@ This part of the documentation services to give you an idea that are otherwise h And now for something completely different. +.. _dyncols: + --------------- Dynamic Columns --------------- @@ -187,15 +186,8 @@ Dynamic Columns .. versionadded:: 0.8.3 Thanks to Josh Ourisman, Tablib now supports adding dynamic columns. A dynamic column is a single callable object (*ie.* a function). -For now, this is only supported on :class:`Dataset` objects that have no defined :class:`headers `. -So, let's save our headers for later, then remove them. :: - - _headers = list(data.headers) - data.headers = None - - -We can now add a dynamic column to our :class:`Dataset` object. In this example, we have a function that generates a random grade for our students. :: +Let's add a dynamic column to our :class:`Dataset` object. In this example, we have a function that generates a random grade for our students. :: import random @@ -203,12 +195,7 @@ We can now add a dynamic column to our :class:`Dataset` object. In this example, """Returns a random integer for entry.""" return (random.randint(60,100)/100.0) - data.append(col=[random_grade]) - - -Now add the headers back, with our new column. :: - - >>> data.headers = _headers + ['Grade'] + data.append(col=[random_grade], header='Grade') Let's have a look at our data. :: @@ -247,19 +234,48 @@ Adding this function to our dataset as a dynamic column would result in: :: - {Age: 20, First Name: Bessie, Gender: Female, Last Name: Monke} +.. _tags: +---------------------------- +Filtering Datasets with Tags +---------------------------- + +.. versionadded:: 0.9.0 + + +When constructing a :class:`Dataset` object, you can add tags to rows by speficying the ``tags`` parameter. +This allows you to filter your :class:`Dataset` later. This can be useful so seperate rows of data based on +arbitrary criteria (*e.g.* origin) that you don't want to include in your :class:`Dataset`. + +Let's tag some students. :: + + students = tablib.Dataset() + + students.headers = ['first', 'last'] + + students.append(['Kenneth', 'Reitz'], tags=['male', 'technical']) + students.append(['Bessie', 'Monke'], tags=['female', 'creative']) + +Now that we have extra meta-data on our rows, we can use easily filter our :class:`Dataset`. Let's just see Male students. :: + + + >>> data.filter(['male']).yaml + - {first: Kenneth, Last: Reitz} + +It's that simple. The original :class:`Dataset` is untouched. Excel Workbook With Multiple Sheets ------------------------------------ -:class:`Databook` +When dealine with a large number of :class:`Datasets ` in spreadsheet format, it's quite common to group mulitple spreadsheets into a single Excel file, known as a Workbook. Tablib makes it extremely easy to build webooks with the handy, :class:`Databook` class. + -:: +Let's say we have 3 different :class:`Datasets `. All we have to do is add then to a :class:`Databook` object... :: - book = tablib.Databook([data, data, data]) + book = tablib.Databook([data1, data2, data3]) -:: +... and export to Excel just like :class:`Datasets `. :: with open('students.xls', 'wb') as f: f.write(book.xls) From 52dcf79c41d34a4c8b7019e077400fff102e65cf Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 4 Nov 2010 05:43:44 -0400 Subject: [PATCH 5/6] No append documentation necessary. --- tablib/core.py | 48 ++++++++++++++++++++---------------------------- 1 file changed, 20 insertions(+), 28 deletions(-) diff --git a/tablib/core.py b/tablib/core.py index 07397c1..43bab93 100644 --- a/tablib/core.py +++ b/tablib/core.py @@ -415,30 +415,11 @@ class Dataset(object): Import assumes (for now) that headers exist. """ - + def append(self, row=None, col=None, header=None, tags=list()): - """Adds a row or column to the :class:`Dataset`. - - Rows and Columns appended must be the correct size (height or width). - - The default behaviour is to append the given row to the :class:`Dataset` object. If the ``col`` parameter is given, however, a new column will be added to the :class:`Dataset` object. If appending a column, and :class:`Dataset.headers` is set, the first item in list will be considered the header for that row. :: - - Append a new row to the dataset: :: - - data.append(('Kenneth', 'Reitz')) - - Append a new column to the dataset: :: - - data.append(col=('Age', 90, 67, 22)) - - You can also add 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. The callable can be written to perform calculations - on the current row. The callable receives a tuple representation of - the current data row as the first parameter. :: - - data.append(col=[random.choice]) + """Adds a row or column to the :class:`Dataset`. + Usage is :class:`Dataset.insert` for documentation. """ if row is not None: @@ -451,7 +432,7 @@ class Dataset(object): sep = (index, text) self._separators.append(sep) - + def append_separator(self, text='-'): """Adds a :ref:`seperator ` to the :class:`Dataset`.""" @@ -472,15 +453,26 @@ class Dataset(object): 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. If - inserting a column, and :class:`Dataset.headers` is set, the first item - in list will be considered the header for the inserted row. :: - + 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 ` to the row you are inserting. + This gives you the ability to :class:`filter ` your + :class:`Dataset` later. + """ if row: self._validate(row) @@ -512,7 +504,7 @@ class Dataset(object): def filter(self, tag): """Returns a new instance of the :class:`Dataset`, excluding any rows - that do not contain the given tags. + that do not contain the given :ref:`tags `. """ _dset = copy(self) _dset._data[:] = [row for row in self._data if row.has_tag(tag)] From dd24edcc24b375235dccdd7ce46606220f94c72a Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 4 Nov 2010 05:47:13 -0400 Subject: [PATCH 6/6] Big history update. --- HISTORY.rst | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index 0e895db..247552a 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -2,12 +2,15 @@ History ------- -?? -++ +0.9.0 (2010-11-04) +++++++++++++++++++ -* Massive documentation update -* Added column insert/delete support -* Added +* Massive documentation update! +* Tablib.org! +* Row taggins and Dataset filtering! +* Column insert/delete support +* Column append API change (header required) +* Internal Changes (Row object and use thereof) 0.8.5 (2010-10-06)