1

For some reason my script refuses to run directly from Text Wrangler but works fine when imported into terminal.

import math

def main():
    print("This program find the real solutions to a quadratic\n")
    a,b,c, = eval(input("Please enter the coefficients (a,b,c): "))
    discRoot = math.sqrt(b * b -4 * a * c)
    root1 = (-b + discRoot) / (2 * a)
    root2 = (-b - discRoot) / (2 * a)
    print("\nThe solutions are:" , root1, root2)


main()

When I run that in textwrangler, I get the error message "TypeError: eval() arg 1 must be a string or code object". Isn't the point of using eval() to imply that the following input is an integer and not a string? Why is this happening?

2 Answers2

4

In Python 2, input() is equivalent to eval(input()) in Python 3. I think that in the terminal you are running it with Python 3, but TextWrangler uses Python 2 Therefore TextWrangle is doing eval(eval(input())) - which evaluates to eval(5), which causes the error you see.

To fix this, you need to update TextWrangler, or use Python 2 in the terminal. If you want the second option, you should replace eval(input()) with input().

Side note - using eval like this is a bad idea (it's dangerous). You should probably do something like a, b, c = map(int, input().split(",")) (in Python 3) instead.

rlms
  • 10,650
  • 8
  • 44
  • 61
  • Yes, I am using 3.4.1 in terminal. Should I add a Shebang line in my script to correct this or is there a way to make TextWrangler run with Python 3.4? – user3580073 Jun 30 '14 at 20:22
  • I'd imagine there is a way to make TextWrangler work with Python 3.4 (most decent text editors should be able to) but I don't know what it is. – rlms Jun 30 '14 at 20:25
  • The map function worked great, thank you so much. Were you saying that eval is dangerous if my input is a tuple? It's OK if it's just a single value right? – user3580073 Jun 30 '14 at 20:43
  • No. As `eval` evaluates any code it gets, someone could enter something like `__import__("subprocess").Popen("delete all the files on the computer")`, and it would be executed. Beyond that, it is just bad style. – rlms Jun 30 '14 at 21:13
0

The problem is not with eval. The problem is with input, which tries to read from sys.stdin, the standard input stream.

If you want to get around it, you should pass the argument to eval as an argument instead of using input.

merlin2011
  • 71,677
  • 44
  • 195
  • 329