0

I want to make sure the input will be number. I have tried testing with signs and letters but the shell just throws an error saying "Invalid literal for Decimal". I'm working on a calculator so thought the decimal module would be best suited. Thanks in advance.

This is my code:

import decimal

while True:
 userInput = (raw_input("Enter number:"))
 try:
  userInput = decimal.Decimal(userInput)
  break
 except ValueError:
  print ("Number please")

Using Python 2.7.6

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
hazra
  • 400
  • 1
  • 6
  • 15
  • Your code seems to do what you ask for - it will detect an error in in input and ask again. – Jan Vlcinsky Jun 04 '14 at 14:10
  • 1
    It seems a different exception than `ValueError` is thrown. Try just `except:`, i.e. catch-all, or better: `except decimal.InvalidOperation:` – tobias_k Jun 04 '14 at 14:13
  • 2
    @tobias_k: No! Please don't advocate Pokemon exception handling. You can catch multiple explicit exception types instead. Also see [Why is "except: pass" a bad programming practice?](http://stackoverflow.com/q/21553327) – Martijn Pieters Jun 04 '14 at 14:13

4 Answers4

9

Catch decimal.InvalidOperation

>>> a = 's'
>>> try:
...     decimal.Decimal(a)
... except decimal.InvalidOperation:
...     print 'fds'
... 
fds
pynovice
  • 7,424
  • 25
  • 69
  • 109
3

Instead of catching a ValueError, catch a decimal.InvalidOperation error. This error is thrown when invalid data is passed to the decimal.Decimal constructor.

BeetDemGuise
  • 954
  • 7
  • 11
1

The correct way to check if a value is a valid input for Decimal is:

from decimal import Decimal, DecimalException

try:
    Decimal(input_value)
except DecimalException:
    pass

https://docs.python.org/2/library/decimal.html#decimal.DecimalException

Dragos C
  • 363
  • 3
  • 7
0

You are catching the wrong Exception. You are catching a ValueError, but the code throws decimal.InvalidOperation for various inputs that are not valid decimal values.

>python test.py
Enter number:10

>python test.py
Enter number:10.2

>python test.py
Enter number:asdf
Traceback (most recent call last):
  File "test.py", line 6, in <module>
    userInput = decimal.Decimal(userInput)
  File "C:\Python27\lib\decimal.py", line 548, in __new__
    "Invalid literal for Decimal: %r" % value)
  File "C:\Python27\lib\decimal.py", line 3872, in _raise_error
    raise error(explanation)
decimal.InvalidOperation: Invalid literal for Decimal: 'asdf'

>python test.py
Enter number:10.23.23
Traceback (most recent call last):
  File "test.py", line 6, in <module>
    userInput = decimal.Decimal(userInput)
  File "C:\Python27\lib\decimal.py", line 548, in __new__
    "Invalid literal for Decimal: %r" % value)
  File "C:\Python27\lib\decimal.py", line 3872, in _raise_error
    raise error(explanation)
decimal.InvalidOperation: Invalid literal for Decimal: '10.23.23'

Change your except line to except decimal.InvalidOperation:

Andy
  • 49,085
  • 60
  • 166
  • 233