2

I am writing a code on the subject of engineering which requires the user to input several values which the program will then work with.

At the moment I have the following code:

while True:
    strainx =input("Please enter a value for strain in the x-direction: ")

    num_format = re.compile("^[1-9][0-9]*\.?[0-9]*")
    isnumber = re.match(num_format,strainx)
    if isnumber:

        break

In simple terms I am trying to ask the user to enter a value for strainx which is a number. If the user enters anything other than a number then the question will be repeated until they enter a number. However, by using this method the code does not accept decimals and there will be instances where the user must enter a decimal. Is there any way around this?

shayward
  • 19
  • 3
  • this could help: http://stackoverflow.com/questions/15357422/python-determine-if-a-string-should-be-converted-into-int-or-float – aldeb Apr 12 '15 at 16:35
  • Could this question be rephrased as "How can I verify that a variable is a number?" – Matt Davidson Apr 12 '15 at 16:37
  • possible duplicate of [Checking if a string can be converted to float in Python](http://stackoverflow.com/questions/736043/checking-if-a-string-can-be-converted-to-float-in-python) – Bas Swinckels Apr 12 '15 at 18:36

4 Answers4

4

Just try casting to a float and catching a ValueError if the user enters something that cannot be cast:

while True:
    strainx = input("Please enter a value for strain in the x-direction: ")  
    try:
       number = float(strainx)
       break # if valid entry we break the loop
    except ValueError:
        # or else we get here, print message and ask again
        print("Invalid entry")

print(number)

casting to float covers both "1" a "1.123" etc..

If you don't want to accept zero you can check after casting is the number is zero, I presume negative numbers are also invalid so we can check if the number is not <= 0.

while True:
    strainx = input("Please enter a value for strain in the x-direction: ")
    try:
        number = float(strainx)
        if number <= 0:
            print("Number must be greater than zero")
            continue  # input was either negative or 0
        break  # if valid entry we break the loop
    except ValueError:
        # or else we get here, print message and ask again
        print("Invalid entry")

print(number)
Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321
  • This is [EAFP](https://docs.python.org/3/glossary.html#term-eafp); it’s easier to ask for forgiveness than permission. Just assume that it’s a vaid number and catch the case where it is not. – poke Apr 12 '15 at 17:06
  • Okay great thanks, that works! I have several of these inputs. For one of them I want to specify that the input cannot equal zero either, is there any way of doing this? – shayward Apr 12 '15 at 17:25
  • Sure. After trying to cast add an if check to see if number is zero. If so print a message then use continue putting the break outside the if – Padraic Cunningham Apr 12 '15 at 17:29
  • I've been trying to write this into the program and I really don't understand how. Could you possibly give me some more guidance? Thanks – shayward Apr 12 '15 at 18:37
2

If you are looking for Integer check then try this -

isinstance( variable_name, int )

If it returns True then the variable is number else it's something else.

But if you want to check if the character value is number or not. eg - a = "2" above script will return False. So try this -

try:
    number = float(variable_name)
    print "variable is number"
except ValueError:
    print "Not a number"
  • 1
    Assuming Python 3, the return value of `input` will always be a string regardless of its content, so the `instanceof` check will never work there. – poke Apr 12 '15 at 17:08
0

If you are using Python 2, instead of using regular expressions, you can use Python's in built type checking mechanisms.

Let's loop while strainx is not a number, then check whether the latest input is a number.

is_number = False
while not is_number:
    strainx =input("Please enter a value for strain in the x-direction: ")
    is_number = isinstance(strainx, float) or isinstance(strainx, int)
Matt Davidson
  • 728
  • 4
  • 9
0

If you insist of using regex, this pattern appears to work:

"^(\-)?[\d]*(\.[\d]*)?$"

Match optional negative sign, match any number of digits, optional decimal with any number of digits.

Tip: You can use isnumber = bool(re.match(num_format,strainx) or the latter part directly into the if statement.

MaxQ
  • 595
  • 1
  • 8
  • 25
  • You don’t need to put single character class escape sequences (`\d`) into separate character classes (`[ ]`). And you also don’t need to escape dashes. You could shorten your expression to just `^-?\d*(\.\d*)?$`. And if you use `re.match`, you don’t actually need the caret `^`. – poke Apr 12 '15 at 17:13