2015年12月29日火曜日

Clingの助けを借りて、その数式をプログラムしてみる

その数式、プログラムできますか?


この書籍を最近読み始めました。
 
 数学的な課題を題材に、公式や定理が考案された歴史的背景や、解法を編み出した人物像と共に解説し、そしてそれを実際のコードに落とし込む場合どうなるかというのを、段階的に思考過程を示しながら、サンプルコードとともに示されています。
 なかなか面白い本だと思います。
 ただ、内容が自分には難しすぎて、実際にサンプルを入力しながら読み進めていかないとついて行くのがなかなか厳しい。さらに、サンプルコードはC++11を前提としており、手元のプライベートなMacbookAirには手軽に使える開発環境がありません。
 気合いで標準導入されたGCCを使うとか、Objective-Cに変換しながらコーディングしてみても良いですが、書籍のサンプルコードは、せいぜい数十行で、関数も単一のものが大半です。気合いを入れたり、統合開発環境をいちいち立ち上げたりなどは少し大げさな感じです。もう少し手軽にサンプルコードを試せる環境が欲しいところです。
 
 PythonではIPythonのようなREPLを使えば、その場その場で思い付いたコードを試す事ができます。この手軽さが理想。C++版のREPLがほしいところです。
 そして有り難い事に、ClingというREPLおよびインタプリタを、CERNが公開していました。CERNは大型ハドロン衝突型加速器で有名なあのCERNです。早速導入してみます。

 

Clingの導入

Clingの導入は、ソースをgit cloneし、Buildする事で行います。Buildには、CERNが提供するBuildScriptを使う方法の他、CMakeやconfigure+Makeを使って手動でBuildする方法があります。

<導入手順(英文)>
https://root.cern.ch/cling-build-instructions
 
 今回は、手元のmac環境にもともとCMakeが導入されていたので、CMakeを使って手動でBuildしてみました。
 英文が読める方は、手順の通り実施すれば多くの場合は問題ないかと思いますが、手動Buildでハマりました。Windowsであるのと、個人的にうっかりミスを誘う記載があり、余分な時間を使った箇所があったので、そのあたりを踏まえた手順を述べたいと思います。
 なお、Clangを全てソースからビルドするので、かなり時間が掛かります。他の作業と並行するなど、時間的な余裕をもっての実施をおすすめします。

 

ソースのビルド

導入するディレクトリを任意の名称(仮に/Users/<login-acount名>/clingとします)で作成した後、まず、CERNのgitからソースをCloneします。リンクの手順(Manual Build)の記載に従い、下記のコマンドを実行します。

<Building with CMake>
git clone http://root.cern.ch/git/llvm.git src
cd src
git checkout cling-patches
cd tools
git clone http://root.cern.ch/git/cling.git
git clone http://root.cern.ch/git/clang.git
cd clang
git checkout cling-patches
cd .. 
 
さて、原文だと最後のcd ..で1階層上にカレントディレクトリを移動していますが、なぜこの操作が記載されているのか良くわかりません。ここは正しくは、「clangを1階層上に登る」ではなく、「最初に作ったディレクトリ配下に移動」が正しいです。ですので、もう2段上にカレントディレクトリを移動しましょう。


cd ..
 
cd ..
pwd (※Windowsでは単にcd)
(pwdの結果)/Users/<login-acount名>/cling
 

 以下のコマンドを実行していきましょう。

mkdir build
cd build
cmake -DCMAKE_INSTALL_PREFIX=[Install Path] ..\src
3行目のコマンドについて、..\src の記載箇所にちょっとした注意が必要です。

cmake -DCMAKE_INSTALL_PREFIX=[Install Path] ..\src

 ..\src はCloneしたソースコード相対パスを示していますが、cernのページはWindowsを前提としているので、バックスラッシュつまり日本語OSでの¥マークであり、一方macなどではバックスラッシュではなく、ただのスラッシュでなければなりません。

<macでのcmakeコマンド実行>
cmake -DCMAKE_INSTALL_PREFIX=[Install Path] ../src

 最初のcmakeの処理が終わったら、以下のコマンドを順次実行していきましょう。
cmake --build . --config [Release/Debug] --target clang
cmake --build . --config [Release/Debug] --target cling
 (※このあたりに時間が掛かります。のんびり待ちましょう)

 全ての手順が終わったら、ビルド後のbinディレクトリに移動して、clingコマンドを実行してみましょう。

cd bin
./cling (※Windowsでは単にcling)

****************** CLING ******************
* Type C++ code and press enter to run it *
*             Type .q to exit             *
*******************************************
[cling]$

 clingの対話式コマンド入力モードになっていれば、導入は成功です。対話モードが不要になった時は.qと入れれば、解除されます。

 

Clingを使った最初の操作

Clingで導入されたClangはC++11対応という事なので、lamdaがつかえます。
 lamda式のコードとともに簡単な操作を行ってみます。必要に応じてclingコマンドを実行し対話モードにしてください。

./cling (※Windowsでは単にcling)
****************** CLING ******************
* Type C++ code and press enter to run it *
*             Type .q to exit             *
*******************************************
[cling]$ #include <stdio.h>
[cling]$ auto f = []{printf("Hello, CLing\n"); };
[cling]$ f()
Hello, CLing
REPL風に、includeからlamdaで記載された関数の定義と、その実行まで順次対話的に入力していきます。入力ミスによるエラーがあっても、行を確定した時点でフィードバックがあるので、再度入力しなおせば、最終的には実行が成功する事になります。

 

サンプルの実行

書籍「その数式、プログラムできますか?」から、足し算のみによってかけ算を実現する「エジプト乗法」というアルゴリズムのコードをサンプルとして、入力から実行までを行ってみます。
 下記のようなコードを入力してみます。 (コードは実際の書籍からアレンジしてます)
auto odd = [](int n)-> bool { return n & 0x1; }
auto half = [](int n)-> int { return n >> 1; }
int mult_acc4(int r, int n, int a) {
    while (true) {
         if (odd(n)) {
             r = r + a;
             if (n == 1) return r;
         }
         n = half(n);
         a = a + a;
     }
}

int multiply4(int n, int a) {
     while (!odd(n)) {
         a = a + a;
         n = half(n);
     }
     if (n == 1) return a;
     return mult_acc4(a, half(n -1), a + a);
コードを入力し、実行してみましょう。
 なお、途中出てくる.rawInputというのは、複数行からなる関数などを書く場合につかいます。行毎にコンパイルしないようにclingに指示するコマンドです。

./cling (※Windowsでは単にcling)
****************** CLING ******************
* Type C++ code and press enter to run it *
*             Type .q to exit             *
*******************************************
[cling]$ auto odd = [](int n)-> bool { return n & 0x1; }
((lambda) &) @0x108afcb30
[cling]$ auto half = [](int n)-> int { return n >> 1; }
((lambda) &) @0x108afcbb0
[cling]$ .rawInput
Using raw input
[cling]! int mult_acc4(int r, int n, int a) {
[cling]! ? while (true) {
[cling]! ?     if (odd(n)) {
[cling]! ?         r = r + a;
[cling]! ?         if (n == 1) return r;
[cling]! ?         }
[cling]! ?     n = half(n);
[cling]! ?     a = a + a;
[cling]! ?     }
[cling]! ? }
[cling]! int multiply4(int n, int a) {
[cling]! ? while (!odd(n)) {
[cling]! ?     a = a + a;
[cling]! ?     n = half(n);
[cling]! ?     }
[cling]! ? if (n == 1) return a;
[cling]! ? return mult_acc4(a, half(n -1), a + a);
[cling]! ? }
[cling]! .rawInput
Not using raw input
 
[cling]$ multiply4(6,80)
(int) 480
[cling]$ multiply4(78,80)
(int) 6240
 
 

 無事、実行できました。Enjoy!

2015年12月12日土曜日

Python mini Hack-a-thonに参加しました

第59回Python mini Hack-a-thonに参加させていただいた。

 Python全くの初心者で有りながら、miniとは言え、まがりなりにもハッカソンと名の付くイベントに無謀にも参加した感想を述べたいと思います。

 まず、第一印象として、参加者全員がOpen Mindで、昨今の技術動向や業務上の相談事など、わりとフランクに話し合われていた。日本もここまで来た。(?)
 こう言う議論が交わされる場があるというのが、IT勉強会の良いところ。貴重な情報収集の機会になります。 

 本題のハッカソンですが、初心者とはいえ、JavaやCのほか、開発のベテランと自負している手前、開発の基本として何よりもまずはTestFirstの実現だ、とばかりに、Unittest2を意気揚々とpipインストール。

 しかしすでにここが間違い。エラーが出る原因を聞いてみたら、今回使用しているPython3.5環境には、既にUnittestがバンドルされているとの指摘。さらにUnitest2は、Python3.2で組みこまれたUnittestをPython2で使用できるようにしたパッケージライブラリであり、Python3.5で動作させようとすること自体が間違い。要は、全面的に間違っていました。
 すかさず、pip uninstall unittest2でアンインストール。追加パッケージを入れずともUnitTestのアサーションはしっかり動きます。最近になって初めてPythonを学習する人は、Python3から始める事も多いかと思います。ただPython2も未だに現役であって、Webの情報もPython2を前提として記載されているケースが多いかもしれません。Python2とPython3の差異がどの程度あるか把握しておいた方が、それぞれどのバージョンについての情報かといった点を切り分けられて、今後の学習でハマる要因を取り除けるので効果的かもしれません。

 その後も、度重なるヘマをしながら、BeautifulSoupとRequestsといったライブラリを使用して、Webスクレイピングの簡単な例をどうにか作って、LTで発表させていただきました。

  個人的に、新しい言語を覚えるには、まずその言語の文字編集処理を学習する事から入るというスタイルを取る事が多いですが、Webスクレイピングでは文字列の部分抽出や検索などを駆使する点から、学習の初め方としては良かったように思います。

 Pythonを使いこなす為に、今後もイベントに参加するなりを続けたい次第です。

2015年11月7日土曜日

セキュアプログラミング開発セミナに参加しました

「リスクに紐付く脆弱性のタイプを見てみる〜ソースから見る脆弱性問題点の把握〜」 こちらに参加しました。
 今日のテーマは、Webアプリケーションのセキュリティに関する脆弱性を如何にして特定するかという内容です。

 なかなか良かったです。
 普段は社内システム向けのプロダクトの開発しかしてないのですが、クラウド環境化の波はどんどん押し寄せます。オンプレミスな環境に対応するだけでは済まない状況であり、セキュアプログラミング開発の知見を得る必要性を感じての参加です。

 
  今日のセミナでは、セキュリティ各種団体の概要の説明、脆弱性の具体例、プロダクト開発者がなぜセキュリティの全体像を知る必要があるのか、といった点について話題が挙がりました。
 共通脆弱性タイプ一覧CWEによって、典型的なプログラム脆弱性のパターンを確認・学習する事ができる点についても説明がありました。
 問題に発展しそうな脆弱性について、普段の調査ではCWEサイトをスポット的に見る機会はありました。しかし、なにしろグローバルな英語サイトなので、英文を読むのがつらくなって、すぐにページから退散する事が多かったです。
 しかしもう少しだけ細かく見ていくと、脆弱性のある不適合コードや、実際の問題事象のサンプルといった情報が豊富に存在しており、セキュリティに関する知見を得られるサイトだったのでした。今日初めて知りました。
 実現しようとする機能には、どのような脆弱性を組みこむ危険性が潜んでいるのか、といった観点からリスク要因を事前に予期・認識できたなら、適切な対処ができます。
 その点で、あらゆる脆弱性パターンの概要を体系だてて理解しておく事は重要です。

 普段からセキュアプログラミングの知識を得ようとする心がけは、プロダクトの品質を高めるだけでなく、プロジェクトを成功に導く為のリスクヘッジとして意義があると感じました。

 今後も定期的に勉強会に参加していきたいと思う次第です。