C++ PR

【ShellExecution】C++とPythonを連携させてC++コードのデバッグやテストをする方法

標準入出力でPythonとC/C++連携
記事内に商品プロモーションを含む場合があります

こんにちは。

現役エンジニアの”はやぶさ”@Cpp_Learningです。

以前、標準入出力を使って手軽にPythonとC/C++を連携する方法の記事を書きました。

標準入出力でPythonとC/C++連携
PythonからC/C++を呼ぶ -標準入出力とsubprocessの使い方-「Python とC++の連携」・「Python とC言語の連携」・「Python と他言語の連携」などを実現するため、標準入出力を使って2つのプログラミング言語を連携する方法を記事にしました。...

(本記事の理解が深まるので、この記事を読んでから、続きを読んでほしいなぁ)

この記事の【応用】として、C++とPythonを連携してC++コードのテストを実践しました。

備忘録も兼ねて本記事を書きます。

やりたいこと(課題)

Pythonでプログラミングをしていると、処理速度を向上させたくて、処理の一部をC++に置き換えることがあります。

いくつか方法はありますが、”Python C API”を使ったりします(下記の記事参照)。

Python C API
【Python C API入門】C/C++で拡張モジュール作ってPythonから呼ぶ -前編-こんにちは。 現役エンジニアの”はやぶさ”@Cpp_Learningです。 仕事の都合もあり「C言語 ⇒ C++ ⇒ Pyt...

一方、C++でプログラミングをしていると、グラフの描画(matplotlib)や表の操作(pandas)などのPythonライブラリを使いたいときがあります。

例えば、こんなとき…

【C++でPythonライブラリが使いたいとき】

  • 自作関数をテストするとき、出力結果を可視化したい
  • 報告書用のグラフや表を手軽に作成したい

C++で出力結果をCSVファイルに保存するコードを作成して、エクセルで結果を可視化することもありますが…

はやぶさ
はやぶさ
できるだけC++コードを汚さずに出力結果を可視化したい

と思い、C++とPythonを連携してテストする方法を検討しました。

Python-ShellExecutionとは

冒頭で手軽にPythonとC/C++を連携する方法の記事を紹介しました。

標準入出力でPythonとC/C++連携
PythonからC/C++を呼ぶ -標準入出力とsubprocessの使い方-「Python とC++の連携」・「Python とC言語の連携」・「Python と他言語の連携」などを実現するため、標準入出力を使って2つのプログラミング言語を連携する方法を記事にしました。...

この記事では、”subprocess”を使ってC++の実行ファイルをPythonから呼び出していました。

今回は、”subprocess”をより使いやすくしたライブラリ”ShellExecution”を見つけたので、有り難く使わせて頂きます。

”ShellExecution”開発者様のブログはこちら↓

スポンサーリンク

Python-ShellExecutionの使い方 -基本編-

本題のテストを実践する前に、”ShellExecution”の一番シンプルな使い方を紹介します。

標準入出力

例えば、C++で作成した足し算ソフト(実行ファイル:a.out)があったとします。

C/C++の標準入出力サンプルプログラム

↑の”2”と”3″はユーザーがキーボードで入力した値ですが、この入力をPythonにやらせます。

標準入出力でPythonとC/C++連携

作成したPythonコード(main.py)が以下です。

main.pyを実行すると、”a=2.2”と”b=3.3″が入力され、C++の演算結果”a+b=5.5”に対し、+1した”6.5”が出力(表示)されます。

Pythonの標準入出力サンプルプログラム”ShellExecution”を使うことで、Pythonから手軽に外部ファイルを実行でき、かつエラーチェックまでしてくれるます。

なので、今回のようにC++で作成した外部ファイル(a.out)の演算結果をPythonから利用することで、手軽にC++とPythonの連携を実現できます。

  • ”ShellExecution”を使えば、Pythonから手軽に外部ファイルを実行できます
  • 外部ファイルをC++など自分の好きな言語で作成すれば、C++とPythonの連携を実現できます

Python-ShellExecutionの使い方 -応用編-

本題のC++テスト用のPythonコードを作成します。

テスト対象と課題

任意の値”x”を入力すると、演算結果”y”を出力するC++の自作関数があったとします。この自作関数がテスト対象です。

C++とPythonの連携例えば、ある値を入力したとき、”36”または”144”が出力されたらNG※とします。

(※自作関数にバグあり、あるいはシステム上、都合の悪い入力値を検出できた)

入力値が少ない場合は、手動でキーボードから値”x”を入力するか、【基本編】のコード(main.py)を使えば良いのですが…

テストしたい入力値が大量にある場合や、最初から自作関数に連続入力するシステムを想定している場合、テスト時の入力は自動化したくなります。

このような課題を”ShellExecution”を使用したPythonコードで解決します!

テスト対象のC++コード

今回は、y=x^2の演算を行う自作関数”square(x)”をテスト対象とします。

最初に”square(x)”を繰り返し呼び出す処理をC++で作成します。

このC++ファイルを”square.cpp”と呼ぶことにします。

「最初の入力値」と「最後の入力値」をユーザーが指定できるようにしました。

以下が実行時のイメージです。

標準入出力でPythonとC/C++連携

C++コード(square.cpp)の動作確認

作成したC++コード(square.cpp)を以下のコマンドでコンパイルします。

g++ square.cpp -o square

これで”square”という実行ファイルが生成されます。

以下のコマンドで”2~15”の二乗を算出します。

./square 2 15

演算結果が出力(表示)されれば動作確認完了です。

一連の流れを実施したときのターミナル画面は以下の通りです。

標準入出力でPythonとC/C++連携

【基本編】同様にユーザーが入力していた部分をPythonにやらせます。

以下がイメージです。

標準入出力でPythonとC/C++連携

C++テスト用のPythonコード

”ShellExecution”を使用する最大のメリットはfor文などの繰り返し処理中の標準出力も扱うことができることです。

コードを見た方が分かりやすいですね。

このPythonファイルを”square.py”と呼ぶことにします。

【基本編】では、”exe”を使って自作コマンド(cmd)を実行しましたが、【応用編】では“realtime_exe”を使いました。

“realtime_exe”を使うことで、C++の標準出力を1つずつPythonが受け取ることができます。

もし、“realtime_exe”ではなく”exe”を使っていたら、最後の標準出力(225)しかPythonは受け取ることができません。

C++コードのテストをPythonで行う

作成したPythonコード(square.py)を以下のコマンドで実行します。

python square.py

一連の流れを実施したときのターミナル画面は以下の通りです。

標準入出力でPythonとC/C++連携

”36”または”144”が出力されたらNGでしたが、ちゃんと”36”と”144”を検出できています。

これだけだと、C++のみでテストしても良い気がしますが、Pythonを使うことで出力結果のリスト(ans_list)を簡単に生成することができました。

このリスト(ans_list)に対し、グラフの描画(matplotlib)や表の操作(pandas)が簡単に実現できます

今回は、matplotlibを使ってテスト結果を可視化してみました。

PythonとC/C++連携 テスト結果の可視化

一目でNGが分かるように”36”と”144”を出力した場合は、”-1”をプロットするようにしました。

はやぶさ
はやぶさ
4番目と10番目の入力値がNGだったことが一目でわかりますね

※0番目があることに注意!あと”2~15”を入力しています

Pythonを使ってテスト結果を手軽に可視化することで、NG結果の見落としを予防できそうです!

C++の演算結果(標準出力)をPythonで受け取り、”NG結果を強調”するような工夫をして、matplotlibなどでテスト結果を可視化すれば、良いことあるかも!

まとめ

Pythonから手軽に外部ファイルを実行できるライブラリ”ShellExecution”を使って以下のことを説明しました。

【基本編】

C++とPythonを連携する方法(外部ファイルをC++で作成)

【応用編】

C++コードのテストをPythonと連携して楽する方法(ループ処理に対応)

Pythonと連携してテストを実施するメリットは以下の通りです。

  • C++コードをあまり汚さずにテストを実施できる(テスト用のコードをC++で書かなくて済む)
  • グラフの描画(matplotlib)や表の操作(pandas)が簡単に実現できる強力なPythonライブラリと連携できる

本記事では、matplotlibを使ってテスト結果の可視化を行い、NG結果を一目で確認できるように工夫しました。

はやぶさ
はやぶさ
どんなテストを実施したいか検討して、Pythonライブラリと上手く連携して下さいね
くるる
くるる
退屈なことはPythonにやらせて、”仕事効率”を上げよー!
はやぶさ
はやぶさ
理系応援ブロガー”はやぶさ”@Cpp_Learningは頑張る理系を応援します!

PICK UP BOOKS

  • 数理モデル入門
    数理モデル
  • Jetoson Nano 超入門
    Jetoson Nano
  • 図解速習DEEP LEARNING
    DEEP LEARNING
  • Pythonによる因果分析
    Python