#!/usr/bin/env python2
"""
iterators.py: Simple iterators
"""
from __future__ import print_function

import os

from mycpp import mylib
from mycpp.mylib import log, iteritems

from typing import Iterator, Tuple


def g(n):
  # type: (int) -> Iterator[Tuple[int, str]]
  for i in f(n):
    yield (i, '2 * %d = %d' % (i, 2*i))


def f(n):
  # type: (int) -> Iterator[int]
  for i in xrange(0, n):
    yield i


class Foo(object):

  def __init__(self):
    # type: () -> None
    pass

  def bar(self, n):
    # type: (int) -> Iterator[int]
    for i in xrange(0, n):
      yield i

  def baz(self, n):
    # type: (int) -> Iterator[Tuple[int, str]]
    it_g = g(n)
    while True:
      try:
        yield it_g.next()
      except StopIteration:
        break


def run_tests():
  # type: () -> None
  log('--- simple iterators')
  for i in f(3):
    log("f() gave %d", i)

  foo = Foo()
  for i in foo.bar(4):
    log("Foo.bar() gave %d", i)

  log('--- nested iterators')
  for i, s in g(3):
    log("g() gave (%d, %r)", i, s)

  for i, s in foo.baz(3):
    log("Foo.baz() gave (%d, %r)", i, s)

  for i in f(3):
    for j in f(3):
      log("f() gave %d, %d", i, j)

  log('--- iterator assignment')
  it_f = f(5)
  while True:
    try:
      log("next(f()) gave %d", it_f.next())
    except StopIteration:
      break

  it_g = g(5)
  while True:
    try:
      i, s = it_g.next()
      log("next(g()) gave (%d, %r)", i, s)
    except StopIteration:
      break


def run_benchmarks():
  # type: () -> None
  pass


if __name__ == '__main__':
  if os.getenv('BENCHMARK'):
    log('Benchmarking...')
    run_benchmarks()
  else:
    run_tests()
