Skip to content

Commit 1261866

Browse files
authored
Beef-up tests for the itertool docs. (gh-116679)
1 parent 2903307 commit 1261866

File tree

1 file changed

+103
-9
lines changed

1 file changed

+103
-9
lines changed

Doc/library/itertools.rst

Lines changed: 103 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -998,7 +998,7 @@ The following recipes have a more mathematical flavor:
998998

999999
def sum_of_squares(it):
10001000
"Add up the squares of the input values."
1001-
# sum_of_squares([10, 20, 30]) -> 1400
1001+
# sum_of_squares([10, 20, 30]) --> 1400
10021002
return math.sumprod(*tee(it))
10031003
10041004
def reshape(matrix, cols):
@@ -1019,17 +1019,16 @@ The following recipes have a more mathematical flavor:
10191019

10201020
def convolve(signal, kernel):
10211021
"""Discrete linear convolution of two iterables.
1022+
Equivalent to polynomial multiplication.
10221023

1023-
The kernel is fully consumed before the calculations begin.
1024-
The signal is consumed lazily and can be infinite.
1025-
1026-
Convolutions are mathematically commutative.
1027-
If the signal and kernel are swapped,
1028-
the output will be the same.
1024+
Convolutions are mathematically commutative; however, the inputs are
1025+
evaluated differently. The signal is consumed lazily and can be
1026+
infinite. The kernel is fully consumed before the calculations begin.
10291027

10301028
Article: https://betterexplained.com/articles/intuitive-convolution/
10311029
Video: https://www.youtube.com/watch?v=KuXjwB4LzSA
10321030
"""
1031+
# convolve([1, -1, -20], [1, -3]) --> 1 -4 -17 60
10331032
# convolve(data, [0.25, 0.25, 0.25, 0.25]) --> Moving average (blur)
10341033
# convolve(data, [1/2, 0, -1/2]) --> 1st derivative estimate
10351034
# convolve(data, [1, -2, 1]) --> 2nd derivative estimate
@@ -1067,7 +1066,7 @@ The following recipes have a more mathematical flavor:
10671066
f(x) = x³ -4x² -17x + 60
10681067
f'(x) = 3x² -8x -17
10691068
"""
1070-
# polynomial_derivative([1, -4, -17, 60]) -> [3, -8, -17]
1069+
# polynomial_derivative([1, -4, -17, 60]) --> [3, -8, -17]
10711070
n = len(coefficients)
10721071
powers = reversed(range(1, n))
10731072
return list(map(operator.mul, coefficients, powers))
@@ -1169,6 +1168,12 @@ The following recipes have a more mathematical flavor:
11691168

11701169
>>> take(10, count())
11711170
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
1171+
>>> # Verify that the input is consumed lazily
1172+
>>> it = iter('abcdef')
1173+
>>> take(3, it)
1174+
['a', 'b', 'c']
1175+
>>> list(it)
1176+
['d', 'e', 'f']
11721177

11731178
>>> list(prepend(1, [2, 3, 4]))
11741179
[1, 2, 3, 4]
@@ -1181,25 +1186,45 @@ The following recipes have a more mathematical flavor:
11811186

11821187
>>> list(tail(3, 'ABCDEFG'))
11831188
['E', 'F', 'G']
1189+
>>> # Verify the input is consumed greedily
1190+
>>> input_iterator = iter('ABCDEFG')
1191+
>>> output_iterator = tail(3, input_iterator)
1192+
>>> list(input_iterator)
1193+
[]
11841194

11851195
>>> it = iter(range(10))
11861196
>>> consume(it, 3)
1197+
>>> # Verify the input is consumed lazily
11871198
>>> next(it)
11881199
3
1200+
>>> # Verify the input is consumed completely
11891201
>>> consume(it)
11901202
>>> next(it, 'Done')
11911203
'Done'
11921204

11931205
>>> nth('abcde', 3)
11941206
'd'
1195-
11961207
>>> nth('abcde', 9) is None
11971208
True
1209+
>>> # Verify that the input is consumed lazily
1210+
>>> it = iter('abcde')
1211+
>>> nth(it, 2)
1212+
'c'
1213+
>>> list(it)
1214+
['d', 'e']
11981215

11991216
>>> [all_equal(s) for s in ('', 'A', 'AAAA', 'AAAB', 'AAABA')]
12001217
[True, True, True, False, False]
12011218
>>> [all_equal(s, key=str.casefold) for s in ('', 'A', 'AaAa', 'AAAB', 'AAABA')]
12021219
[True, True, True, False, False]
1220+
>>> # Verify that the input is consumed lazily and that only
1221+
>>> # one element of a second equivalence class is used to disprove
1222+
>>> # the assertion that all elements are equal.
1223+
>>> it = iter('aaabbbccc')
1224+
>>> all_equal(it)
1225+
False
1226+
>>> ''.join(it)
1227+
'bbccc'
12031228

12041229
>>> quantify(range(99), lambda x: x%2==0)
12051230
50
@@ -1222,6 +1247,11 @@ The following recipes have a more mathematical flavor:
12221247

12231248
>>> list(ncycles('abc', 3))
12241249
['a', 'b', 'c', 'a', 'b', 'c', 'a', 'b', 'c']
1250+
>>> # Verify greedy consumption of input iterator
1251+
>>> input_iterator = iter('abc')
1252+
>>> output_iterator = ncycles(input_iterator, 3)
1253+
>>> list(input_iterator)
1254+
[]
12251255

12261256
>>> sum_of_squares([10, 20, 30])
12271257
1400
@@ -1248,19 +1278,41 @@ The following recipes have a more mathematical flavor:
12481278

12491279
>>> list(transpose([(1, 2, 3), (11, 22, 33)]))
12501280
[(1, 11), (2, 22), (3, 33)]
1281+
>>> # Verify that the inputs are consumed lazily
1282+
>>> input1 = iter([1, 2, 3])
1283+
>>> input2 = iter([11, 22, 33])
1284+
>>> output_iterator = transpose([input1, input2])
1285+
>>> next(output_iterator)
1286+
(1, 11)
1287+
>>> list(zip(input1, input2))
1288+
[(2, 22), (3, 33)]
12511289

12521290
>>> list(matmul([(7, 5), (3, 5)], [[2, 5], [7, 9]]))
12531291
[(49, 80), (41, 60)]
12541292
>>> list(matmul([[2, 5], [7, 9], [3, 4]], [[7, 11, 5, 4, 9], [3, 5, 2, 6, 3]]))
12551293
[(29, 47, 20, 38, 33), (76, 122, 53, 82, 90), (33, 53, 23, 36, 39)]
12561294

1295+
>>> list(convolve([1, -1, -20], [1, -3])) == [1, -4, -17, 60]
1296+
True
12571297
>>> data = [20, 40, 24, 32, 20, 28, 16]
12581298
>>> list(convolve(data, [0.25, 0.25, 0.25, 0.25]))
12591299
[5.0, 15.0, 21.0, 29.0, 29.0, 26.0, 24.0, 16.0, 11.0, 4.0]
12601300
>>> list(convolve(data, [1, -1]))
12611301
[20, 20, -16, 8, -12, 8, -12, -16]
12621302
>>> list(convolve(data, [1, -2, 1]))
12631303
[20, 0, -36, 24, -20, 20, -20, -4, 16]
1304+
>>> # Verify signal is consumed lazily and the kernel greedily
1305+
>>> signal_iterator = iter([10, 20, 30, 40, 50])
1306+
>>> kernel_iterator = iter([1, 2, 3])
1307+
>>> output_iterator = convolve(signal_iterator, kernel_iterator)
1308+
>>> list(kernel_iterator)
1309+
[]
1310+
>>> next(output_iterator)
1311+
10
1312+
>>> next(output_iterator)
1313+
40
1314+
>>> list(signal_iterator)
1315+
[30, 40, 50]
12641316

12651317
>>> from fractions import Fraction
12661318
>>> from decimal import Decimal
@@ -1348,6 +1400,17 @@ The following recipes have a more mathematical flavor:
13481400
>>> # Test list input. Lists do not support None for the stop argument
13491401
>>> list(iter_index(list('AABCADEAF'), 'A'))
13501402
[0, 1, 4, 7]
1403+
>>> # Verify that input is consumed lazily
1404+
>>> input_iterator = iter('AABCADEAF')
1405+
>>> output_iterator = iter_index(input_iterator, 'A')
1406+
>>> next(output_iterator)
1407+
0
1408+
>>> next(output_iterator)
1409+
1
1410+
>>> next(output_iterator)
1411+
4
1412+
>>> ''.join(input_iterator)
1413+
'DEAF'
13511414

13521415
>>> list(sieve(30))
13531416
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
@@ -1499,6 +1562,17 @@ The following recipes have a more mathematical flavor:
14991562
[0, 2, 4, 6, 8]
15001563
>>> list(odds)
15011564
[1, 3, 5, 7, 9]
1565+
>>> # Verify that the input is consumed lazily
1566+
>>> input_iterator = iter(range(10))
1567+
>>> evens, odds = partition(is_odd, input_iterator)
1568+
>>> next(odds)
1569+
1
1570+
>>> next(odds)
1571+
3
1572+
>>> next(evens)
1573+
0
1574+
>>> list(input_iterator)
1575+
[4, 5, 6, 7, 8, 9]
15021576

15031577
>>> list(subslices('ABCD'))
15041578
['A', 'AB', 'ABC', 'ABCD', 'B', 'BC', 'BCD', 'C', 'CD', 'D']
@@ -1518,13 +1592,27 @@ The following recipes have a more mathematical flavor:
15181592
['A', 'B', 'C', 'D']
15191593
>>> list(unique_everseen('ABBcCAD', str.casefold))
15201594
['A', 'B', 'c', 'D']
1595+
>>> # Verify that the input is consumed lazily
1596+
>>> input_iterator = iter('AAAABBBCCDAABBB')
1597+
>>> output_iterator = unique_everseen(input_iterator)
1598+
>>> next(output_iterator)
1599+
'A'
1600+
>>> ''.join(input_iterator)
1601+
'AAABBBCCDAABBB'
15211602

15221603
>>> list(unique_justseen('AAAABBBCCDAABBB'))
15231604
['A', 'B', 'C', 'D', 'A', 'B']
15241605
>>> list(unique_justseen('ABBCcAD', str.casefold))
15251606
['A', 'B', 'C', 'A', 'D']
15261607
>>> list(unique_justseen('ABBcCAD', str.casefold))
15271608
['A', 'B', 'c', 'A', 'D']
1609+
>>> # Verify that the input is consumed lazily
1610+
>>> input_iterator = iter('AAAABBBCCDAABBB')
1611+
>>> output_iterator = unique_justseen(input_iterator)
1612+
>>> next(output_iterator)
1613+
'A'
1614+
>>> ''.join(input_iterator)
1615+
'AAABBBCCDAABBB'
15281616

15291617
>>> d = dict(a=1, b=2, c=3)
15301618
>>> it = iter_except(d.popitem, KeyError)
@@ -1545,6 +1633,12 @@ The following recipes have a more mathematical flavor:
15451633

15461634
>>> first_true('ABC0DEF1', '9', str.isdigit)
15471635
'0'
1636+
>>> # Verify that inputs are consumed lazily
1637+
>>> it = iter('ABC0DEF1')
1638+
>>> first_true(it, predicate=str.isdigit)
1639+
'0'
1640+
>>> ''.join(it)
1641+
'DEF1'
15481642

15491643

15501644
.. testcode::

0 commit comments

Comments
 (0)