5

I'm working on a class project that requires me to obtain a float value from the user. This float value must have exactly two numbers after the decimal in order to be a valid input. This is what I have so far.

while True:
    try:
        cost = float(input("Enter the price: "))
        if cost % 1 == 0:
            print("Invalid input for price.")

        else:
            if cost > 0:
               return cost

    except ValueError:
        print("Invalid input for price.")

Comparing cost % 1 to 0 rules out ints and floats ending in .00, but I'm not sure how I could restrict the accepted input to a float with exactly 2 numbers after the decimal (i.e. x.xx). Also I believe I would need to accept a float like 5.00 so my method isn't going to cut it. I've tried converting cost to a str and setting restrictions on the length, but that still leaves it open to mistakes. Any advice?

Travis
  • 113
  • 1
  • 6

4 Answers4

6

You can check it before converting to float:

cost = input("Enter the price: ")
if len(cost.rsplit('.')[-1]) == 2:
   print('2 digits after decimal point')
vaultah
  • 44,105
  • 12
  • 114
  • 143
  • Clever, I like that solution! I've only used split a few times, so I didn't even think to do it that way. Thank you :) – Travis Apr 26 '14 at 06:10
1

Use this code:

>>> while True:
...     try:
...             x = float(raw_input('Enter the price: '))
...             y = str(x).split('.')
...             if len(y[-1]) != 2:
...                     raise ValueError
...     except ValueError:
...             print 'Please try again!'
...             pass
... 
Enter the price: hello
Please try again!
Enter the price: 5.6
Please try again!
Enter the price: 5.67
Enter the price: 7.65
Enter the price: 7
Please try again!
Enter the price: 

It gets the input as a float, and if the user does not enter a numerical value, it raises a ValueError by default. If it doesn't, then we get the string value of the price using str(x) and assign it to y, which we split by the decimal place. Then we can check if the last value in the list (the yx in $x.yz) has a length that is not equal to 2. If so, raise a ValueError.

A.J. Uppal
  • 19,117
  • 6
  • 45
  • 76
0

Why make it so complicated?

cost = raw_input('Enter the price: ')
if len(cost[cost.rfind('.')+1:]) != 2:
    raise ValueError('Must have two numbers after decimal point')
try:
    cost = float(cost)
except ValueError:
    print('Please enter a valid number')
Burhan Khalid
  • 169,990
  • 18
  • 245
  • 284
0

Use raw_input() instead of input(). That is safer (no use of eval) and it returns the actual string the user entered.

Then check the string with a regular expression.

>>> import re
>>> s = raw_input('Enter a price: ')
Enter a price: 3.14
>>> if not re.match(r'[0-9]*\.[0-9]{2}', s):
        print 'Not a valid price'

>>> price = float(s)
Raymond Hettinger
  • 216,523
  • 63
  • 388
  • 485