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
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
15 $Id: Batch.py,v 1.1 2002-09-05 00:37:09 richard Exp $'''
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
16 __version__='$Revision: 1.1 $'[11:-2]
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
17
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
18 class LazyPrevBatch:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
19 def __of__(self, parent):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
20 return Batch(parent._sequence, parent._size,
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
21 parent.first - parent._size + parent.overlap, 0,
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
22 parent.orphan, parent.overlap)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
23
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
24 class LazyNextBatch:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
25 def __of__(self, parent):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
26 try: parent._sequence[parent.end]
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
27 except IndexError: return None
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
28 return Batch(parent._sequence, parent._size,
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
29 parent.end - parent.overlap, 0,
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
30 parent.orphan, parent.overlap)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
31
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
32 class LazySequenceLength:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
33 def __of__(self, parent):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
34 parent.sequence_length = l = len(parent._sequence)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
35 return l
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
36
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
37 class Batch:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
38 """Create a sequence batch"""
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
39 __allow_access_to_unprotected_subobjects__ = 1
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
40
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
41 previous = LazyPrevBatch()
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
42 next = LazyNextBatch()
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
43 sequence_length = LazySequenceLength()
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
44
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
45 def __init__(self, sequence, size, start=0, end=0,
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
46 orphan=0, overlap=0):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
47 '''Encapsulate "sequence" in batches of "size".
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
48
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
49 Arguments: "start" and "end" are 0-based indexes into the
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
50 sequence. If the next batch would contain no more than
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
51 "orphan" elements, it is combined with the current batch.
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
52 "overlap" is the number of elements shared by adjacent
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
53 batches. If "size" is not specified, it is computed from
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
54 "start" and "end". Failing that, it is 7.
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
55
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
56 Attributes: Note that the "start" attribute, unlike the
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
57 argument, is a 1-based index (I know, lame). "first" is the
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
58 0-based index. "length" is the actual number of elements in
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
59 the batch.
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
60
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
61 "sequence_length" is the length of the original, unbatched, sequence
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
62 '''
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
63
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
64 start = start + 1
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
65
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
66 start,end,sz = opt(start,end,size,orphan,sequence)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
67
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
68 self._sequence = sequence
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
69 self.size = sz
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
70 self._size = size
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
71 self.start = start
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
72 self.end = end
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
73 self.orphan = orphan
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
74 self.overlap = overlap
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
75 self.first = max(start - 1, 0)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
76 self.length = self.end - self.first
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
77 if self.first == 0:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
78 self.previous = None
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
79
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
80
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
81 def __getitem__(self, index):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
82 if index < 0:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
83 if index + self.end < self.first: raise IndexError, index
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
84 return self._sequence[index + self.end]
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
85
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
86 if index >= self.length: raise IndexError, index
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
87 return self._sequence[index+self.first]
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
88
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
89 def __len__(self):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
90 return self.length
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
91
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
92 def opt(start,end,size,orphan,sequence):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
93 if size < 1:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
94 if start > 0 and end > 0 and end >= start:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
95 size=end+1-start
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
96 else: size=7
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
97
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
98 if start > 0:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
99
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
100 try: sequence[start-1]
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
101 except IndexError: start=len(sequence)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
102
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
103 if end > 0:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
104 if end < start: end=start
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
105 else:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
106 end=start+size-1
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
107 try: sequence[end+orphan-1]
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
108 except IndexError: end=len(sequence)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
109 elif end > 0:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
110 try: sequence[end-1]
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
111 except IndexError: end=len(sequence)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
112 start=end+1-size
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
113 if start - 1 < orphan: start=1
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
114 else:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
115 start=1
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
116 end=start+size-1
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
117 try: sequence[end+orphan-1]
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
118 except IndexError: end=len(sequence)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
119 return start,end,size
|