Alternatives to the ".isdigit()" command, that allow decimals and negatives

Viewed 51

I have been learning to code in Python, and I think that I have learnt a lot so far. However, I have a small doubt regarding the ".isdigit()" command. For starters, it seems to only detect whole numbers, and treats all other types as strings. Please tell me alternative codes that I could use.

My current code (for reference):

Valid_Integer = False
while not Valid_Integer:
    addend1 = input("\nEnter Addend #1: ") 
    if addend1.isdigit():
        Valid_Integer = True
    else:
        print("Please enter a number...")
Valid_Integer = False
while not Valid_Integer:
    addend2 = input("Enter Addend #2: ") 
    if addend2.isdigit():
        Valid_Integer = True
    else:
        print("Please enter a number...\n")_

result_add = float(addend1) + float(addend2)
print("\nThe Sum is: ",result_add)
3 Answers

You can use exception (try, except). You try an action, if it doesn't work successfully, the exception is raised. If the number is not able to be converted to a int, float, you ask to the user to submit another one.

valid_integer = False
while not valid_integer:
    try:
        addend1 = float(input("\nEnter Addend #1: ") )
        valid_integer = True
    except:
        valid_integer = False
        print("Please enter a number...")
valid_integer = False
while not valid_integer:
    try:
        addend2 = float(input("\nEnter Addend #2: ") )
        valid_integer = True
    except:
        valid_integer = False
        print("Please enter a number...")

result_add = addend1 + addend2
print("\nThe Sum is: ",result_add)

The numerical values can be tested using regular expressions, via the built-in re library.

Below is a simplified example of your code's logic:

  • Create a regex pattern to match only digit, decimal and negative values. Currently the pattern is intentionally simple, so there are known validation holes, in that it will accept values such as 123.-123.. This can be enhanced, but will mean a more complex pattern.
  • Define a function getinput. This means the prompt only has to be written once, and can be called multiple times.
  • The function is called twice (using for _ in range(2)) in a list comprehension, which stores the values into a list, called values.
  • The sum() function is called on the list of values, to return their sum.

Example code:

import re

rexp = re.compile('[\d\.-]+')

def getinput() -> float:
    """Collect a numerical value from the user."""
    while True:
        resp = input(f"Enter an addend: " )
        if not rexp.match(resp):  # <-- Numerical validation test here.
            print(f"Please enter a number: ")
        else:
            return float(resp)

Usage:

values = [getinput() for _ in range(2)]
print(f'The sum is: {sum(values)}')

>>> Enter an addend: 123
>>> Enter an addend: 123
The sum is: 246.0

You seem to be using isdigit() outside of its scope. If you go into the implementation of isdigit(), you see this

def isdigit(c): return 48 <= _ctoi(c) <= 57

where ctoi is a function that returns the ASCII code for the number/character. Hence it's limited to positive integers.

You can try to use a try except block instead of an if else. Check if the input can be converted to an int. If it cannot, you use the except block exactly how you have used else.

Related