1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
1 ##############################################################################
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
2 #
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
3 # Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
4 #
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
5 # This software is subject to the provisions of the Zope Public License,
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
6 # Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
7 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
10 # FOR A PARTICULAR PURPOSE
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
11 #
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
12 ##############################################################################
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
13 __doc__='''Batch class, for iterating over a sequence in batches
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
14
|
|
2005
|
15 $Id: Batch.py,v 1.3 2004-02-11 23:55:09 richard Exp $'''
|
|
|
16 __docformat__ = 'restructuredtext'
|
|
|
17 __version__='$Revision: 1.3 $'[11:-2]
|
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
18
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
19 class LazyPrevBatch:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
20 def __of__(self, parent):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
21 return Batch(parent._sequence, parent._size,
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
22 parent.first - parent._size + parent.overlap, 0,
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
23 parent.orphan, parent.overlap)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
24
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
25 class LazyNextBatch:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
26 def __of__(self, parent):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
27 try: parent._sequence[parent.end]
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
28 except IndexError: return None
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
29 return Batch(parent._sequence, parent._size,
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
30 parent.end - parent.overlap, 0,
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
31 parent.orphan, parent.overlap)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
32
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
33 class LazySequenceLength:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
34 def __of__(self, parent):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
35 parent.sequence_length = l = len(parent._sequence)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
36 return l
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
37
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
38 class Batch:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
39 """Create a sequence batch"""
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
40 __allow_access_to_unprotected_subobjects__ = 1
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
41
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
42 previous = LazyPrevBatch()
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
43 next = LazyNextBatch()
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
44 sequence_length = LazySequenceLength()
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
45
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
46 def __init__(self, sequence, size, start=0, end=0,
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
47 orphan=0, overlap=0):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
48 '''Encapsulate "sequence" in batches of "size".
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
49
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
50 Arguments: "start" and "end" are 0-based indexes into the
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
51 sequence. If the next batch would contain no more than
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
52 "orphan" elements, it is combined with the current batch.
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
53 "overlap" is the number of elements shared by adjacent
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
54 batches. If "size" is not specified, it is computed from
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
55 "start" and "end". Failing that, it is 7.
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
56
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
57 Attributes: Note that the "start" attribute, unlike the
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
58 argument, is a 1-based index (I know, lame). "first" is the
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
59 0-based index. "length" is the actual number of elements in
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
60 the batch.
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
61
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
62 "sequence_length" is the length of the original, unbatched, sequence
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
63 '''
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
64
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
65 start = start + 1
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
66
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
67 start,end,sz = opt(start,end,size,orphan,sequence)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
68
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
69 self._sequence = sequence
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
70 self.size = sz
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
71 self._size = size
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
72 self.start = start
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
73 self.end = end
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
74 self.orphan = orphan
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
75 self.overlap = overlap
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
76 self.first = max(start - 1, 0)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
77 self.length = self.end - self.first
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
78 if self.first == 0:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
79 self.previous = None
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
80
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
81
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
82 def __getitem__(self, index):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
83 if index < 0:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
84 if index + self.end < self.first: raise IndexError, index
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
85 return self._sequence[index + self.end]
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
86
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
87 if index >= self.length: raise IndexError, index
|
1120
c26471971d18
Exposed the Batch mechanism through the top-level "utils" variable.
Richard Jones <richard@users.sourceforge.net>
diff
changeset
|
88 return self._sequence[index + self.first]
|
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
89
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
90 def __len__(self):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
91 return self.length
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
92
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
93 def opt(start,end,size,orphan,sequence):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
94 if size < 1:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
95 if start > 0 and end > 0 and end >= start:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
96 size=end+1-start
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
97 else: size=7
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
98
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
99 if start > 0:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
100
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
101 try: sequence[start-1]
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
102 except IndexError: start=len(sequence)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
103
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
104 if end > 0:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
105 if end < start: end=start
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
106 else:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
107 end=start+size-1
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
108 try: sequence[end+orphan-1]
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
109 except IndexError: end=len(sequence)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
110 elif end > 0:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
111 try: sequence[end-1]
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
112 except IndexError: end=len(sequence)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
113 start=end+1-size
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
114 if start - 1 < orphan: start=1
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
115 else:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
116 start=1
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
117 end=start+size-1
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
118 try: sequence[end+orphan-1]
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
119 except IndexError: end=len(sequence)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
120 return start,end,size
|