33
votes
a = raw_input('How much is 1 share in that company? ')

while not a.isdigit():
    print("You need to write a number!\n")
    a = raw_input('How much is 1 share in that company? ')

This only works if the user enters an integer, but I want it to work even if they enter a float, but not when they enter a string.

So the user should be able to enter both 9 and 9.2, but not abc.

How should I do it?

8

8 Answers

15
votes

Use regular expressions.

import re

p = re.compile('\d+(\.\d+)?')

a = raw_input('How much is 1 share in that company? ')

while p.match(a) == None:
    print "You need to write a number!\n"
    a = raw_input('How much is 1 share in that company? ')
40
votes

EAFP

try:
    x = float(a)
except ValueError:
    print("You must enter a number")
22
votes

The existing answers are correct in that the more Pythonic way is usually to try...except (i.e. EAFP).

However, if you really want to do the validation, you could remove exactly 1 decimal point before using isdigit().

>>> "124".replace(".", "", 1).isdigit()
True
>>> "12.4".replace(".", "", 1).isdigit()
True
>>> "12..4".replace(".", "", 1).isdigit()
False
>>> "192.168.1.1".replace(".", "", 1).isdigit()
False

Notice that this does not treat floats any different from ints however. You could add that check if you really need it though.

8
votes

Building on dan04's answer:

def isDigit(x):
    try:
        float(x)
        return True
    except ValueError:
        return False

usage:

isDigit(3)     # True
isDigit(3.1)   # True
isDigit("3")   # True
isDigit("3.1") # True
isDigit("hi")  # False
3
votes
s = '12.32'
if s.replace('.', '').replace('-', '').isdigit():
    print(float(s))

Note that this will work for negative floats as well.

3
votes

I think @dan04 has the right approach (EAFP), but unfortunately the real world is often a special case and some additional code is really required to manage things—so below is a more elaborate, but also a bit more pragmatic (and realistic):

import sys

while True:
    try:
        a = raw_input('How much is 1 share in that company? ')
        x = float(a)
        # validity check(s)
        if x < 0: raise ValueError('share price must be positive')
    except ValueError, e:
        print("ValueError: '{}'".format(e))
        print("Please try entering it again...")
    except KeyboardInterrupt:
        sys.exit("\n<terminated by user>")
    except:
        exc_value = sys.exc_info()[1]
        exc_class = exc_value.__class__.__name__
        print("{} exception: '{}'".format(exc_class, exc_value))
        sys.exit("<fatal error encountered>")
    else:
        break  # no exceptions occurred, terminate loop

print("Share price entered: {}".format(x))

Sample usage:

> python numeric_input.py
How much is 1 share in that company? abc
ValueError: 'could not convert string to float: abc'
Please try entering it again...
How much is 1 share in that company? -1
ValueError: 'share price must be positive'
Please try entering it again...
How much is 1 share in that company? 9
Share price entered: 9.0

> python numeric_input.py
How much is 1 share in that company? 9.2
Share price entered: 9.2
3
votes
import re

string1 = "0.5"
string2 = "0.5a"
string3 = "a0.5"
string4 = "a0.5a"

p = re.compile(r'\d+(\.\d+)?$')

if p.match(string1):
    print(string1 + " float or int")
else:
    print(string1 + " not float or int")

if p.match(string2):
    print(string2 + " float or int")
else:
    print(string2 + " not float or int")

if p.match(string3):
    print(string3 + " float or int")
else:
    print(string3 + " not float or int")

if p.match(string4):
    print(string4 + " float or int")
else:
    print(string4 + " not float or int")

output:
0.5 float or int
0.5a not float or int
a0.5 not float or int
a0.5a not float or int
1
votes

The provided answers fail if the string contains some special characters such as underscore (e.g. '1_1'). The following function returns correct answer in all case that I tested.

def IfStringRepresentsFloat(s):
try:
    float(s)
    return str(float(s)) == s
except ValueError:
    return False