Reputation: 11
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
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
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
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