I'm looking to write a Lua script and have it also execute something from Python source code as well, as if it went like so:
#!/bin/lua
-- begin lua part
print "Hello"
-- begin python part
Somehow_Executes_Python {
print "Hello" #In python, of course
}
-- End Script
Getting the idea?
I'm not sure if it's even possible, but if I can somehow implement foreign source code in controlled blocks, that would be great. I've seen other things about calling them from a different file/ link/ source, but I'm looking to have it work directly from inside of the lua source code, not from a different file entirely.
The simplest approach would be something along these lines:
#!/usr/bin/env lua
local python = function(code)
local file = assert(io.popen('python', 'w'))
file:write(code)
file:close()
end
-- begin lua part
print "Hello from Lua"
--begin python part
python [=[
print "Hello from Python"
]=]
-- End Script
Line-by-line explanation (without code highlighting, it seems that it is broken for Lua on the SO):
#!/usr/bin/env lua
-- The above is a more sure-fire way to run Lua on linux from a shebang
-- This function runs python code as follows
local python = function(code)
-- It opens a write pipe to the python executable
local file = assert(io.popen('python', 'w'))
-- pipes the code there
file:write(code)
-- and closes the file
file:close()
-- This is an equivalent of running
-- $ python <code.py
-- in the shell.
end
-- Begin Lua part
-- I added "from Lua" to better see in the output what works or not.
print "Hello from Lua"
-- Begin Python part
-- We're calling our python code running function,
-- passing Lua long string to it. This is equivalent of
-- python('print "Hello from Python"')
python [=[
print "Hello from Python"
]=]
-- End Script
I imagine you would like to have at least some interoperability between Lua and Python code. It is a bit more difficult to implement and the way you should do it highly depends on the details of the problem you're actually solving.
The cleanest way would probably to create a socket pair of one kind or another and to make Lua and Python code to talk over it.
Solutions where you may read a variable or call a function from one VM (say Lua) in another (say Python) and vice-versa usually lead to a mess for a multitude of reasons (I tried a lot of them and implemented several myself).
There is a python-lua package called Lupa. Here's the documentation. See if that helps.
Related
Can I use Python code and libraries in Racket? I have installed PyonR (https://github.com/pedropramos/PyonR) in DrRacket so I can choose "#lang python" and run Python code. But how can I combine Racket and Python language codes for my application?
There is also a limited Python to Lisp translator at https://github.com/nurv/pnil . Is there something similar for Racket?
Edit: As advised in comments, I tried following. This python code in file "pysamples.rkt" works well in DrRacket:
#lang python
def greet(name):
print 'Hello', name
greet('Alfred')
Output:
Hello Alfred
I tried using above definition in Racket code, but it did not work. Following is the Racket code:
#lang racket
; (require python/config) (enable-cpyimport!) ; ran this once; worked.
(#%require "pysamples.rkt")
(greet "Racket_code")
The error is:
greet: unbound identifier in module in: greet
The PyonR project is the closest ready-to-use way of using Python libraries from Racket that I know of. However note that there is a difference between Python libraries written in Python and Python libraries that are a thin Python layer on top of a C library. As you have experienced the latter type is not working (to my knowledge at least - but Pedro is the one to ask).
If you need to use a library written in language X (for X could be Python) you can always write a "listener" program in language X that waits for messages from a Racket program, and when a message is received, computes an answer and sends it back to the Racket program. How to send and receive messages is up to you, but a simple option is to have two files, one "R-to-X" which Racket writes to and X reads from, and another "X-to-R" where Racket receives the messages.
This approach has some overhead, but if the computation takes longer than sending the message, then it is a viable solution.
Accoring to the readme you can import python 2.7 packages, but you need to use cpyimport. One of the examples looks like this:
#lang python
cpyimport numpy as np
from "racket" import time
def add_arrays(n):
result = np.zeros((100,100))
for i in range(n):
result += np.random.randint(0, 100000, (100,100))
return result
print time(add_arrays(10000))
Looking at the code, a pure python library you could just import give that it's in rackets paths and was given #lang python top line. all defined are always exported.
The previous answers and comments addressed difficulties with certain Python libraries, but if you're just interested in using a function from a pure Python file in a Racket module, try something like this:
In file "greetings.py":
#lang python
def greet(name):
print 'Hello', name
In Racket:
#lang racket
(require python)
(py-import "greetings" as python-module)
(py-method-call python-module "greet" "Racket")
I'm running a python script from inside a different software (it provides a python interface to manipulate its data structures).
I'm optimizing my code for speed and would like to see what impact on performance my asserts have.
I'm unable to use python -O. What other options do I have, to programatically disable all asserts in python code? The variable __debug__ (which is cleared by -O flag) cannot be assigned to :(
The docs say,
The value for the built-in variable [__debug__] is determined when the
interpreter starts.
So, if you can not control how the python interpreter is started, then it looks like you can not disable assert.
Here then are some other options:
The safest way is to manually remove all the assert statements.
If all your assert statements occur on lines by themselves, then
perhaps you could remove them with
sed -i 's/assert /pass #assert /g' script.py
Note that this will mangle your code if other code comes after the assert. For example, the sed command above would comment-out the return in a line like this:
assert x; return True
which would change the logic of your program.
If you have code like this, it would probably be best to manually remove the asserts.
There might be a way to remove them programmatically by parsing your
script with the tokenize module, but writing such a program to
remove asserts may take more time than it would take to manually
remove the asserts, especially if this is a one-time job.
If the other piece of software accepts .pyc files, then there is a
dirty trick which seems to work on my machine, though note a Python
core developer warns against this (See Éric Araujo's comment on 2011-09-17). Suppose your script is called script.py.
Make a temporary script called, say, temp.py:
import script
Run python -O temp.py. This creates script.pyo.
Move script.py and script.pyc (if it exists) out of your PYTHONPATH
or whatever directory the other software is reading to find your
script.
Rename script.pyo --> script.pyc.
Now when the other software tries to import your script, it will
only find the pyc file, which has the asserts removed.
For example, if script.py looks like this:
assert False
print('Got here')
then running python temp.py will now print Got here instead of raising an AssertionError.
You may be able to do this with an environment variable, as described in this other answer. Setting PYTHONOPTIMIZE=1 is equivalent to starting Python with the -O option. As an example, this works in Blender 2.78, which embeds Python 3.5:
blender --python-expr 'assert False; print("foo")'
PYTHONOPTIMIZE=1 blender --python-expr 'assert False; print("foo")'
The first command prints a traceback, while the second just prints "foo".
As #unutbu describes, there is no official way of doing this. However, a simple strategy is to define a flag like _test somewhere (for example, as keyword argument to a function, or as a global variable in a module), then include this in your assert statements as follows:
def f(x, _test=True):
assert not _test or x > 0
...
Then you can disable asserts in that function if needed.
f(x, _test=False)
This thread discusses a way of running Python code from within a Bash script.
Is there any way to do something similar from within a Perl script? i.e. is there any way to run Python code typed on a Perl script? Note that I am not asking about running a Python file from a Perl script. I am asking about running Python code directly typed within the same file that has the Perl script (in the same way that the other thread discussed how to run Perl code from which a Bash script).
Example:
# /bin/perl
use 5.010
my $some_perl_variable = 'hello';
# ... BEGIN PYTHON BLOCK ...
# We are still in the same file. But we are now running Python code
import sys;
print some_perl_variable # Notice that this is a perl variable
for r in range(3):
print r
# ... END PYTHON BLOCK ...
say "We are done with the Perl script!"
say "The output of the Python block is:"
print $output"
1;
Should print:
We are done with the Perl script!
The output of the Python block is:
hello
1
2
3
We are done with the perl script
It sounds like you would be interested in the Inline module. It allows Perl to call code in many other languages, and relies on support modules for each language.
You don't say what you want to do, but you mention Python and there is an Inline::Python.
Yes, the same technique (here-docs) can be used for Perl.
Perl in Bash:
perl <<'END' # note single quotes to avoid $variable interpolation
use 5.010;
say "hello world";
END
or
perl -E'say "hello from perl"'
Bash in Perl:
use autodie; # less error handling
open my $bash, "|-", "bash";
print $bash <<'END'; # single quotes again
echo hello from bash
END
Perl in Bash in Perl:
use autodie; # less error handling
open my $bash, "|-", "bash";
print $bash <<'END'; # single quotes again
perl <<'INNER_END'
use 5.010;
say "hello inception";
INNER_END
END
(which I ironically tested on the commandline, in another heredoc)
I'm running a python script from inside a different software (it provides a python interface to manipulate its data structures).
I'm optimizing my code for speed and would like to see what impact on performance my asserts have.
I'm unable to use python -O. What other options do I have, to programatically disable all asserts in python code? The variable __debug__ (which is cleared by -O flag) cannot be assigned to :(
The docs say,
The value for the built-in variable [__debug__] is determined when the
interpreter starts.
So, if you can not control how the python interpreter is started, then it looks like you can not disable assert.
Here then are some other options:
The safest way is to manually remove all the assert statements.
If all your assert statements occur on lines by themselves, then
perhaps you could remove them with
sed -i 's/assert /pass #assert /g' script.py
Note that this will mangle your code if other code comes after the assert. For example, the sed command above would comment-out the return in a line like this:
assert x; return True
which would change the logic of your program.
If you have code like this, it would probably be best to manually remove the asserts.
There might be a way to remove them programmatically by parsing your
script with the tokenize module, but writing such a program to
remove asserts may take more time than it would take to manually
remove the asserts, especially if this is a one-time job.
If the other piece of software accepts .pyc files, then there is a
dirty trick which seems to work on my machine, though note a Python
core developer warns against this (See Éric Araujo's comment on 2011-09-17). Suppose your script is called script.py.
Make a temporary script called, say, temp.py:
import script
Run python -O temp.py. This creates script.pyo.
Move script.py and script.pyc (if it exists) out of your PYTHONPATH
or whatever directory the other software is reading to find your
script.
Rename script.pyo --> script.pyc.
Now when the other software tries to import your script, it will
only find the pyc file, which has the asserts removed.
For example, if script.py looks like this:
assert False
print('Got here')
then running python temp.py will now print Got here instead of raising an AssertionError.
You may be able to do this with an environment variable, as described in this other answer. Setting PYTHONOPTIMIZE=1 is equivalent to starting Python with the -O option. As an example, this works in Blender 2.78, which embeds Python 3.5:
blender --python-expr 'assert False; print("foo")'
PYTHONOPTIMIZE=1 blender --python-expr 'assert False; print("foo")'
The first command prints a traceback, while the second just prints "foo".
As #unutbu describes, there is no official way of doing this. However, a simple strategy is to define a flag like _test somewhere (for example, as keyword argument to a function, or as a global variable in a module), then include this in your assert statements as follows:
def f(x, _test=True):
assert not _test or x > 0
...
Then you can disable asserts in that function if needed.
f(x, _test=False)
Does a easy to use Ruby to Python bridge exist? Or am I better off using system()?
You could try Masaki Fukushima's library for embedding python in ruby, although it doesn't appear to be maintained. YMMV
With this library, Ruby scripts can directly call arbitrary Python modules. Both extension modules and modules written in Python can be used.
The amusingly named Unholy from the ingenious Why the Lucky Stiff might also be of use:
Compile Ruby to Python bytecode.
And, in addition, translate that
bytecode back to Python source code
using Decompyle (included.)
Requires Ruby 1.9 and Python 2.5.
gem install rubypython
rubypython home page
I don't think there's any way to invoke Python from Ruby without forking a process, via system() or something. The language run times are utterly diferent, they'd need to be in separate processes anyway.
If you want to use Python code like your Python script is a function, try IO.popen .
If you wanted to reverse each string in an array using the python script "reverse.py", your ruby code would be as follows.
strings = ["hello", "my", "name", "is", "jimmy"]
#IO.popen: 1st arg is exactly what you would type into the command line to execute your python script.
#(You can do this for non-python scripts as well.)
pythonPortal = IO.popen("python reverse.py", "w+")
pythonPortal.puts strings #anything you puts will be available to your python script from stdin
pythonPortal.close_write
reversed = []
temp = pythonPortal.gets #everything your python script writes to stdout (usually using 'print') will be available using gets
while temp!= nil
reversed<<temp
temp = pythonPortal.gets
end
puts reversed
Then your python script would look something like this
import sys
def reverse(str):
return str[::-1]
temp = sys.stdin.readlines() #Everything your ruby programs "puts" is available to python through stdin
for item in temp:
print reverse(item[:-1]) #Everything your python script "prints" to stdout is available to the ruby script through .gets
#[:-1] to not include the newline at the end, puts "hello" passes "hello\n" to the python script
Output:
olleh
ym
eman
si
ymmij
For python code to run the interpreter needs to be launched as a process. So system() is your best option.
For calling the python code you could use RPC or network sockets, got for the simplest thing which could possibly work.