[Tutor] fractions
Michael P. Reilly
arcege@speakeasy.net
Thu, 26 Apr 2001 09:11:04 -0400 (EDT)
--%--multipart-mixed-boundary-1.1422.988290664--%
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
> Hi all,
>
> Does anyone know of a function to convert fractions to decimals and =
> decimals to fractions?
There is no nice function to do it, simply because there are no fractions
in Python (maybe in P3K?). But a couple of years ago (Jan '99), there
were questions about rational numbers in Python and I whipped up a little
class which I'm attaching.
If you mean simply the division of integers (as opposed to fractions as
a data type). Then you can do something as simple as:
x / float(y)
Division of a float with any other object (except a complex number)
will result in a float. Converting back to a "fraction" is something
else - there has to be the exception where it is not possible. In fact,
I just realized that my rational class doesn't even do this.
-Arcege
--
+----------------------------------+-----------------------------------+
| Michael P. Reilly | arcege@speakeasy.net |
--%--multipart-mixed-boundary-1.1422.988290664--%
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Description: a /usr/local/bin/python script text
Content-Disposition: attachment; filename="rational.py"
#!/usr/local/bin/python
# Copyright (C) 1999 Michael P. Reilly, All rights reserved
class Rational:
def __init__(self, numerator, denominator=1):
if denominator == 0:
raise ValueError, 'undefined value'
if isinstance(numerator, Rational):
denominator = denominator * numerator.d
numerator = numerator.n
if int(numerator) != numerator or int(denominator) != int(denominator):
raise ValueError, 'must supply integer values (for now)'
self.n = int(numerator)
self.d = int(denominator)
self.normalize()
def __int__(self):
return int(self.n/self.d)
def __float__(self):
return float(self.n)/self.d
def __str__(self):
if self.d == 1:
return '%d' % self.n
else:
return '%d/%d' % (self.n, self.d)
def __repr__(self):
return '%s(%d, %d)' % (self.__class__.__name__, self.n, self.d)
def __cmp__(self, other):
s, o, d = self.gcd(other)
return cmp(s, o)
def __rcmp__(self, other):
s, o, d = self.gcd(other)
return cmp(o, s)
def normalize(self):
num = self.n
dem = self.d
# this isn't the best algorithm
i = dem
while i > 0:
if (num % i) == 0 and (dem % i) == 0:
break
i = i - 1
else:
return
self.n = int(num/i)
self.d = int(dem/i)
def gcd(self, other):
sn = self.n * other.d
on = other.n * self.d
d = self.d * other.d
return (sn, on, d)
def __add__(self, other):
s, o, d = self.gcd(other)
r = self.__class__(s+o, d)
return r
__radd__ = __add__
def __sub__(self, other):
s, o, d = self.gcd(other)
r = self.__class__(s-o, d)
return r
def __rsub__(self, other):
s, o, d = self.gcd(other)
r = self.__class__(o-s, d)
return r
def __mul__(self, other):
r = self.__class__(self.n*other.n, self.d*other.d)
return r
__rmul__ = __mul__
def __div__(self, other):
r = self.__class__(self.n*other.d, self.d*other.n)
return r
def __rdiv__(self, other):
r = self.__class__(other.n*self.d, other.d*self.n)
return r
def __mod__(self, other):
r = divmod(self, other)
return r[1]
def __rmod__(self, other):
r = divmod(other, self)
return r[1]
def __divmod__(self, other):
r = self / other
whole = r.n / r.d
remainder = r.n % r.d
return (whole, remainder)
def __rdivmod__(self, other):
r = other / self
whole = r.n / r.d
remainder = r.n % r.d
return (whole, remainder)
def __pow__(self, other):
if other.d < 0: # great, now check for complex
if other.d == -1:
return complex(0, float(self))
else:
raise ValueError, 'not implimented'
sn = pow(self.n, float(other))
sd = pow(self.d, float(other))
r = self.__class__(sn, sd)
return r
def __rpow__(self, other):
return other ** self
def __neg__(self):
r = self.__class__(-self.n, self.d)
return r
def __pos__(self):
r = self.__class__(self.n, self.d)
return r
def __abs__(self):
r = self.__class__(abs(self.n), abs(self.d))
return r
def __coerce__(self, other):
if isinstance(other, Rational):
return self, other
elif type(other) is type(0):
return self, self.__class__(other)
elif type(other) is type(0L):
return self, self.__class__(other)
elif type(other) is type(0.0):
raise ValueError, 'not implimented'
elif type(other) == type(0j):
raise ValueError, 'not implimented'
return self, self.__class__(other.real, other.imag)
--%--multipart-mixed-boundary-1.1422.988290664--%--