I'm trying to write myself a program that calculates a function taken from a Tk.Entry().
The problem is, when I try to run my display() function
(it runs Tkinter, sets up the window, and calls root.Mainloop()),
I get parse errors coming from eval() from a function that is supposed to be called only if the user inputs all of the variables and presses a button (the button's command).
The function uses eval(variable), while variable is entry.get().
What am I doing wrong here?
def cfunc(_n,_f,_t0,_tn,):
xbase=[]
tbase=[]
t=0
n2=eval(_n) #Stuff happens here, cfunc gets entry_n.get() as arguments.
f2=_f #Also, tabs are correct in the original.
tmin2=eval(_t0)
tmax2=eval(_tn)
tr=tmax2-tmin2
sk = tr / n2
i2=tmin2
Also, error:
File "Q:\Py\counter.py", line 89, in
cfunc
n2=eval(_n) File "", line 0
^ SyntaxError: unexpected EOF while parsing
You haven't shown us the code that causes the error (the value of _n) so we can only guess. A couple words of advice:
the error message is telling you the problem: unexpected eof. That means there's a missing closing quote or brace or something like that. The parser got to the end of the "file" (the string being eval'd) before it got the characters it expected.
put a print statement immediately before an eval, and use some special characters to delimit it (eg: puts ">>>$_n<<<") so you can tell precisely what is in the string being eval'd, including any leading or trailing spaces.
Related
I have the following code (it changes the string/filepath, replacing the numbers at the end of the filename + the file extension, and replaces that with "#.exr"). I hope I made the problem replicatable below.
I was doing it this way because the filename can be typed in all kinds of ways, for example:
r_frame.003.exr (but also)
r_12_frame.03.exr
etc.
import pyseq
import re
#create render sequence list
selected_file = 'H:/test/r_frame1.exr'
without_extention = selected_file.replace(".exr", "")
my_regex_pattern = r"\d+\b"
sequence_name_with_replaced_number = re.sub(my_regex_pattern, "#.exr" ,without_extention)
mijn_sequences = fileseq.findSequencesOnDisk(sequence_name_with_replaced_number)
If I print the "sequence_name_with_replaced_number" value, this results in the console in:
'H:/test/r_frame#.exr'
When I use that variable inside that function like this:
mijn_sequences = fileseq.findSequencesOnDisk(sequence_name_with_replaced_number)
Then it does not work.
But when I manually replace that last line into:
mijn_sequences = fileseq.findSequencesOnDisk('H:/test/r_frame#.exr')
Then it works fine. (it's the seems like same value/string)
But this is not an viable option, the whole point of the code if to have the computer do this for thousands of frames.
Anybody any idea what might be the cause of this?
I already tried re-converting the variable into a string with str()
I tried other ways like using an f-string, I wasn't sure how to convert it into a raw string since the variable already exists.
After this I will do simple for loop going trough al the files in that sequence. The reason I'm doing this workflow is to delete the numbers before the .exr file extensions and replace them with # signs. (but ognoring all the bumbers that are not at the end of the filename, hence that regex above. Again, the "sequence_name_with_replaced_number" variable seems ok in the console. It spits out: 'H:/test/r_frame#.exr' (that's what I need it to be)
It's fixed!
the problem was correct, every time I did a cut and past from the variable value in the console and treated it as manual input it worked.
Then I did a len() of both values, and there was a difference by 2!
What happend?
The console added the ''
But in the generated variable it had those baked in as extra letters.
i fixed it by adding
cleaned_sequence = sequence_name_with_replaced_number[1:-1]
so 'H:/test/r_frame1.exr' (as the console showed me)
was not the same as 'H:/test/r_frame1.exr' (what I inserted manually, because I added these marks, in the console there are showed automatically)
It is very similar to this:
How to tell if a string contains valid Python code
The only difference being instead of the entire program being given altogether, I am interested in a single line of code at a time.
Formally, we say a line of python is "syntactically valid" if there exists any syntactically valid python program that uses that particular line.
For instance, I would like to identify these as syntactically valid lines:
for i in range(10):
x = 1
Because one can use these lines in some syntactically valid python programs.
I would like to identify these lines as syntactically invalid lines:
for j in range(10 in range(10(
x =++-+ 1+-
Because no syntactically correct python programs could ever use these lines
The check does not need to be too strict, it just need to be good enough to filter out obviously bogus statements (like the ones shown above). The line is given as a string, of course.
This uses codeop.compile_command to attempt to compile the code. This is the same logic that the code module does to determine whether to ask for another line or immediately fail with a syntax error.
import codeop
def is_valid_code(line):
try:
codeop.compile_command(line)
except SyntaxError:
return False
else:
return True
It can be used as follows:
>>> is_valid_code('for i in range(10):')
True
>>> is_valid_code('')
True
>>> is_valid_code('x = 1')
True
>>> is_valid_code('for j in range(10 in range(10(')
True
>>> is_valid_code('x = ++-+ 1+-')
False
I'm sure at this point, you're saying "what gives? for j in range(10 in range(10( was supposed to be invalid!" The problem with this line is that 10() is technically syntactically valid, at least according to the Python interpreter. In the REPL, you get this:
>>> 10()
Traceback (most recent call last):
File "<pyshell#22>", line 1, in <module>
10()
TypeError: 'int' object is not callable
Notice how this is a TypeError, not a SyntaxError. ast.parse says it is valid as well, and just treats it as a call with the function being an ast.Num.
These kinds of things can't easily be caught until they actually run.
If some kind of monster managed to modify the value of the cached 10 value (which would technically be possible), you might be able to do 10(). It's still allowed by the syntax.
What about the unbalanced parentheses? This fits the same bill as for i in range(10):. This line is invalid on its own, but may be the first line in a multi-line expression. For example, see the following:
>>> is_valid_code('if x ==')
False
>>> is_valid_code('if (x ==')
True
The second line is True because the expression could continue like this:
if (x ==
3):
print('x is 3!')
and the expression would be complete. In fact, codeop.compile_command distinguishes between these different situations by returning a code object if it's a valid self-contained line, None if the line is expected to continue for a full expression, and throwing a SyntaxError on an invalid line.
However, you can also get into a much more complicated problem than initially stated. For example, consider the line ). If it's the start of the module, or the previous line is {, then it's invalid. However, if the previous line is (1,2,, it's completely valid.
The solution given here will work if you only work forward, and append previous lines as context, which is what the code module does for an interactive session. Creating something that can always accurately identify whether a single line could possibly exist in a Python file without considering surrounding lines is going to be extremely difficult, as the Python grammar interacts with newlines in non-trivial ways. This answer responds with whether a given line could be at the beginning of a module and continue on to the next line without failing.
It would be better to identify what the purpose of recognizing single lines is and solve that problem in a different way than trying to solve this for every case.
I am just suggesting, not sure if going to work... But maybe something with exec and try-except?
code_line += "\n" + ("\t" if code_line[-1] == ":" else "") + "pass"
try:
exec code_line
except SyntaxError:
print "Oops! Wrong syntax..."
except:
print "Syntax all right"
else:
print "Syntax all right"
Simple lines should cause an appropriate answer
I've settled on a text-file based save system for my game, storing the values of required variables with keywords - for example, the password that tells the game which chapter to play. However, it appears to be malfunctioning, and I can't see why.
Before starting the game, we have:
if not os.file.isfile('TSGsave{0}.txt'.format(name)):
TSGsave=open('TSGsave{0}.txt'.format(name),'wt')
TSGsave.write('\nw5CT$n<jfW=-#J%4Ya5##')
TSGsave.close()
(the keyword used is a bunch of jibberish so that the user can't change it knowing what's going to happen). This adds w5CT$n<jfW=-#J%4Ya5## to the text file. We then have:
for i in range (len(lines)):
if 'w5CT$n<jfW' in lines[i]:
findpass=lines[i]
for i in range (len(findpass)):
if findpass[i]=='=':
cutfrom=i+1
password=findpass[cutfrom:len(findpass)]
to retrieve the variable (which can change, so it can't be written in as definite value). I know it works, because I added print (password) to the code and it returned -#J%4Ya5##. Then to start the corresponding chapter, the code is:
if password=='-#J%4Ya5##':
but it isn't starting the indented block. In the shell, the program ends and goes back to the >>> line.
If there is a way to fix this code, great - but another code to do the same thing would work just as well.
Your lines contain newlines, and these are being included. Strip these from the line:
findpass = lines[i].rstrip('\n')
Printing a value with a newline in it will simply add an extra black line after the print. Always use the repr() function to produce a Python representation of strings to see such characters:
>>> print '-#J%4Ya5##\n'
-#J%4Ya5##
>>> print repr('-#J%4Ya5##\n')
'-#J%4Ya5##\n'
Your parsing code is overly complicated; you can use str.split() or str.partition() to split your password from the line instead. You should just loop over the lines list directly rather than produce indices with range():
for line in lines:
if 'w5CT$n<jfW' in line:
password = line.partition('=')[2].rstrip('\n')
Quick python question about the exec command. I'm have Python 2.7.6 and am trying to make use of the exec to run some code stored in a .txt file. I've run into a syntax error and am not entirely sure what is causing it.
Traceback (most recent call last):
File "/Users/XYZ/Desktop/parser.py", line 46, in <module>
try_code(block)
File "<string>", line 1
x = 'Hello World!'
^
SyntaxError: invalid syntax
I initially thought it was complaining about carriage returns, but when I tried to edit them .replace them with ' ' I still received this error message. I've tried variations to see what appears to be the issue and it always declares the error as the first ' or " the program encounters when it runs exec.
Here is the try_code(block) method
def try_code(block):
exec block
And the main body of the program
inputFile = open('/Users/XYZ/Desktop/test.txt', 'r+')
starter = False
finished = False
check = 1
block = ""
for val in inputFile:
starter = lookForStart(val)
finished = lookForEnd(val)
if lookForStart:
check = 1
elif finished:
try_code(block)
if check == 1:
check = 0
elif finished == False:
block = block + val
Basically I'm trying to import a file (test.txt) and then look for some embedded code in it. To make it easier I surrounded it with indicators, thus starter and finished. Then I concatenate all the hidden code into one string and call try_code on it. Then try_code attempts to execute it (it does make it there, check with print statements) and fails with the Syntax error.
As a note it works fine if I have hidden something like...
x = 5
print x
so whatever the problem is appears to be dealing with strings for some reason.
EDIT
It would appear that textedit includes some extra characters that aren't displayed normally. I rewrote the test file in a different text editor (text wrangler) and it would seem that the characters have disappeared. Thank you all very much for helping me solve my problem, I appreciate it.
It is a character encoding issue. Unless you've explicitly declared character encoding of your Python source code at the top of the file; it is 'ascii' by default on Python 2.
The code that you're trying to execute contains non-ascii quotes:
>>> print b'\xe2\x80\x98Hello World\xe2\x80\x99'.decode('utf-8')
‘Hello World’
To fix it; use ordinary single quotes instead: 'Hello World'.
You can check that block doesn't contain non-ascii characters using decode method: block.decode('ascii') it raises an exception if there are.
A gentle introduction into the topic: The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)
by Joel Spolsky.
I'm trying to open a program while I'm in a python script using the subprocess.call() function, It opens the program but for some reason the program doesn't allows that and just throw an "Unhandaled exception" error, I know the problem is probably in the program so there may be any other command that will open a program, fill some fields and press "Submit?"
Thanks!
Edit: I've no code to post..
str = 'd:\Softwares\X.exe'
subprocess.call(str)
I've also tried with:
subprocess.call(str,shell=True)
Try calling another program the same way. If the problem persists, the problem is with your code. If it goes away, the problem is with the program.
I think changing to 'D:/Softwares/X.exe' or one of the other string formats will help because the '\' character is the escape character ... used for example to denote a new line '\n'.
It probably works if you use forward-slashes (backslashes are escape symbols in Python). If it doesn't, write the first line like this:
str = r'd:\Softwares\X.exe'
The r tells Python that you are creating a raw string, so it will ignore escape symbols. More information at: https://docs.python.org/2/reference/lexical_analysis.html#string-literals