1

I would like to run LIWC (installed in my Mac) within a python 2.7 script.

I have been reading about subprocess (popen and check_output seem the way to go), but I do not get the syntax for:

  • opening the program;
  • getting a text file to be analysed;
  • running the program;
  • getting the output (analysis) and storing it in a text file.

This is my first approach to subprocess, is this possible? I appreciate the suggestions.

EDIT

This is the closest to implementing a solution (still does not work):

I can open the application.

subprocess.call(['open', '/file.app'])

But cannot make it process the input file and get an output one.

subprocess.Popen(['/file.app', '-input', 'input.txt', '-output', 'output.txt'])

Nothing comes out of this code.

EDIT 2

After reading dozens of posts, I am still very confused about the syntax for the solution.

Following How do I pipe a subprocess call to a text file?

I came out with this code:

g = open('in_file.txt', 'rb', 0)
f = open('out_file.txt', 'wb')

subprocess.call(['open', "file.app"] stdin=g, stdout=f)

The output file comes out empty.

EDIT 3

Following http://www.cplusplus.com/forum/unices/40680/

When I run the following shell script on the Terminal:

cat input.txt | /Path/LIWC > output.txt

The output txt file is empty.

EDIT 4

When I run:

subprocess.check_call(['/PATH/LIWC', 'PATH/input.txt', 'PATH/output.txt'])

It opens LIWC, does not create an output file and freezes.

EDIT 5

When I run:

subprocess.call(['/PATH/LIWC', 'PATH/input.txt', 'PATH/output.txt'])

It runs LIWC, creates an empty output.txt file and freezes (the process does not end).

Community
  • 1
  • 1
Diego
  • 637
  • 3
  • 10
  • 24
  • Does `LIWC` accept an input text on its stdin and/or as a file? Does `LIWC` print the result to its stdout stream and/or to a file? Perhaps you need a ["programmer perspective"](http://stackoverflow.com/questions/14288177/interact-with-other-programs-using-python#comment19842264_14288177) – jfs May 22 '15 at 22:12
  • @J.F.Sebastian, thank you for the questions! LIWC takes a txt file as an input and prints out the result to a txt file and displays it. I hope this helps you to help me. Best. – Diego May 23 '15 at 04:20
  • If `LIWC` gets its input from a file and saves its output to another file then you should be able to get the results using `subprocess`. The necessary steps are: 1. Save a text from a variable to a file that you will pass as an input 2. Run the command providing input/output filenames as a command-line arguments 3. Read the result file and parse it into a dictionary. – jfs May 23 '15 at 11:16
  • @J.F.Sebastian, thank you for the suggestion. The part that I am having trouble with subprocess is the syntax for resolving step 2. What would be the command-line arguments for it? Thanks once again. – Diego May 23 '15 at 12:16
  • If you know how to run LIWC manually in the terminal then just pass each command-line argument as a separate list item e.g., `subprocess.check_call(["ls", "-l", some_path])` – jfs May 23 '15 at 12:22
  • btw, instead of ordinary files on hdd, you could [use pipes and /dev/fd/N names or named pipes so that no data touches the disk](http://stackoverflow.com/a/28840955/4279) (it is an advanced option -- you may ignore it). – jfs May 24 '15 at 11:32
  • Thank you for the follow up. I am still working on the basics (now with `subprocess.check_output(]])`). I do not quite get the command-line arguments syntax for getting the txt to be processed by the program, and for instructing the output. – Diego May 24 '15 at 14:34
  • @J.F.Sebastian, please check out my "Edit" code for suggestions. Thanks! – Diego May 24 '15 at 16:49
  • Do you understand the difference between `call()` and `Popen()`? *"Nothing comes out of this code"* -- describe using words what do you expect to happen and what happens instead, post a full error message if any, specify how are you running this code exactly. For debugging, 1. create a small python script that has the same command-line interface as the application you are trying to run (read input file, write a dummy output (e.g., convert to upper case all input) to the specified output file) 2. make sure it works manually (it read input file, and writes the correct output to another file).. – jfs May 24 '15 at 16:59
  • ..continued. 3. run it with `subprocess` and post the corresponding errors. In other words, [create a minimal complete code example that shows the problem](http://stackoverflow.com/help/mcve) – jfs May 24 '15 at 17:00
  • @J.F.Sebastian, thank you for the orientation. I will try to build a minimal code for this problem. – Diego May 24 '15 at 18:30
  • @J.F.Sebastian, after reading dozens of articles and posts, I think I am closer to a solution (posted as EDIT 2). Though I cannot run a minimal code for this problem. I do not know how to write it for a non-python app. I understand you are trying to coach me into learning more, but at this point I think I could have a better insight of the right code if I see one...Thank you for the patience! – Diego May 24 '15 at 21:03
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/78701/discussion-between-diego-and-j-f-sebastian). – Diego May 25 '15 at 14:46
  • @J.F.Sebastian, I tried EDIT 3 (running code in Terminal). Please comment. Thanks! – Diego May 25 '15 at 14:53
  • If you can't run the command in the Terminal then it is not a Python issue. Find out about how to use LIWC in the Terminal (if it is possible at all) and then it should be straightforward to run it in Python [as I said above](http://stackoverflow.com/questions/30406361/run-liwc-as-external-program-to-python-subprocess#comment48911419_30406361) – jfs May 25 '15 at 20:28
  • Is my command syntax fine (EDIT 3) or is there anything missing/wrong? – Diego May 25 '15 at 20:44

1 Answers1

0

The problem with using 'open' in subprocess.call(['open', "file.app"] stdin=g, stdout=f) is that it requests that a file be opened through a service, and doesn't directly attach it to your python process. You'll need to instead use the path to LIWC. I'm not sure that it supports reading from stdin, though, so you might need to even pass in the path to the file you'd like it to open.

  • Thanks for the suggestion. I ran `subprocess.call([])` without `'open'` and with complete paths both for app and in/out files. It seems to execute but it does not finish the process. I included a `print "Process Ended"` final line and does not print it out. Any advice? – Diego May 25 '15 at 16:12