48568
Node.js+Expressフレームワークを使ってWEBアプリケーションを作成しています。

Node.js内に3次方程式の解を求めるようなプログラムを組み込みたいのですが  
自力で実装すると大変そうなので、Pythonのライブラリの力を借りようと思いました。

以下のように、PythonのSymPyモジュールを使って3つの解を求めて、解をsol変数を入れ  
sol変数をNode.jsの変数に渡すような処理をしたいです。

```

    from sympy import *
    x=Symbol('x') #文字'x'を変数xとして定義
    
    #4x^3+12x^2+8x=0の解を求めて変数solに代入
    sol=solve(4*x**3+12*x**2+8*x, x)
    
```

こういった処理は、Node.jsのpython-shellモジュールなどを使えばできるのでしょうか？  
<https://www.npmjs.com/package/python-shell>

python-shellの使い方を読んでもあまり理解が出来ませんでした。  
以下のような使い方をするのではないかと色々触ってみたのですがエラーで全然前に進めません。

```

    //まずpython-shellモジュールを読み込む
    var PythonShell = require('python-shell');
    
    //json形式で別ファイルのpython(script.py)にデータを渡すことを前提にオブジェクト作成
    var shell = new PythonShell('script.py', { mode: 'json '});
    
    //jsonデータ作成
    var json = {
        "a": "4",
        "b": "12",
        "c": "8"
    }
    
    //pythonにjsonデータを渡してpythonから返り値を受け取る
    var test = shell.receive(json);
    
```

どうしたら出来ますか...?
CC BY-SA 4.0
2018-09-19T16:32:44.147
48567
2018-09-19T17:24:01.293
22541
question
python node.js
Node.js内でPythonを呼び出して相互に変数をやり取りしたい
[python-shellモジュールのテスト](https://github.com/extrabacon/python-
shell/blob/master/test/test-python-shell.ts#L191)が参考になると思います。

まず、今回作成したJSONデータをnode.jsからPython側に送るには、sendメソッドを使う必要があります。

```

    shell.send(json);
    
```

Python側のスクリプトは[このように](https://github.com/extrabacon/python-
shell/blob/master/test/python/echo_json.py)書くとよいようです。すなわち、標準入力にJSONを表す文字列が送られてくるので、それを`json.loads`でデコードします。  
計算が終わってnode.js側に送り返すデータは`json.dumps`で文字列にしたあとprintで標準出力に出力します。

そして、Python側から送られてきたJSONデータは、ドキュメントによればmessageイベントで受け取ることができます。

```

    shell.on('message', function (data) {
        // Pythonスクリプトから送られてきたデータを表示
        console.log(data);
    });
    
```

* * *

以上をまとめると、次のようにすればできます。

**index.js**

```

    //まずpython-shellモジュールを読み込む
    var { PythonShell } = require('python-shell');
    
    //json形式で別ファイルのpython(script.py)にデータを渡すことを前提にオブジェクト作成
    var shell = new PythonShell('script.py', {
        mode: 'json',
    });
    
    //jsonデータ作成
    var json = {
        "a": 4,
        "b": 12,
        "c": 8,
    };
    
    // scirpt.pyにJSONを送信
    shell.send(json);
    
    // script.pyからの返事を待機
    shell.on('message', data => {
        // データを表示 
        console.log(data.result);
    });
    
    // 入力を終了
    shell.end();
    
```

**script.py**

```

    import sys, json
    from sympy import *
    x=Symbol('x') #文字'x'を変数xとして定義
    
    # nodejsスクリプトからデータを受信
    data = json.loads(sys.stdin.readline())
    a = data["a"]
    b = data["b"]
    c = data["c"]
    
    # 方程式の解を求める
    sol=solve(a*x**3+b*x**2+c*x, x)
    
    # 各解をintに変換
    intsol = [int(value) for value in sol]
    
    # オブジェクトを作成
    response = {"result": intsol}
    # JSON文字列にして出力
    print(json.dumps(response))
    
```

これを実行すると`[ -2, -1, 0 ]`のように表示され、正しく解が求まっていることが分かります。

* * *

とりあえずこのスクリプトを実行すれば動きますが、質問文にある元のスクリプトからはいくつか変わっているので注意してください。  
例えば1行目のrequireの行が少し変わっています。元のままだと`PythonShell`をnewできないというエラーが出るはずです。  
また、`{ mode: 'json ' }`という部分ですが、`'json '`という文字列に余計なスペースが含まれておりこれでは正しく動かないはずです。
CC BY-SA 4.0
2018-09-19T17:24:01.293
48568
2018-09-19T17:24:01.293
30079
48567
answer