I have a number of different codes which all take a text file with data as input and write to a different one as output. Three of these codes are written in Python 2.7, but one is written in IDL. My goal is to create one "master" python program which can run all of these codes, by typing "python master.py". However, because of the limitations of my system, I am unable to use the 'pyIDL' or 'pyIDLy' modules referred to in this question. Not sure if it matters, but this is using a linux command prompt.
Currently my 'master.py' code looks like this:
import os
os.system("python pycode_1.py")
os.system("idl")
os.system(".com idlcode.pro")
os.system(".r idlcode,"imputfile.dat"")
os.system("exit")
os.system("python pycode_2.py")
os.system("python pycode_3.py")
This code runs the first python code and enters IDL fine. However, it does not enter the later comands into IDL. This means that the IDL command prompt comes up, but I cannot run the IDL code that follows.
I would be very appreciative about any advice to solve this issue.
Thanks in advance!
If you have IDL 8.5 or later, it ships with the IDL-Python bridge built in. Then your code would look something like:
from idlpy import *
IDL.idlcode()
Hope this helps.
So I have worked out a solution that seems to work well for this problem. The issue above was the use of the os.system function to do things it couldn't. My new codde is:
import os
import subprocess
os.system("python python_code1.py")
p=subprocess.Popen("idl", stdin=subprocess.PIPE, stdout=subprocess.PIPE)
p.stdin.write(".com idlcode.pro\n")
p.stdin.write("idlcode\n")
p.stdin.write("exit")
p.wait()
os.system("python python_code2.py")
os.system("python python_code3.py")
Related
I'm having a tough time figuring out how to run NodeJS from Python. I have no problems running ShellScript from Python and NodeJS from ShellScript, but can't seem to get NodeJS from Python, I just get the following output:
b"
These are the simplified version of my scripts.
NodeJS I am trying to run from within Python.
#!/usr/bin/env node
console.log("Hello " + process.argv[2]);
And here is the Python, using Python3.
from datetime import datetime
import json
import os
import re
import sys
import subprocess
if __name__ == '__main__':
p = subprocess.Popen(['/Users/Brett/scripts/hello.js', 'Brett'], stdout=subprocess.PIPE)
out = p.stdout.read()
print(out)
Thanks for the help! Much appreciated.
EDITS:
I have no issue executing the following from the commandline, as 'hello.js' is executable:
hello.js 'Brett'
shell=true does not fix it.
Additionally, I am on macOS Catalina 10.15.5 and therefore my shell is zsh.
If I add node to the front of the command, I get no such file or directory for node, I tried it as follows:
p = subprocess.Popen(['/Users/Brett/scripts/hello.js', 'Brett'], stdout=subprocess.PIPE)
Thanks everyone for the responses. All were super helpful. Especially #max-stanley and #jared-smith.
The following ended up working for me:
p = subprocess.Popen(['/usr/local/bin/node', '/Users/Brett/scripts/hello.js', 'Brett'], stdout=subprocess.PIPE)
out = p.stdout.read()
print(out)
Not sure why it doesn't work with the shebang in the executable js file but I am not committed to it, so I will just take the working solution and move on. ;-)
Cheers!
Okay after doing some testing based on the comments by Max Stanley:
There is an inconsistency between Linux and MacOS here about the population of the argv array. On Mac you will want the second index (1) and on Linux you will want the third (2).
I recommend using a command-line argument parser like command-line-args which should paper over the platform differences.
In the meantime you can specify node in the python subprocess call Popen(["node", "/Users/Brett/scripts/hello.js", "Brett"]) which has the same behavior on both.
Having tested this on my system, it looks as though you need to either make the hello.js file executable chmod +x ./hello.js or you need to add 'node' to the beginning of the Popen argument list as #Jared had said.
For the life of me i can't figure this one out.
I have 2 applications build in python, so 2 projects in different folders, is there a command to say in the first application like run file2 from documents/project2/test2.py ?
i tried something like os.system('') and exec() but that only seems to work if its in the same folder. How can i give a command a path like documents/project2 and then for example:
exec(documents/project2 python test2.py) ?
short version:
Is there a command that runs python test2.py while that test2 is in a completely different file/project?
thnx for all feedback!
There's a number of approaches to take.
1 - Import the .py
If the path to the other Python script can be made relative to your project, you can simply import the .py. This will cause all the code at the 'root' level of the script to be executed and makes functions as well as type and variable definitions available to the script importing it.
Of course, this only works if you control how and where everything is installed. It's the most preferable solution, but only works in limited situations.
import ..other_package.myscript
2 - Evaluate the code
You can load the contents of the Python file like any other text file and execute the contents. This is considered more of a security risk, but given the interpreted nature of Python in normal use not that much worse than an import under normal circumstances.
Here's how:
with open('/path/to/myscript.py', 'r') as f:
exec(f.read())
Note that, if you need to pass values to code inside the script, or out of it, you probably want to use files in this case.
I'd consider this the least preferable solution, due to it being a bit inflexible and not very secure, but it's definitely very easy to set up.
3 - Call it like any other external program
From a Python script, you can call any other executable, that includes Python itself with another script.
Here's how:
from subprocess import run
run('python path/to/myscript.py')
This is generally the preferable way to go about it. You can use the command line to interface with the script, and capture the output.
You can also pipe in text with stdin= or capture the output from the script with stdout=, using subprocess.Popen directly.
For example, take this script, called quote.py
import sys
text = sys.stdin.read()
print(f'In the words of the poet:\n"{text}"')
This takes any text from standard in and prints them with some extra text, to standard out like any Python script. You could call it like this:
dir | python quote.py
To use it from another Python script:
from subprocess import Popen, PIPE
s_in = b'something to say\nright here\non three lines'
p = Popen(['python', 'quote.py'], stdin=PIPE, stdout=PIPE)
s_out, _ = p.communicate(s_in)
print('Here is what the script produced:\n\n', s_out.decode())
Try this:
exec(open("FilePath").read())
It should work if you got the file path correct.
Mac example:
exec(open("/Users/saudalfaris/Desktop/Test.py").read())
Windows example:
exec(open("C:\Projects\Python\Test.py").read())
This is a follow up on a previous question as I have made progress(which is irrelevant at this point). It is worth noting that I am learning python and barely know what I am doing, however, I am familiar with programming. I am trying to call an SCP command in the windows terminal through python. However, it is not doing the desired effect. The script runs smoothly with no errors and it prints the debug commands as I have written them. However, the SCP call does not actually go through on the other end. To make sure I have the right command, I have it set to print the same command that it called afterwards. When I copy this printed command and paste it into the windows command terminal, it gives the desired effect. Why is the same command not working correctly in python? Thanks. This is my script:
import subprocess
subprocess.run(['scp', 'c:/users/<name>/desktop/OOGA.txt', 'pi#<IP>:here/'], shell=True)
print ("done")
print ('scp', 'c:/users/<name>/desktop/OOGA.txt', 'pi#<IP>:here/')
Try using raw string if shell is set to True:
from subprocess import run as subrun
status = subrun(r'scp c:/users/<name>/desktop/OOGA.txt pi#<IP>:here/',shell=True)
print("Done")
print(status)
I just want to launch my program written in C++ from a Python script.
I wrote the following script:
import subprocess
subprocess.call(['l:\Proj\Silium.exe', '--AddWatch c:\fff.txt'])
But to my c++ application the parameter "--AddWatch c:\fff.txt" arrives without hyphens - it arrives as "AddWatch c:\fff.txt". So my program doesn't work.
Why does this happen, and how can I fix it?
UPD: thx for comments - yours answer helps!
I explain the issue and the solution.
I need to launch my application in the following way:
l:\Proj\Silium.exe --AddWatch c:\fff.txt
When I tried to do this using some hint from internet:
import subprocess
subprocess.call(['l:\Proj\Silium.exe', '--AddWatch c:\fff.txt'])
the key "--AddWatch" arrives to my program without hyphens - like "AddWatch".
The solution is quite simple:
import subprocess
subprocess.call(['l:\Proj\Silium.exe', '--AddCMakeWatch', 'c:\fff.txt',])
And issue gone away.
P.S.: its very strange that my initial code didnt work, I dont have any idea why python corrupt the command line, I think it is the python bug.
Whenever I try to display symbolic math in Spyder via the IPython console, several black console windows pop up and then disappear in quick succession. It prints the expression, but I'd like to know if there is a way to get rid of these windows. The windows have the title "C:\Program Files\MikTex 2.9..." if that helps.
It looks like someone already figured it out and posted a solution on GitHub. This is the link: https://github.com/sympy/sympy/issues/11882
It took me (as a novice) some time to figure out exactly what he did, so the following is just a more detailed explanation:
You first need to find the compatibility module in the sympy package. For me, it was located at "C:\Users\Lucas\Anaconda3\Lib\site-packages\sympy\core\compatibility.py". Next, you need to search (in the source code of that module) for the check_output function. The surrounding code should look something like:
# check_output() is new in Python 2.7
import os
try:
try:
from subprocess import check_output
Finally, you need to get rid of the last line, and replace it with the code found in the GitHub link. The resulting block should look like:
# check_output() is new in Python 2.7
import os
try:
try:
from subprocess import check_output as subprocess_check_output
def check_output(*args, **kwargs):
return subprocess_check_output(*args, **kwargs, creationflags=0x08000000) # CREATE_NO_WINDOW
It appears to me that he defines a function which takes the place of check_output, except that the argument to suppress the output windows is always fed in. Hope this helps anyone else having this problem, and I appreciate the fix from Adam on GitHub.
I submitted a pull request to fix this for good:
https://github.com/sympy/sympy/pull/12391