Boostの簡単な紹介:: program_options

アルゴリズムの開発に携わり、私は常に自分自身を引き上げ、小さなサンプルで機能する変更が突然、他のビッグデータの結果に混乱と動揺をもたらします。 次に、コマンドラインが役立ちます。 最悪なのは、引数パーサーの実装にうんざりするたびに、 ブーストライブラリのprogram_optionsパッケージがC ++プログラマにとって最後の手段ではないことです。



例から始めましょう。 トレーニング用の認識アルゴリズムを開発しており、次のデータがあるとします。 一部のデータと拡張子が.dat(データ)のファイル。 トレーニング情報と拡張子.trn(トレーニング)を持つファイルと、拡張子.prs(パラメーター)を持つパラメーターファイル。 パラメータファイルはトレーニングの結果として取得され、認識に使用されます。 したがって、3つのアクションがあります:トレーニング(トレーニング)、認識(認識)、スコアリング(認識の品質を評価)。 この場合、トレーニング、認識、評価チェーン呼び出しスクリプトは、たとえば次のようになります。



recognizer --type=train --input=train.dat --info=train.trn --output=best.prs recognizer --type=recognize --input=test1.dat --input=test2.dat --params=best.prs --output=./ recognizer --type=score --ethanol=test1_expected.trn --test=test1.trn --output=scores.txt recognizer --type=score --ethanol=test2_expected.trn --test=test2.trn --output=scores.txt
      
      





この例では、データファイルとトレーニングファイルからパラメーターファイルを作成し、パラメーターファイルを使用して別のデータファイルを認識し、認識結果を標準と比較して結果ファイルの最後に追加します。 program_optionsを使用してコマンドラインを解析するこのすべてのロジックをプログラムするには、何もする必要はありません。



  po::options_description desc("General options"); std::string task_type; desc.add_options() ("help,h", "Show help") ("type,t", po::value<std::string>(&task_type), "Select task: train, recognize, score") ; po::options_description train_desc("Train options"); train_desc.add_options() ("input,I", po::value<std::string>(), "Input .dat file") ("info,i", po::value<std::string>(), "Input .trn file") ("output,O", po::value<std::string>(), "Output parameters file .prs") ; po::options_description recognize_desc("Recognize options"); recognize_desc.add_options() ("input,I", po::value<std::vector<std::string> >(), "Input .dat file") ("params,p", po::value<std::string>(), "Input .prs file") ("output,O", po::value<std::string>(), "Output directory") ; po::options_description score_desc("Score options"); score_desc.add_options() ("ethanol,e", po::value<std::string>(), "Etalon .trn file") ("test,t", po::value<std::string>(), "Testing .trn file") ("output,O", po::value<std::string>(), "Output comparison file") ;
      
      





有効なコマンドライン引数の説明には、タイプに関する情報、それぞれの短い口頭の説明、およびグループ化が含まれます。 引数の型の変換をチェックすることにより、不正なデータの心配を最小限に抑えます。 短い説明を使用すると、情報を体系化し、コメントを実質的に回避できます。また、グループ化により、必須の引数をオプションの引数から分離できます。 特定の行を詳しく見てみましょう。



  ("input,I", po::value<std::string>(), "Input .dat file")
      
      





最初の引数は入力です。実際には、引数には2つのオプションがあります。inputは引数の長い名前、Iは短い(大文字と小文字が重要です)。 boost :: program_optionsの特性は、短い名前が常に1文字でなければならないことです(ただし、設定することはできません)。 コマンドラインでの長い名前の呼び出しは次のようになります。



  --input=train.dat
      
      





短い引数が渡され、一見読みにくいですが、私はそれを使用することを好みます:



  -Itrain.dat
      
      





2番目のパラメーターpo :: value <std :: string>()は、引数値(符号の後の部分)の形式を定義し、値が不要な場合は省略できます。 たとえば、次の呼び出しは同等です。



  recognizer --help recognizer -h
      
      





よく見ると、認識グループでは、入力引数のタイプが次のようになっています。



  po::value<std::vector<std::string> >()
      
      





std :: vector <std :: string>は、コマンドライン引数に複数回入力できることを意味します。つまり、この場合、一度に複数のファイルを認識できます。 例:



  recognizer --type=recognize -itest1.dat -itest2.dat -pbest.prs -O./
      
      





3番目の最後のパラメーターは説明です。 特に、レコグナイザーで最後の行を書いてから6か月後に何か他のものを数える必要がある場合、非常に便利なポイントです。 この場合、ヘルプ出力は次のようになります。



 me@my: ./recognizer -h General options: -h [ --help ] Show help -t [ --type ] arg Select task: train, recognize, score Train options: -I [ --input ] arg Input .dat file -i [ --info ] arg Input .trn file -O [ --output ] arg Output parameters file .prs Recognize options: -I [ --input ] arg Input .dat file -p [ --params ] arg Input .prs file -O [ --output ] arg Output directory Score options: -e [ --ethanol ] arg Etalon .trn file -t [ --test ] arg Testing .trn file -O [ --output ] arg Output comparison file
      
      





コマンドライン引数の解析に移りましょう。 最初に行うことは、認識エンジンが実行するタスクを見つけることです。



  namespace po = boost::program_options; po::variables_map vm; po::parsed_options parsed = po::command_line_parser(ac, av).options(desc).allow_unregistered().run(); po::store(parsed, vm); po::notify(vm);
      
      





引数テンプレートとして一般オプションのみを渡します。 allow_unregistered boostへの呼び出しなしでは、program_optionsはテンプレートに記述されていない追加の引数を誓います。この引数には操作とヘルプのタイプのみが含まれます。 このコードを実行すると、task_type変数が設定され、「switch」と書くことができます。



  if(task_type == "train") { desc.add(train_desc); po::store(po::parse_command_line(ac,av,desc), vm); train(vm); } else if(task_type == "recognize") { //... else { desc.add(train_desc).add(recognize_desc).add(score_desc); std::cout << desc << std::endl; }
      
      





適切なグループがテンプレートに追加され、コマンドライン引数が例外なく完全に解析されます。 vm変数は、文字列キーとboost :: anyを値として持つ辞書です。 ご覧のとおり、ヘルプはほとんど無料です。



結果のディクショナリから値を取得する方法を理解するために、train(vm)プロシージャを詳しく見てみましょう。



  void train(const po::variables_map& vm) { std::string input_path, info_path, output_path; if (vm.count("input")) { input_path = vm["input"].as<std::string>(); } if(vm.count("info")) { info_path = vm["info"].as<std::string>(); } if(vm.count("output")) { output_path = vm["output"].as<std::string>(); } //... }
      
      





ご覧のとおり、すべてが単純ですが、引数は説明で渡される行ではなく、 フルネームでアクセスする必要があることに注意してください。 「info、i」と単に「info」を比較します。



おわりに



サンプルの完全版はpastebinにあります。 これはライブラリのすべての機能ではありませんが、すでに真ん中に興味がある人は公式ドキュメントを読みに行きました。



利点:



短所:




All Articles