13
numOfYears = 0
cpi = eval(input("Enter the CPI for July 2015: "))
if cpi.isdigit():
    while cpi < (cpi * 2):
        cpi *= 1.025
        numOfYears += 1
    print("Consumer prices will double in " + str(numOfYears) + " years.")
while not cpi.isdigit():
    print("Bad input")
    cpi = input("Enter the CPI for July 2015: ")

I'm getting the following error.

AttributeError: 'int' object has no attribute 'isdigit'

Since I'm new to programming, I don't really know what it's trying to tell me. I'm using the if cpi.isdigit(): to check to see if what the user entered is a valid number.

CodeMouse92
  • 6,840
  • 14
  • 73
  • 130
Kristofer Ard
  • 133
  • 1
  • 1
  • 5
  • 1
    Why not use `int(input(...))` which will convert string to int – sam Oct 10 '15 at 01:02
  • Can you provide more information like What is the value you are passing? What is your python version? What is the stacktrace? – kingpin Oct 10 '15 at 01:03
  • 1
    I'm entering an integer "239" but when someone else runs the program, they should be able to enter an int or a float. – Kristofer Ard Oct 10 '15 at 01:04
  • 1
    Additional this code has a huge [Arbitrary code execution](http://en.wikipedia.org/wiki/Arbitrary_code_execution) vulnerability due to it `eval`ing user input, which could contain python code. – pppery Oct 10 '15 at 01:08
  • 1
    This code will loop forever, unless `cpi` is negative, because a non-negative number is less than itself times two by basic rules of math. – pppery Oct 10 '15 at 01:16
  • In the condition "while cpi < (cpi * 2)", is there any way I can get the number that the user enters to double its self without having an infinite loop? – Kristofer Ard Oct 11 '15 at 01:30

4 Answers4

7

As documented here isdigit() is a string method. You can't call this method for integers.

This line,

cpi = eval(input("Enter the CPI for July 2015: ")) 

evaluates the user input to integer.

>>> x = eval(input("something: "))
something: 34
>>> type(x)
<class 'int'>
>>> x.isdigit()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'int' object has no attribute 'isdigit'

But if you remove eval method (you should better do that),

>>> x = input("something: ")
something: 54
>>> type(x)
<class 'str'>
>>> x.isdigit()
True

everything will be fine.

by the way using eval without sanitizin user input may cause problems

consider this.

>>> x = eval(input("something: "))
something: __import__('os').listdir()
>>> x
['az.php', 'so', 'form.php', '.htaccess', 'action.php' ...
marmeladze
  • 6,468
  • 3
  • 24
  • 45
6

Use this:

if(str(yourvariable).isdigit()) :
    print "number"

isdigit() works only for strings.

clemens
  • 16,716
  • 11
  • 50
  • 65
usr_11
  • 548
  • 10
  • 31
  • isdigit() will not work with negative numbers. It does not see the - as a digit and returns false. To solve that you can simply use this... yourString.replace("-","").isdigit() – Brént Russęll Mar 14 '19 at 02:37
4
numOfYears = 0
# since it's just suppposed to be a number, don't use eval!
# It's a security risk
# Simply cast it to a string
cpi = str(input("Enter the CPI for July 2015: "))

# keep going until you know it's a digit
while not cpi.isdigit():
    print("Bad input")
    cpi = input("Enter the CPI for July 2015: ")

# now that you know it's a digit, make it a float
cpi = float(cpi)
while cpi < (cpi * 2):
    cpi *= 1.025
    numOfYears += 1
# it's also easier to format the string
print("Consumer prices will double in {} years.".format(numOfYears))
Ben
  • 5,952
  • 4
  • 33
  • 44
0

eval() is very dangerous! And int() built-in function can convert string to digit.

If you want to catch the error if user didn't enter a number, just use try...except like this:

numOfYears = 0

while numOfYears == 0:
    try:
        cpi = int(input("Enter the CPI for July 2015: "))
    except ValueError:
        print("Bad input")
    else:
        while cpi < (cpi * 2):
            cpi *= 1.025
            numOfYears += 1

print("Consumer prices will double in", numOfYears, "years.")
Community
  • 1
  • 1
Remi Guan
  • 21,506
  • 17
  • 64
  • 87