#! /usr/bin/python ### -*-python-*- ### ### Generate input script and expected output for hash tables. import sys as SYS import random as R if SYS.version_info >= (3,): xrange = range ###-------------------------------------------------------------------------- ### Command-line parsing. SYS.argv[0:1] = [] def arg(default = None): if len(SYS.argv): r = SYS.argv[0] SYS.argv[0:1] = [] return r else: return default R.seed(None) SEED = int(arg(str(R.randrange(0, 1 << 32))), 0) R.seed(SEED) LINES = int(arg(1000)) ###-------------------------------------------------------------------------- ### Word list. def word(): def char(): return 'abcdefghijklmnopqrstuvwxyz'[R.randrange(0, 26)] word = char() + char() + char() while R.randrange(0, 6) != 0: word += char() return word ## for i in ['/usr/share/dict/words', '/usr/dict/words']: ## try: ## WORDS = [line[:-1] for line in open(i)] ## raise Exception ## except: ## pass ## else: ## def word(): ## return WORDS[R.randrange(0, len(WORDS))] ## break ###-------------------------------------------------------------------------- ### Initialization. SERIAL = 1 MAP = {} SCRIPT = open('sym.script', 'w') WIN = open('expout', 'w') ###-------------------------------------------------------------------------- ### Utility functions. OPS = [] def op(weight): """ Operation decorator. Add the following function to the operations table, with the given probability WEIGHT. This works as follows: if TOTAL is the total of all the WEIGHTs, then this operation has a probability of WEIGHT/TOTAL of being selected. """ def _(cls): OPS.append((weight, cls)) return cls return _ def serial(): """Return the next number in a simple sequence.""" global SERIAL SERIAL += 1 return SERIAL - 1 ###-------------------------------------------------------------------------- ### The actual operations. @op(10) def op_set(): w = word() n = serial() SCRIPT.write('set %s %d\n' % (w, n)) MAP[w] = n @op(10) def op_get(): w = word() try: WIN.write('%d\n' % MAP[w]) except KeyError: if R.randrange(8): return WIN.write('*MISSING*\n') SCRIPT.write('get %s\n' % (w)) @op(10) def op_del(): w = word() try: del MAP[w] except KeyError: if R.randrange(8): return WIN.write('*MISSING*\n') SCRIPT.write('del %s\n' % (w)) @op(4) def op_count(): SCRIPT.write('count\n') WIN.write('%d\n' % len(MAP)) @op(1) def op_show(): SCRIPT.write('show\n') if not MAP: WIN.write('*EMPTY*\n') else: kk = list(MAP.keys()) kk.sort() WIN.write(' '.join(['%s:%d' % (k, MAP[k]) for k in kk]) + '\n') ###-------------------------------------------------------------------------- ### Generate the output. OPTAB = [] for p, func in OPS: OPTAB += [func] * p for i in xrange(LINES): OPTAB[R.randrange(0, len(OPTAB))]() op_show() SCRIPT.close() WIN.close() open('sym.seed', 'w').write('sym-gtest seed = %08x\n' % SEED) ###----- That's all, folks --------------------------------------------------