Speaking of useful home-made modules, I wrote this primitive module which
does limited math with fractions. Anyone is welcome to expand on it or use
it for any purpose. If anyone would like to submit it as a PEP to be added
to the Python library of reference, that would be great. If anyone wishes to
do that, I ask that you at least add me as a coauthor.
Collin Stocks
On 2/12/07, Marcin Ciura <[EMAIL PROTECTED]> wrote:
Hello,
I hacked together a module implementing exact real
arithmetic via lazily evaluated continued fractions.
You can download it from
http://www-zo.iinf.polsl.gliwice.pl/~mciura/software/cf.py
an use as an almost drop-in replacement for the math module
if you don't care too much about performance.
I'd be happy to hear any feedback and suggestions.
Cheers,
Marcin
--
http://mail.python.org/mailman/listinfo/python-list
from math import sqrt
class Fract(object):
def __init__(self,*args):
if len(args)==2:
self.num,self.den=map(int,args)
if len(args)==1:
try:self.num,self.den=args[0].num,args[0].den
except:self.num,self.den=int(args[0]),int(1)
def __abs__(self):
return Fract(abs(self.num),abs(self.den))
def __add__(self,other):
other=Fract(other)
x=self.change_den(self,other.den)
y=self.change_den(other,self.den)
return Fract(x.num+y.num,x.den)
def __sub__(self,other):
other=Fract(other)
x=self.change_den(self,other.den)
y=self.change_den(other,self.den)
return Fract(x.num-y.num,x.den)
def __div__(self,other):
other=Fract(other)
return Fract(self*self.invert(other))
def __mul__(self,other):
other=Fract(other)
return Fract(self.num*other.num,self.den*other.den)
def __gt__(self,other):
return float(self)>float(other)
def __lt__(self,other):
return float(self)<float(other)
def __ge__(self,other):
return float(self)>=float(other)
def __le__(self,other):
return float(self)<=float(other)
def __eq__(self,other):
return float(self)==float(other)
def __pow__(self,exp):
x=self
for i in range(1,exp):
x=x*self
return x
def __float__(self):
return float(self.num)/float(self.den)
def __int__(self):
return self.num/self.den
def __str__(self):
#print>>s,"string:",self.num,self.den
self.simplify()
return "%s/%s"%(self.num,self.den)
def __repr__(self):
#print>>s,"string:",self.num,self.den
self.simplify()
return "Fract(%s,%s)"%(self.num,self.den)
def simplify(self):
self.num,self.den=reduce(self.num,self.den)
"""
debug=[]
debug.append((self.num,self.den))
for i in [self.num,self.den,2,3,5,7]:
while self.num%i==0 and self.den%i==0 and self.num!=1 and
self.den!=1:
self.num/=i
self.den/=i
for i in xrange(11,int(sqrt(self.den))+3,2):
while self.num%i==0 and self.den%i==0:
self.num/=i
self.den/=i
if self.num==self.den!=1:
print debug
raise "the end"
"""
def invert(self,fraction):
fraction=Fract(fraction)
return Fract(fraction.den,fraction.num)
def change_den(self,fraction,mult):
return Fract(fraction.num*mult,fraction.den*mult)
def scale(*args):
mul=float(args[0])
args=list(args)
length=len(args)
dens=[]
for arg in args:
dens.append(arg.den)
#print>>s,args
for i in range(length):
for j in range(length):
if not i==j:
args[i].num*=dens[j]
args[i].den*=dens[j]
nums=[]
for arg in args:nums.append(arg.num)
args=map(Fract,reduce(*nums))
#print>>s,args
mul=float(args[0])/mul
args.append(mul)
#print>>s,args[0].den==args[1].den==args[2].den
return args
"""
for j in range(len(args)):
args2=list(args)
for i in range(len(args)):
#print>>s,i,j
#print>>s,args,args2
args[i]*=args2[j].den
dens=[]
for arg in args:dens.append(arg.den)
dens=reduce(*dens)
for i in range(len(dens)):args[i].den=dens[i]
#print>>s,args,args2
##args[i].simplify()
return args
"""
def reduce(*args):
args=list(args)
for i in [min(args),2,3,5,7]:
divisible=True
for j in range(len(args)):divisible=(divisible and (args[j]%i==0))
#print>>s,divisible,args,i
if args[0]!=int(args[0]):
raise Warning
while divisible and min(args)!=1:
for loc in range(len(args)):args[loc]/=i
for j in range(len(args)):divisible=(divisible and (args[j]%i==0))
for i in xrange(11,int(sqrt(min(args)))+3,2):
divisible=True
for j in range(len(args)):divisible=(divisible and (args[j]%i==0))
while divisible and min(args)!=1:
for loc in range(len(args)):args[loc]/=i
for j in range(len(args)):divisible=(divisible and (args[j]%i==0))
return args
import sys
s=sys.__stdout__
--
http://mail.python.org/mailman/listinfo/python-list