How can I put the input inside a string which already exist? - python

I have a string called data, you can see below. I just want to take an input from user and put the input inside ability_id field in data.
def main():
ability_id = input("Enter an ability id) # example:abc-123-abc-123
data = '{"paw":"1234","ability_id": f"{ability_id}" ,"obfuscator":"plain-text"}'
print(data)

While I don't think, saving the string like this has a lot of sense, I will still give you an answer to your question.
If you want to do it like this you can, as you already nearly did, use the f-string.
But you can't just simply start an f-string inside a normal string - this is not, how this works. Instead, you have to make the whole thing an f-string and then indicate inside this string, where you want to place the variable. Something like this:
data = f'{{"paw":"1234","ability_id": "{ability_id}" ,"obfuscator":"plain-text"}}'
Attention: Watch out, that you use the double curly-brackets at the beginning and ending of the string, otherwise it will not work

Related

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

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)

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.

Read only a required function in python

I want to guess the type of a variable based on its usage in a function. For this, I decided to use Regex in which I will have a list of expressions for every type. Like, for an integer, a few possible expressions could be,
'''
pattern = [r"[a-z]\s\+", r"[a-z]\s\-", r"[a-z]\s\*", r"[a-z]\s\/", r"[a-z]\s\=\s[0-9]", r"[a-z]\s\=\=\s[0-9]*"]
'''
I want to search for these patterns for every variable in a function and decide the type.
But, To do this, I need to consider only the function,i.e, I need to read the lines of only the required function from a big python file.
Is there a way I can do this?

String to Python statement?

I want to convert a string to a Python statement.
Taking string input from a text file e.g. 'dataframe['Column_name'].sum()'
Executing the string as a Python statement e.g. dataframe['Column_name'].sum()
Storing the result in some variable
It's possible to do this, but not recommended. You do not have any control over what the string contains if it comes from the user. There is probably a better way to achieve what you really want.
If you really, absolutely, unavoidably have to, you can use eval:
x = eval('dataframe["Column_name"].sum()')
But it is probably easier to only take, for example, the column name from the user and use that in a function call:
column_name = "Column_name" # or read it from the file
x = dataframe[column_name].sum()
#previous code
with open("file.txt","r") as f:
x = eval(f.readline())
#the rest of the code, using x however you want
I wouldn't do it if other users are supposed to be able to use the script however they want. If this is for learning purposes of for your own use, it's up to you.

striplines() not working when using finditer python

I am trying to convert a multiline string to a single list which should be possible using splitlines() but for some reason it continues to convert each line into a list instead of processing all the lines at once. I tried to do it out of the for loop but doesnt seem to have any effect. I need the lines as a single list to use it another function. Below is how I get the multiline into a single variable. What am I missing???
multiline_string_final = []
for match_multiline in re.finditer(r'(^(\w+):\sThis particular string\s*|This particular string\s*)\{\s(\w+)\s\{(.*?)\}', string, re.DOTALL):
multi_line_string = match_multiline.group(4)
print multiline_string
This last print statement prints out the strings like this:
blah=0; blah_blah=1; Foo=3;
blah=4; blah_blah=5; Foo=0;
However I need:
['blah=0; blah_blah=1; Foo=3;''blah=4; blah_blah=5; Foo=0;']
I understand it has to be something with the finditer but cant seem to rectify.
Your new problem also has nothing to do with finditer. (Also, your code is still not an MCVE, you still haven't shown us the sample input data, etc., making it harder to help you.)
From this desired output:
['blah=0; blah_blah=1; Foo=3;''blah=4; blah_blah=5; Foo=0;']
I'm pretty sure what you're looking for is to get a list of the matches, instead of printing out each match on its own. That isn't a valid list, because it's missing the comma between the elements,* but I'll assume that's a typo from you making up data instead of building an MCVE and copying and pasting the real output.
Anyway, to get a list, you have to build a list. Printing things to the screen doesn't build anything. So, try this:
multiline_string_final.append(multiline_string)
Then, at the end—not inside the loop, only after the loop has finished—you can print that out:
print multiline_string_final
And it'll look like this:
['blah=0; blah_blah=1; Foo=3;',
'blah=4; blah_blah=5; Foo=0;']
* Actually, it is a valid list, because adjacent strings get concatenated… but it's not the string you wanted, and not a format Python would ever print out for you.
The problem has nothing to do with the finditer, it's that you're doing the wrong thing:
for line in multiline_string:
print multiline_string.splitlines()
If multiline_string really is a multiline string, then for line in multiline_string will iterate over the characters of that string.
Then, within the loop, you completely ignore line anyway, and instead print multiline_string.splitlines()).
So, if multiline_string is this:
abc
def
Then you'll print ['abc\n', 'def\n'] 8 times in a row. That's not what you want (or what you described).
What you want to do is:
split the string into lines
loop over those lines, not over the original un-split string
print each line, not the whole thing
So:
for line in multiline_string.splitlines():
print line

Categories