OILS / mycpp / examples / loops.py View on Github | oilshell.org

229 lines, 115 significant
1#!/usr/bin/env python2
2"""
3loops.py: Common loops
4"""
5from __future__ import print_function
6
7import os
8
9from mycpp import mylib
10from mycpp.mylib import log, iteritems, NewDict
11
12from typing import Dict
13
14
15def TestListComp():
16 # type: () -> None
17 log('--- list comprehension')
18
19 x = [1, 2, 3, 4]
20
21 y = [i * 5 for i in x[1:]]
22
23 log("len = %d", len(y))
24 log("y[0] = %d", y[0])
25 log("y[-1] = %d", y[-1])
26
27 log('--- list comprehension over strings')
28
29 z = ['[%d]' % i for i in x[1:-1]]
30
31 # I think this rewrite might be necessary?
32 #tmp1 = x[1:-1]
33 #z = ['[%d]' % i for i in tmp1]
34
35 if mylib.PYTHON:
36 #log("z = %s", z)
37 pass
38
39 log("len = %d", len(z))
40 log("z[0] = %s", z[0])
41 log("z[-1] = %s", z[-1])
42
43 log('-- list comprehension filtering')
44
45 parts = ['a', None, 'b']
46 tmp = [s for s in parts if s is not None]
47 print(''.join(tmp))
48
49 tmp2 = [s for s in tmp if s.startswith('-')]
50 print(''.join(tmp2))
51
52
53def TestListCompParity():
54 # type: () -> None
55 """
56 Does it have all the same features as 'for' loops?
57
58 - Integers
59 - xrange()
60 - Any type
61 - enumerate()
62
63 - List
64 - unpacking of tuples
65 - Dict
66 - iterate directly over dict
67 - iteritem()
68 """
69 log('-- list comp xrange')
70 # BUG: it only works iterating over an List[T]
71 #numbers = [i+1 for i in xrange(3, 5)]
72 #PrintListStr(numbers)
73
74 log('-- list comp enumerate')
75 mylist = [3, 4, 5]
76 # BUG: crashes on tuple expression
77 # enum = [i+item for i, item in enumerate(mylist)]
78
79 log('-- list comp tuple unpacking')
80
81 pairs = [('one', 1), ('two', 2)]
82
83 # Note: listcomp_iter_var is at TOP level, but it could be SCOPED. It is
84 # also rooted at the top level.
85 first = [listcomp_iter_var for listcomp_iter_var, _ in pairs]
86
87 for s2 in first:
88 log('first = %s', s2)
89
90 log('-- list comp dict')
91 d = NewDict() # type: Dict[str, str]
92 d['k'] = 'v'
93 d['k2'] = 'v2'
94
95 # BUG: generates TODO_DICT
96 #keys = [k for k in d]
97
98 log('-- list comp iteritems')
99
100 # BUG: generates TODO_DICT
101 #values = [v for k, v in iteritems(d)]
102
103
104def TestDict():
105 # type: () -> None
106 log('--- Dict')
107 d = {} # type: Dict[str, int]
108 d['a'] = 99
109 d['c'] = 42
110 d['b'] = 0
111
112 log('a = %d', d['a'])
113 log('b = %d', d['b'])
114 log('c = %d', d['c'])
115
116 for k in d:
117 log("k = %s", k)
118
119 for k, v in iteritems(d):
120 log("k = %s, v = %d", k, v)
121
122
123CATS = ['big', 'small', 'hairless']
124
125
126def TestForLoop():
127 # type: () -> None
128 log('--- iterate over bytes in string')
129 for ch in 'abc':
130 log('ch = %s', ch)
131
132 log('--- iterate over items in list')
133 for item in ['xx', 'yy']:
134 log('item = %s', item)
135
136 log('--- tuple unpacking')
137
138 # Note: tuple_iter_1 and tuple_iter_2 are also top-level locals, and are
139 # rooted at the top level.
140 # They could be SCOPED.
141 list_of_tuples = [(5, 'five'), (6, 'six')]
142 for tuple_iter_1, tuple_iter_2 in list_of_tuples:
143 log("- [%d] %s", tuple_iter_1, tuple_iter_2)
144
145 log('--- one arg xrange()')
146
147 m = 2
148 n = 3
149
150 for j in xrange(m * 2):
151 log("%d", j)
152
153 log('--- two arg xrange()')
154
155 # TODO: reuse index variable j
156 for k in xrange(m + 2, n + 5):
157 log("%d", k)
158
159 log('--- three arg xrange()')
160
161 # should iterate exactly once
162 for m in xrange(0, 5, 2):
163 log("%d", m)
164
165 log('--- three arg reverse xrange()')
166
167 # should iterate exactly once
168 for m in xrange(0, -1, -1):
169 log("reverse %d", m)
170
171 log('--- enumerate()')
172
173 for i, c in enumerate(CATS):
174 log('%d %s', i, c)
175
176 for i, pair in enumerate(list_of_tuples):
177 index, s = pair
178 log('%d %d %s', i, index, s)
179
180 # TODO: Note: might want to combine with enumerate? But we're not using
181 # that. We can specialize it for a list. ReverseListIter().
182 log('--- reversed() list')
183
184 list_of_strings = ['spam', 'eggs']
185 for item in reversed(list_of_strings):
186 log("- %s", item)
187
188 log('--- reversed() list with tuple unpacking')
189 for i, item in reversed(list_of_tuples):
190 log("- [%d] %s", i, item)
191
192
193def run_tests():
194 # type: () -> None
195
196 TestForLoop()
197
198 TestListComp()
199 TestListCompParity()
200
201 TestDict()
202
203
204def run_benchmarks():
205 # type: () -> None
206 n = 500000
207
208 result = 0
209
210 i = 0
211 while i < n:
212 for j in xrange(3, 10):
213 result += j
214
215 for j, c in enumerate(CATS):
216 result += j
217 result += len(c)
218
219 i += 1
220 log('result = %d', result)
221 log('Ran %d iterations of xrange/enumerate', n)
222
223
224if __name__ == '__main__':
225 if os.getenv('BENCHMARK'):
226 log('Benchmarking...')
227 run_benchmarks()
228 else:
229 run_tests()