Archie
Archie

Reputation: 11

How to find datatype of input data

I am new to the python and My program is a simple addition program where it can add any number input by user(int or float) and the loop stops on entering q. Now my problem is that I keep getting "ValueError", every time I enter some numbers and then enter q to stop.

I have used eval() function to determine the datatype of the input data entered. and i have got my addition inside an infinite while loop that breaks on entering q.

This is my code:

sum,sum_i,c=0,0,0
sum_f=0.0

print("Enter q/Q to stop entering numbers.")
while True:
    a=input("Enter number: ")
    try:
        t= eval(a)
        print(type(t))
    except (NameError, ValueError):
        pass

    if(type(t)==int):
        sum_i=sum_i+int(a)
        c=c+1

    elif(type(t)==float):
        sum_f=sum_f+float(a)
        c=c+1

    elif (type(t)==str):
        if (a=='q'or a=='Q'):
            break

    else:
            print("Invalid data entered. Please enter a number to add or q/Q to quit. ")

sum= sum_i+ sum_f
print("You have entered ",c," numbers and their sum is: ",sum)

My output is supposed to provide the sum of the numbers entered on entering q, but this is what i get:

Enter q/Q to stop entering numbers.
Enter number: 3
<class 'int'>
Enter number: 5.5
<class 'float'>
Enter number: 12
<class 'int'>
Enter number: q
Traceback (most recent call last):
  File "/home/netvarth/py test/sum.py", line 14, in <module>
    sum_i=sum_i+int(a)
ValueError: invalid literal for int() with base 10: 'q'

Upvotes: 1

Views: 213

Answers (3)

Josh Friedlander
Josh Friedlander

Reputation: 11657

Your problem is in using eval. If it cannot parse a string as a variable, it should fail, but in your case you already have a t floating around in the namespace. t keeps its old identity as, say, an int, but then you try to add a (a string) to a number.

This code should work:

sum,sum_i,c=0,0,0
sum_f=0.0

print("Enter q/Q to stop entering numbers.")
while True:
    a=input("Enter number: ")
    try:
        t = int(a)
        sum_i=sum_i+int(a)
        c=c+1
        print(type(t))
        continue
    except ValueError:
        pass

    try:
        t = float(a)
        sum_f=sum_f+int(a)
        c=c+1
        print(type(t))
        continue
    except ValueError:
        pass

    try:
        if (a=='q'or a=='Q'):
            break
        else:
            print("Invalid data entered. Please enter a number to add or q/Q to quit. ")
            continue
    except ValueError:
        pass
sum= sum_i+ sum_f
print("You have entered ",c," numbers and their sum is: ",sum)

Upvotes: 0

tripleee
tripleee

Reputation: 189397

Here is a refactoring using nested try/except which solves the problem somewhat more succinctly and Pythonically.

#!/usr/bin/env python3

nums = list()
while True:
    # Usability tweak: Trim surrounding whitespace
    a = input("Enter number: ").strip()
    try:
        t = int(a)
    except ValueError:
        try:
            t = float(a)
        except ValueError:
            if a in ('q', 'Q'):
                break
            print("Invalid data entered. Please enter a number or q/Q to quit.")
            continue
    nums.append(t)
print("You have entered {0} numbers and their sum is {1}".format(
    len(nums), sum(nums)))

Upvotes: 2

Uisdean Chapped
Uisdean Chapped

Reputation: 56

two things: first to check for a type of something it is more pythonian to use

   isinstance(t, int)

but the second thing is where your code fails.

If you evaluate a literal you will get most likely a name error since the variable is not defined anywhere. However if you enter 'c' for example you get something weird entirely. Since the variable c is defined you won't get a name error but it will still fail when casting the literal 'c' to int.

you could use a regular expression to check if the input is a number or not

for example like so.

    if re.match('(\d+(\.\d+)?)', a):
        try:
            t = eval(a)
            print(type(t))
        except (NameError, ValueError):
            pass
    elif a == 'q' or a == 'Q':
        break
    else:
        continue

    if isinstance(t, int):
        sum_i = sum_i + int(a)
        c = c + 1

    elif isinstance(t, float):
        sum_f = sum_f + float(a)
        c = c + 1
    else:
        print("Invalid data entered. Please enter a number to add or q/Q to quit. ")

Upvotes: 1

Related Questions