情報通信系学生の勉強メモ

勉強したことを書いていきます

プログラミングの話とおまけ

最近...

最近私が使用している言語はc++だ。c++は難しくて、提供されている機能を100%使えているとは言い難いが、better cのような感じで使用している。 いつも動的型付けのpythonしか使ってなかった私にとっては、autoとイテレータは便利である。

クソ長い型の名前(○○::iteratorとか)をautoと書き込むだけで済むのだから素晴らしい。

またRも研究の時にたまに使用している、データフレームで一気に計算出来る点が利点である。少し速度に不安があるが他の言語と選択しながらの使用である。

実行速度の早い言語とスクリプト言語を一個使えたらプログラマーにならない限り困らないんじゃないかと考えている。

話は変わるが

私の株の株価が年末から10%以上下がっている。中国経済原則の懸念や産油国日本株を売りまくったせいだ。悲しい。

というわけでそのうち変動の少ない外国株を買おうかと悩んでいる。為替のこともあるので慎重に買わなければ・・・!

nhkの話

先週、夜8時くらいにnhkの女が来た。
なんの用かと思ったら、nhkの契約の催促に来たらしい。
テレビは家にない、と答えると、次はどこのキャリアを使っているか質問してきた。
おそらく僕の持っているスマホワンセグ対応しているかどうかということを聞き出すための質問だったのだろう。
僕はsimフリーのzenfone2でocnと契約していて、回線はドコモでもキャリア(通信事業者)ならocnと答えればいいかなと思い、「ocnと契約しています。」と答えたら、その女は僕を馬鹿にしたかのように笑いだし、どこの会社と契約しているのか、と言い直した。一瞬頭の中がはてなマークで一杯になったが、もしかしてこいつはmvnoを知らないんじゃないか?と思った。そして僕は同じように「ocnです。」と答えると女は諦めたかのように次の質問に移った。
その後も適当に答えて、nhkの女には帰って貰ったが僕には不快感が残ったままだった。

つまりこの女は、今時ニュースや新聞を読んでればmvnoなんて知ってても当然なのに、自分が情弱なのを理解せずに、僕を情弱扱いしたのだ、とんでもない女である。
無知というのは恐ろしい。
だいたい8時に訪問してくること自体考えられない。nhkのことをますます嫌いになりました。

erlangでのプロセスの使い方

プロセスとは

まず初めにプロセスとは、1つのプログラムのことをいいます。このプロセスがクラッシュするとまずいので、共有しない単独アサインロックを避ける、などの安全策がerlangには用意されています。 erlangのプロセスは他の言語でいうスレッドに近いものであり、非常に軽量。

他の言語だとメモリを共有しているものもあるようで、並行処理への評判が悪い言語もあるようです。 研究から同期処理より非同期処理の方が良さそうだとわかって来たのでerlangでは非同期アクターモデルを実装しています。

実装

erlangでは大変なことはすべてvmが面倒を見てくれるので、並列化が容易になっています。2つ目のコアを追加すれば速さ2倍、4コアなら4倍早い。速度の向上とコア数/プロセッサ数の関係を線形のスケールといいます。

どこを並列にするか

erlangは大量のデータを伴う数値計算アルゴリズムの分野は得意ではないです。チャットサーバ、Webサーバー、電話スイッチのような個別のものに並列化は使えます。ただし、どんなに並列化しても、直列の操作で一番遅いものより速くなることはない。この原理を一般化したのがアムダールの法則 です。

実際にプロセスを作ってみる

プロセスは単なる関数に過ぎない、関数を実行し、実行が終わったらプロセスは消えるだけです。

F = fun() -> 2 + 2 end.
spawn(F).

このコードを実行するとプロセス識別子が返ってきます、pidと呼ばれているやつです。 計算結果である返り値は返ってきません。プロセスは返り値を返さないからです。ここでは無名関数ですがspawnに関数を渡してあげれば、渡した関数が実行されます。

メッセージの送受信

  • メッセージの送信
self() ! hi.

erlangのシェルもプロセスから出来ています。self()の返り値はerlangシェルのpidです。 !は演算子でbangシンボルといいます。左辺はpid、右辺は送信するerlang項で、返り値も送信したerlang項です、つまりここでの返り値は hi です。

self() ! self() ! double.

これはself() ! ( self() ! double )と同じです。右から順に double が送信されるのでシェルには二回doubleが送られることになります。 また、flush関数を使うと受信したメッセージを見れます。

  • メッセージの受信

receive式を知らなければメッセージの受信は出来ません、receive文はcase of文と同じ用に、受信したメッセージを変数に束縛します。

receive文ではガードも使えます。receive文がある関数をspawn/3に渡すとプロセスはreceive文のところでメッセージを受信するまで待機します。メッセージを受信したらあとはreceive文のパターンマッチに従って実行されます。

 

receive文を使ったプロセス

bookshelves(BookList) ->
  receive
    {From, {store,Book}} ->
        From ! {self(),ok},
        bookshelves([Book|BookList]);
    {From, {take,Book}} ->
        case lists:member(Book,BookList) of
            true ->
                From ! {self(),{ok,Book}},
                lists:delete(Book,BookList);
            false ->
                From ! {self(), nothing},
                bookshelves(BookList)
        end;
    terminate ->
        ok
  end.

本棚を表す関数を書いてみました。この関数は本棚に本を置くことと、本棚から取り出すことしか出来ません。 それぞれのガードの後に再帰させているのはプロセスが常にメッセージを受け取れるようにするためです。再帰させなかったらそのままプロセスは終了してしまいます。

また、プロセスを終了させたい時はterminateを送信するとプロセスは終了するようになっています。 下記にシェル内での実行結果を書きます。

Eshell V7.0  (abort with ^G)
1> c(kitchen).
{ok,kitchen}
2> Pid = spawn(kitchen , bookshelves , [[math_book]]).
<0.40.0>
3> Pid ! {self(), {store, sugoi_erlang}}.
{<0.33.0>,{store,sugoi_erlang}}
4> Pid ! {self(), {take, sugoi_erlang}}.
{<0.33.0>,{take,sugoi_erlang}}

storeでsugoi_erlangという本を置いて、その後takeで取り出しているのがわかると思います。

python3.5

新機能

注目すべき機能としては行列演算とコルーチン、type hint(型アノテーション)ですかね 。 公式サイトを見ると、以下のようになってます。

PEP 465 , a new matrix multiplication operator
PEP 461 , %-formatting for binary strings
PEP 471 , os.scandir()
PEP 479 , change StopIteration handling inside generators
PEP 441 , improved Python zip application support
PEP 448 , additional unpacking generalizations
PEP 486 , make the Python Launcher aware of virtual environments
PEP 475 , retrying system calls that fail with EINTR
PEP 492 , coroutines with async and await syntax
PEP 488 , elimination of PYO files
PEP 484 , type hints
PEP 489 , redesigning extension module loading
PEP 485 , math.isclose(), a function for testing approximate equality

https://www.python.org/downloads/release/python-350b2/

PEPを見ると、@演算子はデコレーターで使われちゃってるけど、デコレーターはステートメントの最初でしか使われないから大丈夫でしょ、みたいなこと書かれてました。
コルーチンは非同期処理で使われるみたいです。(コルーチンの使い方わかってないので後で勉強してきます・・・・ )

誤差の検定

PEP485では誤差の検定?を導入するようです。多分統計に関連する話なんですが、統計知らない人は「2つの値がどれだけ近い」か調べてると思っていいんじゃないでしょうか。僕は統計かじっただけです^^;
以下が関数です。

isclose(a, b, rel_tol=1e-9, abs_tol=0.0)

  • a,b:テストする値です。
  • rel_tol:比較誤差つまり誤差の許容範囲です。rel_tolが0.05だったら5%になります。小さければ小さいほど、Trueになる二つの値の絶対値の制限が厳しくなります。rel_tolのデフォルト値は1e9です。

  • abs_tol:許容範囲の最小絶対値。デフォルトは0.0です。

細部まで読んでませんが返り値は多分TrueかFalseでしょう

おわり

僕も統計の講義でpython使ってますが、行列を統計や数学で使う人も多いでしょうから、行列の演算子が新しく加わったのは嬉しいんじゃないんでしょうか。
今までpython3系に移行しても迷ってた人もそろそろ移行してもいい頃合いですかね、python2系には当然新機能は来ませんしね。
僕もpython3.5系から面白そうな機能が増えるのでこれを気にpython3系をメインに使っていこうかな。

※python3系でipython使うとTABで補完されなくなる原因誰か教えてください;;

erlangで逆ポーランド記法

すごいerlangという本に沿って勉強しています。

ブログに勉強したことをまとめれば自分の助けになるかなと思いブログを始めることにしました。

 

本を8章まで読んだのですが、erlang逆ポーランド記法を計算させるコードの練習問題をやってみました。

gist3ad2e7d677d25998cf21

rpn:calc("2 4 3 + +")みたいな感じで実行すると空白毎に読み込んで逆ポーランド記法の手順で計算してくれます。

逆ポーランド記法の計算手順はスタックのようになっているので簡単です。数字が読み込まれたらスタックに置いて、演算子や関数が来たらスタック上の数字を作用させるだけです(言葉の使い方間違ってるかも笑)

練習としてサンプルのコードに加えてsumとprogの計算を追加してみました。progというのは僕も初めて聞きましたが数学でいう大文字のπみたいなものです。数字を全部掛ければいいみたいです。

 

関数型のプログラミングは難しいですが、数学のように表すことが出来るので面白いですね。erlangは日本で使ってる人が少ない言語ですが、めげずに頑張りたいです^^;