Welcome, guest | Sign In | My Account | Store | Cart
```import unittest

def makeSigDigs(num, digits, debug=False):
"""Return a numeric string with significant digits of a given number.

Arguments:
num -- a numeric value
digits -- how many significant digits (int)
debug -- boolean; set to True for verbose mode
"""
notsig = ['0', '.', '-', '+', 'e'] # not significant
pad_zeros_left = '' # zeros to pad immed. left of the decimal
pad_zeros_right = '' # zeros to pad immed. right of the decimal
pad_zeros_last = '' # zeros to pad after last number after decimal
str_left = '' # string to prepend to left of zeros and decimal
str_right = '' # string to append to right of decimal and zeros
dec = '.' # the decimal
e_idx = None
e_str = ''
num = float(num)
if debug: print "%s at %s digits:" % (repr(num), digits)
for n in repr(num):
if n not in notsig: # ignore zeros and punctuation
first_idx = repr(num).find(n) # index of first digit we care about
if debug: print "\tfirst digit at %s" % (first_idx)
break
try: first_idx # If it doesn't exist, then we're looking at 0.0
except UnboundLocalError:
return '0.0'
try: e_idx = repr(num).index('e') # get index of e if in scientific notation
except: pass
if debug: print "\te at: %s" % (e_idx)
dec_idx = repr(num).find('.') # index of the decimal
if debug: print "\tdecimal at %s" % (dec_idx)
if dec_idx < first_idx:
"""All sigdigs to right of decimal '0.033'
"""
if debug: print "\tdigits are right of decimal."
last_idx = first_idx + digits -1
if last_idx+1 > len(repr(num)[0:e_idx]): # in case we need extra zeros at the end
if e_idx and last_idx >= e_idx: # fix last_idx if it picks up the 'e'
last_idx = e_idx-1
pad_zeros_right = '0'*(first_idx - dec_idx - 1)
str_right = repr(num)[first_idx:last_idx+1]
elif dec_idx > first_idx + digits - 1:
"""All sigdigs to left of decimal. '3300.0'
"""
if debug: print "\tdigits are left of decimal."
last_idx = first_idx + digits - 1
if e_idx and last_idx >= e_idx: # fix last_idx if it picks up the 'e'
last_idx = e_idx-1
str_left = repr(num)[first_idx]
str_right = repr(num)[first_idx+1:last_idx+1]+'e+'+str(dec_idx-1-first_idx)
else:
"""
if debug: print "\tnumber straddles decimal."
last_idx = first_idx + digits # an extra place for the decimal
if last_idx+1 > len(repr(num)[0:e_idx]): # in case we need extra zeros at the end
if e_idx and last_idx >= e_idx: # fix last_idx if it picks up the 'e'
last_idx = e_idx-1
str_left = repr(num)[first_idx:dec_idx]
str_right = repr(num)[dec_idx+1:last_idx + 1]
if e_idx:
e_str = repr(num)[e_idx:]
if debug: print "\tlast digit at %s" % (last_idx)
if debug: print "\t%s %s %s %s %s %s %s" % (str_left or '_',
dec or '_',
str_right or '_',
e_str or '_')
if debug: print "\tsignificant: %s\n" % (sig_string)
return sig_string

class utMakeSigDigs(unittest.TestCase):
knownValues = [[333.333, 4, '333.3'],
[33.0, 2, '3.3e+1'],
[333.33, 2, '3.3e+2'],
[33300.00, 4, '3.330e+4'],
[0.0033333, 3, '0.00333'],
[3.3e-10, 2, '3.3e-10'],
[0.0001, 2, '0.00010'],
[3.3e-10, 3, '3.30e-10'],
[1.0000000, 6, '1.00000'],
[1.00000001591, 6, '1.00000'],
[33330000000000000000.0, 6, '3.33300e+19'],
[33330000000000000000.03, 6, '3.33300e+19']
]
def testKnownValues(self):
"""MakeSigDigs should return known values for known inputs.
"""
for el in self.knownValues:
self.assertEqual(makeSigDigs(el[0], el[1], debug=True), el[2])

if __name__ == "__main__":
unittest.main()
```

### History

• revision 3 (16 years ago)
• previous revisions are not available