6

I am trying to build calculator using PyQt5 and I get string which I need to evaluate and assign it to a variable so that I can Pass that variable to widgets as an answer . So far I can evaluate the expression but can't assing it . How can I do that ? so far I have following code:-

# this functions gets called when Enter is pressed
def etrp(self):
    eqn =  self.sender().text()                  #I get string like '23+4'
    eqn1 = "{0} = {1}".format("global x",eqn)    #I make it x = 23+4
    x = 0
    exec(eqn1)                                   # I get error here
    print(x)
    #some code .....

When I try to run it without global, it runs without error but x remains 0 and If I ran it like this I get this error:-

qt5ct: using qt5ct plugin
global x = 12+32
Traceback (most recent call last):
  File "/home/orayan/Development/Python/Calculator/calculator.py", line 11, in etrp
    exec(eqn1)
  File "<string>", line 1
    global x = 12+32
             ^
SyntaxError: invalid syntax
[1]    19185 abort (core dumped)  ./main.py

I am very new to python So can't figure out whats going on

orayan
  • 165
  • 2
  • 9
  • 1. Please show us more of the traceback. 2. If you are new to Python, consider familiarizing yourself with the language more before using PyQt5. 3. Don't use global variables. – Daniel May 17 '18 at 12:00
  • @Coal_ 1. I had added complete output .2. I agree But I am very familiar with Qt in C++ thus .. – orayan May 17 '18 at 12:08

3 Answers3

4
global x = 5

is not valid python code.

If you want to assign to a global variable x, you should write

global x
x = 5

Try changing your code as

global x
eqn1 = "{0} = {1}".format("x",eqn)
x = 0
exec(eqn1, globals())

To modify global variables with exec, you need to use globals() function.

EDIT: Add globals() function.

eozd
  • 1,153
  • 1
  • 6
  • 15
4

Hmm, exec and eval are evil. When you use them on a non sanitized string, you implicitely accept to execute almost any Python expression...

But that have not exactly same usages: exec is meant to execute some code, while eval will return a value. Here the correct way would be:

x = eval(eqn)

That is not a correct usage of a global variable anyway because it is only used to get a value from a call, so the correct way is to have the function to return the value, hence eval instead of exec.

But remember: eval is evil so never use that in production code.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
0

On the question of why it doesn't work when one tries to modify a local variable, this is specifically forbidden. See this.

Andrew
  • 41
  • 3
  • Please don't just post urls. – mate00 Sep 03 '19 at 07:46
  • @mate00 I feel justified. I explained completely where the problem arises (in the first case given by OP) and gave a reference. The fact that the explanation is brief is no reason to deride it. I've noticed that StackExch likes people to point to other posts within StExch when they deal with the same problem, so I did. Who could ask for more? – Andrew Sep 05 '19 at 00:16