Merge branch 'release/0.9.0' into develop

This commit is contained in:
Kenneth Reitz
2010-11-04 05:47:36 -04:00
7 changed files with 75 additions and 87 deletions
+8 -5
View File
@@ -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)
+3 -3
View File
@@ -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 <development>`.
+1 -3
View File
@@ -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 <mit>`.
Tablib is an :ref:`MIT Lisenced <mit>` 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 <install>`.
+2 -15
View File
@@ -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:
+38 -22
View File
@@ -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 <Dataset.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 <Dataset>` 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 <Dataset>`. 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 <Dataset>`. ::
with open('students.xls', 'wb') as f:
f.write(book.xls)
+1 -9
View File
@@ -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',
# ],
# }
)
+22 -30
View File
@@ -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'
@@ -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 <seperators>` 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 <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)
@@ -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 <tags>`.
"""
_dset = copy(self)
_dset._data[:] = [row for row in self._data if row.has_tag(tag)]