diff --git a/docs/api.rst b/docs/api.rst index ce169b7..4a0ff52 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -1,8 +1,10 @@ .. _api: +=== API === + .. module:: tablib This part of the documentation covers all the interfaces of Tablib. For @@ -10,18 +12,53 @@ parts where Tablib depends on external libraries, we document the most important right here and provide links to the canonical documentation. +-------------- Dataset Object -------------- + + .. autoclass:: Dataset :inherited-members: +--------------- Databook Object --------------- + .. autoclass:: Databook :inherited-members: +--------- +Functions +--------- + + +.. autofunction:: detect + +.. autofunction:: import_set + + +---------- +Exceptions +---------- + + +.. class:: InvalidDatasetType + + Raised when shit goes down. + + +.. class:: InvalidDimensions + + Raised when shit goes down. + + +.. class:: UnsupportedFormat + + Raised when shit goes down. + + Now, go start some :ref:`Tablib Development `. \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index ff757a6..5dcc564 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -44,7 +44,7 @@ This part of the documentation, which is mostly prose, begins with some backgrou .. toctree:: :maxdepth: 2 - quickstart + tutorial .. toctree:: :maxdepth: 2 diff --git a/docs/quickstart.rst b/docs/tutorial.rst similarity index 62% rename from docs/quickstart.rst rename to docs/tutorial.rst index ae113a4..cfede22 100644 --- a/docs/quickstart.rst +++ b/docs/tutorial.rst @@ -1,7 +1,10 @@ .. _quickstart: + +========== Quickstart ========== + .. module:: tablib @@ -15,9 +18,13 @@ First, make sure that: Lets gets started with some simple use cases and examples. + + +------------------ Creating a Dataset ------------------ + A :class:`Dataset ` is nothing more than what its name implies—a set of data. Creating your own instance of the :class:`tablib.Dataset` object is simple. :: @@ -31,9 +38,12 @@ You can now start filling this :class:`Dataset ` object with dat From here on out, if you see ``data``, assume that it's a fresh :class:`Dataset ` object. + +----------- Adding Rows ----------- + Let's say you want to collect a simple list of names. :: # collection of names @@ -52,9 +62,12 @@ You can get a nice, Pythonic view of the dataset at any time with :class:`Datase [('Kenneth', 'Reitz'), ('Bessie', 'Monke')] + +-------------- Adding Headers -------------- + It's time enhance our :class:`Dataset` by giving our columns some titles. To do so, set :class:`Dataset.headers`. :: data.headers = ['First Name', 'Last Name'] @@ -66,9 +79,14 @@ Let's view the data in YAML this time. :: - {First Name: Bessie, Last Name: Monke} + + + +-------------- Adding Columns -------------- + Now that we have a basic :class:`Dataset` in place, let's add a column of **ages** to it. :: data.append(col=['Age', 22, 20]) @@ -82,9 +100,13 @@ Let's view the data in CSV this time. :: It's that easy. + + +------------------------ Selecting Rows & Columns ------------------------ + You can slice and dice your data, just like a standard Python list. :: >>> data[0] @@ -105,64 +127,97 @@ Let's find the average age. :: +----------------------- +Removing Rows & Columns +----------------------- + +data.insert('MI', ) + +>>> del data['Row Name'] +Fucking easy. + + + +============== +Advanced Usage +============== + +And now for something completely different. + +--------------- Dynamic Columns --------------- .. versionadded:: 0.8.3 -Thanks to Josh Ourisman, Tablib now supports adding dynamic columns. For now, this is only supported on :class:`Dataset` objects that have no defined :class:`headers `. +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 `. -Let's save our headers for later. :: +So, let's save our headers for later, then remove them. :: _headers = list(data.headers) data.headers = None -test :: + +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. :: import random - def random_grade(*args): + def random_grade(row): """Returns a random integer for entry.""" return (random.randint(60,100)/100.0) data.append(col=[random_grade]) -:: - >>> data.yaml - - [Reitz, Kenneth, 22, 0.83] - - [Monke, Bessie, 21, 0.73] +Now add the headers back, with our new column. :: -Now we can add our headers back. -:: >>> data.headers = _headers + ['Random'] -Let's delete that column. +Let's have a look at our data. :: + + >>> data.yaml + - {Age: 22, First Name: Kenneth, Grade: 0.6, Last Name: Reitz} + - {Age: 21, First Name: Bessie, Grade: 0.75, Last Name: Monke} + + +Let's remove that column. :: -:: >>> del data['Grade'] +When you add a dynamic column, the first argument that is passed in to the given callable is the current data row. You can use this to perform calculations against your data row. + +For example, we can use the data available in the row to guess the gender of a student. :: + + def guess_gender(row): + """Calculates gender of given student data row.""" + m_names = ('Kenneth', 'Mike', 'Yuri') + f_names = ('Bessie', 'Samantha', 'Heather') + + name = row[0] + + if name in m_names: + return 'Male' + elif name in f_names: + return 'Female' + else: + return 'Unknown' + +Adding this function to our dataset as a dynamic column would result in: :: + + >>> data.yaml + - {Age: 22, First Name: Kenneth, Gender: Male, Last Name: Reitz} + - {Age: 21, First Name: Bessie, Gender: Female, Last Name: Monke} + + + .. _seperators: +---------- Seperators ---------- - - - -Transposition -------------- - -Thanks to Luca Beltrame, :class:`Dataset` objects -:: - - data.transpose() - - -Shortcuts ---------- - -Population upon instantiation. +.. versionadded:: 0.8.2 Now, go check out the :ref:`API Documentation ` or begin :ref:`Tablib Development `. \ No newline at end of file diff --git a/tablib/core.py b/tablib/core.py index 3bfc312..6e5e60b 100644 --- a/tablib/core.py +++ b/tablib/core.py @@ -96,7 +96,9 @@ class Dataset(object): def __delitem__(self, key): if isinstance(key, basestring): + if key in self.headers: + pos = self.headers.index(key) del self.headers[pos] @@ -352,9 +354,11 @@ class Dataset(object): 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. :: + 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.randint) + data.append(col=[random.choice]) """ if row is not None: self._validate(row)