| 1 | #! /usr/bin/python |
| 2 | ### -*-python-*- |
| 3 | ### |
| 4 | ### Generate input script and expected output for hash tables. |
| 5 | |
| 6 | import sys as SYS |
| 7 | import random as R |
| 8 | |
| 9 | if SYS.version_info >= (3,): xrange = range |
| 10 | |
| 11 | ###-------------------------------------------------------------------------- |
| 12 | ### Command-line parsing. |
| 13 | |
| 14 | SYS.argv[0:1] = [] |
| 15 | def arg(default = None): |
| 16 | if len(SYS.argv): |
| 17 | r = SYS.argv[0] |
| 18 | SYS.argv[0:1] = [] |
| 19 | return r |
| 20 | else: |
| 21 | return default |
| 22 | |
| 23 | R.seed(None) |
| 24 | SEED = int(arg(str(R.randrange(0, 1 << 32))), 0) |
| 25 | R.seed(SEED) |
| 26 | |
| 27 | LINES = int(arg(1000)) |
| 28 | |
| 29 | ###-------------------------------------------------------------------------- |
| 30 | ### Word list. |
| 31 | |
| 32 | def word(): |
| 33 | def char(): return 'abcdefghijklmnopqrstuvwxyz'[R.randrange(0, 26)] |
| 34 | word = char() + char() + char() |
| 35 | while R.randrange(0, 6) != 0: word += char() |
| 36 | return word |
| 37 | |
| 38 | ## for i in ['/usr/share/dict/words', '/usr/dict/words']: |
| 39 | ## try: |
| 40 | ## WORDS = [line[:-1] for line in open(i)] |
| 41 | ## raise Exception |
| 42 | ## except: |
| 43 | ## pass |
| 44 | ## else: |
| 45 | ## def word(): |
| 46 | ## return WORDS[R.randrange(0, len(WORDS))] |
| 47 | ## break |
| 48 | |
| 49 | ###-------------------------------------------------------------------------- |
| 50 | ### Initialization. |
| 51 | |
| 52 | SERIAL = 1 |
| 53 | MAP = {} |
| 54 | |
| 55 | SCRIPT = open('sym.script', 'w') |
| 56 | WIN = open('expout', 'w') |
| 57 | |
| 58 | ###-------------------------------------------------------------------------- |
| 59 | ### Utility functions. |
| 60 | |
| 61 | OPS = [] |
| 62 | def op(weight): |
| 63 | """ |
| 64 | Operation decorator. Add the following function to the operations table, |
| 65 | with the given probability WEIGHT. This works as follows: if TOTAL is the |
| 66 | total of all the WEIGHTs, then this operation has a probability of |
| 67 | WEIGHT/TOTAL of being selected. |
| 68 | """ |
| 69 | def _(cls): |
| 70 | OPS.append((weight, cls)) |
| 71 | return cls |
| 72 | return _ |
| 73 | |
| 74 | def serial(): |
| 75 | """Return the next number in a simple sequence.""" |
| 76 | global SERIAL |
| 77 | SERIAL += 1 |
| 78 | return SERIAL - 1 |
| 79 | |
| 80 | ###-------------------------------------------------------------------------- |
| 81 | ### The actual operations. |
| 82 | |
| 83 | @op(10) |
| 84 | def op_set(): |
| 85 | w = word() |
| 86 | n = serial() |
| 87 | SCRIPT.write('set %s %d\n' % (w, n)) |
| 88 | MAP[w] = n |
| 89 | |
| 90 | @op(10) |
| 91 | def op_get(): |
| 92 | w = word() |
| 93 | try: |
| 94 | WIN.write('%d\n' % MAP[w]) |
| 95 | except KeyError: |
| 96 | if R.randrange(8): return |
| 97 | WIN.write('*MISSING*\n') |
| 98 | SCRIPT.write('get %s\n' % (w)) |
| 99 | |
| 100 | @op(10) |
| 101 | def op_del(): |
| 102 | w = word() |
| 103 | try: |
| 104 | del MAP[w] |
| 105 | except KeyError: |
| 106 | if R.randrange(8): return |
| 107 | WIN.write('*MISSING*\n') |
| 108 | SCRIPT.write('del %s\n' % (w)) |
| 109 | |
| 110 | @op(4) |
| 111 | def op_count(): |
| 112 | SCRIPT.write('count\n') |
| 113 | WIN.write('%d\n' % len(MAP)) |
| 114 | |
| 115 | @op(1) |
| 116 | def op_show(): |
| 117 | SCRIPT.write('show\n') |
| 118 | if not MAP: |
| 119 | WIN.write('*EMPTY*\n') |
| 120 | else: |
| 121 | kk = list(MAP.keys()) |
| 122 | kk.sort() |
| 123 | WIN.write(' '.join(['%s:%d' % (k, MAP[k]) for k in kk]) + '\n') |
| 124 | |
| 125 | ###-------------------------------------------------------------------------- |
| 126 | ### Generate the output. |
| 127 | |
| 128 | OPTAB = [] |
| 129 | for p, func in OPS: |
| 130 | OPTAB += [func] * p |
| 131 | for i in xrange(LINES): |
| 132 | OPTAB[R.randrange(0, len(OPTAB))]() |
| 133 | op_show() |
| 134 | |
| 135 | SCRIPT.close() |
| 136 | WIN.close() |
| 137 | open('sym.seed', 'w').write('sym-gtest seed = %08x\n' % SEED) |
| 138 | |
| 139 | ###----- That's all, folks -------------------------------------------------- |