# -*- coding: utf-8 -*-
# vi:ts=4:et
#
# $Date: 2003/08/18 14:59:50 $
# $Revision: 1.3 $
# =====================================================

"""functional tools"""

# following recipes might help
# "Python Cookbook"
# o 17.11 "Wrapping an Unbounded Iterator"
# o 17.12 "Operating on Iterators"

import itertools


__all__ = [
           'Iterator',
           'drop',
           'take',
           ]

class Iterator(object):
    """functional tools
    """
    def take(self, *args):
        """"take" provides an interface nearly identical to itertools.islice.
        A subiterator limitied to the first n items of iterable's sequence
        """

        it = itertools.islice(iter(self), *args)
        for x in it:
            print x

    def drop(self, n):
        """A subiterator removing the first n items from iterable's sequence
        """
        iterable = iter(self)
        for i in range(n):
            try:
                iterable.next()
            except StopIteration:
                return

        while True:
            try:
                #yield iterable.next()
                print iterable.next()
            except StopIteration:
                return

    def last(self, n):
        """A subiterator limitied to the last n items of iterable's sequence
        """
        iterable = iter(self)
        num_of_drop = self.size() - n
        for i in range(num_of_drop):
            try:
                iterable.next()
            except StopIteration:
                return

        while True:
            try:
                #yield iterable.next()
                print iterable.next()
            except StopIteration:
                return


def take(iterable, *args):
    """A subiterator limitied to the first n items of iterable's sequence"""

    it = itertools.islice(iterable, *args)
    n = 0
    while True:
        yield it.next()


def drop(iterable, n):
    """A subiterator removing the first n items from
    iterable's sequence
    """
    for i in range(n):
        try:
            iterable.next()
        except StopIteration:
            return

    while True:
        try:
            yield iterable.next()
        except StopIteration:
            return


def _test():
    # test
    print "take"
    l = range(20)
    it = iter(l)
    for x in take(l, 5):
        print x

    print "slice"
    l = range(20)
    it = iter(l)
    for x in take(l, 3, 10, 2):
        print x


    print "drop"
    l = range(20)
    it = iter(l)
    for x in drop(it, 5):
        print x

if __name__ == '__main__':
    _test()

# The following sets edit modes for GNU EMACS
# Local Variables:
# mode:python
# End:

