This code was in discussion of getting numeric input to Python.

This function returns the zero-stripped, normalized string form the input string if it is correct, False truth value otherwise (it can not be mixed with number 0 as accepted '0' are returned as string '0').

If string passes the test, it can safely be changed to float by the float function, without causing exception.


More lazy way of implement this is by try..except:

## scanum checks that number is ok, does not yet recognize enginering format (e.g. 1e7)
from __future__ import print_function
import random

def scanum(x):
    try:
        v=float(x)
        return x
    except:
        return False

## do some random testing
num = 4000
chars = 20
ok = 0
for x in range(num):
    i = ''.join([x and i for x in range(1,chars + 1) for i in random.choice('-+1234567890.')])
    i = scanum(i)
    if  i:
        print(i) ## uses also scientific notation
        ok += 1
print()
print( ("Out of %i tested %i long numbers, %i were ok, (%.2f %%)"
       % (num, chars, ok, (float(ok)/num*100)) ))

However, sometimes it is useful practise to do things by yourself for practise or for understanding techniques. Also to this own made function could add features like thousands separator and comma used instead of decimal point.

Edited 6 Years Ago by pyTony: n/a

## scanum checks that number is ok, does not yet recognize enginering format (e.g. 1e7)
from __future__ import print_function
import random

def checkint(i):
    s = [n for n in  i if n.isdigit()]
    return ''.join(s) == i

def scanum(x):
## returns x if it is correct float or integer,
## False otherwise, if you want to raiseValueError comment return False and
## uncomment raise
    x=x.lstrip()
    if x[0]  ==  '-':
        x = x[1:].lstrip('0')
        intpart,found,fracpart = x.partition('.')
        intpart = intpart or '0' ## use 0.234 instead of .234
        ok = checkint(intpart)
        if found:
            ok = ok and checkint(fracpart)
        if not ok:
            return False
            #raise ValueError,'Improper whole or fraction part'
        if found:
            return '-' + intpart + '.' + fracpart.rstrip('0')
        else: return '-' + intpart
    else:
        if x[0] == ' + ': x = x[1:]
        x = x.lstrip('0')
        intpart,found,fracpart = x.partition('.')
        intpart = intpart or '0' ## use 0.234 instead of .234
        ok = checkint(intpart)
        if found:
            ok = ok and checkint(fracpart)
        if not ok:
            return False
            ##raise ValueError,'Improper whole or fraction part'
        if found:
            return intpart + '.' + fracpart.rstrip('0')
        else: return intpart

## do some random testing
num = 4000
chars = 20
ok = 0
for x in range(num):
    i = ''.join([x and i for x in range(1,chars + 1) for i in random.choice('-+1234567890.')])
    i = scanum(i)
    if  i:
        print(i)
        ok += 1
print()
print( ("Out of %i tested %i long numbers, %i were ok, (%.2f %%)"
       % (num, chars, ok, (float(ok)/num*100)) ))

Specialties:
IT/Science/Contracts/Religious translation/interpreting FIN-ENG-FIN
Python programming

You should re-think your logic for the first snippet. And please don't use "i", "l", or "O", especially when you are displaying programing snippets. There are 23 other letters.

def scanum(x):
    try:
        v=float(x)
        return x
    except:
        return False
 
ret_val = scanum(0)
if ret_val:
    print "True"
else:
    print "False"

Edited 6 Years Ago by woooee: n/a

The small code returns same way as long one checked string if it is validated, False otherwise.

Input is any string, which is checked for validity, you have input as number, which has not meaning to use the function as it is surely number.

Also your code would change that one integer to float value.

ok equals zero, not letter O, you can see it from that it is not in quotes.

Edited 6 Years Ago by pyTony: n/a

The article starter has earned a lot of community kudos, and such articles offer a bounty for quality replies.