| 1 | #!/usr/bin/env python2
 | 
| 2 | """
 | 
| 3 | loops.py: Common loops
 | 
| 4 | """
 | 
| 5 | from __future__ import print_function
 | 
| 6 | 
 | 
| 7 | import os
 | 
| 8 | 
 | 
| 9 | from mycpp import mylib
 | 
| 10 | from mycpp.mylib import log, iteritems
 | 
| 11 | 
 | 
| 12 | from typing import Dict
 | 
| 13 | 
 | 
| 14 | 
 | 
| 15 | def 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 changing type')
 | 
| 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 |     pairs = [('one', 1), ('two', 2)]
 | 
| 44 |     first = [s for s, _ in pairs]
 | 
| 45 |     for s2 in first:
 | 
| 46 |         log('first = %s', s2)
 | 
| 47 | 
 | 
| 48 |     parts = ['a', None, 'b']
 | 
| 49 |     tmp = [s for s in parts if s is not None]
 | 
| 50 |     print(''.join(tmp))
 | 
| 51 | 
 | 
| 52 |     tmp2 = [s for s in tmp if s.startswith('-')]
 | 
| 53 |     print(''.join(tmp2))
 | 
| 54 | 
 | 
| 55 | 
 | 
| 56 | def TestDict():
 | 
| 57 |     # type: () -> None
 | 
| 58 |     log('--- Dict')
 | 
| 59 |     d = {}  # type: Dict[str, int]
 | 
| 60 |     d['a'] = 99
 | 
| 61 |     d['c'] = 42
 | 
| 62 |     d['b'] = 0
 | 
| 63 | 
 | 
| 64 |     log('a = %d', d['a'])
 | 
| 65 |     log('b = %d', d['b'])
 | 
| 66 |     log('c = %d', d['c'])
 | 
| 67 | 
 | 
| 68 |     for k in d:
 | 
| 69 |         log("k = %s", k)
 | 
| 70 | 
 | 
| 71 |     for k, v in iteritems(d):
 | 
| 72 |         log("k = %s, v = %d", k, v)
 | 
| 73 | 
 | 
| 74 | 
 | 
| 75 | CATS = ['big', 'small', 'hairless']
 | 
| 76 | 
 | 
| 77 | #EMPTY_DICT = {}  # type: Dict[int, int]
 | 
| 78 | 
 | 
| 79 | 
 | 
| 80 | def run_tests():
 | 
| 81 |     # type: () -> None
 | 
| 82 | 
 | 
| 83 |     log('--- iterate over bytes in string')
 | 
| 84 |     for ch in 'abc':
 | 
| 85 |         log('ch = %s', ch)
 | 
| 86 | 
 | 
| 87 |     log('--- iterate over items in list')
 | 
| 88 |     for item in ['xx', 'yy']:
 | 
| 89 |         log('item = %s', item)
 | 
| 90 | 
 | 
| 91 |     # TODO: iterate over items in dict
 | 
| 92 |     # DictIter gives pairs?  Just do .Key() and .Value()?  Hm that makes sense.
 | 
| 93 | 
 | 
| 94 |     log('--- tuple unpacking')
 | 
| 95 | 
 | 
| 96 |     list_of_tuples = [(5, 'five'), (6, 'six')]
 | 
| 97 |     for i, item in list_of_tuples:
 | 
| 98 |         log("- [%d] %s", i, item)
 | 
| 99 | 
 | 
| 100 |     log('--- one arg xrange()')
 | 
| 101 | 
 | 
| 102 |     m = 2
 | 
| 103 |     n = 3
 | 
| 104 | 
 | 
| 105 |     for j in xrange(m * 2):
 | 
| 106 |         log("%d", j)
 | 
| 107 | 
 | 
| 108 |     log('--- two arg xrange()')
 | 
| 109 | 
 | 
| 110 |     # TODO: reuse index variable j
 | 
| 111 |     for k in xrange(m + 2, n + 5):
 | 
| 112 |         log("%d", k)
 | 
| 113 | 
 | 
| 114 |     log('--- three arg xrange()')
 | 
| 115 | 
 | 
| 116 |     # should iterate exactly once
 | 
| 117 |     for m in xrange(0, 5, 2):
 | 
| 118 |         log("%d", m)
 | 
| 119 | 
 | 
| 120 |     log('--- three arg reverse xrange()')
 | 
| 121 | 
 | 
| 122 |     # should iterate exactly once
 | 
| 123 |     for m in xrange(0, -1, -1):
 | 
| 124 |         log("reverse %d", m)
 | 
| 125 | 
 | 
| 126 |     log('--- enumerate()')
 | 
| 127 | 
 | 
| 128 |     for i, c in enumerate(CATS):
 | 
| 129 |         log('%d %s', i, c)
 | 
| 130 | 
 | 
| 131 |     for i, pair in enumerate(list_of_tuples):
 | 
| 132 |         index, s = pair
 | 
| 133 |         log('%d %d %s', i, index, s)
 | 
| 134 | 
 | 
| 135 |     # TODO: Note: might want to combine with enumerate?  But we're not using
 | 
| 136 |     # that.  We can specialize it for a list.  ReverseListIter().
 | 
| 137 |     log('--- reversed() list')
 | 
| 138 | 
 | 
| 139 |     list_of_strings = ['spam', 'eggs']
 | 
| 140 |     for item in reversed(list_of_strings):
 | 
| 141 |         log("- %s", item)
 | 
| 142 | 
 | 
| 143 |     log('--- reversed() list with tuple unpacking')
 | 
| 144 |     for i, item in reversed(list_of_tuples):
 | 
| 145 |         log("- [%d] %s", i, item)
 | 
| 146 | 
 | 
| 147 |     TestListComp()
 | 
| 148 | 
 | 
| 149 |     TestDict()
 | 
| 150 | 
 | 
| 151 | 
 | 
| 152 | def run_benchmarks():
 | 
| 153 |     # type: () -> None
 | 
| 154 |     n = 500000
 | 
| 155 | 
 | 
| 156 |     result = 0
 | 
| 157 | 
 | 
| 158 |     i = 0
 | 
| 159 |     while i < n:
 | 
| 160 |         for j in xrange(3, 10):
 | 
| 161 |             result += j
 | 
| 162 | 
 | 
| 163 |         for j, c in enumerate(CATS):
 | 
| 164 |             result += j
 | 
| 165 |             result += len(c)
 | 
| 166 | 
 | 
| 167 |         i += 1
 | 
| 168 |     log('result = %d', result)
 | 
| 169 |     log('Ran %d iterations of xrange/enumerate', n)
 | 
| 170 | 
 | 
| 171 | 
 | 
| 172 | if __name__ == '__main__':
 | 
| 173 |     if os.getenv('BENCHMARK'):
 | 
| 174 |         log('Benchmarking...')
 | 
| 175 |         run_benchmarks()
 | 
| 176 |     else:
 | 
| 177 |         run_tests()
 |