From b9e9ff1288d9cf2bddbab7e43b7ad8b7eb827870 Mon Sep 17 00:00:00 2001 From: Tim Peters Date: Sun, 24 Jun 2001 03:44:52 +0000 Subject: [PATCH] More tests. --- Lib/test/test_generators.py | 69 ++++++++++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_generators.py b/Lib/test/test_generators.py index 947697a84c4..f3cba567720 100644 --- a/Lib/test/test_generators.py +++ b/Lib/test/test_generators.py @@ -5,6 +5,10 @@ Let's try a simple generator: ... yield 1 ... yield 2 + >>> for i in f(): + ... print i + 1 + 2 >>> g = f() >>> g.next() 1 @@ -203,7 +207,6 @@ Specification: Try/Except/Finally [1, 2, 4, 5, 8, 9, 10, 11] >>> - Guido's binary tree example. >>> # A binary tree class. @@ -301,6 +304,18 @@ in try/except, not like a return. ... yield 3 >>> list(g()) [1, 2, 3] + +A generator can't be resumed while it's already running. + +>>> def g(): +... i = me.next() +... yield i +>>> me = g() +>>> me.next() +Traceback (most recent call last): + ... + File "", line 2, in g +ValueError: generator already executing """ # Fun tests (for sufficiently warped notions of "fun"). @@ -338,6 +353,58 @@ Build up to a recursive Sieve of Eratosthenes generator. >>> primes = sieve(intsfrom(2)) >>> firstn(primes, 20) [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71] + +Another famous problem: generate all integers of the form + 2**i * 3**j * 5**k +in increasing order, where i,j,k >= 0. Trickier than it may look at first! +Try writing it without generators, and correctly, and without generating +3 internal results for each result output. + +>>> def times(n, g): +... for i in g: +... yield n * i +>>> firstn(times(10, intsfrom(1)), 10) +[10, 20, 30, 40, 50, 60, 70, 80, 90, 100] + +>>> def merge(g, h): +... ng = g.next() +... nh = h.next() +... while 1: +... if ng < nh: +... yield ng +... ng = g.next() +... elif ng > nh: +... yield nh +... nh = h.next() +... else: +... yield ng +... ng = g.next() +... nh = h.next() + +This works, but is doing a whale of a lot or redundant work -- it's not +clear how to get the internal uses of m235 to share a single generator. +Note that me_times2 (etc) each need to see every element in the result +sequence. So this is an example where lazy lists are more natural (you +can look at the head of a lazy list any number of times). + +>>> def m235(): +... yield 1 +... me_times2 = times(2, m235()) +... me_times3 = times(3, m235()) +... me_times5 = times(5, m235()) +... for i in merge(merge(me_times2, +... me_times3), +... me_times5): +... yield i + +>>> result = m235() +>>> for i in range(5): +... print firstn(result, 15) +[1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24] +[25, 27, 30, 32, 36, 40, 45, 48, 50, 54, 60, 64, 72, 75, 80] +[81, 90, 96, 100, 108, 120, 125, 128, 135, 144, 150, 160, 162, 180, 192] +[200, 216, 225, 240, 243, 250, 256, 270, 288, 300, 320, 324, 360, 375, 384] +[400, 405, 432, 450, 480, 486, 500, 512, 540, 576, 600, 625, 640, 648, 675] """ __test__ = {"tut": tutorial_tests,