Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Z
Zope
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
Zope
Commits
53190b64
Commit
53190b64
authored
Dec 12, 2001
by
Evan Simpson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Handle Python 2.2 iterators, implement first() and last().
parent
661377e7
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
213 additions
and
19 deletions
+213
-19
lib/python/ZTUtils/Iterator.py
lib/python/ZTUtils/Iterator.py
+119
-17
lib/python/ZTUtils/tests/testIterator.py
lib/python/ZTUtils/tests/testIterator.py
+94
-2
No files found.
lib/python/ZTUtils/Iterator.py
View file @
53190b64
...
...
@@ -12,8 +12,14 @@
##############################################################################
__doc__
=
'''Iterator class
$Id: Iterator.py,v 1.3 2001/11/28 15:51:22 matt Exp $'''
__version__
=
'$Revision: 1.3 $'
[
11
:
-
2
]
Unlike the builtin iterators of Python 2.2+, these classes are
designed to maintain information about the state of an iteration.
The Iterator() function accepts either a sequence or a Python
iterator. The next() method fetches the next item, and returns
true if it succeeds.
$Id: Iterator.py,v 1.4 2001/12/12 02:21:56 evan Exp $'''
__version__
=
'$Revision: 1.4 $'
[
11
:
-
2
]
import
string
...
...
@@ -21,21 +27,39 @@ class Iterator:
'''Simple Iterator class'''
__allow_access_to_unprotected_subobjects__
=
1
nextIndex
=
0
def
__init__
(
self
,
seq
):
self
.
seq
=
seq
self
.
nextIndex
=
0
if
hasattr
(
seq
,
'next'
):
inner
=
iterInner
else
:
inner
=
seqInner
self
.
_inner
=
inner
self
.
_prep_next
=
inner
.
prep_next
def
__getattr__
(
self
,
name
):
try
:
inner
=
getattr
(
self
.
_inner
,
'it_'
+
name
)
except
AttributeError
:
raise
AttributeError
,
name
return
inner
(
self
)
def
next
(
self
):
i
=
self
.
nextIndex
try
:
self
.
seq
[
i
]
except
IndexError
:
if
not
(
hasattr
(
self
,
'_next'
)
or
self
.
_prep_next
(
self
)):
return
0
self
.
index
=
i
self
.
index
=
i
=
self
.
nextIndex
self
.
nextIndex
=
i
+
1
self
.
_advance
(
self
)
return
1
def
_advance
(
self
,
it
):
self
.
item
=
self
.
_next
del
self
.
_next
del
self
.
end
self
.
_advance
=
self
.
_inner
.
advance
self
.
start
=
1
def
number
(
self
):
return
self
.
nextIndex
def
even
(
self
):
return
not
self
.
index
%
2
...
...
@@ -67,16 +91,94 @@ class Iterator:
def
roman
(
self
,
lower
=
string
.
lower
):
return
lower
(
self
.
Roman
())
def
start
(
self
):
return
self
.
nextIndex
==
1
def
first
(
self
,
name
=
None
):
if
self
.
start
:
return
1
return
not
self
.
same_part
(
name
,
self
.
_last
,
self
.
item
)
def
last
(
self
,
name
=
None
):
if
self
.
end
:
return
1
return
not
self
.
same_part
(
name
,
self
.
item
,
self
.
_next
)
def
same_part
(
self
,
name
,
ob1
,
ob2
):
if
name
is
None
:
return
ob1
==
ob2
no
=
[]
return
getattr
(
ob1
,
name
,
no
)
==
getattr
(
ob2
,
name
,
no
)
is
not
no
def
__iter__
(
self
):
return
IterIter
(
self
)
class
InnerBase
:
'''Base Inner class for Iterators'''
# Prep sets up ._next and .end
def
prep_next
(
self
,
it
):
it
.
next
=
self
.
no_next
it
.
end
=
1
return
0
def
end
(
self
):
try
:
self
.
seq
[
self
.
nextIndex
]
except
IndexError
:
return
1
# Advance knocks them down
def
advance
(
self
,
it
):
it
.
_last
=
it
.
item
it
.
item
=
it
.
_next
del
it
.
_next
del
it
.
end
it
.
start
=
0
def
no_next
(
self
,
it
):
return
0
def
item
(
self
):
return
self
.
seq
[
self
.
index
]
def
it_end
(
self
,
it
):
if
hasattr
(
it
,
'_next'
):
return
0
return
not
self
.
prep_next
(
it
)
def
length
(
self
):
return
len
(
self
.
seq
)
class
SeqInner
(
InnerBase
):
'''Inner class for sequence Iterators'''
def
prep_next
(
self
,
it
):
i
=
it
.
nextIndex
try
:
it
.
_next
=
it
.
seq
[
i
]
except
IndexError
:
it
.
_prep_next
=
self
.
no_next
it
.
end
=
1
return
0
it
.
end
=
0
return
1
def
it_length
(
self
,
it
):
it
.
length
=
l
=
len
(
it
.
seq
)
return
l
try
:
StopIteration
=
StopIteration
except
NameError
:
StopIteration
=
"StopIteration"
class
IterInner
(
InnerBase
):
'''Iterator inner class for Python iterators'''
def
prep_next
(
self
,
it
):
try
:
it
.
_next
=
it
.
seq
.
next
()
except
StopIteration
:
it
.
_prep_next
=
self
.
no_next
it
.
end
=
1
return
0
it
.
end
=
0
return
1
class
IterIter
:
def
__init__
(
self
,
it
):
self
.
it
=
it
self
.
skip
=
it
.
nextIndex
>
0
and
not
it
.
end
def
next
(
self
):
it
=
self
.
it
if
self
.
skip
:
self
.
skip
=
0
return
it
.
item
if
it
.
next
():
return
it
.
item
raise
StopIteration
seqInner
=
SeqInner
()
iterInner
=
IterInner
()
lib/python/ZTUtils/tests/testIterator.py
View file @
53190b64
...
...
@@ -2,6 +2,12 @@ import os, sys, unittest
from
ZTUtils
import
Iterator
try
:
iter
do_piter_test
=
1
except
NameError
:
do_piter_test
=
0
class
IteratorTests
(
unittest
.
TestCase
):
def
testIterator0
(
self
):
...
...
@@ -12,12 +18,98 @@ class IteratorTests(unittest.TestCase):
it
=
Iterator
((
1
,))
assert
it
.
next
()
and
not
it
.
next
(),
"Single-element iterator"
def
testIterator
2
(
self
):
def
testIterator
Many
(
self
):
it
=
Iterator
(
'text'
)
for
c
in
'text'
:
assert
it
.
next
(),
"Multi-element iterator"
assert
not
it
.
next
(),
"Multi-element iterator"
def
testStart
(
self
):
for
size
in
range
(
4
):
it
=
Iterator
(
range
(
size
+
1
))
it
.
next
()
assert
it
.
start
,
"Start true on element 1 of %s"
%
(
size
+
1
)
el
=
1
while
it
.
next
():
el
=
el
+
1
assert
not
it
.
start
,
(
"Start false on element %s of %s"
%
(
el
,
size
+
1
))
def
testEnd
(
self
):
for
size
in
range
(
4
):
size
=
size
+
1
it
=
Iterator
(
range
(
size
))
el
=
0
while
it
.
next
():
el
=
el
+
1
if
el
==
size
:
assert
it
.
end
,
"End true on element %s"
%
size
else
:
assert
not
it
.
end
,
(
"End false on element %s of %s"
%
(
el
,
size
))
def
testIndex
(
self
):
it
=
Iterator
(
range
(
5
))
for
el
in
range
(
5
):
assert
it
.
next
(),
"Iterator stopped too soon"
assert
it
.
index
==
el
,
"Incorrect index"
assert
it
.
number
()
==
el
+
1
,
"Incorrect number"
assert
it
.
item
==
el
,
"Incorrect item"
def
testFirstLast
(
self
):
it
=
Iterator
([
1
])
it
.
next
()
assert
it
.
first
()
==
it
.
last
()
==
1
,
"Bad first/last on singleton"
four
=
range
(
4
)
for
a
in
2
,
3
:
for
b
in
four
:
for
c
in
four
:
s
=
'a'
*
a
+
'b'
*
b
+
'c'
*
c
it
=
Iterator
(
s
)
it
.
next
()
assert
it
.
first
(),
"First element not first()"
last
=
s
[
0
]
lastlast
=
it
.
last
()
while
it
.
next
():
assert
((
it
.
item
!=
last
)
==
it
.
first
()),
(
"first() error"
)
assert
((
it
.
item
!=
last
)
==
lastlast
),
(
"last() error"
%
(
it
.
item
,
last
,
lastlast
))
last
=
it
.
item
lastlast
=
it
.
last
()
assert
lastlast
,
"Last element not last()"
if
do_piter_test
:
def
testIterOfIter
(
self
):
for
i
in
range
(
4
):
r
=
range
(
i
)
it1
=
Iterator
(
r
)
it2
=
Iterator
(
iter
(
r
))
while
it1
.
next
()
and
it2
.
next
():
assert
it1
.
item
==
it2
.
item
,
"Item mismatch with iter()"
assert
it1
.
index
==
it2
.
index
,
(
"Index mismatch with iter()"
)
assert
not
(
it1
.
next
()
or
it2
.
next
()),
(
"Length mismatch with iter()"
)
def
testIterIter
(
self
):
wo_iter
=
map
(
lambda
x
:(
x
,
x
),
range
(
4
))
for
i
in
range
(
4
):
r
=
range
(
i
)
w_iter
=
[]
it
=
Iterator
(
r
)
for
x
in
it
:
w_iter
.
append
((
x
,
it
.
index
))
assert
w_iter
==
wo_iter
[:
i
],
(
"for-loop failure on full iterator"
)
it
=
Iterator
(
range
(
4
))
it
.
next
();
it
.
next
();
it
.
next
()
w_iter
=
[]
for
x
in
it
:
w_iter
.
append
((
x
,
it
.
index
))
assert
w_iter
==
wo_iter
[
2
:],
"for-loop failure on half iteration"
def
test_suite
():
return
unittest
.
makeSuite
(
IteratorTests
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment