chiark / gitweb /
@@@ tvec doc wip
[mLib] / struct / t / sym-gtest
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 --------------------------------------------------