chiark / gitweb /
*/t/*.py: Fix the various testing scripts for Python 3 compatibility.
[mLib] / struct / t / da-gtest.py
1 #! /usr/bin/python
2 ### -*-python-*-
3 ###
4 ### Generate input script and expected output for dynamic array testing.
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 ### Initialization.
31
32 SERIAL = 1
33 ARRAY = []
34
35 SCRIPT = open('da.script', 'w')
36 WIN = open('expout', 'w')
37
38 ###--------------------------------------------------------------------------
39 ### Utility functions.
40
41 OPS = []
42 def op(weight):
43   """
44   Operation decorator.  Add the following function to the operations table,
45   with the given probability WEIGHT.  This works as follows: if TOTAL is the
46   total of all the WEIGHTs, then this operation has a probability of
47   WEIGHT/TOTAL of being selected.
48   """
49   def _(cls):
50     OPS.append((weight, cls))
51     return cls
52   return _
53
54 def serial():
55   """Return the next number in a simple sequence."""
56   global SERIAL
57   SERIAL += 1
58   return SERIAL - 1
59
60 def mkseq():
61   """Return a short list of stuff to be added to the array."""
62   seq = [serial()]
63   while R.randrange(0, 4) < 3: seq.append(serial())
64   return seq
65
66 def mkseqlen():
67   """Return a length of stuff to be removed from the array."""
68   n = 1
69   while R.randrange(0, 4) < 3: n += 1
70   return n
71
72 ###--------------------------------------------------------------------------
73 ### The actual operations.
74
75 @op(20)
76 def op_push():
77   n = serial()
78   SCRIPT.write('push %d\n' % n)
79   ARRAY.append(n)
80 @op(20)
81 def op_pop():
82   SCRIPT.write('pop\n')
83   if not ARRAY:
84     WIN.write('*UFLOW*\n')
85   else:
86     n, = ARRAY[-1:]
87     ARRAY[-1:] = []
88     WIN.write('%d\n' % n)
89 @op(20)
90 def op_unshift():
91   n = serial()
92   SCRIPT.write('unshift %d\n' % n)
93   ARRAY[0:0] = [n]
94 @op(20)
95 def op_shift():
96   SCRIPT.write('shift\n')
97   if not ARRAY:
98     WIN.write('*UFLOW*\n')
99   else:
100     n = ARRAY[0]
101     ARRAY[0:1] = []
102     WIN.write('%d\n' % n)
103
104 @op(10)
105 def op_insert():
106   stuff = mkseq()
107   SCRIPT.write('insert ' + ' '.join(['%d' % i for i in stuff]) + '\n')
108   ARRAY[0:0] = stuff
109 @op(10)
110 def op_append():
111   global ARRAY                          # += is a binding occurrence
112   stuff = mkseq()
113   SCRIPT.write('append ' + ' '.join(['%d' % i for i in stuff]) + '\n')
114   ARRAY += stuff
115
116 @op(20)
117 def op_delete():
118   if len(ARRAY) < LINES/10: return
119   n = mkseqlen()
120   SCRIPT.write('delete %d\n' % n)
121   if n > len(ARRAY): WIN.write('*UFLOW*\n')
122   else: ARRAY[0:n] = []
123 @op(20)
124 def op_reduce():
125   if len(ARRAY) < LINES/10: return
126   n = mkseqlen()
127   SCRIPT.write('reduce %d\n' % n)
128   if n > len(ARRAY): WIN.write('*UFLOW*\n')
129   else: ARRAY[-n:] = []
130
131 def mkindex():
132   if not ARRAY: ix = 0
133   else: ix = R.randrange(0, len(ARRAY))
134   while R.randrange(0, 2) < 1: ix += 1
135   return ix
136
137 @op(20)
138 def op_set():
139   global ARRAY                          # += is a binding occurrence
140   ix, x = mkindex(), serial()
141   SCRIPT.write('set %d %d\n' % (ix, x))
142   if ix >= len(ARRAY): ARRAY += [-1] * (ix - len(ARRAY) + 1)
143   ARRAY[ix] = x
144 @op(20)
145 def op_get():
146   ix = mkindex()
147   SCRIPT.write('get %d\n' % ix)
148   if ix >= len(ARRAY): WIN.write('*RANGE*\n')
149   else: WIN.write('%d\n' % ARRAY[ix])
150
151 @op(10)
152 def op_first():
153   SCRIPT.write('first\n')
154   if len(ARRAY): WIN.write('%d\n' % ARRAY[0])
155   else: WIN.write('*RANGE*\n')
156 @op(10)
157 def op_last():
158   SCRIPT.write('last\n')
159   if len(ARRAY): WIN.write('%d\n' % ARRAY[-1])
160   else: WIN.write('*RANGE*\n')
161
162 @op(1)
163 def op_show():
164   SCRIPT.write('show\n')
165   if not ARRAY: WIN.write('*EMPTY*\n')
166   else: WIN.write(' '.join(['%d' % i for i in ARRAY]) + '\n')
167
168 ###--------------------------------------------------------------------------
169 ### Generate the output.
170
171 OPTAB = []
172 for p, func in OPS:
173   OPTAB += [func] * p
174 for i in xrange(LINES):
175   OPTAB[R.randrange(0, len(OPTAB))]()
176 op_show()
177
178 SCRIPT.close()
179 WIN.close()
180 open('da.seed', 'w').write('da-gtest seed = %08x\n' % SEED)
181
182 ###----- That's all, folks --------------------------------------------------