How to invoke a Perl script that need args from Python - python

I'm writing my script in Python, and I want to invoke a Perl script from it.
This is the line I want to call:
perl conv_intel_hex_2_verilog.pl arg1 arg2
while arg1 is the input from the Python script and arg2 is a new file that I'm creating.
So far I have this:
def main(argv):
file = open("test.hex", "w")
input = argv[0];
subprocess.call(["perl", "conv_intel_hex_2_verilog.pl", input]);
file.close();
This runs and does nothing.
And when I'm changing the
subprocess.call(["perl", "conv_intel_hex_2_verilog.pl", input]);
to
subprocess.call(["perl", "conv_intel_hex_2_verilog.pl", input ,file]);
it doesn't compile...

As you've described it, the program you're running expects its second argument to be the name of a file, so that's what you need to give it. In your current code, you're giving it a Python file object, which is not the same as the string name of a file.
subprocess.call(["perl", "conv_intel_hex_2_verilog.pl", input, "test.hex"]);
There is no need to create the file object prior to running that code, either. The other program will surely create it for you, and might even balk if it finds that the file already exists.

You cannot just give it a filehandle (or whatever that is called in Python). You are constructing a call to another program, and that program expects a filename, so pass the filename as a string.
subprocess.call(["perl", "conv_intel_hex_2_verilog.pl", input ,"test.hex"]);
You also don't need to open the file first.

Related

What is 'target' in 'target = open(...)'

I'm learning Python as someone more familiar with databases and ETL. I'm not sure where target comes from in the following code.
from sys import argv
script, filename = argv
target = open(filename, 'w')
I think argv is a class in the sys module, but I don't think target comes from argv.
If you run type(target), you will get this: <_io.TextIOWrapper name='dde-recommendation-engine/sample_data/synthetic-micro/ratings.txt' mode='r' encoding='UTF-8'>
What that means in simple terms is that it is an object accessing that particular file (with only write permission because you have a w mode).
You can use this object to add stuff into the file by target.write(.....)
Do remember to close the file however by doing target.close() at the end.
Another way to do the same and I prefer this most of the times is:
with open(filename, 'w') as target:
target.write(...)
This way the file is closed automatically once you are out of the with context.
argv is the list populated by the arguments provided by user while running the program from shell. Please see https://docs.python.org/3/library/sys.html#sys.argv for more info on that.
User supplied the filename from shell, program used the open call https://docs.python.org/3/library/functions.html#open to get a file handle on that filename
And that file handle is stored in variable called target (which could be named anything you like) so that you can process the file using other file methods.
You are using open() - a built-in function in python. This function returns an File object - which is assigned to target variable. Now you can interact with target to write data (since you are using the w mode)
.

I created a file type and an interpreter for the file type. I want to enable the interpreter run the file type once the file type is doublr clicked

I created a file type called oox, I created an interpreter for the file type. I used to do all of the task python.
I compiled the source code with pyinstaller to get the exe of the interpreter, the exe works perfectly; now i want to make the program to run the file type without asking user for input, but rather; through double clicking on the oox file.
What do i need to add to the source code to perform the task?.
The first set of lines after the import statements for the interpreter are below:
print('Please input the .oox file:')
doc = input() #This is the oox file
The normal solution is to pass the path to the file to operate on as a command-line argument, which can be provided non-interactively, rather than prompting the user for interactive input using the input function.
The argparse module in the standard library provides a wealth of tools for parsing command-line arguments. In a simple case like this, though, you can just use sys.argv[1] to get the first command-line argument as a string.

I am trying to process a file passed as a command line argument

I am trying to process a file passed as a command line argument. Right now there is only one argument, but I plan to add others.
Here is my code so far:
import argparse
parser = argparse.ArgumentParser(description="Sample arg parsing")
parser.add_argument('-f',type=file)
try:
print parser.parse_args()
except IOError, msg:
parser.error(str(msg))
I can't figure out how to pass the argument to file handle to open and process.
And yes, I am a n00b.
The try block is just there for testing.
You need to pass the filename as a string. Then, you can use open() to open the file from the filename. Refer to the python docs here (7.2 - Reading & Writing Files).

"sys.argv[x]" is out of range

I must run the exact command:
python3 main.py flip pattern.ppm > flippedpattern.ppm
on the following code:
def main(args):
if sys.argv[1] == "flip":
fileName = sys.argv[2]
method = read_ppm(fileName)
print(method.flip())
return
if __name__ == '__main__':
sys.exit(main(sys.argv))
I have a ppm file and I am trying to manipulating it using another module, but it keeps telling me sys.argv[4] is out of range when assigning it to the variable 'outputFile'
The code executed should be essentially this for the flip command
method = "flip"
method = read_ppm("pattern.ppm")
f.write(method.flip())
Doing exactly that using the repl in visual studio leads to success but when I try to run it from the command line through the main module it doesn't work. Why is this? Does the '>' character somehow interfere with sys.argv or am I making a clear counting mistake that I can't see?
The else statement would account for the input not catching and simply printing, using the input
python3 main.py flip pattern.ppm
without any file redirect.
The argument after > is not part of the command line passed to python. It is the file that the shell writes standard output to. So, for example, print "Hello" will write Hello to flippedpattern.ppm.
If you want flippedpattern.ppm to be the fourth command line argument, just leave out the > in the call. (Then, standard output will be written to the screen.)
Edit: Given your modified description, you can write sys.stdout.write(method.flip()). The only difference between this and print(method.flip()) is that print adds a newline character at the end of the string, while .write doesn't.
I'm not sure how Visual Studio works, but if it works with argv[4] it's probably interpreting every word after the script name like another argument (as it's not bash to have a special interpretation for ">").
So for it to work from bash, you should probably change argv[4] in the code to argv[3], and pass the output file as another argument instead of redirecting:
python main.py flip pattern.ppm flippedpattern.ppm
, or leave the code as it is and add a "dummy" third argument so the output file will be the 4th, for example force it to treat ">" as a regular argument as well:
python3 main.py flip pattern.ppm ">" flippedpattern.ppm

Python stdin filename

I'm trying to get the filename thats given in the command line. For example:
python3 ritwc.py < DarkAndStormyNight.txt
I'm trying to get DarkAndStormyNight.txt
When I try fileinput.filename() I get back same with sys.stdin. Is this possible? I'm not looking for sys.argv[0] which returns the current script name.
Thanks!
In general it is not possible to obtain the filename in a platform-agnostic way. The other answers cover sensible alternatives like passing the name on the command-line.
On Linux, and some related systems, you can obtain the name of the file through the following trick:
import os
print(os.readlink('/proc/self/fd/0'))
/proc/ is a special filesystem on Linux that gives information about processes on the machine. self means the current running process (the one that opens the file). fd is a directory containing symbolic links for each open file descriptor in the process. 0 is the file descriptor number for stdin.
You can use ArgumentParser, which automattically gives you interface with commandline arguments, and even provides help, etc
from argparse import ArgumentParser
parser = ArgumentParser()
parser.add_argument('fname', metavar='FILE', help='file to process')
args = parser.parse_args()
with open(args.fname) as f:
#do stuff with f
Now you call python2 ritwc.py DarkAndStormyNight.txt. If you call python3 ritwc.py with no argument, it'll give an error saying it expected argument for FILE. You can also now call python3 ritwc.py -h and it will explain that a file to process is required.
PS here's a great intro in how to use it: http://docs.python.org/3.3/howto/argparse.html
In fact, as it seams that python cannot see that filename when the stdin is redirected from the console, you have an alternative:
Call your program like this:
python3 ritwc.py -i your_file.txt
and then add the following code to redirect the stdin from inside python, so that you have access to the filename through the variable "filename_in":
import sys
flag=0
for arg in sys.argv:
if flag:
filename_in = arg
break
if arg=="-i":
flag=1
sys.stdin = open(filename_in, 'r')
#the rest of your code...
If now you use the command:
print(sys.stdin.name)
you get your filename; however, when you do the same print command after redirecting stdin from the console you would got the result: <stdin>, which shall be an evidence that python can't see the filename in that way.
I don't think it's possible. As far as your python script is concerned it's writing to stdout. The fact that you are capturing what is written to stdout and writing it to file in your shell has nothing to do with the python script.

Categories

Resources