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