Python function accepting a string, but not when its inside a variable - python

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)

Related

discord.utils.escape_mentions don't work?

I am trying to use discord.utils.escape_mentions to get rid of mentions in message.content.
Long story short, I noticed that it's not working as I expect.
var = discord.utils.escape_mentions("test #!334765815435886592 test")
print(var)
Prints to me source string as output
test #​!334765815435886592 test
However, here is the escape_mentions definition
return re.sub(r'#(everyone|here|[!&]?[0-9]{17,20})', '#\u200b\\1', text)
and if I just copy that and replace '#\u200b\1' with an empty string all works well and I am getting a nice result
test test
Can someone explain to me this behavior and how I can get to work this function?
I beleive you're misunderstanding what escape_mentions really does. It looks like you expect it to replace #[0-9]+ with an empty string, which it does not do.
re.sub takes 3 arguments -- a pattern, the text to replace it with (in a sense), and the text to operate on. Take a look at this:
As you can see, I get <#\u200b700796664276844612> as my output. The interesting thing is, if I were to print it, I get this instead:
Notice how it looks the same as my original text. The reason for this is because \u200b is actually a zero width space, which when printed is invisible.
So, in reality, escape_mentions inserts a zero width space in between the # and the id. So in discord, instead of it being a mention, it will merely be text.

How do I let Sympy parse an expression while only regarding arbitrary previously defined strings as symbols?

So what I am trying to do is write a script that lets me input some function and a list of the variables inside it, then processes it into some other formular, computes a result, and then outputs both the new formular and the result as Latex code. Everything works fine as long as I only input variables which do not contain "^", "{", or "}". The problem is, I want to use, or, at the very least, output the names exactly as they are written in my Latex document, and as such they do often contain these characters.
I am aware that there is a built-in Latex-Parser in Sympy, but as I understood it requires some other package (antlr4), and I would like to try to avoid that, since I am planning to distribute the script to my fellow students, and don't want to add another requirement for running the script.
So what I thought of is that I could use the list of variable names (which I input anyway together with their values to allow the program to compute a final result): I tried to define a "transformation", as it is described on the Sympy documentation on parsing. It looks like this:
#Defining the transformation
def can_split(symbol):
#Check if symbol is in one of the lists of inputted values (the two lists contain tuples of variable names[0] and their corresponding values[1])
if symbol not in ([i[0] for i in uncertainValues]+[i[0] for i in certainValues]):
return _token_splittable(symbol)
return False
#Read function definition from TKinter text field, split only by custom defined symbols
function=parse_expr(functionEntry.get("1.0", "end-1c"),transformations = (split_symbols_custom(can_split)))
The problem is that if I run this script, and input e. g. "a^b*c", and the variable names "a^b" and "c", which should normally be read as "the variable 'a^b' multiplied with the variable 'c'"I get the exception: "NameError: name 'a' is not defined".
If anyone could help me with this, or maybe propose another way to do this properly, I would be very thankful. Also, if there is more code or context needed to find a better solution, I'll provide more - I just felt everything would get too long-winding if I explained the whole idea. But as I said, I'll be glad to do that if it helps.
Quick but dirty workaround:
For now I ended up using the dirty method of replacing all problematic characters with unique strings at input, and replacing them with their symbols again before outputting.

Python variables stored in text files not working, but should be

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')

Iterating through python string array gives unexpected output

I was debugging some python code and as any begginer, I'm using print statements. I narrowed down the problem to:
paths = ("../somepath") #is this not how you declare an array/list?
for path in paths:
print path
I was expecting the whole string to be printed out, but only . is. Since I planned on expanding it anyway to cover more paths, it appears that
paths = ("../somepath", "../someotherpath")
fixes the problem and correctly prints out both strings.
I'm assuming the initial version treats the string as an array of characters (or maybe that's just the C++ in me talking) and just prints out characters.?...??
I'd still like to know why this happens.
("../somepath")
is nothing but a string covered in parenthesis. So, it is the same as "../somepath". Since Python's for loop can iterate through any iterable and a string happens to be an iterable, it prints one character at a time.
To create a tuple with one element, use comma at the end
("../somepath",)
If you want to create a list, you need to use square brackets, like this
["../somepath"]
paths = ["../somepath","abc"]
This way you can create list.Now your code will work .
paths = ("../somepath", "../someotherpath") this worked as it formed a tuple.Which again is a type of non mutable list.
Tested it and the output is one character per line
So all is printed one character per character
To get what you want you need
# your code goes here
paths = ['../somepath'] #is this not how you declare an array/list?
for path in paths:
print path

pydoc.render_doc() adds characters - how to avoid that?

There are already some questions touching this but no one seems to actually solve it.
import pydoc
hlpTxt = pydoc.render_doc(help)
already does what I want! looks flawless when printed to the (right) console but it has those extra characters included:
_\x08_H\x08He\x08el\x08lp\x08pe\x08er\x08r
In Maya for instance it looks like its filled up with ◘-symbols! While help() renders it flawless as well.
Removing \x08 leaves me with an extra letter each:
__HHeellppeerr
which is also not very useful.
Someone commented that it works for him when piped to a subprocess or into a file. I also failed to do that already. Is there another way than
hlpFile = open('c:/help.txt', 'w')
hlpFile.write(hlpTxt)
hlpFile.close()
? Because this leaves me with the same problem. Notepad++ actually shows BS symbols at the places. Yes for backspace obwiously.
Anyway: There must be a reason that these symbols are added and removing them afterwards might work but I can't imagine there isn't a way to have them not created in the first place!
So finally is there another pydoc method I'm missing? Or a str.encode/decode thing I have not yet seen?
btw: I'm not looking for help.__doc__!
In python 2, you can remove the boldface sequences with pydoc.plain:
pydoc.plain(pydoc.render_doc(help))
>>> help(pydoc.plain)
Help on function plain in module pydoc:
plain(text)
Remove boldface formatting from text.
In python 3 pydoc.render_doc accepts a renderer:
pydoc.render_doc(help, renderer=pydoc.plaintext)

Categories