Transforming a str to an operator

D

Duke Normandin

Hey....

I'm a Python noob....

So far so good!

I've written the following:

num1 = raw_input('Enter the first number: ')
num2 = raw_input('Enter the second number: ')
op = raw_input('Select one of the following [+-*/]: ')
print 'The answer is: ', int(num1), eval(op), int(num2)
^^^^^^^^

How do I convert the contents of "op" from a string to an actual
arithmetic operator? eval() does not seem to be the answer. TIA!
 
R

r

How do I convert the contents of "op" from a string to an actual
arithmetic operator? eval() does not seem to be the answer. TIA!


Try this..
3


you could also use string formatting.
 
R

r

In general, ‘eval’ on unsanitised input is not the answer.

Yes i agree.
I would use the following approach:

Abviously the OP is a python baby noob and casting your irrational
fear (and many others irrational fears) of eval at him is akin to
tales of Chupacabras running a muck in the jungle sucking the blood
from live goats in the twilight hours. I use eval all the time and
quite love it.

This is nothing more than a throw away academic exercise that will
serve no useful purpose for him in the future, but serves the very
useful purpose now of establishing an IO between the student and
Python interpretor. I'll bet most your example (albeit a good example)
flew miles above his head into la-la land.

The OP has plenty of time to learn about malicious input and
protecting against it, right now the fundamentals are well...
fundamental :)
 
D

Duke Normandin

num1 = raw_input('Enter the first number: ')
num2 = raw_input('Enter the second number: ')
op = raw_input('Select one of the following [+-*/]: ')
print 'The answer is: ', int(num1), eval(op), int(num2)
^^^^^^^^

How do I convert the contents of "op" from a string to an actual
arithmetic operator? eval() does not seem to be the answer. TIA!

You could eval(num1+op+num2), but it'd be safer to do:

import operator
operators = {"+": operator.add, "-": operator.sub, "*": operator.mul, "/":
operator.div}
fn = operators[op]
print "The answer is:", fn(int(num1), int(num2))

Its best to avoid eval when possible :)

--S

In *any* language "eval" is dangerous, so your second example would
also be my choice. Thanks for the clue.

BTW, I hunted hi-n-lo for something that would address my question at
http://docs.python.org. I obviously didn't have much luck. Something
about those docs that is confusing....
 
D

Duke Normandin

Try this..

3


you could also use string formatting.

I see! Concatenate the strings within the "eval()" function. Of
course, it's prudent not to expose "eval" to the outside world. But
for learning purposes ....

Thanks for the input!
 
D

Duke Normandin

Duke Normandin said:
Hey....

I'm a Python noob....

So far so good!

I've written the following:

num1 = raw_input('Enter the first number: ')
num2 = raw_input('Enter the second number: ')
op = raw_input('Select one of the following [+-*/]: ')
print 'The answer is: ', int(num1), eval(op), int(num2)
^^^^^^^^

How do I convert the contents of "op" from a string to an actual
arithmetic operator? eval() does not seem to be the answer. TIA!

In general, ‘eval’ on unsanitised input is not the answer.

Agreed! If I were to expose "eval" to the 'net, I would have some
input error checking and "type" checks to insure that only integers
and valid operators were being input.
I would use the following approach:

import operator

op_funcs = {
'+': operator.add,
'-': operator.sub,
'*': operator.mul,
'/': operator.div,
}

num_1 = int(raw_input('Enter the first number: '))
num_2 = int(raw_input('Enter the second number: '))
op_prompt = (
"Select an operator "
+ "[" + "".join(s for s in op_funcs.keys()) + "]"
+ ": ")
op_symbol = raw_input(op_prompt)
op_func = op_funcs[op_symbol]
print 'The answer is: ', op_func(num_1, num_2)

This has several advantages:

* The input isn't evaluated directly as code.

* The operator symbols are specified in one place, the ‘op_funcs’
mapping; if you want to change the set of possible operators, you just
change it there.

* If the input results in an operator that's not defined, it won't
attempt to perform it; instead, a simple KeyError will result when
trying to find the corresponding operator function.

Cool! Something useful to study...

Thanks for the input!
 
A

Anny Mous

r said:
Abviously the OP is a python baby noob and casting your irrational
fear (and many others irrational fears) of eval

It isn't irrational to have a healthy caution towards eval.

Apart from the security issues, running code in eval takes a massive
performance hit. Its about ten times slower to run eval("x+1") than to run
x+1 directly.


at him is akin to
tales of Chupacabras running a muck in the jungle sucking the blood
from live goats in the twilight hours. I use eval all the time and
quite love it.

LOL I'm not surprised.

This is nothing more than a throw away academic exercise that will
serve no useful purpose for him in the future,

What makes you think that learning to program well in Python is a throw-away
exercise of no useful purpose? I'm sure the code itself will be thrown away
and forgotten, but it has a very important purpose: for the OP to learn
good programming skills. Looks like you want him to learn bad skills, then
spend the rest of his life trying to unlearn them.

but serves the very
useful purpose now of establishing an IO between the student and
Python interpretor. I'll bet most your example (albeit a good example)
flew miles above his head into la-la land.

How insulting. Is there anything that gave you the impression the OP was
stupid?

The OP has plenty of time to learn about malicious input and
protecting against it, right now the fundamentals are well...
fundamental :)

When would you recommend he learns? When his web app is hijacked by
gangsters in Russia and the personal details and financial records of fifty
thousand people stolen? Protecting against malicious input *IS*
fundamental.
 
R

r

It isn't irrational to have a healthy caution towards eval.

Ignorance is never an excuse for stupidity. No caution is needed if
you know how to properly use eval. You can't shoot yourself in the
foot without first pulling the trigger.
Apart from the security issues, running code in eval takes a massive
performance hit. Its about ten times slower to run eval("x+1") than to run
x+1 directly.

And the point is...?
eval is only for corner cases. Nobody is suggesting he eval entire
scripts. Performance is the last of my worries. Optimizations can come
later. First understand the problem at hand, code up a working
solution, then tweak and optimize the code to perfection.
What makes you think that learning to program well in Python is a throw-away
exercise of no useful purpose? I'm sure the code itself will be thrown away
and forgotten, but it has a very important purpose: for the OP to learn
good programming skills. Looks like you want him to learn bad skills, then
spend the rest of his life trying to unlearn them.

No i want him to use eval properly .If you think eval is scary well
thats just your opinion. I showed the OP how to successfully pass the
arguments into eval the way he was unsuccesfully struggling to pass
them. Ben's approach is the professional/proper way to handle such
input in the real world (there are other ways too), however the OP
also must know that you don't *have* to go by the book all the time
(python is not Java ya know?).
How insulting. Is there anything that gave you the impression the OP was
stupid?

Please quote the line from my post were i called the OP stupid or used
otherwise derogatory comments? And if you can i'll buy you a beer.
Obviously anyone who shows example code as the OP did is a noob and
needs proper training on how to use it and there is nothing wrong with
that. We have all been there, remember?
When would you recommend he learns? When his web app is hijacked by
gangsters in Russia and the personal details and financial records of fifty
thousand people stolen? Protecting against malicious input *IS*
fundamental.

If the OP uses eval without inderstanding it and then shoots himself
in the foot, well then i can't think of a better learning experience
for him. I'll bet the next time he will read the docs first or ask on
this list before he goes off on a turkey hunt ;).

Fear is a product of ignorance. Educate yourself and your irrational
fears shall bother you no more.
 
M

MRAB

r said:
Ignorance is never an excuse for stupidity. No caution is needed if
you know how to properly use eval. You can't shoot yourself in the
foot without first pulling the trigger.


And the point is...?
eval is only for corner cases. Nobody is suggesting he eval entire
scripts. Performance is the last of my worries. Optimizations can come
later. First understand the problem at hand, code up a working
solution, then tweak and optimize the code to perfection.


No i want him to use eval properly .If you think eval is scary well
thats just your opinion. I showed the OP how to successfully pass the
arguments into eval the way he was unsuccesfully struggling to pass
them. Ben's approach is the professional/proper way to handle such
input in the real world (there are other ways too), however the OP
also must know that you don't *have* to go by the book all the time
(python is not Java ya know?).


Please quote the line from my post were i called the OP stupid or used
otherwise derogatory comments? And if you can i'll buy you a beer.
Obviously anyone who shows example code as the OP did is a noob and
needs proper training on how to use it and there is nothing wrong with
that. We have all been there, remember?


If the OP uses eval without inderstanding it and then shoots himself
in the foot, well then i can't think of a better learning experience
for him. I'll bet the next time he will read the docs first or ask on
this list before he goes off on a turkey hunt ;).

Fear is a product of ignorance. Educate yourself and your irrational
fears shall bother you no more.
I think it's a good idea to warn the OP about the dangers of eval. If he
still wants to use it, then that's his choice (and his problem).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,906
Latest member
SkinfixSkintag

Latest Threads

Top