fix cpp generation for 'import .. as'
[shedskin:mainline.git] / unit.py
1 #!/usr/bin/env python
2
3 from ss import *
4 from sets import Set
5 import traceback, sys, os, time
6
7 tests = [
8
9 ('''fixes for 0.0.29; datetime''', '''
10 #equality..
11 hex=['A','B','C','D','E','F']
12 try:
13     print hex.index('A'.upper())
14     print hex.count('A'+'')
15 except Exception, e:
16     print e
17
18 #datetime
19 from datetime import date, tzinfo, timedelta, datetime
20
21 # enable keyword args
22 print date(2007,4,3).replace(month=11)
23
24 # template problem
25 class TZ2(tzinfo):
26     def utcoffset(self, dt): return timedelta(0,0,0,0,-339)
27
28 try:
29     dt = datetime(2007,4,3, tzinfo=TZ2())
30     print dt
31 except Exception, e:
32     print e
33
34 #random.randrange
35 import random
36
37 print random.randrange(1)
38 print random.randrange(0,1)
39 print random.randrange(0,1,1)
40
41 #staticmethod decorator
42 class C:
43     @staticmethod
44     def id(x):
45         return x
46 print C.id(1)
47
48 #improve import mechanism
49 import os.path
50 print os.getcwd()
51
52 from os import path 
53 print path.curdir
54
55 from os.path import curdir
56 print curdir
57
58 import os as os2
59 print os2.path.curdir
60
61 ''', '''
62 output(equal=True)
63 '''),
64
65 ('''fixes for 0.0.28; socket''', '''
66 #time.strptime
67 import time
68 print time.strftime("%d %b %Y %H:%M:%S", time.strptime("2001-11-12 18:31:01", "%Y-%m-%d %H:%M:%S")) 
69 print time.strftime("%Y", time.strptime("2001", "%Y"))
70
71 #improve default arguments
72 import bert
73 print bert.def1()
74
75 print bert.def2()
76 bert.a = 16
77 print bert.huh()
78 print bert.def2()
79
80 print bert.def3()
81
82 def bleh(l=[1,2]):
83     return l
84 print bleh()
85
86 bert.def4()
87
88 #C++ bool type 
89 def h(x):
90     if x in ['False', '0']: return 0
91     elif x in ['True', '1']: return 1
92     else: return 2
93
94 print hex(1==2), hex(1!=2)
95 print oct(1==2), oct(1!=2)
96 print abs(1==2), abs(1!=2)
97 print h(str(1==2)), h(str(1!=2))
98 print h(repr(1==2)), h(repr(1!=2))
99 print int(1==2), int(1!=2)
100 print float(1==2), float(1!=2)
101 print ord(chr(1==2)), ord(chr(1!=2))
102
103 #random.sample/choice 
104 import random
105 print random.sample(xrange(1), 1)
106 print random.sample(set([1]), 1)
107
108 #fast_for_neg in listcomp_for
109 print [(i, i) for i in range(29, -1, -1)]
110
111 #works, but add as test
112 def ah():
113    pass
114 def bh(func=ah):
115    func()
116 bh()
117
118 # sorted, list.sort: cmp and reverse args 
119 def mut(a,b):
120     return -cmp(a,b)
121
122 def cmut(a,b):
123     return -cmp(a,b)
124
125 print sorted([5,1,3,2,4])
126 print sorted([5,1,3,2,4], reverse=True)
127 print sorted([5,1,3,2,4], cmp=mut)
128 print sorted([5,1,3,2,4], cmp=mut, reverse=True)
129
130 print sorted(set([5,1,3,2,4]))
131 print sorted(set([5,1,3,2,4]), reverse=True)
132 print sorted(set([5,1,3,2,4]), cmp=mut)
133 print sorted(set([5,1,3,2,4]), cmp=mut, reverse=True)
134
135 print sorted('abcde')
136 print sorted('abcde', reverse=True)
137 print sorted('abcde', cmp=cmut)
138 print sorted('abcde', cmp=cmut, reverse=True)
139
140 l = [1,4,5,2,3]
141 l.sort(); print l
142 l.sort(cmp=mut); print l
143 l.sort(reverse=True); print l
144 l.sort(cmp=mut, reverse=True); print l
145
146 # tempvars/new nodes and inheritance (XXX add more here)
147 class network:
148     def shortestpath(self):
149         for node in set([1]): 
150             print node
151
152         print [node for node in [1]]
153
154 class smallworld(network):
155     pass
156
157 s = smallworld() 
158 s.shortestpath()
159
160 # ss-progs regression
161 class LowLevel:
162    def bslTxRx(self, blkout=None):
163        pass
164
165 class BootStrapLoader(LowLevel):
166    def actionRun(self):
167        self.bslTxRx()
168
169 bsl = BootStrapLoader()
170 bsl.actionRun()
171
172 # test compilation
173 import socket
174 import stat
175
176 # test all cases
177 a = 1
178
179 print [x for x in range(1,10,1)]
180 print [x for x in range(10,1,-1)]
181 print [x for x in range(1,10,+1)]
182 print [x for x in range(1,10,a)]
183 print [x for x in range(10,1,-a)]
184 print [x for x in range(1,10,+a)]
185 print [x for x in range(1,10,a*1)]
186 print [x for x in range(1,10,-(-1))]
187 print [x for x in range(1,10,+(+a))]
188
189 for x in range(1,10,1): print x,
190 print
191 for x in range(1,10,+1): print x,
192 print
193 for x in range(1,10,a): print x,
194 print
195 for x in range(1,10,+a): print x,
196 print
197 for x in range(1,10,-(-1)): print x,
198 print
199 for x in range(1,10,+(+1)): print x,
200 print
201 for x in range(1,10,+(+a)): print x,
202 print
203 for x in range(10,1,-1): print x,
204 print
205 for x in range(10,1,-a): print x,
206 print
207
208 ''', '''
209 output(equal=True)
210
211 '''),
212
213 ('''fixes for 0.0.27; re, time''', '''
214 #re
215 import re
216
217 try:
218         a = re.compile(r'\\b(?P<email_name>[\\w.-]+?)@(?P<email_domain>[a-z.-]{3,})\\b', re.IGNORECASE)
219         b = 'bob (BoB@gmaiL.com) said to sally (sally123_43.d@hOtmail.co.uk) that no-name (not_a-real@em_ail.dres) was annoying...'
220         
221         print a.search(b, 20).group(0)
222         print a.match(b, 5).expand(r'the found name: \\g<email_name>\\nthe domain: \\g<email_domain>')
223         print a.subn(r'\\1 AT \\g<email_domain>', b)
224         print a.sub(r'<a href="mailto:\\g<0>">\\1</a>', b)
225 #       print a.findall(b)
226         
227         c = re.compile(r\'\'\'
228                 \\b
229                 (?P<protocol>https?|(ftp)|(?P<mailto>mailto))
230                 :(?(mailto)|//)
231                 (
232                         (?P<user>[\\w._-]+?)
233                         (?(mailto)
234                                         
235                                 |
236                                         :(?P<pass>[\\w._-]*?)
237                         )
238                         @
239                 )?
240                 (?P<domain>[\\w.-]+)
241                 (?(mailto)
242                                 
243                         |
244                                 (?P<path>/[^\\s]*)
245                 )
246                 \\b
247                 \'\'\', re.X)
248         d = 'fasdf mailto:bob@gmail.com, dasdfed ftp://haha:hoho@bla.com/files, http://fsesdf@asd.com orRLY!!?!L!? \\
249         https://example.com/OMG.html'
250         
251         allm = c.finditer(d)
252         i = 1
253         for mo in allm:
254                 s = str(i) + ': \\n'
255                 s += '\\tfull: ' + mo.group(0)
256                 s += '\\n\\tnamed: '
257                 
258                 gd = mo.groupdict()
259                 for k in sorted(gd):
260                         if gd[k] == None: continue
261                         s += '\\n\\t\\t' + k + ': ' + gd[k]
262                 
263                 print s
264                 i += 1
265         
266         print re.split(r'\\W+', b)
267         print re.split(r'(\\W+)', b, 2)
268         
269 except re.error, msg:
270         print msg
271
272 #time
273 import time
274 try:
275     print time.mktime(time.struct_time((1970, 2, 17, 23, 33, 34, 1, 48, -1)))
276     print time.mktime((1970, 2, 17, 23, 33, 34, 3, 17, -1))
277     print time.localtime(4142014)    
278 #    print time.localtime()
279 #    print time.localtime(time.mktime(time.localtime()))
280 #    print time.gmtime(time.mktime(time.gmtime()))
281 #    print time.asctime()
282     print time.asctime(time.struct_time((2008, 6, 24, 12, 50, 00, 0, 120, -1)))
283 #    print time.ctime()
284     print time.ctime(1000000)
285     y = (2008, 6, 24, 12, 50, 00, 0, 120, -1)
286     x = time.struct_time(y)
287     print x
288     print x.tm_mon
289     print x[6]
290 #    print time.strftime("%R",time.localtime())
291 #    print time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime())
292     print time.strftime("%a, %d %b %Y %H:%M:%S",
293             (2008, 6, 24, 12, 50, 00, 0, 120, -1))
294 #    print time.strftime("%d %b %Y %H:%M:%S", time.strptime("2001-11-12 18:31:01", "%Y-%m-%d %H:%M:%S")) # XXX %a
295 #    print time.strftime("%Y", time.strptime("2001", "%Y")) # XXX %a
296 #    print time.timezone
297     print time.tzname
298
299 except TypeError, e:
300     print e
301
302 #corner cases
303 print int(''.isdigit())
304 print int(''.isalpha())
305 print int(''.isalnum())
306 print int(''.islower())
307 print int(''.isupper())
308 print int(''.istitle())
309
310 #glob, fnmatch
311 import glob
312 print glob.glob('ss.py')
313 import fnmatch
314 print int(fnmatch.fnmatch('ss.py', 'ss.[py]y'))
315
316 #staticmethod, property
317 class woef(object):
318     def x(a):
319         print a
320     def y(self, b):
321         print b
322
323     def getz(self):
324         return 15+self._x
325     def setz(self, x):
326         self._x = x
327
328     x = staticmethod(x)
329     z = property(getz, setz)
330
331 w = woef()
332 w.y(4321)
333 woef.x(1234)
334
335 woef.k = 1
336 woef.k
337
338 w.z = 14
339 print w.z
340
341 class base:
342     def x():
343         return 12
344
345     def gety(self):
346         return self.value
347     def sety(self, val):
348         self.value = val
349
350     x = staticmethod(x)
351     y = property(gety, sety)
352     z = 21
353
354 class der(base):
355     pass
356
357 print der.x()
358 derder = der()
359 derder.y = 99
360 print derder.y
361 #print der.z # XXX
362
363 #unaryadd
364 class V:
365     def __init__(self, x):
366         self.x = x
367     def __pos__(self):
368         return V(self.x+1)
369     def __neg__(self):
370         return V(self.x-1)
371     def __repr__(self):
372         return 'V(%d)' % self.x
373
374 v = V(1)
375 print ++v, +-+-v
376
377 #multidir fixes
378 from testdata import crap
379 print crap.incrap()
380 import bert
381 print bert.hello(1)
382 from testdata import crap2
383 crap2.incrap2()
384 import testdata.crap2
385 tc2c2 = testdata.crap2.crap2()
386
387 #int/double crap
388 def to_ints(l):
389     return [int(x) for x in l]
390
391 print to_ints([4.0, 4.0, 61]), to_ints((4.0, 4.0, 61))
392 print int(min(4.0, 4.0, 2))
393 print int(max(4.0, 4.0, 6))
394 print int(min(4.0, 4.0, 4.0, 2))
395 print int(max(4.0, 4.0, 4, 0, 6))
396 l = [6]
397 l.append(1.0)
398 print to_ints(l)
399
400 #assorted fixes
401 [1] != []
402
403 from collections import defaultdict
404 print sorted(defaultdict.fromkeys(range(7,10), 'a').items())
405 import collections
406 print sorted(collections.defaultdict.fromkeys(range(7,10), 'a').items())
407
408 from string import *
409 class string: pass
410 string.x = 4
411
412 ''', '''
413 output(equal=True)
414
415 '''),
416
417 ('''fixes for 0.0.26; os.path, defaultdict''', '''
418 #simple fixes
419 print 8+(2 if 1 else 3)
420 print repr('\\377ai\\37aoi\\001123\\00hoi\\01hoi\\0hoi')
421
422 # add_strs()
423 print 'x'+'x'+'x'
424
425 #os.path
426 import os.path
427
428 print os.path.join('heuk')
429 print os.path.join('heuk', 'emeuk')
430 print os.path.join('heuk', 'emeuk', 'meuk')
431
432 from os.path import *
433
434 print join('a','b','c')
435
436 realpath('ss.py')
437 commonprefix(['xxx', 'xxxx'])
438 normcase('hoei')
439 splitext('hoei/woei')
440 splitdrive('hoei/woei')
441 basename('hoei/woei')
442 dirname('hoei/woei')
443 exists('testdata')
444 lexists('testdata')
445 isdir('testdata')
446 isfile('testdata')
447
448 def bleh(arg, top, names):
449     pass
450 def bleh2(arg, top, names):
451     pass
452
453 walk('testdata', bleh, 77)
454 walk('testdata', bleh2, 'hoei')
455
456 getsize('ss.py')
457 getatime('ss.py')
458 getctime('ss.py')
459 getmtime('ss.py')
460
461 #locally overloading builtin definition 
462 str = '4'
463
464 t = ('aha', 2)
465 str, x = t
466
467 def heuk(str):
468     pass
469 heuk('aha')
470
471 for str in ['hah']:
472     pass
473 [0 for str in ['hah']]
474
475 for (str,bah) in [('hah', 'bah')]:
476     pass
477 [0 for (str,bah) in [('hah', 'bah')]]
478
479 #missing string methods
480 print 'ab\\ncd\\r\\nef\\rghi\\n'.splitlines()
481 print 'ab\\ncd\\r\\nef\\rghi\\n'.splitlines(1)
482 print int('This Is A Title'.istitle())
483 print int('This is not a title'.istitle())
484 print 'a and b and c'.partition('and')
485 print 'a and b and c'.rpartition('and')
486
487 #default argument problem
488 def msplit(sep=0, spl=-1):
489     return ['']
490
491 cnf = msplit()
492
493 #ctype
494 import string
495 print repr(string.lowercase)
496 print repr(string.uppercase)
497 print repr(string.letters)
498 print repr(string.printable)
499 print repr(string.punctuation)
500 print repr(string.whitespace)
501 print repr(string.digits)
502 print repr(string.hexdigits)
503 print repr(string.octdigits)
504
505 #dict.get problem
506 print {'wah': 2}.get('aap', 3)
507
508 #finish getopt
509 from getopt import getopt, gnu_getopt
510
511 args = ['-ahoei', '--alpha=4', 'meuk']
512
513 print getopt(args, "a:b", ["alpha=", "beta"])
514 print getopt(args, "a:b", {"alpha=" : 0, "beta" : 0})
515 print gnu_getopt(args, "a:b", ["alpha=", "beta"])
516 print gnu_getopt(args, "a:b", {"alpha=" : 0, "beta" : 0})
517 print getopt(args, "a:b", "alpha=")
518 print gnu_getopt(args, "a:b", "alpha=")
519
520 #OSError
521 import os
522
523 try:
524     os.chdir('ontehunoe')
525
526 except OSError, e:
527 #    print e
528 #    print repr(e)
529     print e.errno
530 #    print e.strerror
531     print e.filename
532
533 #int(), float(), str(); test all
534 print int(), float(), list(), dict(), set(), tuple(), frozenset(), # XXX repr(str())
535
536 #collections.defaultdict
537 from collections import defaultdict
538
539 s1 = 'mississippi'
540 d1 = defaultdict(int)
541 for k1 in s1:
542     d1[k1] += 1
543
544 print sorted(d1.items())
545
546 s2 = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
547 d2 = defaultdict(list)
548 for k2, v2 in s2:
549     d2[k2].append(v2)
550
551 print sorted(d2.items())
552
553 s3 = [('red', 1), ('blue', 2), ('red', 3), ('blue', 4), ('red', 1), ('blue', 4)]
554 d3 = defaultdict(set)
555 for k3, v3 in s3:
556     d3[k3].add(v3)
557
558 print sorted(d3.items())
559
560 ''', '''
561 output(equal=True)
562
563 '''),
564
565 ('''fixes for 0.0.25''', '''
566 # --- more aug assignment
567 f = -112
568 print f
569 f /= -3
570 print f, f / -3
571 f %= -3
572 print f
573 f //= -1
574 print f
575
576 d={}
577
578 somme = 9.0
579 i=4
580 j=5
581
582 d[i,j] = 3.0
583 d[i,j] += somme
584 d[i,j] *= somme
585 d[i,j] /= somme
586  
587 print d
588
589 e = {}
590 e[i,j] = -7
591 e[i,j] /= -2
592 e[i,j] *= -2
593 e[i,j] %= -2
594 e[i,j] //= -2
595
596 print e
597
598 # --- tests these for once
599 print max([1])
600 print max(1, 2)
601 print max(7.7, 7)
602 print max(7, 7.7)
603 print max(1, 2, 3)
604 print max(1, 2, 3, 4, 5)
605
606 print min([1])
607 print min(1, 2)
608 print min(6.7, 7)
609 print min(7, 6.7)
610 print min(1, 2, 3)
611 print min(1, 2, 3, 4, 5)
612
613 # --- virtual test case 1
614 class Z:
615     def boink(self, a):
616         pass
617
618     def beh(self):
619         print self.boink(9)
620
621 class Y(Z):
622     def boink(self, a):
623         return a
624
625 y = Y()
626 y.beh()
627
628 # --- virtual test case 2
629 class C:
630     def boink(self):
631         print 'C'
632
633 class D(C):
634     pass
635
636 class A(C):
637     def boink(self):
638         print 'A'
639
640 class B(C):
641     pass
642
643 c = D()
644 c.boink()
645
646 b = B()
647 b = A()
648 b.boink()
649
650 # --- virtual case 3
651 class CC:
652     pass
653
654 class AA(CC):
655     def __init__(self):
656         self.a = 4
657
658 class BB(CC):
659     def __init__(self):
660         self.a = 5
661
662 cc = AA()
663 cc = BB()
664 print cc.a
665
666 # --- just in case
667 this = 1
668
669 # --- good to test also
670 import struct
671
672 ''', '''
673 output(equal=True)
674 '''),
675
676 ('''fixes for 0.0.24''', '''
677 # --- import problem
678 from testdata.bert import *
679 z = zeug()
680
681 # --- '_' renaming mangle
682 import testdata.bert
683
684 class hello:
685     def hello(self):
686         testdata.bert.hello(1)
687
688 s=hello().hello()
689
690 ''', '''
691 output(equal=True)
692 '''),
693
694 ('''fixes for 0.0.23''', '''
695 # --- string formatting problem
696 print '%i%%-%i%%' % (1,2)
697 numbers = (1,2)
698 print '%i%%-%i%%' % numbers
699 print '%i%%-%s%%' % (12, '21')
700 t2 = (12, '21')
701 print '%i%%-%s%%' % t2
702
703 # --- aug assign problem (or: the value of testing)
704 a = [1,2,3,4,5]
705 c = a
706 b = [6,7,8,9,10]
707
708 a += b
709 print a, c
710
711 ah = '12345'
712 ch = ah
713 bh = '67890'
714 ah += bh
715 print ah, ch
716
717 # --- __iadd__ etc.
718 class C:
719     def __init__(self, value):
720         self.value = value 
721
722     def __iadd__(self, other):
723         self.value += other.value
724         return self
725
726     def __floordiv__(self, b):
727         return C(self.value // b.value)
728
729     def __ifloordiv__(self, b):
730         self.value //= b.value
731         return self
732
733     def __str__(self):
734         return str(self.value)
735
736 x = C(4)
737 x += x
738 x.__iadd__(x)
739 print x
740
741 print [1,2].__iadd__([2,3])
742
743 y = [1,2,3]
744 y += set([4,5])
745 print y
746
747 v = 3
748 v += 1.5
749 print v
750
751 hm = []
752 hm += set([1])
753 print hm
754
755 d = C(8)
756 print d // C(3)
757 d //= C(3) 
758 print d
759
760 # --- inheritance problem
761 class Maze(object):
762     def __init__(self):
763         self.maze = [[0]]
764         self.maze[0][0] |= 1
765
766 class ASCIIMaze(Maze):
767     pass
768         
769 maze = ASCIIMaze() 
770
771 ''', '''
772 output(equal=True)
773
774 '''),
775
776 ('''fixes for 0.0.22''', '''
777 # --- out of bounds can be okay 
778 a = range(5)
779 print a[:10], a[:10:2]
780 print a[-10:], a[-10::2]
781
782 # --- abs
783 class C:
784   def __abs__(self):
785       return self
786   def __neg__(self):
787       return self
788   def __repr__(self):
789       return 'C'
790
791 print abs(C()), abs(23), abs(-1.3), -abs(C())
792       
793 # --- str.translate problem
794 import string
795 atable = string.maketrans("bc", "ef")
796 print 'abcdeg'.translate(atable, "cde")
797 gtable = string.maketrans("", "")
798 word = 'aachen\\n'
799 key = word.translate(gtable, "a\\n")
800 print 'word', repr(word)
801
802 # --- string.{capitalize, capwords, swapcase, center, atoi, atol, atof}
803 print string.capitalize('hoi'), ' hoi'.capitalize()
804 print string.capwords('yo   momma')+'!'+string.capwords(' yo momma ')+'!'+string.capwords(' yo momma ', 'mm')+'!'
805 allchars = ''.join([chr(x) for x in range(256)])
806 print repr(allchars.swapcase()), repr(string.swapcase(allchars))
807 print string.center('hoi', 10), string.center('hoi', 10, 'u')
808 print 'hoi'.center(10, 'u')
809 for i in range(10):
810     print '!'+'hoi'.center(i)+'!'
811 print string.atoi('+0x10', 0), string.atol('-100l', 0), string.atof('-1.234')
812
813 # --- improve overloading
814 class D:
815     def __int__(self): return 7
816     def __float__(self): return 7.0
817     def __str__(self): return '__str__'
818     def __repr__(self): return '__repr__'
819     def __cmp__(self, b): return 1
820     def __nonzero__(self): return 1
821     def __len__(self): return 1
822
823 d = D()
824
825 print [0,1][bool(d)], str(d), int(d), float(d), max([d,d]), min([d,d])
826 if 5: print 5
827 if d: print 6
828
829 ''', '''
830 output(equal=True)
831
832
833 '''),
834
835 ('''fixes for 0.0.21; collections.deque''', '''
836 # iter.__len__
837 print len(xrange(10))
838
839 # try.. else
840 try: print 'probeer'
841 except Exception: pass
842 else: print 'geen exceptie..'
843
844 # collections 
845 from collections import deque
846
847 d = deque([3,2,1])
848 d.append(4)
849 d.appendleft(0)
850
851 print len(d)
852
853 for i in range(len(d)):
854     print d[i],
855 print
856
857 print d.pop(), d.popleft()
858
859 print d
860
861 while d:
862     print d
863     d.pop()
864
865 d = deque([3,2,1])
866 e = iter(d)
867 print [x for x in e]
868
869 d.extend(set([4,5]))
870 print d
871 d.extendleft(set([6,7]))
872 print d
873
874 print sorted(d), [e for e in reversed(d)]
875
876 d[2] = d[-2] = 4
877 print d
878
879 print [0,1][4 in d], [0,1][9 in d]
880
881 #d.remove(1) # python 2.5
882 #print d
883
884 d.rotate(3)
885 print d
886 d.rotate(-2)
887 print d
888
889 d = deque()
890 print d
891
892 d.rotate(1) # no error
893 print d
894
895 d.clear()
896 print d
897
898 d.extend(xrange(10))
899 del d[-4]
900 print d
901
902 print [e for e in reversed(deque(xrange(10)))]
903
904 # bisect
905 from bisect import *
906
907 def blah(s, e):
908     print bisect_left(s, e)
909     print bisect_left(s, e, 0)
910     print bisect_left(s, e, 0, len(s))
911     print bisect_right(s, e)
912     print bisect(s, e)
913
914     insort_left(s, e)
915     insort_right(s, e)
916     insort(s, e)
917     print s
918
919
920 blah([1,2,3,4,5,6,6,7], 4)
921 blah(['1','2','3','4','5','6','7'], '4')
922
923 # copy 
924 import copy
925
926 kb = [1,2]
927 ka = copy.copy(kb)
928 ka.append(3)
929 print ka, kb, copy.copy(178)
930
931 print copy.copy((1, 2)), copy.deepcopy((2, 3))
932 print copy.copy('1234'), copy.deepcopy('1234')
933 print copy.copy((1, '1')), copy.deepcopy((1, '1'))
934 print sorted(copy.copy(set([1, 2]))), sorted(copy.deepcopy(set([1, 2])))
935 print copy.copy({1 : 1.0}), copy.deepcopy({1.0 : 1})
936 print copy.copy(deque(range(10))), copy.deepcopy(deque(xrange(10)))
937
938 kc = [1,2]
939 kd = (kc,)
940 ke = copy.deepcopy(kd)
941 ke[0][0] = 3
942 print kd, ke
943
944 rll = [1, 2]
945 bll = [rll, rll]
946 cll = copy.deepcopy(bll)
947 cll[0].append(3)
948 print cll
949
950 class bert:
951     pass
952
953 abert = bert()
954 abert.a = 1
955
956 cbert = bert()
957 cbert.a = 1.0
958
959 print abert.a, cbert.a
960
961 copy.copy(abert)
962 copy.deepcopy(abert)
963
964 class dert:
965     pass
966
967 adert = dert()
968 adert.a = [1,2]
969
970 bdert = copy.copy(adert)
971 bdert = copy.deepcopy(adert)
972 bdert.a.append(3)
973
974 # reversed(xrange)
975 import random
976 random.seed(1)
977
978 for z in range(1000):
979     l,u,s = random.randrange(-5,5), random.randrange(-5,5), random.randrange(-5,5)
980     print l, u, s
981     
982     try:
983         x = xrange(l,u,s)
984         y = reversed(xrange(l,u,s))
985
986         xl = [e for e in x]
987         yl = [e for e in y]
988
989         print xl, yl, [0, 1][xl == list(reversed(yl))]
990
991     except ValueError, v:
992         print v
993
994 # for _ in (x)range
995 total = 0
996 for _ in range(10):
997     for _ in range(10):
998         total += 1
999 print total
1000
1001 print [0 for _ in range(10)]
1002
1003 # remove ifa_empty_constructors
1004 fromage = []
1005 def non_internal(ptree):
1006     noni = [c for c in ptree]
1007
1008 ptree = [1,2]
1009 row_pointers = [None, ptree]
1010 non_internal(row_pointers[1])
1011
1012 # string.maketrans
1013 import string
1014 si = 'abcde'
1015 t1 = string.maketrans('abc', 'xyz')
1016 print si.translate(t1)
1017
1018 # optimize dict[..] += ..
1019 dd = {}
1020 dd['hoi'] = 0
1021 dd['hoi'] += 10
1022 print dd['hoi']
1023
1024
1025 ''', '''
1026 output(equal=True)
1027
1028
1029 '''),
1030
1031 ('''fixes for 0.0.20''', '''
1032 # --- division revisited
1033 print -496 // 3, 496 // 3, -496 // -3, 496 // -3
1034 print -496.0 // 3.0, 496.0 // 3.0, -496.0 // -3.0, 496.0 // -3.0
1035 print -496.0 // 3, 496 // 3.0, -496.0 // -3, 496 // -3.0
1036 print -496 / 3, 496 / 3, -496 / -3, 496 / -3
1037
1038 print '%g' % (-496.0 / 3.0), '%g' % (496.0 / 3.0), '%g' % (-496.0 / -3.0), '%g' % (496.0 / -3.0) # XXX no '%g'
1039 print '%g' % (-496.0 / 3), '%g' % (496 / 3.0), '%g' % (-496.0 / -3), '%g' % (496 / -3.0)
1040
1041 xx, yy, zz = divmod(-496, 3), divmod(-496.0, 3), divmod(-496, 3.0)
1042 print xx, yy, zz
1043
1044 print divmod(-496, 3), divmod(496, 3), divmod(-496, -3), divmod(496,-3)
1045 print divmod(-496.0, 3.0), divmod(496.0, 3.0), divmod(-496.0, -3.0), divmod(496.0,-3.0)
1046 print divmod(-496.0, 3), divmod(496, 3.0), divmod(-496.0, -3), divmod(496,-3.0)
1047
1048 # --- don't crash
1049 print [0]*-4, (0,)*-4, repr('0'*-4)
1050
1051 # --- list.extend takes iterable
1052 w = [1,2]
1053 w.extend(set([3]))
1054 print w
1055
1056 # --- use %.12g to print floats
1057 print 1/3.0, 1.1234123412341234, 9.12341234e20, 1.1, 8.0
1058
1059 # --- slice assignment (random test) 
1060 import random
1061 random.seed(10)
1062
1063 for x in range(1000):
1064     l,u,s = random.randrange(-5,5), random.randrange(-5,5), random.randrange(-5,5)
1065     a = range(5)
1066     print a, 'lower', l, 'upper', u, 'step', s
1067     try:
1068         z = range(random.randrange(0,5))
1069         print 'xrange', z
1070         a[l:u:s] = z
1071         print 'done', a
1072     except ValueError, v:
1073         print v
1074         
1075 ax = range(10)
1076 ax[-2:-3] = [0,1]
1077 print ax
1078
1079 # --- do not print space after 14
1080 print 14,
1081 print
1082 print 'boe'
1083
1084 # --- aug assignment revisited
1085 class hoepa:
1086     def __init__(self):
1087         self.elems = [1,2,3]
1088         self.smurf = 1
1089     def __getitem__(self, index):
1090         print 'get', index
1091         return self.elems[index]
1092     def __setitem__(self, index, elem):
1093         print 'set', index, elem
1094         self.elems[index] = elem
1095
1096 uh = hoepa()
1097
1098 uh[2] = 3
1099 print uh[2]
1100 uh[2] += 4
1101 print uh.elems
1102  
1103 ux = 1
1104 ux += 1
1105 print ux
1106
1107 uy = [1]
1108 uy += [2]
1109 print uy
1110
1111 uh.smurf += 1
1112 print uh.smurf
1113
1114 blah = [1,2,4]
1115 blah[2] += 5
1116 print blah
1117
1118 ud = {'7': 7}
1119 print ud['7']
1120 ud['7'] = 8
1121 ud['7'] += 1
1122 print ud
1123
1124 class hoepa2:
1125     def __init__(self):
1126        self.hop = {}
1127     def __getitem__(self, index):
1128         print 'get', index
1129         return self.hop[index]
1130     def __setitem__(self, index, elem):
1131         print 'set', index, elem
1132         self.hop[index] = elem
1133     def __delitem__(self, index):
1134         del self.hop[index]
1135
1136 yh = hoepa2()
1137 yh[1,2] = 10
1138 yh[1,2] += 10
1139 print yh[1,2]
1140
1141 # --- __delitem__
1142 print yh.hop
1143 del yh[1,2] 
1144 print yh.hop
1145
1146 yx = [1,2,3]
1147 del yx[1]
1148 print yx
1149
1150 # --- some string tests
1151 import string
1152 print string.join(['a','b'])
1153 print string.join(['a','b'], '_')
1154 print string.find('abc', 'b')
1155 print string.find('abc', 'b', 0)
1156 print string.find('abc', 'b', 0, 3)
1157 print string.split('a b c')
1158 print string.split('a b c', ' ')
1159 print string.split('a b c', ' ', 1)
1160 print string.replace('abc', 'c', 'd') 
1161 print string.replace('abc', 'c', 'd', 1) 
1162 print string.count('abc', 'b')
1163 print string.count('abc', 'b', 0)
1164 print string.count('abc', 'b', 0, 3)
1165 print string.expandtabs('abc')
1166 print string.expandtabs('abc', 4)
1167 print string.strip(' abc ')
1168 print string.strip('xabcx', 'x')
1169 print string.ljust('abc', 8)
1170 print string.ljust('abc', 8, '_')
1171 print string.rsplit('a b c', ' ', 1)
1172
1173 # --- recursive generator test
1174 def A003714():
1175     yield 1
1176     for x in A003714():
1177         yield 2*x
1178         if not (x & 1):
1179             yield 2*x+1
1180
1181 hop = A003714()
1182 for x in range(20):
1183     print hop.next(),
1184 print
1185
1186 # --- allow 'self' as formal argument in non-method function
1187 def blahx(self, x):
1188     print self, x
1189 blahx(18, 19)
1190
1191
1192 ''', '''
1193 output(equal=True)
1194
1195 '''),
1196
1197 ('''random module''', '''
1198
1199 import random
1200
1201 # --- module-level functions
1202 random.seed(37)
1203 rstate = random.getstate()   # (state is not cross-compatible with CPython)
1204 random.setstate(rstate)
1205 for i in range(25):
1206     print "%.8f" % random.random()
1207     print random.randrange(-30,15)
1208     print random.randrange(-15,15,3)
1209     print random.randint(50,100)
1210     fibs = [0,1,1,2,3,5,8,13,21]
1211     print fibs
1212     print random.choice(fibs)
1213     print random.sample(fibs,3)
1214     random.shuffle(fibs)
1215     print fibs
1216     nums = [3.141, 2.71828, 1.41421, 1.0]
1217     print nums
1218     print random.choice(nums)
1219     print random.sample(nums,3)
1220     random.shuffle(nums)
1221     print nums
1222     print "%.8f" % random.uniform(-0.5,0.5)
1223     print "%.8f" % random.normalvariate(0.0, 1.0)
1224     print "%.8f" % random.lognormvariate(0.0, 1.0)
1225     print "%.8f" % random.expovariate(1.0)
1226     print "%.8f" % random.vonmisesvariate(0.0, 1.0)
1227     print "%.8f" % random.gammavariate(20.0, 1.0)
1228     print "%.8f" % random.gauss(0.0, 1.0)
1229     print "%.8f" % random.betavariate(3.0, 3.0)
1230     print "%.8f" % random.paretovariate(1.0)
1231     print "%.8f" % random.weibullvariate(1.0, 1.0)
1232     #print "%.8f" % random.stdgamma(1.0,1.0,1.0,1.0) # deprecated in CPython
1233     #print "%.8f" % random.cunifvariate(0.0,1.0)     # deprecated in CPython
1234     print random.getrandbits(8)
1235     print random.getrandbits(16)
1236     print random.getrandbits(30)
1237     print ''
1238
1239 # --- (test set for RNGs)
1240 def runrng(r):
1241     print "%.8f" % r.random()
1242     print r.randrange(0,10)
1243     print r.randrange(-10,10,2)
1244     print r.randint(-5,5)
1245     fibs = [0,1,1,2,3,5,8,13,21]
1246     print fibs
1247     print r.choice(fibs)
1248     print r.sample(fibs,4)
1249     r.shuffle(fibs)
1250     print fibs
1251     nums = [3.141, 2.71828, 1.41421, 1.0]
1252     print nums
1253     print random.choice(nums)
1254     print random.sample(nums,1)
1255     random.shuffle(nums)
1256     print nums
1257     print "%.8f" % r.uniform(-0.5,0.5)
1258     print "%.8f" % r.normalvariate(0.0, 1.0)
1259     print "%.8f" % r.lognormvariate(0.0, 1.0)
1260     print "%.8f" % r.expovariate(1.0)
1261     print "%.8f" % r.vonmisesvariate(0.0, 1.0)
1262     print "%.8f" % r.gammavariate(20.0, 1.0)
1263     print "%.8f" % r.gauss(0.0, 1.0)
1264     print "%.8f" % r.betavariate(3.0, 3.0)
1265     print "%.8f" % r.paretovariate(1.0)
1266     print "%.8f" % r.weibullvariate(1.0, 1.0)
1267     #print "%.8f" % r.stdgamma(1.0, 1.0, 1.0, 1.0) # deprecated in CPython
1268     #print "%.8f" % r.cunifvariate(0.0, 1.0)       # deprecated in CPython
1269     print ''
1270
1271 # --- random.Random (Mersenne Twister)
1272 mt = random.Random()
1273 mt.seed()
1274 mt.seed(79)
1275 mtstate = mt.getstate()   # (state is not cross-compatible with CPython)
1276 mt.setstate(mtstate)
1277 #mt.jumpahead(1000000)    # (not yet supported)
1278 for i in range(25): runrng(mt)
1279
1280 # --- random.WichmannHill
1281 wh = random.WichmannHill()
1282 wh.seed()
1283 wh.seed(86)
1284 wh.whseed()
1285 wh.whseed(41)
1286 whstate = wh.getstate()   # (state is not cross-compatible with CPython)
1287 wh.setstate(whstate)
1288 wh.jumpahead(1000000)
1289 for i in range(25): runrng(wh)
1290
1291 ''', '''
1292 output(equal=True)
1293
1294 '''),
1295
1296 ('''fixes for 0.0.19; iterators''', '''
1297 # --- math.pow 
1298 import math
1299 print int(math.pow(2,3))
1300 print pow(2.0,3.0)
1301 print pow(2,3.0)
1302 print pow(2.0,3)
1303 print pow(2,3)
1304 print pow(1000,1000,1234)
1305
1306 # --- end-of-file problem
1307 print [l for l in file('testdata/scene.txt') if l.startswith('material')]
1308
1309 # --- append '.0' when printing 'integer' floats (but not in case of %g!)
1310 print 8.0, '%g' % 8.0
1311
1312 # --- iterators
1313 b = [1,2,3]
1314 for a in b:
1315     print a, 
1316 print
1317 print [a for a in b]
1318
1319 g = iter(b)
1320 for x in range(3):
1321     print g.next(),
1322 print
1323 print [n for n in iter(b)]
1324
1325 h = iter(b)
1326 e = iter(h)
1327 for f in e:
1328     print f,
1329 print
1330
1331 i = [1,2,3]
1332 i = iter(i)
1333 i = [1,2,3]
1334
1335 for j in i:
1336     print j,
1337 print
1338
1339 print [j for j in i]
1340
1341 print [y for y in 'stroop']
1342 print [n for n in {1: '1', 2: '2', 3: '3'}]
1343 print [z for z in [[1],[2],[3]]]
1344 print sorted([m for m in set([1.0,2.0,3.0])])
1345 print [l for l in file('testdata/hoppa')]
1346
1347 # --- generators
1348
1349 def blah(a):
1350     while a > 0:
1351         yield a
1352         yield 17 
1353         a -= 1
1354
1355 hop = blah(3)
1356 for x in range(4):
1357     print hop.next(),
1358 print
1359 hop = blah(1)
1360 try:
1361     for x in range(4):
1362         print hop.next(),
1363     print
1364 except StopIteration:
1365     print 'klaar.'
1366
1367 # --- verify some things still work
1368 import os.path
1369 print os.path.split('hoempa/nohu')
1370 import math
1371 print '%g' % math.log(10)
1372
1373 # --- % revisited 
1374 print -2 % 3
1375 print 2 % 3
1376 print math.fmod(-2.0, 3)
1377 print -2.0 % 3
1378 print 4 % 3
1379 print 4 % 3.0
1380 print math.fmod(2.0, -3)
1381 print -2.0 % -3
1382 print -2.0 % -3.0
1383 print 2.0 % -3.0
1384 print '%g' % 3.0
1385
1386 # --- and/or revisited
1387 print 0 or 5 or 4
1388 print 0 or 0
1389 print 1 > 2 or 3
1390 ax = [1]
1391 ax = []
1392 bx = [2]
1393 print ax or bx
1394 print [0,1][(ax or None) is None]
1395 print bx or None
1396 print None or bx
1397 print 1 and 4, 4 and 1
1398 print bx and []
1399
1400 def ef(x):
1401     print 'hah', x
1402     return 0
1403 ef(5) and ef(6)
1404
1405 # --- allow mixing when result is not used
1406 n = 1
1407 n < 0 or bx
1408 bx and n > 1
1409
1410 # --- make this compile (XXX we shouldn't implicitly call parent constructors though)
1411 class smurf:
1412     def __init__(self, a=-1):
1413         print 'hallo', a
1414      
1415 class baviaan(smurf):
1416     def __init__(self, a=-1):
1417         print 'oehoehoe', a
1418
1419 smurf()
1420 baviaan()
1421
1422 # --- simple itertools functions
1423 #import itertools
1424 #gg = itertools.count()
1425 #print [gg.next() for i in range(10)]
1426 #
1427 #cycle = itertools.cycle(range(3))
1428 #print [cycle.next() for i in range(10)]
1429 #
1430 #repeat = itertools.repeat([1,2,3], 10)
1431 #print [repeat.next() for i in range(3)]
1432
1433 # --- xrange, enumerate, reversed as iterators
1434 ah = xrange(10)
1435 for x in ah: print x,
1436 print
1437 ah = xrange(0,10,3)
1438 for x in ah: print x,
1439 print
1440 ah = xrange(10,0,-3)
1441 for x in ah: print x,
1442 print
1443
1444 bh = enumerate(xrange(10,0,-3))
1445 print [y for y in bh]
1446 ch = enumerate([(1.0, 's') for x in range(4)])
1447 print [z for z in ch]
1448
1449 print [zz for zz in reversed(range(10))]
1450 print [zzz for zzz in reversed(xrange(10))]
1451
1452 # --- dict.{iterkeys, itervalues, iteritems}
1453 waa = {1: '2', 2: '4'}
1454
1455 for wax in waa.iterkeys():
1456     print wax,
1457 print
1458 for way in waa.itervalues():
1459     print way,
1460 print
1461 for wat in waa.iteritems():
1462     print wat,
1463 print
1464
1465 ''', '''
1466 output(equal=True)
1467
1468 '''),
1469
1470 ('''fixes for 0.0.18''', '''
1471 # --- model list.__str__ call to elem.__repr__
1472 class Vertex(object):
1473     def __repr__(self):
1474         return 'rrrepr'
1475 print [Vertex()]
1476
1477 # --- always true/false, but should work
1478 print [0,1][isinstance(7.0, float)]
1479 print [0,1][isinstance(7, int)]
1480
1481 # --- initialize class attrs in .cpp file
1482 class blah:
1483     blah = 'blah'
1484     blah2 = ('blah', 'blah')
1485     blah3 = abs(-1)
1486 print blah.blah, blah.blah2, blah.blah3
1487
1488 # --- inf
1489 a,b = -1e500, 1e500; print a,b
1490
1491 # --- argh
1492 print sorted('hopla')
1493
1494 # --- dict<void *, void*> *
1495 d = {}
1496 print d
1497
1498 # --- cl attr problem
1499 class FilebasedMazeGame: 
1500     hop = 18
1501     def __init__(self):
1502         a = FilebasedMazeGame.hop
1503         print a
1504
1505 FilebasedMazeGame()
1506
1507 # --- define cl before use
1508 def print_aap():
1509     aap = Aap()
1510     print aap
1511
1512 class Aap:
1513     def __repr__(self):
1514         return 'hrngh!'
1515
1516 print_aap()
1517
1518 # --- virtual case
1519 class hop:
1520     def hop(self):
1521         self.hop2()
1522
1523 class hop2(hop):
1524     def hop2(self):
1525         print 'hop2'
1526
1527 hop2().hop()
1528
1529 # --- str.split
1530 s = " foo zbr bar "
1531
1532 print "default separator:"
1533 print s.split(None)
1534 print s.split(None, 0)
1535 print s.split(None, 1)
1536  
1537 print "space separator:"
1538 print s.split(' ')
1539 print s.split(' ', 0)
1540
1541 # --- comparison
1542 class g: pass
1543 e, f = g(), g()
1544 print (e < f) + (e > f), [0,1][e == f]
1545
1546 ''', '''
1547 output(equal=True)
1548
1549 '''),
1550
1551 ('''fixes for 0.0.17''', '''
1552 # --- assignment expressions
1553 bweh = (2,[4,6])
1554 [a, (b,c)] = bweh
1555 print a,b,c
1556 (a,b), (c,d) = (6,9), (8,7)
1557 print a,b,c,d
1558 [(a,b), (c,d)] = (9,8), (7,6)
1559 print a,b,c,d
1560 [(a,b), (c,d)] = [(1,8), (7,2)]
1561 print a,b,c,d
1562 [[a,b],c] = (5,6),3
1563 print a,b,c
1564 [[a,b],c] = [[4,5],6]
1565 print a,b,c
1566 a, [b,c] = [1, (2,3)]
1567 print a,b,c 
1568 a, (b,c,d) = 1, (1,2,3)
1569 print a,b,c,d
1570 [(a,b), [c,d]] = [[1,2], (3,4)]
1571 print a,b,c,d
1572 njeh = [[8,7,6],[5,4,3],[2,1,0]]
1573 [[a,b,c],[d,e,f],[g,h,i]] = njeh
1574 print a,b,c,d,e,f,g,h,i
1575 [dx,[a,b,c],ex] = njeh
1576 print dx,a,b,c,ex
1577 blah = (1,2,3,4,5,6)
1578 a,b,c,d,e,f = blah
1579 print a,b,c,d,e,f
1580
1581 # --- underscore in assignment
1582 _ = 4
1583 a, _ = 1, '2'
1584 huh = 1, 2
1585 _, b = huh
1586 mtx = [[1,2,3],[4,5,6],[6,7,8]]
1587 [du, [x, y, _], _] = mtx
1588 print du, x, y
1589 hop = [(1,(2,3))]
1590 for _ in hop: print 'hop'
1591 for _, (a,b) in hop: print 'hop', a, b
1592 for a, (_,b) in hop: print 'hop', a, b
1593 for a, _ in hop: print 'hop', a
1594 print ['hop' for _ in hop]
1595 print ['hop %d %d' % (a,b) for _, [a,b] in hop]
1596 print ['hop %d %d' % (a,b) for a, [_,b] in hop]
1597 print ['hop %d' % a for a, _ in hop]
1598
1599 # --- except 'tuple'
1600 for a in range(2):
1601     try:
1602         if not a: assert 1 > 2, 'parasmurf'
1603         else: {1:2}[3]
1604     except (AssertionError, KeyError), m:
1605         print 'foutje3 of 4', m
1606
1607 # --- getopt.GetoptError test
1608 import getopt
1609 try:
1610     opts, args = getopt.getopt(['-x'], 'nf:', ['nowrap', 'flags='])
1611 except getopt.GetoptError:
1612     print 'fout'
1613
1614 ''', '''
1615 output(equal=True)
1616
1617 '''),
1618
1619 ('''frozenset''', '''
1620 a = frozenset([1])
1621 d = a & a
1622 d = a | a
1623 d = a - a
1624 d = a ^ a
1625 print a, d
1626
1627 c = set([1,2])
1628 e = set([])
1629 f = set()
1630 print c, e, f
1631     
1632 g = frozenset([1])
1633 h = {}
1634 h[g] = 4
1635 print h
1636 h[frozenset([3,2,1])] = 5
1637 del h[frozenset([1])]
1638 for x in h:
1639     print sorted(x), h[x]
1640
1641 try:
1642     {set([1]): 1}
1643 except TypeError, m:
1644     print m
1645     
1646 z,y  = [(1,2),(3,), (4,5,6)], [(3,),(4,5,6),(1,2)]
1647 v, w = frozenset(z), frozenset(y)
1648 print 'eq', [0, 1][v == w]
1649 print 'hash', [0, 1][hash(v) == hash(w)]
1650
1651 k = set([1])
1652 k = frozenset([2])
1653
1654 ''', '''
1655 output(equal=True)
1656
1657 '''),
1658
1659 ('''fixes for 0.0.16''', '''
1660 print '', 
1661 print 'hoi', 'huh',
1662 print 'hophop'
1663 print '', 
1664 print 'beh'
1665
1666 print [1,2,3,1].index(1)
1667 print [1,2,3,1].index(1, 1)
1668 print [1,2,3,1].index(1, -1)
1669 print [1,2,3,1].index(1, -4)
1670 print [1,2,3,1].index(1, -3, 4)
1671
1672 def RemoveElts(list):
1673    newlist=list[:]
1674    return newlist
1675 print RemoveElts([3])
1676
1677 try:
1678     try: 
1679        {1:2}[3]
1680     except KeyError, e:
1681        raise e
1682 except KeyError, m:
1683     print m
1684
1685 blah = set([])
1686 blah.add(1)
1687 print blah
1688
1689 def MergeAndVerify(newModList,finalModHash):
1690     if newModList == []:
1691         return finalModHash
1692
1693
1694 ''', '''
1695 output(equal=True)
1696
1697 '''),
1698
1699 ('''fixes for 0.0.14''', '''
1700 # optional start/end arguments for str.{count, startswith, endswith}
1701
1702 def hop(b):
1703     if b: print 1
1704     else: print 0
1705
1706 hop('hoi'.startswith('ho', 0))
1707 hop('hoi'.startswith('ho', 0, 3))
1708 hop('hoi'.startswith('ho', 0, -1))
1709 hop('hoi'.endswith('oi'))
1710 hop('hoi'.endswith('oi', 0, 3))
1711 hop('hoi'.endswith('ho', 0, -1))
1712 hop('hoi'.endswith('ho', -3, 2))
1713 hop('hoi'.startswith(':', 3))
1714 hop('hoi:'.startswith(':', 3))
1715
1716 print 'hoooi'.count('o')
1717 print 'hoooi'.count('o', 2)
1718 print 'hoooi'.count('o', 0, -2)
1719
1720 # mother contour (6,5) -> (1,1) instead of (1,5)
1721 def getopt(args, longopts):
1722     opts = []
1723     opts.append(('',))
1724
1725     do_longs(opts, longopts)
1726
1727 def do_longs(opts, longopts):
1728     [o for o in longopts] 
1729
1730 wa = ['']
1731
1732 getopt(wa, wa)
1733
1734 # cStringIO.StringIO, file.seek 
1735 import cStringIO, sys
1736
1737 s = cStringIO.StringIO(file('testdata/hopsakee').read())
1738 print s.readlines()
1739
1740 s = file('testdata/hopsakee')
1741 print s.read()
1742
1743 f = file('testdata/hopsakee')
1744 print f.read()
1745 f.seek(0)
1746 print f.read()
1747 f.close()
1748
1749 s = cStringIO.StringIO('blaat')
1750 s.seek(-3, 2)
1751 print s.read()
1752
1753 s = cStringIO.StringIO() 
1754 s.write('hallo\\njoh')
1755 s.seek(0, 0)
1756 print s.readlines()
1757 s.seek(0, 0)
1758 s.write('hoi')
1759 print s.readlines()
1760
1761 blah = set([])
1762
1763 ''', '''
1764 output(equal=True)
1765
1766 '''),
1767
1768 ('''new print/mod/file implementation''', '''
1769 print 1, 2, '3', '%.2f' % 4.1
1770 print '%04x' % 0xfeda
1771
1772 # '..' % (..)
1773 print '%d %x %d' % (10, 11, 12)
1774 print '%d %s' % (1, 'een')
1775 print '%d %s %.2f' % (1, 'een', 8.1)
1776
1777 # '..' % tuple
1778 t = (10, 11, 12)
1779 print '%x %d %x' % t
1780 t2 = ('twee', 2)
1781 print '%s %04x' % t2
1782
1783 # mod
1784 a = '%04x' % 0xdefa
1785 print a, a, '%02x' % 0x1234
1786
1787 # all chars
1788 print '%o' % 10
1789 print "%.4s %.4r\\n" % ("abcdefg", "\\0hoplakee")
1790
1791 # print to file
1792 f = file('testdata/binf', 'w')
1793 print >>f, 'ik haat %04x\\n' % 0xfeda, 'smurven..\\n'
1794 f.close()
1795
1796 # conversions
1797 print repr('?%% %c?' % 70), repr('?%c?%%' % 0), '%c' % 'X'
1798 print '!%s!' % [1,2,3]
1799 print '%.2f %d %.2f %d' % (4, 4.4, 5.5, 5)
1800 print '%s.' % 1, '%s.' % (1,)
1801
1802 # %s, %r
1803 print repr(18), repr('x')
1804 print 'aha %s %r' % (18, 19)
1805
1806 # class file 
1807 f = file('testdata/hopsakee')
1808 print 1, f.readline(),
1809 print f.readline(5)
1810 print f.readline(),
1811 f.close()
1812
1813 print 2, file('testdata/hopsakee').read()
1814
1815 print 3, file('testdata/hopsakee').readlines()
1816
1817 for line in file('testdata/hopsakee'):
1818     print 'aha', line,
1819
1820
1821 ''', '''
1822 output(equal=True)
1823
1824 '''),
1825
1826 ('''fixes for 0.0.13''', '''
1827 # basic string module support
1828 import string
1829 print string.join(['hello', 'world!']), string.join(['hello', 'world!'], '_')
1830
1831 # add random.shuffle
1832 import random
1833 l = [1,2,3,4,5]
1834 random.shuffle(l)
1835 print set(l)
1836
1837 # add __or__ to builtin.int..
1838 class c: # grr
1839    def a(self):         
1840        return 1|1      
1841    def b(self):
1842        return 1&1
1843    def c(self):
1844        return 1^1
1845    def d(self):
1846        return ~1
1847
1848 a_c = c()           
1849 print a_c.a(), a_c.b(), a_c.c(), a_c.d()
1850
1851 # fake child nodes conflicting for binary tuples (e.g. one for unit and one for first)
1852 class LowLevel:
1853    def comRxHeader(self):
1854        ('a', 'h')
1855        (7, 8)
1856
1857 bsl = LowLevel()
1858 bsl.comRxHeader()
1859
1860 # self.mergeinh instead of self.merge XXX fix others
1861 class LowLevel2:
1862    def bslTxRx(self, addr): 
1863        addr % 2
1864
1865 class BootStrapLoader2(LowLevel2):
1866     pass
1867
1868 bsl2 = BootStrapLoader2()
1869 bsl2.bslTxRx(0) 
1870
1871 # improve parent constructor calls
1872 class L:
1873     def __init__(self):
1874         pass
1875
1876 class BSL(L):
1877     def __init__(self, a, b):
1878         L.__init__(self)
1879
1880 BSL(1, 2)
1881
1882 # for/while-else construction
1883 bla = True
1884 while bla:
1885     for a in range(10):
1886         for b in range(10):
1887             pass
1888         else:
1889             print 'bah1'
1890         while bla:
1891             bla = False
1892             break
1893         else:
1894             print 'bah4'
1895         break
1896     else:
1897         print 'bah2'
1898 else:
1899     print 'bah3'
1900
1901 # user-defined exception class problems
1902 class MyException(Exception):
1903     pass
1904
1905 try:
1906     raise MyException('hoepa')
1907 except MyException, m:
1908     print m
1909
1910 # parent constructor call and default arguments
1911 class LowLevel3:
1912     def __init__(self, a=1):
1913         pass
1914
1915 class BootStrapLoader3(LowLevel3):
1916     def __init__(self):
1917         LowLevel3.__init__(self)
1918
1919 BootStrapLoader3() 
1920
1921 ''', '''
1922 output(equal=True)
1923
1924 '''),
1925
1926 ('''fixes for 0.0.12''', '''
1927 import time
1928 time.sleep(1.01)
1929
1930 import sys
1931 #print 'Python version:', sys.version
1932 sys.stdout.flush()
1933
1934 a = '\\001\\00\\0boink'
1935 print repr('hello, world')
1936 print repr('hello\\0, world2')
1937
1938 print 'hello, world'
1939 print repr('hello\\0, world2') # XXX no repr!
1940
1941 print repr(a), len(a)
1942 print repr(chr(0)), len(chr(0)+chr(0))
1943 print repr('\\0')
1944 print repr(''.join([chr(i) for i in range(256)]))
1945
1946 class behh:
1947     def __init__(self, a, b, c):
1948         pass
1949
1950 behh(1,2,c=3)
1951
1952 # sudoku solver!! see: http://markbyers.com/moinmoin/moin.cgi/ShortestSudokuSolver
1953 def r(a):
1954   i=a.find('0')
1955   if not ~i: print a; sys.exit()
1956   [m in [a[j] for j in range(81) if not (i-j)%9*(i/9^j/9)*(i/27^j/27|i%9/3^j%9/3)] or r(a[:i]+m+a[i+1:]) for m in '3814697265625']
1957   return 1 # because the type of an 'or' clause is the superset of its terms, we cannot (implicitly) return None here
1958
1959 r(81*'0')
1960
1961 ''', '''
1962 output(equal=True)
1963
1964 '''),
1965
1966 ('''fixes for 0.0.11''', '''
1967 class City(object):
1968     def __init__(self):
1969         self.latitude = 1
1970
1971 class SortedTree(object):
1972     def __init__(self, compareKey): 
1973         self.compareKey = compareKey
1974
1975 class Map(object):
1976     def __init__(self):
1977         st = SortedTree(lambda x: x.latitude)
1978         st.compareKey(c)
1979
1980 c = City()
1981 m = Map()
1982
1983 print "1, 3, 5".replace(",", "")
1984 print "1, 3, 5".replace(",", "", -1)
1985 print "1, 3, 5".replace(",", "", 0)
1986 print "1, 3, 5".replace(",", "", 1)
1987
1988 a = []
1989 a = [[]]
1990 a = [[1]]
1991
1992 b = []
1993 b = [1]
1994
1995 d = ()
1996 d = (5,)
1997
1998 print a, b, d
1999
2000 def bla(t):
2001     print t
2002
2003 bla(())
2004 bla((1,))
2005
2006 def oink():
2007     return [[1]]
2008     return [[]]
2009
2010 oink()
2011
2012 def test(t=()):
2013   if t: 
2014       print t
2015   else: 
2016       test(t + (5,))
2017   
2018 test()
2019
2020 e = {}
2021 e[2,3] = 4
2022
2023 f = {}
2024 f[5] = 6
2025
2026 print e, f
2027
2028 import os
2029 x = os.listdir('.')
2030
2031 ''', '''
2032 output(equal=True)
2033
2034 '''),
2035
2036 ('''fixes for 0.0.10''', '''
2037 bla = {}
2038 meuk = (12, 13)
2039 z = (5,(3,4))
2040
2041 bla[1], (c, d) = z
2042 print bla
2043
2044 class X: pass
2045 x = X()
2046
2047 for x.z in [1,2,3]: print x.z
2048 x.y, (c, d) = z
2049
2050 print x.y, x.z
2051
2052 s = ['a', 'b', 'c']
2053 s = 'abc'
2054 for y in s: print y
2055 print
2056 print s, str(s), repr(s)
2057
2058 t2 = 1, 'een'
2059 print '%d %s' % t2
2060
2061 f = dict([(1,'1'), (2, '2')])
2062 print f
2063
2064 ''', '''
2065 output(equal=True)
2066
2067 '''),
2068
2069 ('''richards benchmark''', '''
2070 #  Based on original version written in BCPL by Dr Martin Richards
2071 #  in 1981 at Cambridge University Computer Laboratory, England
2072 #  and a C++ version derived from a Smalltalk version written by
2073 #  L Peter Deutsch.
2074 #  Translation from C++, Mario Wolczko
2075 #  Outer loop added by Alex Jacoby
2076
2077 # Task IDs
2078 I_IDLE = 1
2079 I_WORK = 2
2080 I_HANDLERA = 3
2081 I_HANDLERB = 4
2082 I_DEVA = 5
2083 I_DEVB = 6
2084
2085 # Packet types
2086 K_DEV = 1000
2087 K_WORK = 1001
2088
2089 # Packet
2090
2091 BUFSIZE = 4
2092
2093 BUFSIZE_RANGE = range(BUFSIZE)
2094
2095 class Packet(object):
2096     def __init__(self,l,i,k):
2097         self.link = l
2098         self.ident = i
2099         self.kind = k
2100         self.datum = 0
2101         self.data = [0] * BUFSIZE
2102
2103     def append_to(self,lst):
2104         self.link = None
2105         if lst is None:
2106             return self
2107         else:
2108             p = lst
2109             next = p.link
2110             while next is not None:
2111                 p = next
2112                 next = p.link
2113             p.link = self
2114             return lst
2115
2116 # Task Records
2117
2118 class TaskRec(object):
2119     pass
2120
2121 class DeviceTaskRec(TaskRec):
2122     def __init__(self):
2123         self.pending = None
2124
2125 class IdleTaskRec(TaskRec):
2126     def __init__(self):
2127         self.control = 1
2128         self.count = 10000
2129
2130 class HandlerTaskRec(TaskRec):
2131     def __init__(self):
2132         self.work_in = None
2133         self.device_in = None
2134
2135     def workInAdd(self,p):
2136         self.work_in = p.append_to(self.work_in)
2137         return self.work_in
2138
2139     def deviceInAdd(self,p):
2140         self.device_in = p.append_to(self.device_in)
2141         return self.device_in
2142
2143 class WorkerTaskRec(TaskRec):
2144     def __init__(self):
2145         self.destination = I_HANDLERA
2146         self.count = 0
2147 # Task
2148
2149 class TaskState(object):
2150     def __init__(self):
2151         self.packet_pending = True
2152         self.task_waiting = False
2153         self.task_holding = False
2154
2155     def packetPending(self):
2156         self.packet_pending = True
2157         self.task_waiting = False
2158         self.task_holding = False
2159         return self
2160
2161     def waiting(self):
2162         self.packet_pending = False
2163         self.task_waiting = True
2164         self.task_holding = False
2165         return self
2166
2167     def running(self):
2168         self.packet_pending = False
2169         self.task_waiting = False
2170         self.task_holding = False
2171         return self
2172         
2173     def waitingWithPacket(self):
2174         self.packet_pending = True
2175         self.task_waiting = True
2176         self.task_holding = False
2177         return self
2178         
2179     def isPacketPending(self):
2180         return self.packet_pending
2181
2182     def isTaskWaiting(self):
2183         return self.task_waiting
2184
2185     def isTaskHolding(self):
2186         return self.task_holding
2187
2188     def isTaskHoldingOrWaiting(self):
2189         return self.task_holding or (not self.packet_pending and self.task_waiting)
2190
2191     def isWaitingWithPacket(self):
2192         return self.packet_pending and self.task_waiting and not self.task_holding
2193
2194
2195
2196
2197
2198 tracing = False
2199 layout = 0
2200
2201 def trace(a):
2202     global layout
2203     layout -= 1
2204     if layout <= 0:
2205         print
2206         layout = 50
2207     print a
2208     print a,
2209
2210
2211 TASKTABSIZE = 10
2212
2213 class TaskWorkArea(object):
2214     def __init__(self):
2215         self.taskTab = [None] * TASKTABSIZE
2216
2217         self.taskList = None
2218
2219         self.holdCount = 0
2220         self.qpktCount = 0
2221
2222 taskWorkArea = TaskWorkArea()
2223
2224 class Task(TaskState):
2225
2226
2227     def __init__(self,i,p,w,initialState,r):
2228         self.link = taskWorkArea.taskList
2229         self.ident = i
2230         self.priority = p
2231         self.input = w
2232
2233         self.packet_pending = initialState.isPacketPending()
2234         self.task_waiting = initialState.isTaskWaiting()
2235         self.task_holding = initialState.isTaskHolding()
2236
2237         self.handle = r
2238
2239         taskWorkArea.taskList = self
2240         taskWorkArea.taskTab[i] = self
2241
2242     def fn(self,pkt,r):
2243         raise NotImplementedError
2244
2245
2246     def addPacket(self,p,old):
2247         if self.input is None:
2248             self.input = p
2249             self.packet_pending = True
2250             if self.priority > old.priority:
2251                 return self
2252         else:
2253             p.append_to(self.input)
2254         return old
2255
2256
2257     def runTask(self):
2258         if self.isWaitingWithPacket():
2259             msg = self.input
2260             self.input = msg.link
2261             if self.input is None:
2262                 self.running()
2263             else:
2264                 self.packetPending()
2265         else:
2266             msg = None
2267
2268         self
2269         return self.fn(msg,self.handle)
2270
2271
2272     def waitTask(self):
2273         self.task_waiting = True
2274         return self
2275
2276
2277     def hold(self):
2278         taskWorkArea.holdCount += 1
2279         self.task_holding = True
2280         return self.link
2281
2282
2283     def release(self,i):
2284         t = self.findtcb(i)
2285         t.task_holding = False
2286         if t.priority > self.priority:
2287             return t
2288         else:
2289             return self
2290
2291
2292     def qpkt(self,pkt):
2293         t = self.findtcb(pkt.ident)
2294         taskWorkArea.qpktCount += 1
2295         pkt.link = None
2296         pkt.ident = self.ident
2297         return t.addPacket(pkt,self)
2298
2299
2300     def findtcb(self,id):
2301         t = taskWorkArea.taskTab[id]
2302         if t is None:
2303             raise Exception("Bad task id %d" % id)
2304         return t
2305             
2306
2307 # DeviceTask
2308
2309
2310 class DeviceTask(Task):
2311     def __init__(self,i,p,w,s,r):
2312         Task.__init__(self,i,p,w,s,r)
2313
2314     def fn(self,pkt,r):
2315         d = r
2316         assert isinstance(d, DeviceTaskRec)
2317         if pkt is None:
2318             pkt = d.pending
2319             if pkt is None:
2320                 return self.waitTask()
2321             else:
2322                 d.pending = None
2323                 return self.qpkt(pkt)
2324         else:
2325             d.pending = pkt
2326             if tracing: trace(pkt.datum)
2327             return self.hold()
2328
2329
2330
2331 class HandlerTask(Task):
2332     def __init__(self,i,p,w,s,r):
2333         Task.__init__(self,i,p,w,s,r)
2334
2335     def fn(self,pkt,r):
2336         h = r
2337         assert isinstance(h, HandlerTaskRec)
2338         if pkt is not None:
2339             if pkt.kind == K_WORK:
2340                 h.workInAdd(pkt)
2341             else:
2342                 h.deviceInAdd(pkt)
2343         work = h.work_in
2344         if work is None:
2345             return self.waitTask()
2346         count = work.datum
2347         if count >= BUFSIZE:
2348             h.work_in = work.link
2349             return self.qpkt(work)
2350
2351         dev = h.device_in
2352         if dev is None:
2353             return self.waitTask()
2354
2355         h.device_in = dev.link
2356         dev.datum = work.data[count]
2357         work.datum = count + 1
2358         return self.qpkt(dev)
2359
2360 # IdleTask
2361
2362
2363 class IdleTask(Task):
2364     def __init__(self,i,p,w,s,r):
2365         Task.__init__(self,i,0,None,s,r)
2366
2367     def fn(self,pkt,r):
2368         i = r
2369         assert isinstance(i, IdleTaskRec)
2370         i.count -= 1
2371         if i.count == 0:
2372             return self.hold()
2373         elif i.control & 1 == 0:
2374             i.control /= 2
2375             return self.release(I_DEVA)
2376         else:
2377             i.control = i.control/2 ^ 0xd008
2378             return self.release(I_DEVB)
2379             
2380
2381 # WorkTask
2382
2383
2384 A = ord('A')
2385
2386 class WorkTask(Task):
2387     def __init__(self,i,p,w,s,r):
2388         Task.__init__(self,i,p,w,s,r)
2389
2390     def fn(self,pkt,r):
2391         w = r
2392         assert isinstance(w, WorkerTaskRec)
2393         if pkt is None:
2394             return self.waitTask()
2395
2396         if w.destination == I_HANDLERA:
2397             dest = I_HANDLERB
2398         else:
2399             dest = I_HANDLERA
2400
2401         w.destination = dest
2402         pkt.ident = dest
2403         pkt.datum = 0
2404
2405         for i in BUFSIZE_RANGE: # xrange(BUFSIZE)
2406             w.count += 1
2407             if w.count > 26:
2408                 w.count = 1
2409             pkt.data[i] = A + w.count - 1
2410
2411         return self.qpkt(pkt)
2412
2413 import time
2414
2415
2416
2417 def schedule():
2418     t = taskWorkArea.taskList
2419     while t is not None:
2420         pkt = None
2421
2422         if tracing:
2423             print "tcb =",t.ident
2424
2425         #print '*', t.__class__
2426
2427         if t.isTaskHoldingOrWaiting():
2428             t = t.link
2429         else:
2430             if tracing: trace(chr(ord("0")+t.ident))
2431             t = t.runTask()
2432
2433 class Richards(object):
2434
2435     def run(self, iterations):
2436         for i in xrange(iterations):
2437             taskWorkArea.holdCount = 0
2438             taskWorkArea.qpktCount = 0
2439
2440             IdleTask(I_IDLE, 1, 10000, TaskState().running(), IdleTaskRec())
2441
2442             wkq = Packet(None, 0, K_WORK)
2443             wkq = Packet(wkq , 0, K_WORK)
2444             WorkTask(I_WORK, 1000, wkq, TaskState().waitingWithPacket(), WorkerTaskRec())
2445
2446             wkq = Packet(None, I_DEVA, K_DEV)
2447             wkq = Packet(wkq , I_DEVA, K_DEV)
2448             wkq = Packet(wkq , I_DEVA, K_DEV)
2449             HandlerTask(I_HANDLERA, 2000, wkq, TaskState().waitingWithPacket(), HandlerTaskRec())
2450
2451             wkq = Packet(None, I_DEVB, K_DEV)
2452             wkq = Packet(wkq , I_DEVB, K_DEV)
2453             wkq = Packet(wkq , I_DEVB, K_DEV)
2454             HandlerTask(I_HANDLERB, 3000, wkq, TaskState().waitingWithPacket(), HandlerTaskRec())
2455
2456             wkq = None;
2457             DeviceTask(I_DEVA, 4000, wkq, TaskState().waiting(), DeviceTaskRec());
2458             DeviceTask(I_DEVB, 5000, wkq, TaskState().waiting(), DeviceTaskRec());
2459             
2460             schedule()
2461
2462             if taskWorkArea.holdCount == 9297 and taskWorkArea.qpktCount == 23246:
2463                 pass
2464             else:
2465                 return False
2466
2467         return True
2468
2469 r = Richards()
2470 iterations = 10
2471 result = r.run(iterations)
2472 print result
2473 ''', '''
2474 output('1\\n')
2475
2476 '''),
2477
2478 ('''pystone benchmark''', ''' 
2479 # (c) Reinhold P. Weicker,  CACM Vol 27, No 10, 10/84 pg. 1013.
2480 # --- Translated from ADA to C by Rick Richardson.
2481 # --- Translated from C to Python by Guido van Rossum.
2482
2483 from time import clock
2484
2485 LOOPS = 50000
2486 Ident1, Ident2, Ident3, Ident4, Ident5 = range(1,6)
2487
2488 class Record:
2489     def __init__(self, PtrComp = None, Discr = 0, EnumComp = 0,
2490                        IntComp = 0, StringComp = ''): # XXX '' should be None
2491         self.PtrComp = PtrComp
2492         self.Discr = Discr
2493         self.EnumComp = EnumComp
2494         self.IntComp = IntComp
2495         self.StringComp = StringComp
2496
2497     def copy(self):
2498         return Record(self.PtrComp, self.Discr, self.EnumComp,
2499                       self.IntComp, self.StringComp)
2500
2501 TRUE = 1
2502 FALSE = 0
2503
2504 def main(loops=LOOPS):
2505     benchtime, stones = pystones(loops)
2506 #    print "Pystone(%s) time for %d passes = %g" % \
2507 #          (__version__, loops, benchtime)
2508 #    print "This machine benchmarks at %g pystones/second" % stones
2509     print 'ugh', benchtime, stones
2510     print "This machine benchmarks at %f pystones/second" % stones
2511
2512
2513 def pystones(loops=LOOPS):
2514     return Proc0(loops)
2515
2516 IntGlob = 0
2517 BoolGlob = FALSE
2518 Char1Glob = ' ' # ! 
2519 Char2Glob = ' '
2520 Array1Glob = [0]*51
2521 #Array2Glob = map(lambda x: x[:], [Array1Glob]*51)
2522 Array2Glob = [x[:] for x in [Array1Glob]*51]
2523 PtrGlb = None
2524 PtrGlbNext = None
2525
2526 def Proc0(loops=LOOPS):
2527     global IntGlob
2528     global BoolGlob
2529     global Char1Glob
2530     global Char2Glob
2531     global Array1Glob
2532     global Array2Glob
2533     global PtrGlb
2534     global PtrGlbNext
2535
2536     starttime = clock()
2537     for i in range(loops):
2538         pass
2539     nulltime = clock() - starttime
2540
2541     PtrGlbNext = Record()
2542     PtrGlb = Record()
2543     PtrGlb.PtrComp = PtrGlbNext
2544     PtrGlb.Discr = Ident1
2545     PtrGlb.EnumComp = Ident3
2546     PtrGlb.IntComp = 40
2547     PtrGlb.StringComp = "DHRYSTONE PROGRAM, SOME STRING"
2548     String1Loc = "DHRYSTONE PROGRAM, 1'ST STRING"
2549     Array2Glob[8][7] = 10
2550
2551     starttime = clock()
2552
2553     for i in range(loops):
2554         Proc5()
2555         Proc4()
2556         IntLoc1 = 2
2557         IntLoc2 = 3
2558         String2Loc = "DHRYSTONE PROGRAM, 2'ND STRING"
2559         EnumLoc = Ident2
2560         BoolGlob = not Func2(String1Loc, String2Loc)
2561         while IntLoc1 < IntLoc2:
2562             IntLoc3 = 5 * IntLoc1 - IntLoc2
2563             IntLoc3 = Proc7(IntLoc1, IntLoc2)
2564             IntLoc1 = IntLoc1 + 1
2565         Proc8(Array1Glob, Array2Glob, IntLoc1, IntLoc3)
2566         PtrGlb = Proc1(PtrGlb)
2567         CharIndex = 'A'
2568         while CharIndex <= Char2Glob:
2569             if EnumLoc == Func1(CharIndex, 'C'):
2570                 EnumLoc = Proc6(Ident1)
2571             CharIndex = chr(ord(CharIndex)+1)
2572         IntLoc3 = IntLoc2 * IntLoc1
2573         IntLoc2 = IntLoc3 / IntLoc1
2574         IntLoc2 = 7 * (IntLoc3 - IntLoc2) - IntLoc1
2575         IntLoc1 = Proc2(IntLoc1)
2576
2577     benchtime = clock() - starttime - nulltime
2578     return benchtime, (loops / benchtime)
2579
2580 def Proc1(PtrParIn):
2581     PtrParIn.PtrComp = NextRecord = PtrGlb.copy()
2582     PtrParIn.IntComp = 5
2583     NextRecord.IntComp = PtrParIn.IntComp
2584     NextRecord.PtrComp = PtrParIn.PtrComp
2585     NextRecord.PtrComp = Proc3(NextRecord.PtrComp)
2586     if NextRecord.Discr == Ident1:
2587         NextRecord.IntComp = 6
2588         NextRecord.EnumComp = Proc6(PtrParIn.EnumComp)
2589         NextRecord.PtrComp = PtrGlb.PtrComp
2590         NextRecord.IntComp = Proc7(NextRecord.IntComp, 10)
2591     else:
2592         PtrParIn = NextRecord.copy()
2593     NextRecord.PtrComp = None
2594     return PtrParIn
2595
2596 def Proc2(IntParIO):
2597     IntLoc = IntParIO + 10
2598     while 1:
2599         if Char1Glob == 'A':
2600             IntLoc = IntLoc - 1
2601             IntParIO = IntLoc - IntGlob
2602             EnumLoc = Ident1
2603         if EnumLoc == Ident1:
2604             break
2605     return IntParIO
2606
2607 def Proc3(PtrParOut):
2608     global IntGlob
2609
2610     if PtrGlb is not None:
2611         PtrParOut = PtrGlb.PtrComp
2612     else:
2613         IntGlob = 100
2614     PtrGlb.IntComp = Proc7(10, IntGlob)
2615     return PtrParOut
2616
2617 def Proc4():
2618     global Char2Glob
2619
2620     BoolLoc = Char1Glob == 'A'
2621     BoolLoc = BoolLoc or BoolGlob
2622     Char2Glob = 'B'
2623
2624 def Proc5():
2625     global Char1Glob
2626     global BoolGlob
2627
2628     Char1Glob = 'A'
2629     BoolGlob = FALSE
2630
2631 def Proc6(EnumParIn):
2632     EnumParOut = EnumParIn
2633     if not Func3(EnumParIn):
2634         EnumParOut = Ident4
2635     if EnumParIn == Ident1:
2636         EnumParOut = Ident1
2637     elif EnumParIn == Ident2:
2638         if IntGlob > 100:
2639             EnumParOut = Ident1
2640         else:
2641             EnumParOut = Ident4
2642     elif EnumParIn == Ident3:
2643         EnumParOut = Ident2
2644     elif EnumParIn == Ident4:
2645         pass
2646     elif EnumParIn == Ident5:
2647         EnumParOut = Ident3
2648     return EnumParOut
2649
2650 def Proc7(IntParI1, IntParI2):
2651     IntLoc = IntParI1 + 2
2652     IntParOut = IntParI2 + IntLoc
2653     return IntParOut
2654
2655 def Proc8(Array1Par, Array2Par, IntParI1, IntParI2):
2656     global IntGlob
2657
2658     IntLoc = IntParI1 + 5
2659     Array1Par[IntLoc] = IntParI2
2660     Array1Par[IntLoc+1] = Array1Par[IntLoc]
2661     Array1Par[IntLoc+30] = IntLoc
2662     for IntIndex in range(IntLoc, IntLoc+2):
2663         Array2Par[IntLoc][IntIndex] = IntLoc
2664     Array2Par[IntLoc][IntLoc-1] = Array2Par[IntLoc][IntLoc-1] + 1
2665     Array2Par[IntLoc+20][IntLoc] = Array1Par[IntLoc]
2666     IntGlob = 5
2667
2668 def Func1(CharPar1, CharPar2):
2669     CharLoc1 = CharPar1
2670     CharLoc2 = CharLoc1
2671     if CharLoc2 != CharPar2:
2672         return Ident1
2673     else:
2674         return Ident2
2675
2676 def Func2(StrParI1, StrParI2):
2677     IntLoc = 1
2678     while IntLoc <= 1:
2679         if Func1(StrParI1[IntLoc], StrParI2[IntLoc+1]) == Ident1:
2680             CharLoc = 'A'
2681             IntLoc = IntLoc + 1
2682     if CharLoc >= 'W' and CharLoc <= 'Z':
2683         IntLoc = 7
2684     if CharLoc == 'X':
2685         return TRUE
2686     else:
2687         if StrParI1 > StrParI2:
2688             IntLoc = IntLoc + 7
2689             return TRUE
2690         else:
2691             return FALSE
2692
2693 def Func3(EnumParIn):
2694     EnumLoc = EnumParIn
2695     if EnumLoc == Ident3: return TRUE
2696     return FALSE
2697
2698 main(LOOPS)
2699
2700 ''', '''
2701 output()
2702
2703 '''),
2704
2705 ('''fixes for 0.0.8''', '''
2706 def appl(predicate, x): return predicate(x)
2707 print [0,1][appl(lambda n: n>5, 10)], [0,1][appl(lambda n: n>10, 8)]
2708
2709 def split(seq, predicate):
2710     pair = [], []
2711     for el in seq:
2712         pair[not predicate(el)].append(el)
2713     return pair
2714 print split(range(-5,6), lambda n: n%2==0)
2715
2716 class Obj:
2717     def __init__(self, n): self.n = n
2718     def __gt__(self, other): return self.n > other.n
2719     def __str__(self): return str(self.n)
2720 def mymax(seq):
2721     maxval = seq[0]
2722     for el in seq:
2723         if el > maxval: # gives error
2724             maxval = el
2725     return maxval
2726 l = [Obj(i) for i in xrange(100)]
2727 print mymax(l), mymax(range(100))
2728
2729 class Num:
2730     def __init__(self, n): self.n = float(n)
2731     def __str__(self): return str(self.n)
2732     def __add__(self, other): return Num(self.n + other.n)
2733 print sum([Num(i) for i in range(5)], Num(0))
2734 print sum(range(5))
2735
2736 for a in 1,2: print a
2737 for a in [1,2]: print a
2738 for a in 1,2,3: print a
2739
2740 print 'aaaa'.replace('a','b', 2)
2741 print 'aaaa'.replace('a','b', -1)
2742
2743 print 'aaaa'.split('a', 2)
2744 print 'aaaa'.split('a', -1)
2745
2746 ''', '''
2747 output(equal=True)
2748 #output("1 0\\n([-4, -2, 0, 2, 4], [-5, -3, -1, 1, 3, 5])\\n99 99\\n10.0\\n10\\n1\\n2\\n1\\n2\\n1\\n2\\n3\\nbbaa\\nbbbb\\n['', '', 'aa']\\n['', '', '', '', '']\\n")
2749
2750 '''),
2751
2752 ('''pythonchess speed test engine''', '''
2753 # This is an extremely simple chess like speed test program written in Python
2754 # This program can be distributed under GNU General Public License Version 2.
2755 # (C) Jyrki Alakuijala 2005
2756 #
2757 # Despite its looks, this program was written in Python, not converted to it.
2758 # This program is incomplete, castlings, enpassant situation etc. are not properly implemented
2759 # game ending is not recognized. The evaluator as simple as it ever could be. 
2760 #
2761 # The board is an 160-element array of ints, Nones and Booleans,
2762 # The board contains the real board in squares indexed in variable 'squares'
2763 # The oversized board is to allow for "0x88" chess programming trick for move generation.
2764 # Other board data:
2765 # 4x castling flags, indices [10-13], queen side white, king side white, queen side black, king side white
2766 # turn, enpassant [26, 27]
2767
2768 from copy import copy
2769
2770 iNone = -999
2771 iTrue = 1
2772 iFalse = 0
2773
2774 setup = (4, 2, 3, 5, 6, 3, 2, 4, iNone, iNone) + (True,)*4 + (iNone, iNone) + \
2775   (1,) * 8 + (iNone, iNone, True, iNone, iNone, iNone, iNone, iNone,) + \
2776   ((0, ) * 8 + (iNone,) * 8) * 4 + \
2777   (-1,) * 8 + (iNone,) * 8 + \
2778   (-4, -2, -3, -5, -6, -3, -2, -4) + (iNone,) * 40
2779
2780 squares = tuple([i for i in range(128) if not i & 8])
2781 knightMoves = (-33, -31, -18, -14, 14, 18, 31, 33)
2782 bishopLines = (tuple(range(17, 120, 17)), tuple(range(-17, -120, -17)), tuple(range(15, 106, 15)), tuple(range(-15, -106, -15)))
2783 rookLines = (tuple(range(1, 8)), tuple(range(-1, -8, -1)), tuple(range(16, 128, 16)), tuple(range(-16, -128, -16)))
2784 queenLines = bishopLines + rookLines
2785 kingMoves = (-17, -16, -15, -1, 1, 15, 16, 17)
2786
2787 linePieces = ((), (), (), bishopLines, rookLines, queenLines, (), (), queenLines, rookLines, bishopLines, (), ())
2788
2789 clearCastlingOpportunities = [None] * 0x80
2790 for (i, v) in ((0x0, (10,)), (0x4, (10, 11)), (0x7, (11,)), (0x70, (12,)), (0x74, (12, 13)), (0x77, (13,))):
2791   clearCastlingOpportunities[i] = v
2792
2793 pieces = ".pnbrqkKQRBNP"
2794
2795 def evaluate(board):
2796   evals = (0, 100, 300, 330, 510, 950, 100000, -100000, -950, -510, -330, -300, -100)
2797   return sum([evals[board[i]] for i in squares])
2798
2799 def printBoard(board):
2800   for i in range(7,-1,-1):
2801     for j in range(8):
2802       ix = i * 16 + j
2803       print pieces[board[ix]],
2804     print
2805
2806 def move(board, mv):
2807   ix = (mv >> 8) & 0xff
2808   board[mv & 0xff] = board[ix]
2809   board[ix] = 0
2810   if clearCastlingOpportunities[ix]:
2811     for i in clearCastlingOpportunities[ix]:
2812       board[i] = False
2813
2814   board[26] = not board[26] # Turn
2815   if (mv & 0x7fff0000) == 0:
2816     return
2817   if (mv & 0x01000000): # double step
2818     board[27] = mv & 7
2819   else:
2820     board[27] = iNone # no enpassant
2821   if (mv & 0x04000000): # castling
2822     toix = mv & 0xff
2823     if toix == 0x02:
2824       board[0x00] = 0
2825       board[0x03] = 4
2826     elif toix == 0x06:
2827       board[0x07] = 0
2828       board[0x05] = 4
2829     elif toix == 0x72:
2830       board[0x70] = 0
2831       board[0x73] = -4
2832     elif toix == 0x76:
2833       board[0x77] = 0
2834       board[0x75] = -4
2835     else:
2836       raise "faulty castling"
2837   if mv & 0x08000000: # enpassant capture
2838     if board[26]: # turn after this move
2839       board[mv & 0x07 + 64] = 0
2840     else:
2841       board[mv & 0x07 + 48] = 0
2842   if mv & 0x10000000: # promotion
2843     a = (mv & 0xff0000) >> 16
2844     if (a >= 0x80):
2845       a = a - 0x100 
2846     board[mv & 0xff] = a
2847
2848 def toString(move):
2849   fr = (move >> 8) & 0xff
2850   to = move & 0xff
2851   letters = "abcdefgh"
2852   numbers = "12345678"
2853   mid = "-"
2854   if (move & 0x04000000):
2855     if (move & 0x7) == 0x02:
2856       return "O-O-O"
2857     else:
2858       return "O-O"
2859   if move & 0x02000000:
2860     mid = "x"
2861   retval = letters[fr & 7] + numbers[fr >> 4] + mid + letters[to & 7] + numbers[to >> 4]
2862   return retval
2863
2864 def moveStr(board, strMove):
2865   moves = pseudoLegalMoves(board)
2866   for m in moves:
2867     if strMove == toString(m):
2868       move(board, m)
2869       return
2870   for m in moves:
2871     print toString(m)
2872   raise "no move found", strMove
2873
2874 def rowAttack(board, attackers, ix, dir):
2875   own = attackers[0]
2876   for k in [i + ix for i in dir]:
2877     if k & 0x88:
2878       return False
2879     if board[k]:
2880       return (board[k] * own < 0) and board[k] in attackers
2881
2882 def nonpawnAttacks(board, ix, color):
2883   return (max([board[ix + i] == color * 2 for i in knightMoves]) or 
2884           max([rowAttack(board, (color * 3, color * 5), ix, bishopLine) for bishopLine in bishopLines]) or
2885           max([rowAttack(board, (color * 4, color * 5), ix, rookLine) for rookLine in rookLines]))
2886
2887 nonpawnBlackAttacks = lambda board, ix: nonpawnAttacks(board, ix, -1)
2888 nonpawnWhiteAttacks = lambda board, ix: nonpawnAttacks(board, ix, 1)
2889
2890 def pseudoLegalMovesWhite(board):
2891   retval = pseudoLegalCapturesWhite(board)
2892   for sq in squares:
2893     b = board[sq]
2894     if b >= 1:
2895       if b == 1 and not (sq + 16 & 0x88) and board[sq + 16] == 0:
2896         if sq >= 16 and sq < 32 and board[sq + 32] == 0:
2897           retval.append(sq * 0x101 + 32)
2898         retval.append(sq * 0x101 + 16)
2899       elif b == 2:
2900         for k in knightMoves:
2901           if board[k + sq] == 0:
2902             retval.append(sq * 0x101 + k)
2903       elif b == 3 or b == 5:
2904         for line in bishopLines:
2905           for k in line:
2906             if (k + sq & 0x88) or board[k + sq] != 0:
2907               break
2908             retval.append(sq * 0x101 + k)
2909       if b == 4 or b == 5:
2910         for line in rookLines:
2911           for k in line:
2912             if (k + sq & 0x88) or board[k + sq] != 0:
2913               break
2914             retval.append(sq * 0x101 + k)
2915       elif b == 6:
2916         for k in kingMoves:
2917           if not (k + sq & 0x88) and board[k + sq] == 0:
2918             retval.append(sq * 0x101 + k)
2919   if (board[10] and board[1] == 0 and board[2] == 0 and board[3] == 0 and
2920       not -1 in board[17:22] and
2921       not nonpawnBlackAttacks(board, 2) and not nonpawnBlackAttacks(board, 3) and not nonpawnBlackAttacks(board, 4)):
2922     retval.append(0x04000000 + 4 * 0x101 - 2)
2923   if (board[11] and board[5] == 0 and board[6] == 0 and
2924       not -1 in board[19:24] and
2925       not nonpawnBlackAttacks(board, 4) and not nonpawnBlackAttacks(board, 5) and not nonpawnBlackAttacks(board, 6)):
2926     retval.append(0x04000000 + 4 * 0x101 + 2)
2927   return retval
2928
2929 def pseudoLegalMovesBlack(board):
2930   retval = pseudoLegalCapturesBlack(board)
2931   for sq in squares:
2932     b = board[sq]
2933     if b < 0:
2934       if b == -1 and not (sq + 16 & 0x88) and board[sq - 16] == 0:
2935         if sq >= 96 and sq < 112 and board[sq - 32] == 0:
2936           retval.append(sq * 0x101 - 32)
2937         retval.append(sq * 0x101 - 16)
2938       elif b == -2:
2939         for k in knightMoves:
2940           if board[k + sq] == 0:
2941             retval.append(sq * 0x101 + k)
2942       elif b == -3 or b == -5: 
2943         for line in bishopLines:
2944           for k in line:
2945             if (k + sq & 0x88) or board[k + sq] != 0:
2946               break
2947             retval.append(sq * 0x101 + k)
2948
2949       if b == -4 or b == -5:
2950         for line in rookLines:
2951           for k in line:
2952             if (k + sq & 0x88) or board[k + sq] != 0:
2953               break
2954             retval.append(sq * 0x101 + k)
2955       elif b == -6: 
2956         for k in kingMoves:
2957           if not (k + sq & 0x88) and board[k + sq] == 0:
2958             retval.append(sq * 0x101 + k)
2959   if (board[12] and board[0x71] == 0 and board[0x72] == 0 and board[0x73] == 0 and
2960       not 1 in board[0x61:0x65] and
2961       not nonpawnWhiteAttacks(board, 0x72) and not nonpawnWhiteAttacks(board, 0x73) and not nonpawnWhiteAttacks(board, 0x74)):
2962     retval.append(0x04000000 + 0x74 * 0x101 - 2)
2963   if (board[11] and board[0x75] == 0 and board[0x76] == 0 and
2964       not -1 in board[0x63:0x68] and
2965       not nonpawnWhiteAttacks(board, 0x74) and not nonpawnWhiteAttacks(board, 0x75) and not nonpawnWhiteAttacks(board, 0x76)):
2966     retval.append(0x04000000 + 0x74 * 0x101 + 2)
2967   return retval
2968
2969 def pseudoLegalMoves(board):
2970   if board[26]:
2971     return pseudoLegalMovesWhite(board)
2972   else:
2973     return pseudoLegalMovesBlack(board)
2974
2975 def pseudoLegalCapturesWhite(board):
2976   retval = []
2977   for sq in squares:
2978     b = board[sq]
2979     if b >= 1:
2980       if b == 1: 
2981         if not (sq + 17 & 0x88) and board[sq + 17] < 0:
2982           retval.append(0x02000000 + sq * 0x101 + 17)
2983         if not (sq + 15 & 0x88) and board[sq + 15] < 0:
2984           retval.append(0x02000000 + sq * 0x101 + 15)
2985         if sq >= 64 and sq < 72 and abs((sq & 7) - board[27]) == 1: # enpassant
2986           retval.append(0x02000000 + sq * 0x100 + (sq & 0x70) + 16 + board[27])
2987       elif b == 2:
2988         for k in knightMoves:
2989           if not (sq + k & 0x88) and board[k + sq] < 0:
2990             retval.append(0x02000000 + sq * 0x101 + k)
2991       elif b == 6:
2992         for k in kingMoves:
2993           if not(k + sq & 0x88) and board[k + sq] < 0:
2994             retval.append(0x02000000 + sq * 0x101 + k)
2995       else:
2996         for line in linePieces[b]:
2997           for k in line:
2998             if (sq + k & 0x88) or board[k + sq] >= 1:
2999               break
3000             if board[k + sq] < 0:
3001               retval.append(0x02000000 + sq * 0x101 + k)
3002               break
3003   return retval
3004
3005 def pseudoLegalCapturesBlack(board):
3006   retval = []
3007   for sq in squares:
3008     b = board[sq]
3009     if b < 0:
3010       if b == -1: 
3011         if board[sq - 17] >= 1:
3012           retval.append(0x02000000 + sq * 0x101 - 17)
3013         if board[sq - 15] >= 1:
3014           retval.append(0x02000000 + sq * 0x101 - 15)
3015         if sq >= 48 and sq < 56 and abs((sq & 7) - board[27]) == 1: # enpassant
3016           retval.append(0x0a000000 + sq * 0x100 + (sq & 0x70) - 16 + board[27])
3017       elif b == -2:
3018         for k in knightMoves:
3019           if not (sq + k & 0x88) and board[k + sq] >= 1:
3020             retval.append(0x02000000 + sq * 0x101 + k)
3021       elif b == -3:
3022         for line in bishopLines:
3023           for k in line:
3024             if board[k + sq] < 0:
3025               break
3026             if board[k + sq] >= 1:
3027               retval.append(0x02000000 + sq * 0x101 + k)
3028               break
3029       elif b == -4:
3030         for line in rookLines:
3031           for k in line:
3032             if board[k + sq] < 0:
3033               break
3034             if board[k + sq] >= 1:
3035               retval.append(0x02000000 + sq * 0x101 + k)
3036               break
3037       elif b == -5:
3038         for line in queenLines:
3039           for k in line:
3040             if board[k + sq] < 0:
3041               break
3042             if board[k + sq] >= 1:
3043               retval.append(0x02000000 + sq * 0x101 + k)
3044               break
3045       elif b == -6:
3046         for k in kingMoves:
3047           if board[k + sq] >= 1:
3048             retval.append(0x02000000 + sq * 0x101 + k)
3049   return retval
3050
3051 def pseudoLegalCaptures(board):
3052   if board[26]:
3053     return pseudoLegalCapturesWhite(board)
3054   else:
3055     return pseudoLegalCapturesBlack(board)
3056
3057 def legalMoves(board):
3058   allMoves = pseudoLegalMoves(board)
3059   retval = []
3060   #from copy import copy
3061   kingVal = 6
3062   if board[26]:
3063     kingVal = -kingVal
3064   for mv in allMoves:
3065     board2 = copy(board)
3066     move(board2, mv)
3067     #print "trying to reduce move", toString(mv)
3068     if not [i for i in pseudoLegalCaptures(board2) if board2[i & 0xff] == kingVal]:
3069       retval.append(mv)
3070   return retval
3071
3072 def alphaBetaQui(board, alpha, beta, n):
3073   e = evaluate(board)
3074   if not board[26]:
3075     e = -e
3076   if e >= beta:
3077     return (beta, iNone) # XXX
3078   if (e > alpha): 
3079     alpha = e
3080   bestMove = iNone # XXX
3081   if n >= -4:
3082     #from copy import copy
3083     for mv in pseudoLegalCaptures(board):
3084       newboard = copy(board)
3085       move(newboard, mv)
3086       value = alphaBetaQui(newboard, -beta, -alpha, n - 1)
3087       value = (-value[0], value[1])
3088       if value[0] >= beta:
3089         return (beta, mv)
3090       if (value[0] > alpha):
3091         alpha = value[0]
3092         bestMove = mv
3093   return (alpha, bestMove)
3094
3095 def alphaBeta(board, alpha, beta, n):
3096   if n == 0:
3097     return alphaBetaQui(board, alpha, beta, n)
3098 #  from copy import copy
3099   bestMove = iNone # XXX
3100
3101   for mv in legalMoves(board):
3102     newboard = copy(board)
3103     move(newboard, mv)
3104     value = alphaBeta(newboard, -beta, -alpha, n - 1)
3105     value = (-value[0], value[1])
3106     if value[0] >= beta:
3107       return (beta, mv)
3108     if (value[0] > alpha):
3109       alpha = value[0]
3110       bestMove = mv
3111   return (alpha, bestMove)
3112
3113 def speedTest():
3114   board = list(setup)
3115   moveStr(board, "c2-c4")
3116   moveStr(board, "e7-e5")
3117   moveStr(board, "d2-d4")
3118
3119   res = alphaBeta(board, -99999999, 99999999, 4)
3120   print res
3121   moveStr(board, "d7-d6")
3122   res = alphaBeta(board, -99999999, 99999999, 4)
3123   print res
3124
3125 speedTest()
3126 ''', '''
3127 output('(0, 33571891)\\n(0, 33567556)\\n')
3128
3129 '''),
3130
3131 ('''final batch of minor fixes for 0.0.6''', '''
3132 print 'he\\\\"'
3133
3134 class A:
3135     def __init__(self):
3136         pass
3137
3138 a = A()
3139 a.__init__()
3140
3141 class B:
3142     def __init__(self, n):
3143         print 'b init with', n
3144
3145     def huhu(self):
3146         self.__init__(4)
3147
3148 b = B(5)
3149 b.huhu()
3150
3151 class C:
3152     def __init__(self):
3153         pass
3154
3155 c = C()
3156
3157
3158 # Probably simpler OOP problems
3159 class Pet:
3160     def speak(self): pass
3161 class Cat(Pet):
3162     def speak(self): print "meow!"
3163 class Dog(Pet):
3164     def speak(self): print "woof!"
3165 def command(pet): pet.speak()
3166 pets = Cat(), Dog()
3167 for pet in pets: command(pet)
3168 for pet in (pets[1], pets[0]): command(pet)
3169
3170 clearCastlingOpportunities = [None] 
3171 clearCastlingOpportunities[0] = (10,)
3172
3173 board = [1,2,3]
3174 board[0] = 0
3175
3176 print clearCastlingOpportunities, board
3177
3178 print range(-17, -120, -17)
3179
3180 v = -1
3181 w = 4 
3182
3183 for x in range(w,-2,v):
3184     print x
3185
3186 for x in range(w+1,-2,2*v):
3187     print x
3188
3189 for x in range(0,w+1,1):
3190     print x
3191
3192 d = [i for i in xrange(10)]
3193 print d
3194 d[::2] = [1,2,3,4,5]
3195 print d
3196 d[::-2] = range(5)
3197 print d
3198
3199 e = ["X" for i in xrange(10)]
3200 e[::2] = "abcde"
3201 print e
3202
3203 f = ["Y" for i in xrange(10)]
3204 f[1::2] = tuple("abcde")
3205 print f
3206
3207 def sgn(x):
3208     if x < 0: return -1
3209     else: return 1
3210 for j in [-2, -1]:
3211     print [i for i in xrange(-10*sgn(j), -1*sgn(j), j) if True for k in range(2) if k]
3212
3213 ''', '''
3214 output(equal=True)
3215
3216 '''),
3217
3218 ('''sudoku solver 3''', '''
3219 # (c) Peter Cock
3220 # --- http://www2.warwick.ac.uk/fac/sci/moac/currentstudents/peter_cock/python/sudoku/
3221
3222 TRIPLETS = [[0,1,2],[3,4,5],[6,7,8]]
3223
3224 ROW_ITER = [[(row,col) for col in range(0,9)] for row in range(0,9)]
3225 COL_ITER = [[(row,col) for row in range(0,9)] for col in range(0,9)]
3226 TxT_ITER = [[(row,col) for row in rows for col in cols] for rows in TRIPLETS for cols in TRIPLETS]
3227
3228 class soduko:
3229     def __init__(self, start_grid=None) :
3230         self.squares =[ [range(1,10)  for col in range(0,9)] for row in range(0,9)]
3231         
3232         if start_grid is not None:
3233             assert len(start_grid)==9, "Bad input!"
3234             for row in range(0,9) :
3235                 self.set_row(row, start_grid[row])
3236                 
3237         self._changed=False
3238     
3239     def copy(self) :
3240         soduko_copy = soduko(None)
3241         for row in range(0,9) :
3242             for col in range(0,9) :
3243                 soduko_copy.squares[row][col] = self.squares[row][col][:] 
3244         soduko_copy._changed=False
3245         return soduko_copy
3246     
3247     def set_row(self,row, x_list) :
3248         assert len(x_list)==9, 'not 9'
3249         for col in range(0,9) :
3250             try :
3251                 x = int(x_list[col])
3252             except :
3253                 x = 0
3254             self.set_cell(row,col,x)
3255
3256     def set_cell(self,row,col,x):
3257         if self.squares[row][col] == [x] :
3258             pass
3259         elif x not in range(1,9+1) :
3260             pass
3261         else:
3262             assert x in self.squares[row][col], "bugger2" 
3263             
3264             self.squares[row][col] = [x]
3265             self.update_neighbours(row,col,x)
3266             self._changed=True
3267             
3268     def cell_exclude(self, row,col,x) :
3269         assert x in range(1,9+1), 'inra'
3270         if x in self.squares[row][col] :
3271             self.squares[row][col].remove(x)
3272             assert len(self.squares[row][col]) > 0, "bugger"
3273             if len(self.squares[row][col]) == 1 :
3274                 self._changed=True
3275                 self.update_neighbours(row,col,self.squares[row][col][0])
3276         else :
3277             pass
3278         return
3279
3280     def update_neighbours(self,set_row,set_col,x) :
3281         for row in range(0,9) :
3282             if row <> set_row :
3283                 self.cell_exclude(row,set_col,x)
3284         for col in range(0,9) :
3285             if col <> set_col :
3286                 self.cell_exclude(set_row,col,x)
3287         for triplet in TRIPLETS :
3288             if set_row in triplet : rows = triplet[:]
3289             if set_col in triplet : cols = triplet[:]
3290         rows.remove(set_row)
3291         cols.remove(set_col)
3292         for row in rows :
3293             for col in cols :
3294                 assert row <> set_row or col <> set_col , 'meuh'
3295                 self.cell_exclude(row,col,x)
3296             
3297     def get_cell_digit_str(self,row,col) :
3298         if len(self.squares[row][col])==1 :
3299             return str(self.squares[row][col][0])
3300         else :
3301             return "0"
3302             
3303     def __str__(self):
3304         answer = "   123   456   789\\n"
3305         for row in range(0,9) :
3306             answer = answer + str(row+1) \
3307                         +   " [" + "".join([self.get_cell_digit_str(row,col).replace("0","?") for col in range(0,3)]) \
3308                         + "] [" + "".join([self.get_cell_digit_str(row,col).replace("0","?") for col in range(3,6)]) \
3309                         + "] [" + "".join([self.get_cell_digit_str(row,col).replace("0","?") for col in range(6,9)]) \
3310                         + "]\\n"
3311             if row+1 in [3,6] : 
3312               answer = answer + "   ---   ---   ---\\n"
3313         return answer
3314