#1
  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. #2
  3. 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 01:08 PM.
  4. #3
  5. 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?
  6. #4
  7. 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.
  8. #5
  9. Contributing User
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    Aug 2011
    Posts
    5,974
    Rep Power
    510

    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
    >>>
    [code]Code tags[/code] are essential for python code and Makefiles!
  10. #6
  11. 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)
    My armada: Debian GNU/Linux 8 (desktop, home laptop, work laptop), Raspbian GNU/Linux 8 (nameserver), Ubuntu 14.04.3 LTS (HTPC), PC-BSD 10.2 (testbed), Android 4.2.1 (tablet)
  12. #7
  13. 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)

    Comments on this post

    • Will-O-The-Wisp agrees : Unfortunately, as b49P23Tlvg says below, you'll need to reload a page to edit your post. Our tech team is working on a solution - they're just on the small size and busy with lots of projects at the moment. Sorry for the inconvenience!
    My armada: Debian GNU/Linux 8 (desktop, home laptop, work laptop), Raspbian GNU/Linux 8 (nameserver), Ubuntu 14.04.3 LTS (HTPC), PC-BSD 10.2 (testbed), Android 4.2.1 (tablet)
  14. #8
  15. Contributing User
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    Aug 2011
    Posts
    5,974
    Rep Power
    510
    Reloading the page enables post editing for me. Imploring the web site developers to retract this version of the program hasn't worked.

    Comments on this post

    • SuperOscar agrees : Sigh.
    [code]Code tags[/code] are essential for python code and Makefiles!

IMN logo majestic logo threadwatch logo seochat tools logo