Decimals -> Fraction strings, my solution

Scott kain at cableadmin.com
Tue May 16 23:51:40 CEST 2000


Hi all,

I've come up with one solution to my problem. Its probably quite
inefficient, but it does what I need for now.  Feel free to
tear it apart and/or give any advice on how to better implement it.
This code will take either a number or a string (ie '0.5') and return
a string of the fraction (ie '1/2').  Here it is:

#!/usr/bin/env python
# fract.py convert numbers/decimal strings to fraction strings

import string

def plist (num):
    """Returns a list of numbers that evenly divide into num.
    This is seems quite inefficient and probably should be changed"""
    p = []
    for x in range (2, num+1):
        if num % x == 0:
            p.append (x)
    p.append (num)
    return p


def gcd (numer, denom):
    """Return the greatest common denominator of two numbers"""
    if denom % numer == 0:
        return numer
    
    p1 = plist (numer)
    p2 = plist (denom)
    p1.reverse ()
    for x in p1:
        if x in p2:
            return x


def coerce (num):
    """Coerce a string into a number.  If not, return 0"""
    try:
        n = string.atoi (num)
    except ValueError:
        n = 0
    except TypeError:
        n = 0
    return n


def makefract (dec):
    """Makes a fractional string from a decimial number
    passed in string or numerical format"""
    
    if type (dec) == type (''):
        if string.find (dec, '.') < 0:
            return dec
    
        whole_str, frac_str = string.split (dec, '.')
        
        whole = coerce (whole_str)
        numer = coerce (frac_str)

        denom = pow (10, len (frac_str))

    else:
        if type(dec) == type(0):
            return str (dec)
        
        whole = int (dec)
        if dec - whole:
            numer = int ((dec - int (dec)) * \
                         (pow (10, len (str(dec-int(dec)))-2)))
            denom = pow (10, len (str (numer)))
        else:
            numer = 0
            denom = 0


    if numer == 0 and whole == 0:
        return '0'
    if numer == 0:
        return '%d' % whole
    
    gd = gcd (numer, denom)

    numer = numer/gd
    denom = denom/gd

    if whole:
        return '%d %d/%d' % (whole, numer, denom)
    else:
        return '%d/%d' % (numer, denom)



if __name__ == '__main__':

    print '0.5625  : ',
    print makefract ('0.5625')

    print '69.4375 : ',
    print makefract (69.4375)

    print '35      : ',
    print makefract (35)

    print '38.0    : ',
    print makefract (38.0)





More information about the Python-list mailing list