How to make sure an input() is a number in python 3


#1

How do I make sure an input() is a number?

import time

x = input("Hey")

x = int(x)

y = x%3

print(y)

time.sleep(0.25)

if y != 0:
    print("Oh, there's a remainder!")

So I convert it to integer, but then I don’t know how to throw an error if the user enters something that isn’t a number - since input() is always a string until I convert it to integer, I found.

I want to know if there’s a way to check if input is a number.


#2

One way to do it is to use try and except. Here is something I learned in the Computer Science Path and played around with it again to get the results i think you are looking for. There is a isinstance() thing that I think would be optional:

while True:
  try:
    answer = int(input( "Enter interger"))
    if isinstance(answer, int):  #optional
        print( "Yay!")  #optional
        break
  except ValueError:
    print("Not an Interger")

I tested it with a non-integer and saw what error it threw and it was ValueError so that is what I added to the except portion.


#3

Hm, okay. So if I read that correctly, it doesn’t matter if you converted the answer to integer in the initial assignment, because it will still read letters as strings? I wonder why that is.


#4

I get this

Traceback (most recent call last):
  File "C:\Users\User\Documents\Python Scripts\tryexcept to test for number in input.py", line 10, in <module>
    print(answer/3)
NameError: name 'answer' is not defined

From this code

import time

while True:
    try:
        answer = int(input( "Will divide by 3.  Enter integer: "))
        #if isinstance(answer, int):  #optional
         #   break
    except ValueError:
        print("Not an Interger")
    print(answer/3)
    y = answer%3
    
    time.sleep(0.25)

    if y != 0:
        print("Oh, there's a remainder, mon!  It's "+str(y))
        break

The problem, it seems, is that it assigns answer only inside the try block, but not outside of it.

The problem is, of course, that when I move input outside of the try, it just shuts down as normal when I don’t enter a number.

EDIT: Okay I managed a fix by putting everything into try.

import time

while True:
    try:
        answer = int(input( "Will divide by 3.  Enter integer: "))
        if isinstance(answer, int):  #optional
            print(answer/3)
            y = answer%3
            if y != 0:
                time.sleep(0.25)
                print("Oh, there's a remainder, mon!  It's "+str(y))
                break
    except ValueError:
        print("Not an Interger")

Putting everything in try is what SentDex (on youtube) does too, I noticed. I dunno if there’s any alternative…

Also I’m still confused as to why it only works when I convert to int directly at input


#5

I don’t think you have to have int() at the input, but you do need to save it somewhere before it starts being used. I think what you had above should have worked. You just didn’t have a check for an integer. For example, I changed your code to look more like what you originally had:

import time

while True:
    try:
        x = input( "Will divide by 3.  Enter integer: ")
        x= int(x)
        #if isinstance(answer, int):  #optional
         #   break
        print(x/3)
        y = x%3
    
        time.sleep(0.25)

        if y != 0:
            print("Oh, there's a remainder, mon!  It's "+str(y))
            break

    except ValueError:
        print("Not an Interger")

it worked for me.

I tested to make sure it was an integer by:

x = input("Hey")

x = int(x)
print(isinstance(answer, int))

And it comes back as True when an integer is placed


#6

Working with exceptions means not having to use built-ins to test a value.

>>> x = 'hey'
>>> x = int(x)
Traceback (most recent call last):
  File "<pyshell#271>", line 1, in <module>
    x = int(x)
ValueError: invalid literal for int() with base 10: 'hey'
>>> 

Notice how invoking the int() constructor raised a ValueError. That is where try comes in.

def get_int():
  while True:
    x = input("Enter an integer: ")
    try:
      return int(x)
    except ValueError:
      print ("Try again...")

y = get_int()
# now do the math on y

Extended

>>> def get_float():
  while True:
    x = input("Enter any number: ")
    try:
      return float(x)
    except ValueError:
      print ("Try again...")

      
>>> get_float()
Enter any number: hey
Try again...
Enter any number: 42
42.0
>>> 

#7
import time

while True:
    answer = input( "Will divide by 3.  Enter integer: ")
    try:
        int(answer)
    except ValueError:
        print("Not an Integer")
        continue
    print(answer/3)
    y = answer%3
    if y != 0:
        time.sleep(0.25)
        print("Oh, there's a remainder, mon!  It's "+str(y))
        break

I get this, when I input a number. Inputting a string like ‘jaldfja’ trips the except.

Traceback (most recent call last):
  File "C:\Users\User\Documents\Python Scripts\tryexcept to test for number in input.py", line 10, in <module>
    print(answer/3)
TypeError: unsupported operand type(s) for /: 'str' and 'int'

If I convert the input to type int, then it errors on line 4 when I input a non-number instead.

Traceback (most recent call last):
  File "C:\Users\User\Documents\Python Scripts\tryexcept to test for number in input.py", line 4, in <module>
    answer = int(input( "Will divide by 3.  Enter integer: "))
ValueError: invalid literal for int() with base 10: 'ajsfljsd'

Basically, it switches it around.


#8

The math should not be done inside the function or loop that gets your input. You’re loading up too many tasks. They’re meant to be simple, and predictible.

Do it like shown. after the function returns (or loop allows to escape) a number, not inside the poor thing.


#10

Didn’t get what you were saying, but I did figure it out