[Checkins] SVN: z3c.batching/trunk/ Moved the advanced batching of z3c.table into a helper function of z3c.batching
Christophe Combelles
ccomb at free.fr
Sat Oct 11 07:24:17 EDT 2008
Log message for revision 92031:
Moved the advanced batching of z3c.table into a helper function of z3c.batching
Changed:
U z3c.batching/trunk/CHANGES.txt
U z3c.batching/trunk/setup.py
U z3c.batching/trunk/src/z3c/batching/README.txt
U z3c.batching/trunk/src/z3c/batching/batch.py
-=-
Modified: z3c.batching/trunk/CHANGES.txt
===================================================================
--- z3c.batching/trunk/CHANGES.txt 2008-10-10 23:25:42 UTC (rev 92030)
+++ z3c.batching/trunk/CHANGES.txt 2008-10-11 11:24:15 UTC (rev 92031)
@@ -2,6 +2,12 @@
CHANGES
=======
+1.1.0 (unreleased)
+------------------
+
+- Added a function to build a small neighbourhood list of the current batch,
+ from a large batch list. (extracted from z3c.table)
+
1.0.1 (2008-09-09)
------------------
Modified: z3c.batching/trunk/setup.py
===================================================================
--- z3c.batching/trunk/setup.py 2008-10-10 23:25:42 UTC (rev 92030)
+++ z3c.batching/trunk/setup.py 2008-10-11 11:24:15 UTC (rev 92031)
@@ -28,13 +28,14 @@
description='Batching',
long_description=(
read('README.txt')
- + '\n\n' +
- 'Detailed Dcoumentation\n' +
- '======================\n'
- + '\n\n' +
- read('src', 'z3c', 'batching', 'README.txt')
- + '\n\n' +
- read('CHANGES.txt')
+ + '\n\n'
+ + '======================\n'
+ + 'Detailed Documentation\n'
+ + '======================\n'
+ + '\n\n'
+ + read('src', 'z3c', 'batching', 'README.txt')
+ + '\n\n'
+ + read('CHANGES.txt')
),
keywords = "zope3 batching",
classifiers = [
Modified: z3c.batching/trunk/src/z3c/batching/README.txt
===================================================================
--- z3c.batching/trunk/src/z3c/batching/README.txt 2008-10-10 23:25:42 UTC (rev 92030)
+++ z3c.batching/trunk/src/z3c/batching/README.txt 2008-10-11 11:24:15 UTC (rev 92031)
@@ -1,12 +1,14 @@
-===============
+
+.. contents::
+
Simple Batching
-===============
+---------------
This module implements a simple batching mechanism that allows you to split a
large sequence into smaller batches. Let's start by creating a simple list,
which will be our full sequence:
-Batch on empty root
+Batch on empty root::
>>> from z3c.batching.batch import Batch
>>> batch = Batch([], size=3)
@@ -37,24 +39,24 @@
>>> sequence = ['one', 'two', 'three', 'four', 'five', 'six', 'seven',
... 'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen']
-We can now create a batch for this sequence. Let's make our batch size 3:
+We can now create a batch for this sequence. Let's make our batch size 3::
>>> batch = Batch(sequence, size=3)
The first argument to the batch is always the full sequence. If no start
-element is specified, the batch starts at the first element:
+element is specified, the batch starts at the first element::
>>> list(batch)
['one', 'two', 'three']
-The start index is commonly specified in the constructor though:
+The start index is commonly specified in the constructor though::
>>> batch = Batch(sequence, start=6, size=3)
>>> list(batch)
['seven', 'eight', 'nine']
Note that the start is an index and starts at zero. If the start index is
-greater than the largest index of the sequence, an index error is raised:
+greater than the largest index of the sequence, an index error is raised::
>>> Batch(sequence, start=15, size=3)
Traceback (most recent call last):
@@ -62,18 +64,18 @@
IndexError: start index key out of range
A batch implements the finite sequence interface and thus supports some
-standard methods. For example, you can ask the batch for its length:
+standard methods. For example, you can ask the batch for its length::
>>> len(batch)
3
Note that the length returns the true size of the batch, not the size we asked
-for:
+for::
>>> len(Batch(sequence, start=12, size=3))
1
-You can also get an element by index, which is relative to the batch:
+You can also get an element by index, which is relative to the batch::
>>> batch[0]
'seven'
@@ -82,7 +84,7 @@
>>> batch[2]
'nine'
-Slicing
+Slicing::
>>> batch[:1]
['seven']
@@ -100,14 +102,14 @@
[]
-If you ask for index that is out of range, an index error is raised:
+If you ask for index that is out of range, an index error is raised::
>>> batch[3]
Traceback (most recent call last):
...
IndexError: batch index out of range
-You can also iterate through the batch:
+You can also iterate through the batch::
>>> iterator = iter(batch)
>>> iterator.next()
@@ -117,7 +119,7 @@
>>> iterator.next()
'nine'
-Batch also implement some of IReadSequence interface
+Batch also implement some of IReadSequence interface::
>>> 'eight' in batch
True
@@ -135,48 +137,48 @@
True
Besides all of those common API methods, there are several properties that were
-designed to make your life simpler. The start and size are specified:
+designed to make your life simpler. The start and size are specified::
>>> batch.start
6
>>> batch.size
3
-The end index of the batch is immediately computed:
+The end index of the batch is immediately computed::
>>> batch.end
8
-The UI often requires that the number of the btach and the total number of
-batches is computed:
+The UI often requires that the number of the batch and the total number of
+batches is computed::
>>> batch.number
3
>>> batch.total
5
-You can also ask for the next batch:
+You can also ask for the next batch::
>>> batch.next
<Batch start=9, size=3>
-If the current batch is the last one, the next batch is None:
+If the current batch is the last one, the next batch is None::
>>> Batch(sequence, start=12, size=3).next is None
True
-The previous batch shows the previous batch:
+The previous batch shows the previous batch::
>>> batch.previous
<Batch start=3, size=3>
-If the current batch is the first one, the previous batch is None:
+If the current batch is the first one, the previous batch is None::
>>> Batch(sequence, start=0, size=3).previous is None
True
The final two properties deal with the elements within the batch. They ask for
-the first and last element of the batch:
+the first and last element of the batch::
>>> batch.firstElement
'seven'
@@ -185,13 +187,13 @@
'nine'
-Total batches
+Total batches::
>>> batch = Batch(sequence[:-1], size=3)
>>> batch.total
4
-We can get access to all batches
+We can get access to all batches::
>>> len(batch.batches)
4
@@ -213,19 +215,40 @@
>>> batch.batches[-2]
<Batch start=6, size=3>
-Slicing
+Slicing::
>>> batch.batches[:1]
[<Batch start=0, size=3>]
-
+
>>> batch.batches[:]
[<Batch start=0, size=3>, <Batch start=3, size=3>, <Batch start=6, size=3>, <Batch start=9, size=3>]
-
+
>>> batch.batches[1:2]
[<Batch start=3, size=3>]
-
+
>>> batch.batches[1:]
[<Batch start=3, size=3>, <Batch start=6, size=3>, <Batch start=9, size=3>]
>>> batch.batches[10:]
[]
+
+Batch neighbourhood of a large batch list
+-----------------------------------------
+
+When the full list of batches is too large to be displayed in a user interface,
+we want to display only a subset of all the batches.
+A helper function is provided for that purpose:
+
+First build a large sequence of batches (or anything else)::
+
+ >>> batches = range(100)
+
+Then extract only the first and last items, as well as the neighbourhood of the
+46th item (index = 45). We want 3 neighbours at the left, 5 at the right::
+
+ >>> from z3c.batching.batch import first_neighbours_last
+ >>> first_neighbours_last(batches, 45, 3, 5)
+ [0, None, 42, 43, 44, 45, 46, 47, 48, 49, 50, None, 99]
+
+'None' can be used to display a separator in a user interface (see z3c.table)
+
Modified: z3c.batching/trunk/src/z3c/batching/batch.py
===================================================================
--- z3c.batching/trunk/src/z3c/batching/batch.py 2008-10-10 23:25:42 UTC (rev 92030)
+++ z3c.batching/trunk/src/z3c/batching/batch.py 2008-10-11 11:24:15 UTC (rev 92031)
@@ -25,6 +25,8 @@
class Batch(object):
+ """Batch implementation. See IBatch"""
+
zope.interface.implements(interfaces.IBatch)
start = FieldProperty(interfaces.IBatch['start'])
@@ -146,6 +148,10 @@
class Batches(object):
+ """A sequence object representing all the batches.
+ Used by a Batch.
+ """
+
zope.interface.implements(IFiniteSequence)
def __init__(self, batch):
@@ -177,3 +183,126 @@
j = self.total-1
return [self[idx] for idx in range(i, j)]
+
+
+def first_neighbours_last(batches, currentBatchIdx, nb_left, nb_right):
+ """Build a sublist from a large batch list.
+
+ This is used to display batch links for a large table.
+
+ arguments:
+ * batches: a large sequence (may be a batches as well)
+ * currentBatchIdx: index of the current batch or item
+ * nb_left: number of neighbours before the current batch
+ * nb_right: number of neighbours after the current batch
+
+ The returned list gives:
+ * the first batch
+ * a None separator if necessary
+ * left neighbours of the current batch
+ * the current batch
+ * right neighbours of the current batch
+ * a None separator if necessary
+ * the last batch
+
+ Example::
+
+ >>> from z3c.batching.batch import first_neighbours_last as f_n_l
+ >>> batches = range(100) # it works with real batches as well
+
+ We try to get subsets at different levels::
+
+ >>> for i in range(0,6):
+ ... f_n_l(batches, i, 2, 2)
+ [0, 1, 2, None, 99]
+ [0, 1, 2, 3, None, 99]
+ [0, 1, 2, 3, 4, None, 99]
+ [0, 1, 2, 3, 4, 5, None, 99]
+ [0, None, 2, 3, 4, 5, 6, None, 99]
+ [0, None, 3, 4, 5, 6, 7, None, 99]
+
+ >>> for i in range(93, 99):
+ ... f_n_l(batches, i, 2, 2)
+ [0, None, 91, 92, 93, 94, 95, None, 99]
+ [0, None, 92, 93, 94, 95, 96, None, 99]
+ [0, None, 93, 94, 95, 96, 97, None, 99]
+ [0, None, 94, 95, 96, 97, 98, 99]
+ [0, None, 95, 96, 97, 98, 99]
+ [0, None, 96, 97, 98, 99]
+
+ Try with no previous and no next batch::
+
+ >>> f_n_l(batches, 0, 0, 0)
+ [0, None, 99]
+ >>> f_n_l(batches, 1, 0, 0)
+ [0, 1, None, 99]
+ >>> f_n_l(batches, 2, 0, 0)
+ [0, None, 2, None, 99]
+
+ Try with only 1 previous and 1 next batch::
+
+ >>> f_n_l(batches, 0, 1, 1)
+ [0, 1, None, 99]
+ >>> f_n_l(batches, 1, 1, 1)
+ [0, 1, 2, None, 99]
+ >>> f_n_l(batches, 2, 1, 1)
+ [0, 1, 2, 3, None, 99]
+ >>> f_n_l(batches, 3, 1, 1)
+ [0, None, 2, 3, 4, None, 99]
+
+ Try with incoherent values::
+
+ >>> f_n_l(batches, 0, -4, -10)
+ Traceback (most recent call last):
+ ...
+ AssertionError
+ >>> f_n_l(batches, 2000, 3, 3)
+ Traceback (most recent call last):
+ ...
+ AssertionError
+ """
+ sublist = []
+ # setup some batches and indexes
+ firstIdx = 0
+ lastIdx = len(batches) - 1
+ assert(currentBatchIdx >= 0 and currentBatchIdx <= lastIdx)
+ assert(nb_left >= 0 and nb_right >= 0)
+ prevIdx = currentBatchIdx - nb_left
+ nextIdx = currentBatchIdx + 1
+ firstBatch = batches[0]
+ lastBatch = batches[len(batches)-1]
+
+ # add first batch
+ if firstIdx < currentBatchIdx:
+ sublist.append(firstBatch)
+
+ # there must probably be space
+ if firstIdx + 1 < prevIdx:
+ # we skip batches between first batch and first previous batch
+ sublist.append(None)
+
+ # add previous batches
+ for i in range(prevIdx, prevIdx + nb_left):
+ if firstIdx < i:
+ # append previous batches
+ sublist.append(batches[i])
+
+ # add current batch
+ sublist.append(batches[currentBatchIdx])
+
+ # add next batches
+ for i in range(nextIdx, nextIdx + nb_right):
+ if i < lastIdx:
+ # append previous batch
+ sublist.append(batches[i])
+
+ # there must probably be space
+ if nextIdx + nb_right < lastIdx:
+ # we skip batches between last batch and last next batch
+ sublist.append(None)
+
+ # add last batch
+ if currentBatchIdx < lastIdx:
+ sublist.append(lastBatch)
+ return sublist
+
More information about the Checkins
mailing list