mirror of
https://github.com/python/cpython.git
synced 2025-07-24 03:35:53 +00:00
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:
parent
4f237b6870
commit
946c53ed7f
10 changed files with 981 additions and 981 deletions
|
@ -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()
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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__':
|
||||||
|
|
|
@ -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:]
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue