Luchino Gregoretti
Luchino Gregoretti

Reputation: 3

Python : Limiting input as numbers and numbers with decimal places

How to limit input to only integers or numbers with two decimal places, else (alphabet or other symbols) it will display 'invalid' and allow the user to enter again.

code:

counter = 100
income = input("Enter income: ")

while counter >0:
    try:
       val = int(income)
       print ("YES")
       income = input("Enter money: ")
       counter = counter - 1
    except ValueError:
       print("NO")
       income = input("Enter money: ")
       counter = counter - 1

I've taken the val = int (???) from another question and it works if it's limiting to integer input only, since my program involves money I need it to go up to two decimal places but it does not accept decimals. (The counter are only for me to test the program)

Upvotes: 0

Views: 3039

Answers (4)

jwilner
jwilner

Reputation: 6606

With this many constraints on the pattern, I really think a regex is more declarative and readable.

import re 
NUM_REGEX = re.compile(r"^\d+(?:\.\d{,2})?$")

input_str = input("give me a number") 

while NUM_REGEX.match(input_str) is None:
    input_str = input("Nope, not valid. Give me another.")

return float(input_str) 

Upvotes: 1

cdarke
cdarke

Reputation: 44354

In my opinion you need a regular expression for the features you need, in particular ensuring exactly two digits after the decimal point, while making that optional.

I have imposed the income as pence or cents. This is because you may get rounding issues using float.

import re

# income as pence/cents
income = None

while income is None:
    instr = input("Enter money: ")
    m = re.fullmatch(r'(\d+)(?:\.(\d{2}))?', instr)
    if m:
        full, cents =  m.groups()
        if cents == '' or cents is None: 
            cents = '0'
        income = (int(full) * 100) + int(cents)
    else:
        print("NO")

print("Income is %d.%02d" % (income/100, income % 100))

Upvotes: 1

manu190466
manu190466

Reputation: 1603

You could use regexp :

import re
is_number=re.compile('^\d+\.?\d{,2}$')

>>>is_number.match('3.14') is not None
True
>>>is_number.match('32222') is not None
True
>>> is_number.match('32A') is not None
False
>>> is_number.match('3.1445') is not None
False

Upvotes: 1

You could define your own input function

def input_number(msg):
    while True:
        try:
            res = round(float(input(msg)), 2)
            break
        except:
            print("Invalid")
    return res

income = input_number("Enter money:\n")

Upvotes: 1

Related Questions