1

I am trying to write a very simple code which I will feed it two numbers (with the input function) and it'll give me a result based on these numbers. When the numbers are just numbers (e.g., 12 or 15) everything works fine, but when instead of a number is, for example, an addition (i.e., 6 + 6) then I get an error saying "could not convert string to float: '6 + 6'.

Please see below a reproducible example:

def calc_sal(number1, number2):
    return number1 * 4.5 + number2

number1 = float(input("Give number1 "))
number2 = float(input("Give number2 "))

print(calc_sal(number1, number2))

and this is the error:

Give number1 6 + 6
Traceback (most recent call last):
  File "SalaryCalc.py", line 4, in <module>
    number1 = float(input("Give number1 "))
ValueError: could not convert string to float: '6 + 6'

It appears to me that I cannot perform an addition through the input function, instead it thinks that it's a string "6 + 6". However, when I am running the same code line by line in an interactive session, everything works just fine (i.e., when the input is 6 + 6, the output is 12, rather than "6 + 6"). So do you why is this happening only when I am running the programme through the terminal and not interactively? And how to resolve this?

Thank you.

N. Doe
  • 35
  • 7

1 Answers1

1

It depends on who is going to use this code:

  • If it's only you, you could use the eval funciton:

    >>> eval('6+6')
    12
    
  • If you're going to let someone else enter numbers, eval is evil. It can format your hard drive if malicious code is entered! (see also How harmful is eval)

    Consider other possibilities like ast.literal_eval (only for + and -, even * is too hard for it), pyparsing (powerful, but requires writing a program for this) , etc

You could also consider numexpr library (installs numpy as a requirement and returns numpy array as a result):

>>> import numexpr as ne
>>> ne.evaluate('6**2')
array(36, dtype=int32)
>>> print(ne.evaluate('6**2'))
36
Antony Hatchkins
  • 31,947
  • 10
  • 111
  • 111
  • Any comments on downvote? – Antony Hatchkins Dec 10 '17 at 12:36
  • 2
    I imagine because suggesting `eval` to someone that doesn't yet know the difference between a Python expression in the interpreter and a string literal taken from the input (warning or not) is at best not helpful and at worst actually harmful... – Jon Clements Dec 10 '17 at 12:37
  • Not my downvote, but I thought that `literal_eval` would be the weapon of choice to minimise dangers: https://stackoverflow.com/a/15197698/8881141 – Mr. T Dec 10 '17 at 12:43
  • @JonClements The most important thing In my answer is a note that it is harmful. If OP finds this function himself he might not realize how harmful it is. On the other hand if OP doesn't find an answer to a question that simple he might lose interest in python in general. `eval` is a function present in all interpreted languages and I see no harm in _knowing_ about it. – Antony Hatchkins Dec 10 '17 at 12:44
  • @Piinthesky `literal_eval` only does **literals** - it doesn't do expressions... – Jon Clements Dec 10 '17 at 12:47
  • @JonClements I see. I just tried it with the OP's example using addition and subtraction, which worked. On SO I have seen now [this version](https://stackoverflow.com/a/2371789/8881141), how to parse mathematical expressions. Surely slightly more complicated than using `eval`. – Mr. T Dec 10 '17 at 12:57
  • 1
    @Piinthesky I would say negligeably ;) – Antony Hatchkins Dec 10 '17 at 13:01
  • I did some look-around with regards the potential dangers of the eval function, and I've been urged to use ast.literal_eval() as an alternative. Many thanks for your replies. – N. Doe Dec 10 '17 at 13:08
  • Hmm.. Python has it's own solution for everything,,, I thought of https://en.wikipedia.org/wiki/Reverse_Polish_notation anyways This answer is better +1 upvote from me. I guess some one downvoted so it is 0 still.., – VISWESWARAN NAGASIVAM Dec 10 '17 at 13:31