Grabbing the output of MAPLE via Python

2020-03-26 05:58发布

问题:

How would I use the subprocess module in Python to start a command line instance of MAPLE to feed and return output to the main code? For example I'd like:

X = '1+1;'
print MAPLE(X)

To return the value of "2".

The best I've seen is a SAGE wrapper around the MAPLE commands, but I'd like to not install and use the overhead of SAGE for my purposes.

回答1:

Trying to drive a subprocess "interactively" more often than not runs into issues with the subprocess doing some buffering, which blocks things.

That's why for such purposes I suggest instead using pexpect (everywhere but Windows: wexpect on Windows), which is designed exactly for this purpose -- letting your program simulate (from the subprocess's viewpoint) a human user typing input/commands and looking at results at a terminal/console.



回答2:

Using the tip from Alex Martelli (thank you!), I've came up with an explicit answer to my question. Posting here in hopes that others may find useful:

import pexpect
MW = "/usr/local/maple12/bin/maple -tu"
X = '1+1;'
child = pexpect.spawn(MW)
child.expect('#--')
child.sendline(X)
child.expect('#--')
out = child.before
out = out[out.find(';')+1:].strip()
out = ''.join(out.split('\r\n'))
print out

The parsing of the output is needed as MAPLE deems it necessary to break up long outputs onto many lines. This approach has the advantage of keeping a connection open to MAPLE for future computation.



回答3:

Here's an example of how to do interactive IO with a command line program. I used something similar to build a spell checker based on the ispell command line utility:

f = popen2.Popen3("ispell -a")
f.fromchild.readline() #skip the credit line

for word in words:
    f.tochild.write(word+'\n') #send a word to ispell
    f.tochild.flush()

    line = f.fromchild.readline() #get the result line
    f.fromchild.readline() #skip the empty line after the result

    #do something useful with the output:
    status = parse_status(line)
    suggestions = parse_suggestions(line)
    #etc..

The only problem with this is that it's very brittle and a trial-and-error process to make sure you're not sending any bad input and handling all the different output the program could produce.