# -*- coding: utf-8 -*-
# q1011_answer_2.py
# 使用した Python のバージョン:
# ・Python(Python 2.7.3)/Python3(Python 3.2.3)
# 工夫した点・苦労した点・感想等(ご自由にお書きください):
# ・インスタンス変数 _cache を導入し、オリジナルの it の生成結果を保持するようにしました。
# 必要に応じてここに import 文を挿入してもOKです。
# 例:import itertools
class IteratorCloner:
def __init__(self, it):
self._it = iter(it)
self._cache = []
def get_clone(self):
index = 0
while True:
if len(self._cache) <= index:
next_val = next(self._it)
self._cache.append(next_val)
yield self._cache[index]
index += 1
# ※これ以降は変更しないこと。
if __name__ == '__main__':
import unittest
import random
from itertools import islice, takewhile
def rand_enum():
while True:
# 1〜20の整数値をランダムに列挙
yield random.randint(1, 20)
def fib():
a, b = 0, 1
while True:
yield b
a, b = b, a + b
def take_10(it):
return list(islice(it, 10))
def take_under_100(it):
return list(takewhile(lambda n: n < 100, it))
class IteratorClonerTest(unittest.TestCase):
def setUp(self):
self.cloner = IteratorCloner(fib())
def test_fib_clone1(self):
fib = self.cloner.get_clone()
expected = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
result = take_under_100(fib)
self.assertEqual(result, expected)
def test_fib_clone2(self):
fib1 = self.cloner.get_clone()
fib2 = self.cloner.get_clone()
expected = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
result1 = take_10(fib1) # dispose
result2 = take_under_100(fib2)
self.assertEqual(result2, expected)
def test_fib_cloneN(self):
expected = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
result = None
# 3回以上10回以下のランダム回数繰り返す
for i in range(random.randint(3, 10)):
result = take_under_100(self.cloner.get_clone())
self.assertEqual(result, expected)
def test_rand_enum(self):
cloner = IteratorCloner(rand_enum())
expected = take_10(cloner.get_clone())
result = take_10(cloner.get_clone())
self.assertEqual(result, expected)
# run tests
unittest.main()