Run these demo scripts through reindent.py to give them 4-space indents. I've verified that their output is unchanged.

This commit is contained in:
Andrew M. Kuchling 2003-04-24 17:13:18 +00:00
parent 4f237b6870
commit 946c53ed7f
10 changed files with 981 additions and 981 deletions

View file

@ -16,8 +16,8 @@
# ToComplex(z) -> a complex number equal to z; z itself if IsComplex(z) is true # ToComplex(z) -> a complex number equal to z; z itself if IsComplex(z) is true
# if z is a tuple(re, im) it will also be converted # if z is a tuple(re, im) it will also be converted
# PolarToComplex([r [,phi [,fullcircle]]]) -> # PolarToComplex([r [,phi [,fullcircle]]]) ->
# the complex number z for which r == z.radius() and phi == z.angle(fullcircle) # the complex number z for which r == z.radius() and phi == z.angle(fullcircle)
# (r and phi default to 0) # (r and phi default to 0)
# exp(z) -> returns the complex exponential of z. Equivalent to pow(math.e,z). # exp(z) -> returns the complex exponential of z. Equivalent to pow(math.e,z).
# #
# Complex numbers have the following methods: # Complex numbers have the following methods:
@ -69,230 +69,230 @@ twopi = math.pi*2.0
halfpi = math.pi/2.0 halfpi = math.pi/2.0
def IsComplex(obj): def IsComplex(obj):
return hasattr(obj, 're') and hasattr(obj, 'im') return hasattr(obj, 're') and hasattr(obj, 'im')
def ToComplex(obj): def ToComplex(obj):
if IsComplex(obj): if IsComplex(obj):
return obj return obj
elif type(obj) == types.TupleType: elif type(obj) == types.TupleType:
return apply(Complex, obj) return apply(Complex, obj)
else: else:
return Complex(obj) return Complex(obj)
def PolarToComplex(r = 0, phi = 0, fullcircle = twopi): def PolarToComplex(r = 0, phi = 0, fullcircle = twopi):
phi = phi * (twopi / fullcircle) phi = phi * (twopi / fullcircle)
return Complex(math.cos(phi)*r, math.sin(phi)*r) return Complex(math.cos(phi)*r, math.sin(phi)*r)
def Re(obj): def Re(obj):
if IsComplex(obj): if IsComplex(obj):
return obj.re return obj.re
else: else:
return obj return obj
def Im(obj): def Im(obj):
if IsComplex(obj): if IsComplex(obj):
return obj.im return obj.im
else: else:
return obj return obj
class Complex: class Complex:
def __init__(self, re=0, im=0): def __init__(self, re=0, im=0):
if IsComplex(re): if IsComplex(re):
im = i + Complex(0, re.im) im = i + Complex(0, re.im)
re = re.re re = re.re
if IsComplex(im): if IsComplex(im):
re = re - im.im re = re - im.im
im = im.re im = im.re
self.__dict__['re'] = re self.__dict__['re'] = re
self.__dict__['im'] = im self.__dict__['im'] = im
def __setattr__(self, name, value):
raise TypeError, 'Complex numbers are immutable'
def __hash__(self): def __setattr__(self, name, value):
if not self.im: return hash(self.re) raise TypeError, 'Complex numbers are immutable'
mod = sys.maxint + 1L
return int((hash(self.re) + 2L*hash(self.im) + mod) % (2L*mod) - mod)
def __repr__(self): def __hash__(self):
if not self.im: if not self.im: return hash(self.re)
return 'Complex(%s)' % `self.re` mod = sys.maxint + 1L
else: return int((hash(self.re) + 2L*hash(self.im) + mod) % (2L*mod) - mod)
return 'Complex(%s, %s)' % (`self.re`, `self.im`)
def __str__(self): def __repr__(self):
if not self.im: if not self.im:
return `self.re` return 'Complex(%s)' % `self.re`
else: else:
return 'Complex(%s, %s)' % (`self.re`, `self.im`) return 'Complex(%s, %s)' % (`self.re`, `self.im`)
def __neg__(self): def __str__(self):
return Complex(-self.re, -self.im) if not self.im:
return `self.re`
else:
return 'Complex(%s, %s)' % (`self.re`, `self.im`)
def __pos__(self): def __neg__(self):
return self return Complex(-self.re, -self.im)
def __abs__(self): def __pos__(self):
# XXX could be done differently to avoid overflow! return self
return math.sqrt(self.re*self.re + self.im*self.im)
def __int__(self): def __abs__(self):
if self.im: # XXX could be done differently to avoid overflow!
raise ValueError, "can't convert Complex with nonzero im to int" return math.sqrt(self.re*self.re + self.im*self.im)
return int(self.re)
def __long__(self): def __int__(self):
if self.im: if self.im:
raise ValueError, "can't convert Complex with nonzero im to long" raise ValueError, "can't convert Complex with nonzero im to int"
return long(self.re) return int(self.re)
def __float__(self): def __long__(self):
if self.im: if self.im:
raise ValueError, "can't convert Complex with nonzero im to float" raise ValueError, "can't convert Complex with nonzero im to long"
return float(self.re) return long(self.re)
def __cmp__(self, other): def __float__(self):
other = ToComplex(other) if self.im:
return cmp((self.re, self.im), (other.re, other.im)) raise ValueError, "can't convert Complex with nonzero im to float"
return float(self.re)
def __rcmp__(self, other): def __cmp__(self, other):
other = ToComplex(other) other = ToComplex(other)
return cmp(other, self) return cmp((self.re, self.im), (other.re, other.im))
def __nonzero__(self):
return not (self.re == self.im == 0)
abs = radius = __abs__ def __rcmp__(self, other):
other = ToComplex(other)
return cmp(other, self)
def angle(self, fullcircle = twopi): def __nonzero__(self):
return (fullcircle/twopi) * ((halfpi - math.atan2(self.re, self.im)) % twopi) return not (self.re == self.im == 0)
phi = angle abs = radius = __abs__
def __add__(self, other): def angle(self, fullcircle = twopi):
other = ToComplex(other) return (fullcircle/twopi) * ((halfpi - math.atan2(self.re, self.im)) % twopi)
return Complex(self.re + other.re, self.im + other.im)
__radd__ = __add__ phi = angle
def __sub__(self, other): def __add__(self, other):
other = ToComplex(other) other = ToComplex(other)
return Complex(self.re - other.re, self.im - other.im) return Complex(self.re + other.re, self.im + other.im)
def __rsub__(self, other): __radd__ = __add__
other = ToComplex(other)
return other - self
def __mul__(self, other): def __sub__(self, other):
other = ToComplex(other) other = ToComplex(other)
return Complex(self.re*other.re - self.im*other.im, return Complex(self.re - other.re, self.im - other.im)
self.re*other.im + self.im*other.re)
__rmul__ = __mul__ def __rsub__(self, other):
other = ToComplex(other)
return other - self
def __div__(self, other): def __mul__(self, other):
other = ToComplex(other) other = ToComplex(other)
d = float(other.re*other.re + other.im*other.im) return Complex(self.re*other.re - self.im*other.im,
if not d: raise ZeroDivisionError, 'Complex division' self.re*other.im + self.im*other.re)
return Complex((self.re*other.re + self.im*other.im) / d,
(self.im*other.re - self.re*other.im) / d)
def __rdiv__(self, other): __rmul__ = __mul__
other = ToComplex(other)
return other / self def __div__(self, other):
other = ToComplex(other)
d = float(other.re*other.re + other.im*other.im)
if not d: raise ZeroDivisionError, 'Complex division'
return Complex((self.re*other.re + self.im*other.im) / d,
(self.im*other.re - self.re*other.im) / d)
def __rdiv__(self, other):
other = ToComplex(other)
return other / self
def __pow__(self, n, z=None):
if z is not None:
raise TypeError, 'Complex does not support ternary pow()'
if IsComplex(n):
if n.im:
if self.im: raise TypeError, 'Complex to the Complex power'
else: return exp(math.log(self.re)*n)
n = n.re
r = pow(self.abs(), n)
phi = n*self.angle()
return Complex(math.cos(phi)*r, math.sin(phi)*r)
def __rpow__(self, base):
base = ToComplex(base)
return pow(base, self)
def __pow__(self, n, z=None):
if z is not None:
raise TypeError, 'Complex does not support ternary pow()'
if IsComplex(n):
if n.im:
if self.im: raise TypeError, 'Complex to the Complex power'
else: return exp(math.log(self.re)*n)
n = n.re
r = pow(self.abs(), n)
phi = n*self.angle()
return Complex(math.cos(phi)*r, math.sin(phi)*r)
def __rpow__(self, base):
base = ToComplex(base)
return pow(base, self)
def exp(z): def exp(z):
r = math.exp(z.re) r = math.exp(z.re)
return Complex(math.cos(z.im)*r,math.sin(z.im)*r) return Complex(math.cos(z.im)*r,math.sin(z.im)*r)
def checkop(expr, a, b, value, fuzz = 1e-6): def checkop(expr, a, b, value, fuzz = 1e-6):
import sys import sys
print ' ', a, 'and', b, print ' ', a, 'and', b,
try: try:
result = eval(expr) result = eval(expr)
except: except:
result = sys.exc_type result = sys.exc_type
print '->', result print '->', result
if (type(result) == type('') or type(value) == type('')): if (type(result) == type('') or type(value) == type('')):
ok = result == value ok = result == value
else: else:
ok = abs(result - value) <= fuzz ok = abs(result - value) <= fuzz
if not ok: if not ok:
print '!!\t!!\t!! should be', value, 'diff', abs(result - value) print '!!\t!!\t!! should be', value, 'diff', abs(result - value)
def test(): def test():
testsuite = { testsuite = {
'a+b': [ 'a+b': [
(1, 10, 11), (1, 10, 11),
(1, Complex(0,10), Complex(1,10)), (1, Complex(0,10), Complex(1,10)),
(Complex(0,10), 1, Complex(1,10)), (Complex(0,10), 1, Complex(1,10)),
(Complex(0,10), Complex(1), Complex(1,10)), (Complex(0,10), Complex(1), Complex(1,10)),
(Complex(1), Complex(0,10), Complex(1,10)), (Complex(1), Complex(0,10), Complex(1,10)),
], ],
'a-b': [ 'a-b': [
(1, 10, -9), (1, 10, -9),
(1, Complex(0,10), Complex(1,-10)), (1, Complex(0,10), Complex(1,-10)),
(Complex(0,10), 1, Complex(-1,10)), (Complex(0,10), 1, Complex(-1,10)),
(Complex(0,10), Complex(1), Complex(-1,10)), (Complex(0,10), Complex(1), Complex(-1,10)),
(Complex(1), Complex(0,10), Complex(1,-10)), (Complex(1), Complex(0,10), Complex(1,-10)),
], ],
'a*b': [ 'a*b': [
(1, 10, 10), (1, 10, 10),
(1, Complex(0,10), Complex(0, 10)), (1, Complex(0,10), Complex(0, 10)),
(Complex(0,10), 1, Complex(0,10)), (Complex(0,10), 1, Complex(0,10)),
(Complex(0,10), Complex(1), Complex(0,10)), (Complex(0,10), Complex(1), Complex(0,10)),
(Complex(1), Complex(0,10), Complex(0,10)), (Complex(1), Complex(0,10), Complex(0,10)),
], ],
'a/b': [ 'a/b': [
(1., 10, 0.1), (1., 10, 0.1),
(1, Complex(0,10), Complex(0, -0.1)), (1, Complex(0,10), Complex(0, -0.1)),
(Complex(0, 10), 1, Complex(0, 10)), (Complex(0, 10), 1, Complex(0, 10)),
(Complex(0, 10), Complex(1), Complex(0, 10)), (Complex(0, 10), Complex(1), Complex(0, 10)),
(Complex(1), Complex(0,10), Complex(0, -0.1)), (Complex(1), Complex(0,10), Complex(0, -0.1)),
], ],
'pow(a,b)': [ 'pow(a,b)': [
(1, 10, 1), (1, 10, 1),
(1, Complex(0,10), 1), (1, Complex(0,10), 1),
(Complex(0,10), 1, Complex(0,10)), (Complex(0,10), 1, Complex(0,10)),
(Complex(0,10), Complex(1), Complex(0,10)), (Complex(0,10), Complex(1), Complex(0,10)),
(Complex(1), Complex(0,10), 1), (Complex(1), Complex(0,10), 1),
(2, Complex(4,0), 16), (2, Complex(4,0), 16),
], ],
'cmp(a,b)': [ 'cmp(a,b)': [
(1, 10, -1), (1, 10, -1),
(1, Complex(0,10), 1), (1, Complex(0,10), 1),
(Complex(0,10), 1, -1), (Complex(0,10), 1, -1),
(Complex(0,10), Complex(1), -1), (Complex(0,10), Complex(1), -1),
(Complex(1), Complex(0,10), 1), (Complex(1), Complex(0,10), 1),
], ],
} }
exprs = testsuite.keys() exprs = testsuite.keys()
exprs.sort() exprs.sort()
for expr in exprs: for expr in exprs:
print expr + ':' print expr + ':'
t = (expr,) t = (expr,)
for item in testsuite[expr]: for item in testsuite[expr]:
apply(checkop, t+item) apply(checkop, t+item)
if __name__ == '__main__': if __name__ == '__main__':
test() test()

View file

@ -6,61 +6,61 @@
class Dbm: class Dbm:
def __init__(self, filename, mode, perm): def __init__(self, filename, mode, perm):
import dbm import dbm
self.db = dbm.open(filename, mode, perm) self.db = dbm.open(filename, mode, perm)
def __repr__(self): def __repr__(self):
s = '' s = ''
for key in self.keys(): for key in self.keys():
t = `key` + ': ' + `self[key]` t = `key` + ': ' + `self[key]`
if s: t = ', ' + t if s: t = ', ' + t
s = s + t s = s + t
return '{' + s + '}' return '{' + s + '}'
def __len__(self): def __len__(self):
return len(self.db) return len(self.db)
def __getitem__(self, key): def __getitem__(self, key):
return eval(self.db[`key`]) return eval(self.db[`key`])
def __setitem__(self, key, value): def __setitem__(self, key, value):
self.db[`key`] = `value` self.db[`key`] = `value`
def __delitem__(self, key): def __delitem__(self, key):
del self.db[`key`] del self.db[`key`]
def keys(self): def keys(self):
res = [] res = []
for key in self.db.keys(): for key in self.db.keys():
res.append(eval(key)) res.append(eval(key))
return res return res
def has_key(self, key): def has_key(self, key):
return self.db.has_key(`key`) return self.db.has_key(`key`)
def test(): def test():
d = Dbm('@dbm', 'rw', 0600) d = Dbm('@dbm', 'rw', 0600)
print d print d
while 1: while 1:
try: try:
key = input('key: ') key = input('key: ')
if d.has_key(key): if d.has_key(key):
value = d[key] value = d[key]
print 'currently:', value print 'currently:', value
value = input('value: ') value = input('value: ')
if value == None: if value == None:
del d[key] del d[key]
else: else:
d[key] = value d[key] = value
except KeyboardInterrupt: except KeyboardInterrupt:
print '' print ''
print d print d
except EOFError: except EOFError:
print '[eof]' print '[eof]'
break break
print d print d
test() test()

View file

@ -7,17 +7,17 @@
# Wrapper function to emulate the complicated range() arguments # Wrapper function to emulate the complicated range() arguments
def range(*a): def range(*a):
if len(a) == 1: if len(a) == 1:
start, stop, step = 0, a[0], 1 start, stop, step = 0, a[0], 1
elif len(a) == 2: elif len(a) == 2:
start, stop = a start, stop = a
step = 1 step = 1
elif len(a) == 3: elif len(a) == 3:
start, stop, step = a start, stop, step = a
else: else:
raise TypeError, 'range() needs 1-3 arguments' raise TypeError, 'range() needs 1-3 arguments'
return Range(start, stop, step) return Range(start, stop, step)
# Class implementing a range object. # Class implementing a range object.
# To the user the instances feel like immutable sequences # To the user the instances feel like immutable sequences
@ -25,47 +25,47 @@ def range(*a):
class Range: class Range:
# initialization -- should be called only by range() above # initialization -- should be called only by range() above
def __init__(self, start, stop, step): def __init__(self, start, stop, step):
if step == 0: if step == 0:
raise ValueError, 'range() called with zero step' raise ValueError, 'range() called with zero step'
self.start = start self.start = start
self.stop = stop self.stop = stop
self.step = step self.step = step
self.len = max(0, int((self.stop - self.start) / self.step)) self.len = max(0, int((self.stop - self.start) / self.step))
# implement `x` and is also used by print x # implement `x` and is also used by print x
def __repr__(self): def __repr__(self):
return 'range' + `self.start, self.stop, self.step` return 'range' + `self.start, self.stop, self.step`
# implement len(x) # implement len(x)
def __len__(self): def __len__(self):
return self.len return self.len
# implement x[i] # implement x[i]
def __getitem__(self, i): def __getitem__(self, i):
if 0 <= i < self.len: if 0 <= i < self.len:
return self.start + self.step * i return self.start + self.step * i
else: else:
raise IndexError, 'range[i] index out of range' raise IndexError, 'range[i] index out of range'
# Small test program # Small test program
def test(): def test():
import time, __builtin__ import time, __builtin__
print range(10), range(-10, 10), range(0, 10, 2) print range(10), range(-10, 10), range(0, 10, 2)
for i in range(100, -100, -10): print i, for i in range(100, -100, -10): print i,
print print
t1 = time.time() t1 = time.time()
for i in range(1000): for i in range(1000):
pass pass
t2 = time.time() t2 = time.time()
for i in __builtin__.range(1000): for i in __builtin__.range(1000):
pass pass
t3 = time.time() t3 = time.time()
print t2-t1, 'sec (class)' print t2-t1, 'sec (class)'
print t3-t2, 'sec (built-in)' print t3-t2, 'sec (built-in)'
test() test()

View file

@ -2,7 +2,7 @@
This module implements rational numbers. This module implements rational numbers.
The entry point of this module is the function The entry point of this module is the function
rat(numerator, denominator) rat(numerator, denominator)
If either numerator or denominator is of an integral or rational type, If either numerator or denominator is of an integral or rational type,
the result is a rational number, else, the result is the simplest of the result is a rational number, else, the result is the simplest of
the types float and complex which can hold numerator/denominator. the types float and complex which can hold numerator/denominator.
@ -11,7 +11,7 @@ Rational numbers can be used in calculations with any other numeric
type. The result of the calculation will be rational if possible. type. The result of the calculation will be rational if possible.
There is also a test function with calling sequence There is also a test function with calling sequence
test() test()
The documentation string of the test function contains the expected The documentation string of the test function contains the expected
output. output.
''' '''
@ -21,289 +21,289 @@ output.
from types import * from types import *
def gcd(a, b): def gcd(a, b):
'''Calculate the Greatest Common Divisor.''' '''Calculate the Greatest Common Divisor.'''
while b: while b:
a, b = b, a%b a, b = b, a%b
return a return a
def rat(num, den = 1): def rat(num, den = 1):
# must check complex before float # must check complex before float
if isinstance(num, complex) or isinstance(den, complex): if isinstance(num, complex) or isinstance(den, complex):
# numerator or denominator is complex: return a complex # numerator or denominator is complex: return a complex
return complex(num) / complex(den) return complex(num) / complex(den)
if isinstance(num, float) or isinstance(den, float): if isinstance(num, float) or isinstance(den, float):
# numerator or denominator is float: return a float # numerator or denominator is float: return a float
return float(num) / float(den) return float(num) / float(den)
# otherwise return a rational # otherwise return a rational
return Rat(num, den) return Rat(num, den)
class Rat: class Rat:
'''This class implements rational numbers.''' '''This class implements rational numbers.'''
def __init__(self, num, den = 1): def __init__(self, num, den = 1):
if den == 0: if den == 0:
raise ZeroDivisionError, 'rat(x, 0)' raise ZeroDivisionError, 'rat(x, 0)'
# normalize # normalize
# must check complex before float # must check complex before float
if (isinstance(num, complex) or if (isinstance(num, complex) or
isinstance(den, complex)): isinstance(den, complex)):
# numerator or denominator is complex: # numerator or denominator is complex:
# normalized form has denominator == 1+0j # normalized form has denominator == 1+0j
self.__num = complex(num) / complex(den) self.__num = complex(num) / complex(den)
self.__den = complex(1) self.__den = complex(1)
return return
if isinstance(num, float) or isinstance(den, float): if isinstance(num, float) or isinstance(den, float):
# numerator or denominator is float: # numerator or denominator is float:
# normalized form has denominator == 1.0 # normalized form has denominator == 1.0
self.__num = float(num) / float(den) self.__num = float(num) / float(den)
self.__den = 1.0 self.__den = 1.0
return return
if (isinstance(num, self.__class__) or if (isinstance(num, self.__class__) or
isinstance(den, self.__class__)): isinstance(den, self.__class__)):
# numerator or denominator is rational # numerator or denominator is rational
new = num / den new = num / den
if not isinstance(new, self.__class__): if not isinstance(new, self.__class__):
self.__num = new self.__num = new
if isinstance(new, complex): if isinstance(new, complex):
self.__den = complex(1) self.__den = complex(1)
else: else:
self.__den = 1.0 self.__den = 1.0
else: else:
self.__num = new.__num self.__num = new.__num
self.__den = new.__den self.__den = new.__den
else: else:
# make sure numerator and denominator don't # make sure numerator and denominator don't
# have common factors # have common factors
# this also makes sure that denominator > 0 # this also makes sure that denominator > 0
g = gcd(num, den) g = gcd(num, den)
self.__num = num / g self.__num = num / g
self.__den = den / g self.__den = den / g
# try making numerator and denominator of IntType if they fit # try making numerator and denominator of IntType if they fit
try: try:
numi = int(self.__num) numi = int(self.__num)
deni = int(self.__den) deni = int(self.__den)
except (OverflowError, TypeError): except (OverflowError, TypeError):
pass pass
else: else:
if self.__num == numi and self.__den == deni: if self.__num == numi and self.__den == deni:
self.__num = numi self.__num = numi
self.__den = deni self.__den = deni
def __repr__(self): def __repr__(self):
return 'Rat(%s,%s)' % (self.__num, self.__den) return 'Rat(%s,%s)' % (self.__num, self.__den)
def __str__(self): def __str__(self):
if self.__den == 1: if self.__den == 1:
return str(self.__num) return str(self.__num)
else: else:
return '(%s/%s)' % (str(self.__num), str(self.__den)) return '(%s/%s)' % (str(self.__num), str(self.__den))
# a + b # a + b
def __add__(a, b): def __add__(a, b):
try: try:
return rat(a.__num * b.__den + b.__num * a.__den, return rat(a.__num * b.__den + b.__num * a.__den,
a.__den * b.__den) a.__den * b.__den)
except OverflowError: except OverflowError:
return rat(long(a.__num) * long(b.__den) + return rat(long(a.__num) * long(b.__den) +
long(b.__num) * long(a.__den), long(b.__num) * long(a.__den),
long(a.__den) * long(b.__den)) long(a.__den) * long(b.__den))
def __radd__(b, a): def __radd__(b, a):
return Rat(a) + b return Rat(a) + b
# a - b # a - b
def __sub__(a, b): def __sub__(a, b):
try: try:
return rat(a.__num * b.__den - b.__num * a.__den, return rat(a.__num * b.__den - b.__num * a.__den,
a.__den * b.__den) a.__den * b.__den)
except OverflowError: except OverflowError:
return rat(long(a.__num) * long(b.__den) - return rat(long(a.__num) * long(b.__den) -
long(b.__num) * long(a.__den), long(b.__num) * long(a.__den),
long(a.__den) * long(b.__den)) long(a.__den) * long(b.__den))
def __rsub__(b, a): def __rsub__(b, a):
return Rat(a) - b return Rat(a) - b
# a * b # a * b
def __mul__(a, b): def __mul__(a, b):
try: try:
return rat(a.__num * b.__num, a.__den * b.__den) return rat(a.__num * b.__num, a.__den * b.__den)
except OverflowError: except OverflowError:
return rat(long(a.__num) * long(b.__num), return rat(long(a.__num) * long(b.__num),
long(a.__den) * long(b.__den)) long(a.__den) * long(b.__den))
def __rmul__(b, a): def __rmul__(b, a):
return Rat(a) * b return Rat(a) * b
# a / b # a / b
def __div__(a, b): def __div__(a, b):
try: try:
return rat(a.__num * b.__den, a.__den * b.__num) return rat(a.__num * b.__den, a.__den * b.__num)
except OverflowError: except OverflowError:
return rat(long(a.__num) * long(b.__den), return rat(long(a.__num) * long(b.__den),
long(a.__den) * long(b.__num)) long(a.__den) * long(b.__num))
def __rdiv__(b, a): def __rdiv__(b, a):
return Rat(a) / b return Rat(a) / b
# a % b # a % b
def __mod__(a, b): def __mod__(a, b):
div = a / b div = a / b
try: try:
div = int(div) div = int(div)
except OverflowError: except OverflowError:
div = long(div) div = long(div)
return a - b * div return a - b * div
def __rmod__(b, a): def __rmod__(b, a):
return Rat(a) % b return Rat(a) % b
# a ** b # a ** b
def __pow__(a, b): def __pow__(a, b):
if b.__den != 1: if b.__den != 1:
if isinstance(a.__num, complex): if isinstance(a.__num, complex):
a = complex(a) a = complex(a)
else: else:
a = float(a) a = float(a)
if isinstance(b.__num, complex): if isinstance(b.__num, complex):
b = complex(b) b = complex(b)
else: else:
b = float(b) b = float(b)
return a ** b return a ** b
try: try:
return rat(a.__num ** b.__num, a.__den ** b.__num) return rat(a.__num ** b.__num, a.__den ** b.__num)
except OverflowError: except OverflowError:
return rat(long(a.__num) ** b.__num, return rat(long(a.__num) ** b.__num,
long(a.__den) ** b.__num) long(a.__den) ** b.__num)
def __rpow__(b, a): def __rpow__(b, a):
return Rat(a) ** b return Rat(a) ** b
# -a # -a
def __neg__(a): def __neg__(a):
try: try:
return rat(-a.__num, a.__den) return rat(-a.__num, a.__den)
except OverflowError: except OverflowError:
# a.__num == sys.maxint # a.__num == sys.maxint
return rat(-long(a.__num), a.__den) return rat(-long(a.__num), a.__den)
# abs(a) # abs(a)
def __abs__(a): def __abs__(a):
return rat(abs(a.__num), a.__den) return rat(abs(a.__num), a.__den)
# int(a) # int(a)
def __int__(a): def __int__(a):
return int(a.__num / a.__den) return int(a.__num / a.__den)
# long(a) # long(a)
def __long__(a): def __long__(a):
return long(a.__num) / long(a.__den) return long(a.__num) / long(a.__den)
# float(a) # float(a)
def __float__(a): def __float__(a):
return float(a.__num) / float(a.__den) return float(a.__num) / float(a.__den)
# complex(a) # complex(a)
def __complex__(a): def __complex__(a):
return complex(a.__num) / complex(a.__den) return complex(a.__num) / complex(a.__den)
# cmp(a,b) # cmp(a,b)
def __cmp__(a, b): def __cmp__(a, b):
diff = Rat(a - b) diff = Rat(a - b)
if diff.__num < 0: if diff.__num < 0:
return -1 return -1
elif diff.__num > 0: elif diff.__num > 0:
return 1 return 1
else: else:
return 0 return 0
def __rcmp__(b, a): def __rcmp__(b, a):
return cmp(Rat(a), b) return cmp(Rat(a), b)
# a != 0 # a != 0
def __nonzero__(a): def __nonzero__(a):
return a.__num != 0 return a.__num != 0
# coercion # coercion
def __coerce__(a, b): def __coerce__(a, b):
return a, Rat(b) return a, Rat(b)
def test(): def test():
'''\ '''\
Test function for rat module. Test function for rat module.
The expected output is (module some differences in floating The expected output is (module some differences in floating
precission): precission):
-1 -1
-1 -1
0 0L 0.1 (0.1+0j) 0 0L 0.1 (0.1+0j)
[Rat(1,2), Rat(-3,10), Rat(1,25), Rat(1,4)] [Rat(1,2), Rat(-3,10), Rat(1,25), Rat(1,4)]
[Rat(-3,10), Rat(1,25), Rat(1,4), Rat(1,2)] [Rat(-3,10), Rat(1,25), Rat(1,4), Rat(1,2)]
0 0
(11/10) (11/10)
(11/10) (11/10)
1.1 1.1
OK OK
2 1.5 (3/2) (1.5+1.5j) (15707963/5000000) 2 1.5 (3/2) (1.5+1.5j) (15707963/5000000)
2 2 2.0 (2+0j) 2 2 2.0 (2+0j)
4 0 4 1 4 0 4 0 4 1 4 0
3.5 0.5 3.0 1.33333333333 2.82842712475 1 3.5 0.5 3.0 1.33333333333 2.82842712475 1
(7/2) (1/2) 3 (4/3) 2.82842712475 1 (7/2) (1/2) 3 (4/3) 2.82842712475 1
(3.5+1.5j) (0.5-1.5j) (3+3j) (0.666666666667-0.666666666667j) (1.43248815986+2.43884761145j) 1 (3.5+1.5j) (0.5-1.5j) (3+3j) (0.666666666667-0.666666666667j) (1.43248815986+2.43884761145j) 1
1.5 1 1.5 (1.5+0j) 1.5 1 1.5 (1.5+0j)
3.5 -0.5 3.0 0.75 2.25 -1 3.5 -0.5 3.0 0.75 2.25 -1
3.0 0.0 2.25 1.0 1.83711730709 0 3.0 0.0 2.25 1.0 1.83711730709 0
3.0 0.0 2.25 1.0 1.83711730709 1 3.0 0.0 2.25 1.0 1.83711730709 1
(3+1.5j) -1.5j (2.25+2.25j) (0.5-0.5j) (1.50768393746+1.04970907623j) -1 (3+1.5j) -1.5j (2.25+2.25j) (0.5-0.5j) (1.50768393746+1.04970907623j) -1
(3/2) 1 1.5 (1.5+0j) (3/2) 1 1.5 (1.5+0j)
(7/2) (-1/2) 3 (3/4) (9/4) -1 (7/2) (-1/2) 3 (3/4) (9/4) -1
3.0 0.0 2.25 1.0 1.83711730709 -1 3.0 0.0 2.25 1.0 1.83711730709 -1
3 0 (9/4) 1 1.83711730709 0 3 0 (9/4) 1 1.83711730709 0
(3+1.5j) -1.5j (2.25+2.25j) (0.5-0.5j) (1.50768393746+1.04970907623j) -1 (3+1.5j) -1.5j (2.25+2.25j) (0.5-0.5j) (1.50768393746+1.04970907623j) -1
(1.5+1.5j) (1.5+1.5j) (1.5+1.5j) (1.5+1.5j)
(3.5+1.5j) (-0.5+1.5j) (3+3j) (0.75+0.75j) 4.5j -1 (3.5+1.5j) (-0.5+1.5j) (3+3j) (0.75+0.75j) 4.5j -1
(3+1.5j) 1.5j (2.25+2.25j) (1+1j) (1.18235814075+2.85446505899j) 1 (3+1.5j) 1.5j (2.25+2.25j) (1+1j) (1.18235814075+2.85446505899j) 1
(3+1.5j) 1.5j (2.25+2.25j) (1+1j) (1.18235814075+2.85446505899j) 1 (3+1.5j) 1.5j (2.25+2.25j) (1+1j) (1.18235814075+2.85446505899j) 1
(3+3j) 0j 4.5j (1+0j) (-0.638110484918+0.705394566962j) 0 (3+3j) 0j 4.5j (1+0j) (-0.638110484918+0.705394566962j) 0
''' '''
print rat(-1L, 1) print rat(-1L, 1)
print rat(1, -1) print rat(1, -1)
a = rat(1, 10) a = rat(1, 10)
print int(a), long(a), float(a), complex(a) print int(a), long(a), float(a), complex(a)
b = rat(2, 5) b = rat(2, 5)
l = [a+b, a-b, a*b, a/b] l = [a+b, a-b, a*b, a/b]
print l print l
l.sort() l.sort()
print l print l
print rat(0, 1) print rat(0, 1)
print a+1 print a+1
print a+1L print a+1L
print a+1.0 print a+1.0
try: try:
print rat(1, 0) print rat(1, 0)
raise SystemError, 'should have been ZeroDivisionError' raise SystemError, 'should have been ZeroDivisionError'
except ZeroDivisionError: except ZeroDivisionError:
print 'OK' print 'OK'
print rat(2), rat(1.5), rat(3, 2), rat(1.5+1.5j), rat(31415926,10000000) print rat(2), rat(1.5), rat(3, 2), rat(1.5+1.5j), rat(31415926,10000000)
list = [2, 1.5, rat(3,2), 1.5+1.5j] list = [2, 1.5, rat(3,2), 1.5+1.5j]
for i in list: for i in list:
print i, print i,
if not isinstance(i, complex): if not isinstance(i, complex):
print int(i), float(i), print int(i), float(i),
print complex(i) print complex(i)
print print
for j in list: for j in list:
print i + j, i - j, i * j, i / j, i ** j, print i + j, i - j, i * j, i / j, i ** j,
if not (isinstance(i, complex) or if not (isinstance(i, complex) or
isinstance(j, complex)): isinstance(j, complex)):
print cmp(i, j) print cmp(i, j)
print print
if __name__ == '__main__': if __name__ == '__main__':

View file

@ -5,13 +5,13 @@
# #
# >>> for c in Rev( 'Hello World!' ) : sys.stdout.write( c ) # >>> for c in Rev( 'Hello World!' ) : sys.stdout.write( c )
# ... else: sys.stdout.write( '\n' ) # ... else: sys.stdout.write( '\n' )
# ... # ...
# !dlroW olleH # !dlroW olleH
# #
# The .forw is so you can use anonymous sequences in __init__, and still # The .forw is so you can use anonymous sequences in __init__, and still
# keep a reference the forward sequence. ) # keep a reference the forward sequence. )
# If you give it a non-anonymous mutable sequence, the reverse sequence # If you give it a non-anonymous mutable sequence, the reverse sequence
# will track the updated values. ( but not reassignment! - another # will track the updated values. ( but not reassignment! - another
# good reason to use anonymous values in creating the sequence to avoid # good reason to use anonymous values in creating the sequence to avoid
# confusion. Maybe it should be change to copy input sequence to break # confusion. Maybe it should be change to copy input sequence to break
# the connection completely ? ) # the connection completely ? )
@ -19,14 +19,14 @@
# >>> nnn = range( 0, 3 ) # >>> nnn = range( 0, 3 )
# >>> rnn = Rev( nnn ) # >>> rnn = Rev( nnn )
# >>> for n in rnn: print n # >>> for n in rnn: print n
# ... # ...
# 2 # 2
# 1 # 1
# 0 # 0
# >>> for n in range( 4, 6 ): nnn.append( n ) # update nnn # >>> for n in range( 4, 6 ): nnn.append( n ) # update nnn
# ... # ...
# >>> for n in rnn: print n # prints reversed updated values # >>> for n in rnn: print n # prints reversed updated values
# ... # ...
# 5 # 5
# 4 # 4
# 2 # 2
@ -35,55 +35,55 @@
# >>> nnn = nnn[1:-1] # >>> nnn = nnn[1:-1]
# >>> nnn # >>> nnn
# [1, 2, 4] # [1, 2, 4]
# >>> for n in rnn: print n # prints reversed values of old nnn # >>> for n in rnn: print n # prints reversed values of old nnn
# ... # ...
# 5 # 5
# 4 # 4
# 2 # 2
# 1 # 1
# 0 # 0
# >>> # >>>
# #
# WH = Rev( 'Hello World!' ) # WH = Rev( 'Hello World!' )
# print WH.forw, WH.back # print WH.forw, WH.back
# nnn = Rev( range( 1, 10 ) ) # nnn = Rev( range( 1, 10 ) )
# print nnn.forw # print nnn.forw
# print nnn # print nnn
# #
# produces output: # produces output:
# #
# Hello World! !dlroW olleH # Hello World! !dlroW olleH
# [1, 2, 3, 4, 5, 6, 7, 8, 9] # [1, 2, 3, 4, 5, 6, 7, 8, 9]
# [9, 8, 7, 6, 5, 4, 3, 2, 1] # [9, 8, 7, 6, 5, 4, 3, 2, 1]
# #
# >>>rrr = Rev( nnn ) # >>>rrr = Rev( nnn )
# >>>rrr # >>>rrr
# <1, 2, 3, 4, 5, 6, 7, 8, 9> # <1, 2, 3, 4, 5, 6, 7, 8, 9>
from string import joinfields from string import joinfields
class Rev: class Rev:
def __init__( self, seq ): def __init__( self, seq ):
self.forw = seq self.forw = seq
self.back = self self.back = self
def __len__( self ): def __len__( self ):
return len( self.forw ) return len( self.forw )
def __getitem__( self, j ): def __getitem__( self, j ):
return self.forw[ -( j + 1 ) ] return self.forw[ -( j + 1 ) ]
def __repr__( self ): def __repr__( self ):
seq = self.forw seq = self.forw
if type(seq) == type( [] ) : if type(seq) == type( [] ) :
wrap = '[]' wrap = '[]'
sep = ', ' sep = ', '
elif type(seq) == type( () ) : elif type(seq) == type( () ) :
wrap = '()' wrap = '()'
sep = ', ' sep = ', '
elif type(seq) == type( '' ) : elif type(seq) == type( '' ) :
wrap = '' wrap = ''
sep = '' sep = ''
else: else:
wrap = '<>' wrap = '<>'
sep = ', ' sep = ', '
outstrs = [] outstrs = []
for item in self.back : for item in self.back :
outstrs.append( str( item ) ) outstrs.append( str( item ) )
return wrap[:1] + joinfields( outstrs, sep ) + wrap[-1:] return wrap[:1] + joinfields( outstrs, sep ) + wrap[-1:]

View file

@ -2,63 +2,63 @@
def vec(*v): def vec(*v):
return apply(Vec, v) return apply(Vec, v)
class Vec: class Vec:
def __init__(self, *v): def __init__(self, *v):
self.v = [] self.v = []
for x in v: for x in v:
self.v.append(x) self.v.append(x)
def fromlist(self, v): def fromlist(self, v):
self.v = [] self.v = []
if type(v) <> type([]): if type(v) <> type([]):
raise TypeError raise TypeError
self.v = v[:] self.v = v[:]
return self return self
def __repr__(self): def __repr__(self):
return 'vec(' + `self.v`[1:-1] + ')' return 'vec(' + `self.v`[1:-1] + ')'
def __len__(self): def __len__(self):
return len(self.v) return len(self.v)
def __getitem__(self, i): def __getitem__(self, i):
return self.v[i] return self.v[i]
def __add__(a, b): def __add__(a, b):
# Element-wise addition # Element-wise addition
v = [] v = []
for i in range(len(a)): for i in range(len(a)):
v.append(a[i] + b[i]) v.append(a[i] + b[i])
return Vec().fromlist(v) return Vec().fromlist(v)
def __sub__(a, b): def __sub__(a, b):
# Element-wise subtraction # Element-wise subtraction
v = [] v = []
for i in range(len(a)): for i in range(len(a)):
v.append(a[i] - b[i]) v.append(a[i] - b[i])
return Vec().fromlist(v) return Vec().fromlist(v)
def __mul__(self, scalar): def __mul__(self, scalar):
# Multiply by scalar # Multiply by scalar
v = [] v = []
for i in range(len(self.v)): for i in range(len(self.v)):
v.append(self.v[i]*scalar) v.append(self.v[i]*scalar)
return Vec().fromlist(v) return Vec().fromlist(v)
def test(): def test():
a = vec(1, 2, 3) a = vec(1, 2, 3)
b = vec(3, 2, 1) b = vec(3, 2, 1)
print a print a
print b print b
print a+b print a+b
print a*3.0 print a*3.0
test() test()

View file

@ -10,323 +10,323 @@ error = 'bitvec.error'
def _check_value(value): def _check_value(value):
if type(value) != type(0) or not 0 <= value < 2: if type(value) != type(0) or not 0 <= value < 2:
raise error, 'bitvec() items must have int value 0 or 1' raise error, 'bitvec() items must have int value 0 or 1'
import math import math
def _compute_len(param): def _compute_len(param):
mant, l = math.frexp(float(param)) mant, l = math.frexp(float(param))
bitmask = 1L << l bitmask = 1L << l
if bitmask <= param: if bitmask <= param:
raise 'FATAL', '(param, l) = ' + `param, l` raise 'FATAL', '(param, l) = ' + `param, l`
while l: while l:
bitmask = bitmask >> 1 bitmask = bitmask >> 1
if param & bitmask: if param & bitmask:
break break
l = l - 1 l = l - 1
return l return l
def _check_key(len, key): def _check_key(len, key):
if type(key) != type(0): if type(key) != type(0):
raise TypeError, 'sequence subscript not int' raise TypeError, 'sequence subscript not int'
if key < 0: if key < 0:
key = key + len key = key + len
if not 0 <= key < len: if not 0 <= key < len:
raise IndexError, 'list index out of range' raise IndexError, 'list index out of range'
return key return key
def _check_slice(len, i, j): def _check_slice(len, i, j):
#the type is ok, Python already checked that #the type is ok, Python already checked that
i, j = max(i, 0), min(len, j) i, j = max(i, 0), min(len, j)
if i > j: if i > j:
i = j i = j
return i, j return i, j
class BitVec: class BitVec:
def __init__(self, *params): def __init__(self, *params):
self._data = 0L self._data = 0L
self._len = 0 self._len = 0
if not len(params): if not len(params):
pass pass
elif len(params) == 1: elif len(params) == 1:
param, = params param, = params
if type(param) == type([]): if type(param) == type([]):
value = 0L value = 0L
bit_mask = 1L bit_mask = 1L
for item in param: for item in param:
# strict check # strict check
#_check_value(item) #_check_value(item)
if item: if item:
value = value | bit_mask value = value | bit_mask
bit_mask = bit_mask << 1 bit_mask = bit_mask << 1
self._data = value self._data = value
self._len = len(param) self._len = len(param)
elif type(param) == type(0L): elif type(param) == type(0L):
if param < 0: if param < 0:
raise error, 'bitvec() can\'t handle negative longs' raise error, 'bitvec() can\'t handle negative longs'
self._data = param self._data = param
self._len = _compute_len(param) self._len = _compute_len(param)
else: else:
raise error, 'bitvec() requires array or long parameter' raise error, 'bitvec() requires array or long parameter'
elif len(params) == 2: elif len(params) == 2:
param, length = params param, length = params
if type(param) == type(0L): if type(param) == type(0L):
if param < 0: if param < 0:
raise error, \ raise error, \
'can\'t handle negative longs' 'can\'t handle negative longs'
self._data = param self._data = param
if type(length) != type(0): if type(length) != type(0):
raise error, 'bitvec()\'s 2nd parameter must be int' raise error, 'bitvec()\'s 2nd parameter must be int'
computed_length = _compute_len(param) computed_length = _compute_len(param)
if computed_length > length: if computed_length > length:
print 'warning: bitvec() value is longer than the length indicates, truncating value' print 'warning: bitvec() value is longer than the length indicates, truncating value'
self._data = self._data & \ self._data = self._data & \
((1L << length) - 1) ((1L << length) - 1)
self._len = length self._len = length
else: else:
raise error, 'bitvec() requires array or long parameter' raise error, 'bitvec() requires array or long parameter'
else: else:
raise error, 'bitvec() requires 0 -- 2 parameter(s)' raise error, 'bitvec() requires 0 -- 2 parameter(s)'
def append(self, item):
#_check_value(item)
#self[self._len:self._len] = [item]
self[self._len:self._len] = \
BitVec(long(not not item), 1)
def count(self, value):
#_check_value(value)
if value:
data = self._data
else:
data = (~self)._data
count = 0
while data:
data, count = data >> 1, count + (data & 1 != 0)
return count
def index(self, value): def append(self, item):
#_check_value(value): #_check_value(item)
if value: #self[self._len:self._len] = [item]
data = self._data self[self._len:self._len] = \
else: BitVec(long(not not item), 1)
data = (~self)._data
index = 0
if not data:
raise ValueError, 'list.index(x): x not in list'
while not (data & 1):
data, index = data >> 1, index + 1
return index
def insert(self, index, item): def count(self, value):
#_check_value(item) #_check_value(value)
#self[index:index] = [item] if value:
self[index:index] = BitVec(long(not not item), 1) data = self._data
else:
data = (~self)._data
count = 0
while data:
data, count = data >> 1, count + (data & 1 != 0)
return count
def remove(self, value): def index(self, value):
del self[self.index(value)] #_check_value(value):
if value:
data = self._data
else:
data = (~self)._data
index = 0
if not data:
raise ValueError, 'list.index(x): x not in list'
while not (data & 1):
data, index = data >> 1, index + 1
return index
def reverse(self): def insert(self, index, item):
#ouch, this one is expensive! #_check_value(item)
#for i in self._len>>1: self[i], self[l-i] = self[l-i], self[i] #self[index:index] = [item]
data, result = self._data, 0L self[index:index] = BitVec(long(not not item), 1)
for i in range(self._len):
if not data:
result = result << (self._len - i)
break
result, data = (result << 1) | (data & 1), data >> 1
self._data = result
def sort(self):
c = self.count(1)
self._data = ((1L << c) - 1) << (self._len - c)
def copy(self): def remove(self, value):
return BitVec(self._data, self._len) del self[self.index(value)]
def seq(self): def reverse(self):
result = [] #ouch, this one is expensive!
for i in self: #for i in self._len>>1: self[i], self[l-i] = self[l-i], self[i]
result.append(i) data, result = self._data, 0L
return result for i in range(self._len):
if not data:
result = result << (self._len - i)
def __repr__(self): break
##rprt('<bitvec class instance object>.' + '__repr__()\n') result, data = (result << 1) | (data & 1), data >> 1
return 'bitvec' + `self._data, self._len` self._data = result
def __cmp__(self, other, *rest):
#rprt(`self`+'.__cmp__'+`(other, ) + rest`+'\n')
if type(other) != type(self):
other = apply(bitvec, (other, ) + rest)
#expensive solution... recursive binary, with slicing
length = self._len
if length == 0 or other._len == 0:
return cmp(length, other._len)
if length != other._len:
min_length = min(length, other._len)
return cmp(self[:min_length], other[:min_length]) or \
cmp(self[min_length:], other[min_length:])
#the lengths are the same now...
if self._data == other._data:
return 0
if length == 1:
return cmp(self[0], other[0])
else:
length = length >> 1
return cmp(self[:length], other[:length]) or \
cmp(self[length:], other[length:])
def __len__(self):
#rprt(`self`+'.__len__()\n')
return self._len
def __getitem__(self, key):
#rprt(`self`+'.__getitem__('+`key`+')\n')
key = _check_key(self._len, key)
return self._data & (1L << key) != 0
def __setitem__(self, key, value):
#rprt(`self`+'.__setitem__'+`key, value`+'\n')
key = _check_key(self._len, key)
#_check_value(value)
if value:
self._data = self._data | (1L << key)
else:
self._data = self._data & ~(1L << key)
def __delitem__(self, key):
#rprt(`self`+'.__delitem__('+`key`+')\n')
key = _check_key(self._len, key)
#el cheapo solution...
self._data = self[:key]._data | self[key+1:]._data >> key
self._len = self._len - 1
def __getslice__(self, i, j):
#rprt(`self`+'.__getslice__'+`i, j`+'\n')
i, j = _check_slice(self._len, i, j)
if i >= j:
return BitVec(0L, 0)
if i:
ndata = self._data >> i
else:
ndata = self._data
nlength = j - i
if j != self._len:
#we'll have to invent faster variants here
#e.g. mod_2exp
ndata = ndata & ((1L << nlength) - 1)
return BitVec(ndata, nlength)
def __setslice__(self, i, j, sequence, *rest):
#rprt(`self`+'.__setslice__'+`(i, j, sequence) + rest`+'\n')
i, j = _check_slice(self._len, i, j)
if type(sequence) != type(self):
sequence = apply(bitvec, (sequence, ) + rest)
#sequence is now of our own type
ls_part = self[:i]
ms_part = self[j:]
self._data = ls_part._data | \
((sequence._data | \
(ms_part._data << sequence._len)) << ls_part._len)
self._len = self._len - j + i + sequence._len
def __delslice__(self, i, j):
#rprt(`self`+'.__delslice__'+`i, j`+'\n')
i, j = _check_slice(self._len, i, j)
if i == 0 and j == self._len:
self._data, self._len = 0L, 0
elif i < j:
self._data = self[:i]._data | (self[j:]._data >> i)
self._len = self._len - j + i
def __add__(self, other):
#rprt(`self`+'.__add__('+`other`+')\n')
retval = self.copy()
retval[self._len:self._len] = other
return retval
def __mul__(self, multiplier):
#rprt(`self`+'.__mul__('+`multiplier`+')\n')
if type(multiplier) != type(0):
raise TypeError, 'sequence subscript not int'
if multiplier <= 0:
return BitVec(0L, 0)
elif multiplier == 1:
return self.copy()
#handle special cases all 0 or all 1...
if self._data == 0L:
return BitVec(0L, self._len * multiplier)
elif (~self)._data == 0L:
return ~BitVec(0L, self._len * multiplier)
#otherwise el cheapo again...
retval = BitVec(0L, 0)
while multiplier:
retval, multiplier = retval + self, multiplier - 1
return retval
def __and__(self, otherseq, *rest):
#rprt(`self`+'.__and__'+`(otherseq, ) + rest`+'\n')
if type(otherseq) != type(self):
otherseq = apply(bitvec, (otherseq, ) + rest)
#sequence is now of our own type
return BitVec(self._data & otherseq._data, \
min(self._len, otherseq._len))
def __xor__(self, otherseq, *rest): def sort(self):
#rprt(`self`+'.__xor__'+`(otherseq, ) + rest`+'\n') c = self.count(1)
if type(otherseq) != type(self): self._data = ((1L << c) - 1) << (self._len - c)
otherseq = apply(bitvec, (otherseq, ) + rest)
#sequence is now of our own type
return BitVec(self._data ^ otherseq._data, \
max(self._len, otherseq._len))
def __or__(self, otherseq, *rest): def copy(self):
#rprt(`self`+'.__or__'+`(otherseq, ) + rest`+'\n') return BitVec(self._data, self._len)
if type(otherseq) != type(self):
otherseq = apply(bitvec, (otherseq, ) + rest)
#sequence is now of our own type
return BitVec(self._data | otherseq._data, \
max(self._len, otherseq._len))
def __invert__(self): def seq(self):
#rprt(`self`+'.__invert__()\n') result = []
return BitVec(~self._data & ((1L << self._len) - 1), \ for i in self:
self._len) result.append(i)
return result
def __coerce__(self, otherseq, *rest):
#needed for *some* of the arithmetic operations
#rprt(`self`+'.__coerce__'+`(otherseq, ) + rest`+'\n')
if type(otherseq) != type(self):
otherseq = apply(bitvec, (otherseq, ) + rest)
return self, otherseq
def __int__(self): def __repr__(self):
return int(self._data) ##rprt('<bitvec class instance object>.' + '__repr__()\n')
return 'bitvec' + `self._data, self._len`
def __long__(self): def __cmp__(self, other, *rest):
return long(self._data) #rprt(`self`+'.__cmp__'+`(other, ) + rest`+'\n')
if type(other) != type(self):
other = apply(bitvec, (other, ) + rest)
#expensive solution... recursive binary, with slicing
length = self._len
if length == 0 or other._len == 0:
return cmp(length, other._len)
if length != other._len:
min_length = min(length, other._len)
return cmp(self[:min_length], other[:min_length]) or \
cmp(self[min_length:], other[min_length:])
#the lengths are the same now...
if self._data == other._data:
return 0
if length == 1:
return cmp(self[0], other[0])
else:
length = length >> 1
return cmp(self[:length], other[:length]) or \
cmp(self[length:], other[length:])
def __float__(self):
return float(self._data) def __len__(self):
#rprt(`self`+'.__len__()\n')
return self._len
def __getitem__(self, key):
#rprt(`self`+'.__getitem__('+`key`+')\n')
key = _check_key(self._len, key)
return self._data & (1L << key) != 0
def __setitem__(self, key, value):
#rprt(`self`+'.__setitem__'+`key, value`+'\n')
key = _check_key(self._len, key)
#_check_value(value)
if value:
self._data = self._data | (1L << key)
else:
self._data = self._data & ~(1L << key)
def __delitem__(self, key):
#rprt(`self`+'.__delitem__('+`key`+')\n')
key = _check_key(self._len, key)
#el cheapo solution...
self._data = self[:key]._data | self[key+1:]._data >> key
self._len = self._len - 1
def __getslice__(self, i, j):
#rprt(`self`+'.__getslice__'+`i, j`+'\n')
i, j = _check_slice(self._len, i, j)
if i >= j:
return BitVec(0L, 0)
if i:
ndata = self._data >> i
else:
ndata = self._data
nlength = j - i
if j != self._len:
#we'll have to invent faster variants here
#e.g. mod_2exp
ndata = ndata & ((1L << nlength) - 1)
return BitVec(ndata, nlength)
def __setslice__(self, i, j, sequence, *rest):
#rprt(`self`+'.__setslice__'+`(i, j, sequence) + rest`+'\n')
i, j = _check_slice(self._len, i, j)
if type(sequence) != type(self):
sequence = apply(bitvec, (sequence, ) + rest)
#sequence is now of our own type
ls_part = self[:i]
ms_part = self[j:]
self._data = ls_part._data | \
((sequence._data | \
(ms_part._data << sequence._len)) << ls_part._len)
self._len = self._len - j + i + sequence._len
def __delslice__(self, i, j):
#rprt(`self`+'.__delslice__'+`i, j`+'\n')
i, j = _check_slice(self._len, i, j)
if i == 0 and j == self._len:
self._data, self._len = 0L, 0
elif i < j:
self._data = self[:i]._data | (self[j:]._data >> i)
self._len = self._len - j + i
def __add__(self, other):
#rprt(`self`+'.__add__('+`other`+')\n')
retval = self.copy()
retval[self._len:self._len] = other
return retval
def __mul__(self, multiplier):
#rprt(`self`+'.__mul__('+`multiplier`+')\n')
if type(multiplier) != type(0):
raise TypeError, 'sequence subscript not int'
if multiplier <= 0:
return BitVec(0L, 0)
elif multiplier == 1:
return self.copy()
#handle special cases all 0 or all 1...
if self._data == 0L:
return BitVec(0L, self._len * multiplier)
elif (~self)._data == 0L:
return ~BitVec(0L, self._len * multiplier)
#otherwise el cheapo again...
retval = BitVec(0L, 0)
while multiplier:
retval, multiplier = retval + self, multiplier - 1
return retval
def __and__(self, otherseq, *rest):
#rprt(`self`+'.__and__'+`(otherseq, ) + rest`+'\n')
if type(otherseq) != type(self):
otherseq = apply(bitvec, (otherseq, ) + rest)
#sequence is now of our own type
return BitVec(self._data & otherseq._data, \
min(self._len, otherseq._len))
def __xor__(self, otherseq, *rest):
#rprt(`self`+'.__xor__'+`(otherseq, ) + rest`+'\n')
if type(otherseq) != type(self):
otherseq = apply(bitvec, (otherseq, ) + rest)
#sequence is now of our own type
return BitVec(self._data ^ otherseq._data, \
max(self._len, otherseq._len))
def __or__(self, otherseq, *rest):
#rprt(`self`+'.__or__'+`(otherseq, ) + rest`+'\n')
if type(otherseq) != type(self):
otherseq = apply(bitvec, (otherseq, ) + rest)
#sequence is now of our own type
return BitVec(self._data | otherseq._data, \
max(self._len, otherseq._len))
def __invert__(self):
#rprt(`self`+'.__invert__()\n')
return BitVec(~self._data & ((1L << self._len) - 1), \
self._len)
def __coerce__(self, otherseq, *rest):
#needed for *some* of the arithmetic operations
#rprt(`self`+'.__coerce__'+`(otherseq, ) + rest`+'\n')
if type(otherseq) != type(self):
otherseq = apply(bitvec, (otherseq, ) + rest)
return self, otherseq
def __int__(self):
return int(self._data)
def __long__(self):
return long(self._data)
def __float__(self):
return float(self._data)
bitvec = BitVec bitvec = BitVec

View file

@ -1,13 +1,13 @@
#! /usr/bin/env python #! /usr/bin/env python
# 1) Regular Expressions Test # 1) Regular Expressions Test
# #
# Read a file of (extended per egrep) regular expressions (one per line), # Read a file of (extended per egrep) regular expressions (one per line),
# and apply those to all files whose names are listed on the command line. # and apply those to all files whose names are listed on the command line.
# Basically, an 'egrep -f' simulator. Test it with 20 "vt100" patterns # Basically, an 'egrep -f' simulator. Test it with 20 "vt100" patterns
# against a five /etc/termcap files. Tests using more elaborate patters # against a five /etc/termcap files. Tests using more elaborate patters
# would also be interesting. Your code should not break if given hundreds # would also be interesting. Your code should not break if given hundreds
# of regular expressions or binary files to scan. # of regular expressions or binary files to scan.
# This implementation: # This implementation:
# - combines all patterns into a single one using ( ... | ... | ... ) # - combines all patterns into a single one using ( ... | ... | ... )
@ -24,27 +24,27 @@ from regex_syntax import *
regex.set_syntax(RE_SYNTAX_EGREP) regex.set_syntax(RE_SYNTAX_EGREP)
def main(): def main():
pats = map(chomp, sys.stdin.readlines()) pats = map(chomp, sys.stdin.readlines())
bigpat = '(' + string.joinfields(pats, '|') + ')' bigpat = '(' + string.joinfields(pats, '|') + ')'
prog = regex.compile(bigpat) prog = regex.compile(bigpat)
for file in sys.argv[1:]: for file in sys.argv[1:]:
try: try:
fp = open(file, 'r') fp = open(file, 'r')
except IOError, msg: except IOError, msg:
print "%s: %s" % (file, msg) print "%s: %s" % (file, msg)
continue continue
lineno = 0 lineno = 0
while 1: while 1:
line = fp.readline() line = fp.readline()
if not line: if not line:
break break
lineno = lineno + 1 lineno = lineno + 1
if prog.search(line) >= 0: if prog.search(line) >= 0:
print "%s:%s:%s" % (file, lineno, line), print "%s:%s:%s" % (file, lineno, line),
def chomp(s): def chomp(s):
if s[-1:] == '\n': return s[:-1] if s[-1:] == '\n': return s[:-1]
else: return s else: return s
main() main()

View file

@ -1,17 +1,17 @@
#! /usr/bin/env python #! /usr/bin/env python
# 2) Sorting Test # 2) Sorting Test
# #
# Sort an input file that consists of lines like this # Sort an input file that consists of lines like this
# #
# var1=23 other=14 ditto=23 fred=2 # var1=23 other=14 ditto=23 fred=2
# #
# such that each output line is sorted WRT to the number. Order # such that each output line is sorted WRT to the number. Order
# of output lines does not change. Resolve collisions using the # of output lines does not change. Resolve collisions using the
# variable name. e.g. # variable name. e.g.
# #
# fred=2 other=14 ditto=23 var1=23 # fred=2 other=14 ditto=23 var1=23
# #
# Lines may be up to several kilobytes in length and contain # Lines may be up to several kilobytes in length and contain
# zillions of variables. # zillions of variables.
@ -28,23 +28,23 @@ import string
import sys import sys
def main(): def main():
prog = regex.compile('^\(.*\)=\([-+]?[0-9]+\)') prog = regex.compile('^\(.*\)=\([-+]?[0-9]+\)')
def makekey(item, prog=prog): def makekey(item, prog=prog):
if prog.match(item) >= 0: if prog.match(item) >= 0:
var, num = prog.group(1, 2) var, num = prog.group(1, 2)
return string.atoi(num), var return string.atoi(num), var
else: else:
# Bad input -- pretend it's a var with value 0 # Bad input -- pretend it's a var with value 0
return 0, item return 0, item
while 1: while 1:
line = sys.stdin.readline() line = sys.stdin.readline()
if not line: if not line:
break break
items = string.split(line) items = string.split(line)
items = map(makekey, items) items = map(makekey, items)
items.sort() items.sort()
for num, var in items: for num, var in items:
print "%s=%s" % (var, num), print "%s=%s" % (var, num),
print print
main() main()

View file

@ -1,7 +1,7 @@
#! /usr/bin/env python #! /usr/bin/env python
# 3) System Test # 3) System Test
# #
# Given a list of directories, report any bogus symbolic links contained # Given a list of directories, report any bogus symbolic links contained
# anywhere in those subtrees. A bogus symbolic link is one that cannot # anywhere in those subtrees. A bogus symbolic link is one that cannot
# be resolved because it points to a nonexistent or otherwise # be resolved because it points to a nonexistent or otherwise
@ -21,54 +21,54 @@ import sys
from stat import * from stat import *
def main(): def main():
try: try:
# Note: can't test for presence of lstat -- it's always there # Note: can't test for presence of lstat -- it's always there
dummy = os.readlink dummy = os.readlink
except AttributeError: except AttributeError:
print "This system doesn't have symbolic links" print "This system doesn't have symbolic links"
sys.exit(0) sys.exit(0)
if sys.argv[1:]: if sys.argv[1:]:
prefix = sys.argv[1] prefix = sys.argv[1]
else: else:
prefix = '' prefix = ''
if prefix: if prefix:
os.chdir(prefix) os.chdir(prefix)
if prefix[-1:] != '/': prefix = prefix + '/' if prefix[-1:] != '/': prefix = prefix + '/'
reportboguslinks(prefix) reportboguslinks(prefix)
else: else:
reportboguslinks('') reportboguslinks('')
def reportboguslinks(prefix): def reportboguslinks(prefix):
try: try:
names = os.listdir('.') names = os.listdir('.')
except os.error, msg: except os.error, msg:
print "%s%s: can't list: %s" % (prefix, '.', msg) print "%s%s: can't list: %s" % (prefix, '.', msg)
return return
names.sort() names.sort()
for name in names: for name in names:
if name == os.curdir or name == os.pardir: if name == os.curdir or name == os.pardir:
continue continue
try: try:
mode = os.lstat(name)[ST_MODE] mode = os.lstat(name)[ST_MODE]
except os.error: except os.error:
print "%s%s: can't stat: %s" % (prefix, name, msg) print "%s%s: can't stat: %s" % (prefix, name, msg)
continue continue
if S_ISLNK(mode): if S_ISLNK(mode):
try: try:
os.stat(name) os.stat(name)
except os.error: except os.error:
print "%s%s -> %s" % \ print "%s%s -> %s" % \
(prefix, name, os.readlink(name)) (prefix, name, os.readlink(name))
elif S_ISDIR(mode): elif S_ISDIR(mode):
try: try:
os.chdir(name) os.chdir(name)
except os.error, msg: except os.error, msg:
print "%s%s: can't chdir: %s" % \ print "%s%s: can't chdir: %s" % \
(prefix, name, msg) (prefix, name, msg)
continue continue
try: try:
reportboguslinks(prefix + name + '/') reportboguslinks(prefix + name + '/')
finally: finally:
os.chdir('..') os.chdir('..')
main() main()