mirror of
https://github.com/kennethreitz/tablib.git
synced 2026-06-05 23:10:17 +00:00
Merge branch 'release/0.9.0' into develop
This commit is contained in:
+8
-5
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
@@ -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)]
|
||||
|
||||
Reference in New Issue
Block a user