How to execute a code from another script and pass arguments - python-3.x

I have a python code try.py which has to execute another one called prova.py.
I do it as folows and it works:
exec(open("prova.py").read())
Now, I have some variables I need to pass to prova.py, and I did it as follows according to what found here: https://www.geeksforgeeks.org/exec-in-python/
var = {key:val for key, val in enumerate(lista_gp_todict)}
exec(open("prova.py").read(), var)
try.py does not give error which means the way I write exec now is still correct in terms of syntax, but in the moment this exec runs it gives error in prova.py:
NameError: name 'var' is not defined
which mean that the code prova.py which has inside the variable var does not recognise it, like it was not declared. In fact var is not declared into prova.py because if I pass it I assume it already there.
What am I doing wrong?
PS: my OS is windows

Typically you would call another script with the subprocess module.
subprocess.run() accepts an iterable of strings as arguments to be run as a separate process. You can use the arguments exactly as you would call them from command line.
subprocess.run(['python', 'prova.py', my_argument])
Since you wish to pass a dict to your script, you can do so by first serializing to json, which is just a nice way of saying "convert it to a string".
Since var is your dict you can do so like.
subprocess.run(['python', 'prova.py', json.dumps(var)])
And then deserialize or "convert back to a dict" in prova.py.
var = json.loads(sys.argv[1])
Alternatively, you could import prova.py if all you intend to use from it are functions, classes, or variables.
For example, if prova.py contains:
# prova.py
def my_func(var):
# do some stuff to var
You can then do this in your main script:
import prova
var = {key:val for key, val in enumerate(lista_gp_todict)}
prova.my_func(var)

Related

Passing argument to lua function after evaluating function in string

I have functions process and matrix. The following code works
process(matrix({{2,4,6},{8,10,12},{14,16,20}}))
However the following doesn't work.
n='matrix({{2,4,6},{8,10,12},{14,16,20}})'
process(n)
It throws some error. The reason is obvious that process takes n as string rather than the output of the function matrix. So the basic difficulty involved here is about evaluating string from variable n and then give it as argument to the function process. Here loadstring function is of no use as matrix is local function and can't be referred from loadstring.
Is there any work around for this? I hope that I have clearly stated the problem here. It is about evaluating (or unloading) string and then passing it as argument to another function. Any help will be appreciated. Thanks.
as matrix is local function
Lua takes local declarations seriously. If a variable is declared local, it can only be accessed by code which is statically within the local scope of that variable. Strings which you later turn into code are not statically in the local scope and therefore cannot access local variables.
Now, with Lua 5.2+, you can provide load with a second parameter, a table which represents the global environment against which that Lua chunk will be built. If that table contains a matrix value, then the loaded string can access it. For Lua 5.1, you'd have to use setfenv on the function returned to load to accomplish a similar effect. The Lua 5.2+ method would look like this:
local env = {matrix = matrix}
local func = load("return matrix({{2,4,6},{8,10,12},{14,16,20}})", nil, "t", env)
process(func())
Note the following:
You must create an explicit table which is the global environment. There's nothing you can pass that says "make my locals available"; you have to put every local you'd like to access there. Which is, generally speaking, why you pass these things as parameters or just make them globals.
You explicitly need the "return " there if you want to get the results of the call to matrix.
You have to call the function. Functions are values in Lua, so you can freely pass them around. But if you want to pass the results of a function to another function, you have to actually call it.

Using a commandline argument to call a class method

Aplogies if I have the terminology all wrong; I am still learning the basics of Python. I have been unable to google this issue, probably in large part because I don't know the terminology..
So. I have built a class within a .py script with LOTS of methods/functions. To keep this remotely simple, I want to call these from a commandline argument. I have no idea how to explain it, and I can't find anhy examples, so I will try to demo it:
Take for example mute_on as the function that I want to call. I run the script with the function/method in the argument, like:
python3 ./myscript.py mute_on
I assume we'd import sys(?), define the class and the function, and create the relevant object from the class:
import sys
class TelnetAVR(PioneerDevice):
def mute_on(self, mute):
self.telnet_command("MO")
mypioneer = PioneerDevice('Pioneer AVR', '192.168.2.89', 8102, 10)
...and lastly I would like the commandline argument to call the method/function - instead of calling it explicitly like:
mypioneer.mute_volume()
..I want to use the arg (sys.argv[1]) to dynamically call the function, like:
mypioneer.{sys.argv[1]}()
Any ideas, kind people? I have been auto-referred to What is getattr() exactly and how do I use it? but I have no idea how that information can help me here.
I have tried setting cmnd = 'turn_off' and then the following failed...;
getattr(mypioneer, str(cmnd))
getattr(mypioneer, cmnd)
Thanks!
This answer seems a little basic, but I cannot complain as to its efficacy;
mypioneer = PioneerDevice('Pioneer AVR', '192.168.2.89', 8102, 10)
exp = 'mypioneer.' + sys.argv[1] + '()'
print('Executing: ' + exp )
exec(exp)
I gave up loking for a graceful answer, and simply constructed a string that I wanted to execute (exp) based on the commandline argument. Works great.. Home Assistant can use the same script to call 50 telnet controls over my Pioneer AVR.

Calling functions with variables multiple times

I'm making a program for a school project and I'm having an issue.
I have defined a function called DidThisWork like so:
def DidThisWork():
global DidThisWork
DidThisWork = input('\n\nDid this solution work? - ').lower()
Throughout my code, I want to call this function multiple times, however, I'm not able to. Is there a way, to call it multiple times, and like reset the DidThisWork variable inside the function after I used it in if statements?
You define a function def DidThisWork(): then within that very function you overwrite the newly created DidThisWork variable (which points to the function) to the result of your input(..) call.
So at the first call to DidThisWork(), the DidThisWork variable no longer points to the function, rather to the string returned by input(...).
If you rename either the function or the variable storing the string returned by input() it should work.
By the way, there are some naming conventions in Python you may want to look into https://www.python.org/dev/peps/pep-0008/#id30. Typically you'd use snake_case instead of camelCase and not only start a class with an upper case letter
worked = None
def did_this_work():
global worked
worked = input('\n\nDid this solution work? - ').lower()
print(worked)
did_this_work()
print(worked)
did_this_work()
print(worked)

Passing List of Variables In Bash To External Program

Good Afternoon Everyone,
This is probably a no-brainer but, I'm currently having issues passing a variable to a program in my bash script.
Here's what I'm trying to do:
regions=ne,se,vt,ma,sw,nw and so on and so forth
After that variable has been defined in my bash script, I'd then like to pass that variable into GrADS, where my script will read each of the regions one after the other until it reaches the end.
The most reliable means of passing variables I've found is to generate a text file with the code (or just the string) you want to pass from within the code. Alternatively, you could call GrADS (?) from within whatever program is generating the variable, and pass "$regions" as an argument.

Julia #everywhere variables

I am trying to implement code in parallel using Julia. I'm using the #everywhere macro in order to make all processes fetch data from a RemoteRef.
Is it possible to use a variable name thats only defined on the first process in the #everywhere expression and somehow specify that I want it to send the value of that variable, and not the variable name, to all processes?
Example:
r = RemoteRef()
put(r, data)
#everywhere data = fetch(r)
This returns an error because r is not defined on all processes.
How should I move data to all processes?
Also, can I tell Julia to put the value instead of the variable name in the expression?
Something akin to how name = "John"; println("Hello, $name") will print "Hello, John"
To find the functions (and macros) Spencer pointed in a nice little package, checkout ParallelDataTransfer.jl. The tests are good examples of usage (and the CI shows that these tests pass on v0.5 on all platforms).
For your problem, you can use the sendto function:
z = randn(10, 10); sendto(workers(), z=z)
#everywhere println(z)

Resources