yasin.yazici - 6 months ago 23

Python Question

I'm running the python code below which evaluates mean of an array:

`def matlab_func1(array):`

p = os.popen('matlab -nodesktop -nosplash -r "mean('+str(array)+');exit"')

while 1:

line = p.readline()

if not line:

break

print line

matlab_func1([1,2,3])

From the matlab script below, it can be seen output return to y. I want to catch this output from python.

`function y = mean(x,dim)`

...

...

end

The solution must be applicable to the other matlab function. The 'mean' function is just an example.

Answer

Use `fprintf`

to write needed text into `stderr`

. Just add an extra argument `2`

in the beginning.

```
import subprocess
import os
def matlab_func1(array):
p = subprocess.Popen(['/home/user/Matlab/bin/matlab', '-nodesktop', '-nosplash', '-r "m = mean(' + str(array) + ');fprintf(2, \'%d\\n\',m);exit" >/dev/null'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
while 1:
try:
out, err = p.communicate()
except ValueError:
break
print 'hello' + err
matlab_func1('[1,2,3]')
```

A few things to note:

- Changed the Python command to
`subprocess.Popen`

, which allows`stderr`

piping. - In Matlab command, use
`fprintf`

to write wanted info into`stderr`

. This can separate code ouput from Matlab's header lines. - Back into Python, use
`Popen.communicate()`

to catch`stderr`

output. - The exception
`ValueError`

handles exit event of Matlab (`p`

is closed).

EDIT:

say a Matlab function is

```
function [y, z] = foo(x)
y = x+1;
z = x*20;
end
```

The point is use `fprintf`

to throw the output, while doing all other things as you always do normally in Matlab.

```
p = subprocess.Popen(['/home/user/Matlab/bin/matlab', '-nodesktop', '-nosplash', '-r "[y, z] = foo(' + str(array) + ');for ii=1:length(y) fprintf(2, \'%d %d\\n\',y(ii),z(ii)); end; exit" >/dev/null'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
```

First create a new `caller.m`

script

```
[y, z] = foo(x);
for ii=1:length(y)
fprintf(2, '%d %d\n',y(ii),z(ii));
end
```

Note that `x`

is to be assigned when calling from Python; scripts share the same stack. (Remember NOT to `clear`

the workspace in the caller script. )

Then, call the script from Python

```
p = subprocess.Popen(['/home/user/Matlab/bin/matlab', '-nodesktop', '-nosplash', '-r "x=' + str(array) + ';caller; exit" >/dev/null'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
```

When passing data through

`stdout`

/`stderr`

pipe:Refer to this and

`subprocess.check_output()`

.When handling serious data like

`double`

or binary:Write the data into an external file with Matlab. Then read this file with Python. A protocol with which both side talk with each other should be defined.