### Thread: How eval(input()) deals with taking in strings instead of numbers.

1. No Profile Picture
Registered User
Devshed Newbie (0 - 499 posts)

Join Date
May 2015
Posts
18
Rep Power
0

#### How eval(input()) deals with taking in strings instead of numbers.

Hi. I wrote a simple mock-calculator program that accepts user input for three items: A first number
a second number, and an operation to perform on those two numbers. I wanted to provide
the user with an option to type "exit" at any given point that they are prompted to enter one of
the three items.

Code:
```def calculate():
operation = " "
while operation != "exit":
x = eval(input ("Enter a number:"))
if x == "exit":
break
y = eval(input ("Enter another number:"))
if y == "exit":
break```
However since eval(input()) is primed to accept integers and floats the break is not executing
it seems. How can i code this so that the user can type exit when they're prompted to enter
a number and the loop will be automatically executed? Thanks in advance.
2. No Profile Picture
Contributing User
Devshed Novice (500 - 999 posts)

Join Date
May 2009
Posts
667
Rep Power
40
Try it the other way around, i.e. check for "exit" first. Also you do not need eval to just input a number. If you want a formula, then use eval, print eval('1+2+6'), note that eval is indeed passed a string. You should know the built-in limitations of floating point numbers in a binary world, Lahey - Floating point Python, like all programming languages has a package that is more exact. It is the Decimal package in Python but again is only necessary when you want more, or more exact decimal places.

The "standard" way to get input which allows for typos like unintended letters:
Code:
```    def input_number():
x = input ("Enter a number: ")
if x == "exit":
return False, -1
try:
x_float=float(x)
return True, x_float
except:
print(x, "is not a valid number")

return False, 0```
Last edited by dwblas; May 23rd, 2015 at 12:08 PM.
3. No Profile Picture
Registered User
Devshed Newbie (0 - 499 posts)

Join Date
May 2015
Posts
18
Rep Power
0
Thanks for the answer. In your code example I'm confused about a couple things. in False, -1 what is the negative one's purpose. Also what is x_float?
4. No Profile Picture
Contributing User
Devshed Novice (500 - 999 posts)

Join Date
May 2009
Posts
667
Rep Power
40
x_float is the result of the function call to convert the string to a float (see this statement x_float=float(x)). Print it to see print(x_float, type(x_float)) You have to have some way to differentiate between an input typo=ask again, and "exit". False & -1= exit, False & 0 = typo, but you can use whatever return values you like to indicate that.
5. #### a tiresome post

Specify a dictionary to use eval safely. The goal is to prevent

eval('destroy_the_universe(or_otherwise_compromise_your_system)')

while providing some functionality.

Code:
```>>> help(eval)
Help on built-in function eval in module builtins:

eval(...)
eval(source[, globals[, locals]]) -> value

Evaluate the source in the context of globals and locals.
The source may be a string representing a Python expression
or a code object as returned by compile().
The globals must be a dictionary and locals can be any mapping,
defaulting to the current globals and locals.
If only globals is given, locals defaults to it.

>>> import math
>>> eval('math.sin(3)')  # the global and local namespaces are available!
0.1411200080598672
>>> eval('sin(3)',dict(sin=math.sin))  # enable some special functions
0.1411200080598672
>>> eval('math.sin(3)',dict(sin=math.sin))  # destroy is disabled
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1, in <module>
NameError: name 'math' is not defined
>>>```
6. No Profile Picture
Contributing User
Devshed Newbie (0 - 499 posts)

Join Date
Jul 2007
Location
Joensuu, Finland
Posts
471
Rep Power
71
Originally Posted by dwblas
You have to have some way to differentiate between an input typo=ask again, and "exit".
Exceptions are particularly suitable for that, as in:

[code]class ExitProgram(Exception):
pass
# ...
def input_number():
x = input('Enter number: ').lower()
if x == 'exit':
raise ExitProgram
# May raise ValueError, handle in caller
return float(x)
7. No Profile Picture
Contributing User
Devshed Newbie (0 - 499 posts)

Join Date
Jul 2007
Location
Joensuu, Finland
Posts
471
Rep Power
71
D*** it, is there no way to edit your posts any longer?!

Here’s the code again:

Code:
```class ExitProgram(Exception):
pass
# ...
def input_number():
x = input('Enter number: ').lower()
if x == 'exit':
raise ExitProgram
# May raise ValueError, handle in caller
return float(x)```