0

I have a string like '102.3k' I would like to convert this string with an engineer prefix notation to a float number.

http://en.wikipedia.org/wiki/Engineering_notation

Allowed prefixes are

posPrefixes = ['k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']
negPrefixes = ['m', 'µ', 'n', 'p', 'f', 'a', 'z', 'y']

k means 10^3

M means 10^6

m means 10^-3

µ means 10^-6

I think I should use regex to do this but I have very few experience with regex.

edit: ideally the solution should also be able to convert any string so '102.3' (without prefix) should also be converted to float

working4coins
  • 1,997
  • 3
  • 22
  • 30
  • I am not sure if people will really read up wiki to answer the question. You might want to include the expected output. – thefourtheye Feb 18 '14 at 06:49

2 Answers2

4

Try this out, no regex needed:

pos_postfixes = ['k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']
neg_postfixes = ['m', 'µ', 'n', 'p', 'f', 'a', 'z', 'y']

num_postfix = n[-1]
if num_postfix in pos_postfixes:
    num = float(n[:-1])
    num*=10**((pos_postfixes.index(num_postfix)+1)*3)
elif num_postfix in neg_postfixes:
    num = float(n[:-1])
    num*=10**(-(neg_postfixes.index(num_postfix)+1)*3)
else:
    num = float(n)
print(num)

Another thing to note is that in python, it is more common to use underscore variable names than camelcasing, see the pep-8: http://www.python.org/dev/peps/pep-0008/

simonzack
  • 19,729
  • 13
  • 73
  • 118
  • the neg_postfixes one should be `num*=10**((neg_postfixes.index(num_postfix) + 1) * -3)` – algrebe Feb 18 '14 at 06:59
  • Yeah, i was writing the answer really nicely and then u posted an answer :P so figured id just check it. Also, does neg_postfixes work ? i tried it on [link](http://www.compileonline.com/execute_python_online.php) and it gave me an error **Non-ASCII character '\xc2'** for the second element 'µ' – algrebe Feb 18 '14 at 07:02
  • Thanks for proofreading it :P It should work on python 3, python 2 might have some unicode problems, so you might need to use u'µ'. Also you might need to add `# -*- encoding: utf-8 -*-` to the source file. – simonzack Feb 18 '14 at 07:04
  • Thanks but it only solve my problem if my string have a prefix. I would prefer a solution that can also convert string such a '102.3', '102.3 k', '102.3k' – working4coins Feb 18 '14 at 07:32
  • Yes... but I wonder how you could improve that to take into account also 'da' prefix. here is my code http://pastebin.com/BP0SRW6S – working4coins Feb 18 '14 at 07:48
1

If you want to control the value, you could try this:

import decimal
posPrefixes = {'k':'10E3', 'M':'10E6', 'G':'10E9', 'T':'10E12', 'P':'10E15', 'E':'10E18', 'Z':'10E21', 'Y':'10E24'}
negPrefixes = {'m':'10E-3', '?':'10E-6', 'n':'10E-9', 'p':'10E-12', 'f':'10E-15', 'a':'10E-18', 'z':'10E-21', 'y':'10E-24'}
val='102.3k'
if val[-1] in posPrefixes.keys():
    v = decimal.Decimal(val[:-1])
    print v*decimal.Decimal(posPrefixes[val[-1]])

val ='102.3n'
if val[-1] in negPrefixes.keys():
    v = decimal.Decimal(val[:-1])
    print v*decimal.Decimal(negPrefixes[val[-1]])

Output:

1.0230E+6

1.023e-06

venpa
  • 4,268
  • 21
  • 23