class iterator_counter (object):
    def __init__ (self, start=0, stop=None, by=1):
        self._value = start
        self._stop = stop
        self._by = by

    def __iter__ (self):
        return self

    def next (self):
        val = self._value
        if self._stop is not None and val >= self._stop:
            raise StopIteration
        self._value += self._by
        return val

def generator_counter (start=0, stop=None, by=1):
    if stop is None:
        while True:
            yield start
            start += by
    else:
        while start < stop:
            yield start
            start += by

class more_efficient_iterator_counter (object):

    def __init__ (self, start=0, stop=None, by=1):
        self._value = start
        self._by = by
        if stop is None:
            self._next = self._next_no_stop
        else:
            self._next = self._next_with_stop
            self._stop = stop

    def __iter__ (self):
        return self

    def next (self):
        return self._next()

    def _next_no_stop (self):
        val = self._value
        self._value += self._by
        return val

    def _next_with_stop (self):
        val = self._value
        if val >= self._stop:
            raise StopIteration
        self._value += self._by
        return val
