Erlangでリスト操作(map, filter, foldl等)
今、時間があるときにErlangを触っているのだけれど、関数型デザインの言語だけあってリスト操作の関数が充実している。そこで、Erlangのリスト操作関数の内、よく使いそうなものを以下にリストアップしてみた。
map
リストの各値に関数を適用した新しいリストを返す。
map_test() -> L1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], AddOne = fun(X) -> X + 1 end, lists:map(AddOne, L1).
filter
リストの各値をフィルターしたリストを返す。
filter_test() -> L1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], IsEven = fun(X) -> X rem 2 == 0 end, lists:filter(IsEven, L1).
fold
リストの各値を畳み込んだ値を返す。リストの左から計算するか右から計算するかによってfoldlとfoldrがある。
fold_test() -> L1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], Add = fun(Acc, X) -> Acc + X end, lists:foldl(Add, 0, L1).
zip
2つのリストを合体させる。下の例だと[{1, 11}, {2, 12}, ...]のようなタプルが入ったリストになる。
zip_test() -> L1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], L2 = lists:map(fun(X) -> X + 10 end, L1), lists:zip(L1, L2).
flatten
ネストされたリストからネストのないリストを作る。
flatten_test() -> L1 = [1, 2, 3, [4, 5, 6], 7, 8, 9, 10], lists:flatten(L1).
flatmap
値からリストを作る関数を受け取り、それを引数のリストの値に対して適用してから、flattenする。下の例だと[1,1,1,2,2,2,...]のように返る。
flatmap_test() -> L1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lists:flatmap(fun(X) -> [X, X, X] end, L1).
takewhile, drop while
takewhileは比較関数がtrueまでの値の入ったリストを返す。drop whileはその逆。
takewhile_test() -> L1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], IsLess5 = fun(X) -> X < 5 end, lists:takewhile(IsLess5, L1).
dropwhile_test() -> L1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], IsLess5 = fun(X) -> X < 5 end, lists:dropwhile(IsLess5, L1).
partition
比較関数でリストを分割する。
partition_test() -> L1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], IsLess5 = fun(X) -> X < 5 end, lists:partition(IsLess5, L1).
merge
二つのリストをソートして合体させる。merge/3はソートに用いる比較関数を引数に取れる。
merge_test() -> L1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], L2 = lists:map(fun(X) -> X + 10 end, L1), lists:merge(L1, L2).
JSだとunderscoreとかを使わなきゃいけないことも組み込みで入っていて便利。
Ubuntu 16.04でcaps lockをCtrlに変更
どおりに。
- gnome-tweak-toolをインストール
sudo apt-get install gnome-tweak-tool
tweak toolを起動
Typings -> Caps Lock Key behavio -> MakeCaps Lock an additional Ctrl
かんたん。
(ちなみにTyping -> Alt / Win key behavior -> Alt is mapped to Win keysでaltとwinを交換できたりする)
- 出版社/メーカー: 東プレ
- 発売日: 2006/02/25
- メディア: Personal Computers
- 購入: 14人 クリック: 732回
- この商品を含むブログ (61件) を見る
机の上においたボタンを押すとリアルタイムでSlack上に寿司を食べたいことを通知できるシステムを構築した
机の上においたボタンを押すとSlack上に寿司を食べたいことを通知できるシステムを構築した。
動機
寿司を食べたい時にそれをSlackで報告するためわざわざキーボードに手を伸ばすのは非常に面倒である。机の上に専用のスイッチがありそれを押すだけで寿司が食べたいことを通知できれば非常に素晴らしいユーザー体験が得られるはずだ。昔遊んでいたArduinoが家にあったので、それとSlackを組み合わせることでシステムを構築していく。
作り方
Arduino側
100均に行ってボタンっぽいものを購入する。
スイッチ式のシーリングライトがあったので流用。ライトなので押すと光る。
(光る)
気合で内部のスイッチを見つけ出して配線。
内部を開けるとこんなかんじになっていた。緑と黄色のリード線は自分で結線した。
適当に抵抗を繋いでやばい電流がArduinoにいかないようにする。 回路図を示したいところだが、そもそも100均ボタン側の回路が不明なのでプレッドボード側も勘で配線した。 とりあえず5Vを直接グラウンドに繋いではいけないことがわかった。
Arduinoにコードをデプロイ。
const int SWITCH = 2; void setup() { pinMode(SWITCH, INPUT); Serial.begin(9600); } void loop() { if (digitalRead(SWITCH) == HIGH) { Serial.print("1\n"); } else { Serial.print("0\n"); } delay(500); }
Arduinoに繋いでシリアルモニタでチェック。"1"と"0"がボタンに応じて出力されていればOK
。出てなかったら配線とか抵抗を見直す。
Python側
PySerialというモジュールがあるので、それをpipでインストール(Arduinoとの通信)。
こちらを参考にした。
slackwebというモジュールがあるので、それをpipでインストール(Slackとの通信)。
SlackのIncoming WebHookを用いた。異常に簡単にSlackにメッセージを流せる。
Slackにincoming webhook経由でpythonからメッセージをPOSTする - Qiita
コードはこちらを参考にした。 Incoming WebHookのURLは環境変数に格納し、実行時に読み込むようにした。
pythonを実行
import slackweb import os import serial import time url = os.environ["SLACK_OHA"] slack = slackweb.Slack(url=url) port = "/dev/cu.usbmodem1421" current_oha_state = False # ボード側は500ms間隔でserialにHIGH -> b"1", LOW -> b"0"を送信する with serial.Serial(port=port, baudrate=9600, timeout=1) as ser: while True: # time.sleep(0.1) flag = ser.readline() # switch ON if (bytes(b"0") in flag and not current_oha_state): current_oha_state = True print("oha") slack.notify(text="スシ食べたい🍣") # switch OFF elif (bytes(b"1") in flag and current_oha_state): current_oha_state = False print("otu") slack.notify(text="スシいらない🍣") print(flag, current_oha_state)
結果
とりあえずボタンをポチポチ押す。すると、
ほぼリアルタイムでこのようになる。ギリギリIoTの範疇に入る気がする。
これで快適に他人にスシを食べたいことを通知できるようになった。 会社のCTOがArduinoの無線モジュールを入手したようなので、それを使えばボタンをPCから独立させることも可能な気がする。未来っぽい。
最急降下法をPythonで実装した
関数x2 + xは、どうやら最小値がひとつだけ存在するらしい。どうしてもその値を知りたくなったので、最急降下法を使ってPythonでその値を求めてみた。
#!/usr/bin/env python # -*- coding: utf-8 -*- import random learning_late = 0.01 loop_max = 1000 def main(): initial = random.uniform(-10, 10) old = initial new = 0.0 for _ in range(1000): # 更新式 new = old - learning_late * diff_func(old) # 目的関数の値を確認 y = object_func(new) print(y) # 値を更新 old = new print(new, y) # 目的関数 def object_func(x): return x * x + x # x ^ 2 + x の微分 def diff_func(x): return 2 * x + 1 if __name__=='__main__': main()
これを実行すると、
# x、y (-0.5000000145792641, -0.24999999999999978)
と、xが-0.5付近の時に目的の関数が最小値となることがわかった。なるほどというかんじ。
- 作者: 中井悦司
- 出版社/メーカー: 技術評論社
- 発売日: 2015/10/17
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (1件) を見る
- 作者: 高村大也,奥村学
- 出版社/メーカー: コロナ社
- 発売日: 2010/07
- メディア: 単行本
- 購入: 13人 クリック: 235回
- この商品を含むブログ (41件) を見る
平方イコルスン『スペシャル』読んだ
平方イコルスン『スペシャル』読んだ。いかにも検索にひっかからなそうな書名であり、売る気が全くないかんじがうかがえる。 内容は、登下校時も授業中も常にヘルメットを被っている女子校生がいるのだけれど、好きな男の子に近づくと緊張してしまい、ヘルメットが少し頭から浮いてしまうというストーリである。帯に、『このマンガは優しさ100%で出来ています。』と記述されているので、もしかしたらそれらも全て作者の優しさのなせる技なのかもしれない。日常ほのぼのマンガです。
(こちらはレギュラーガソリンの匂いが大好きな女の子が陰謀によりハイオクの匂いを嗅がされ怒り狂っているコマです)
- 作者: 平方イコルスン
- 出版社/メーカー: リイド社
- 発売日: 2016/04/11
- メディア: コミック
- この商品を含むブログ (3件) を見る
- 作者: 平方イコルスン
- 出版社/メーカー: 白泉社
- 発売日: 2012/07/31
- メディア: コミック
- 購入: 5人 クリック: 92回
- この商品を含むブログ (29件) を見る
- 作者: 平方イコルスン
- 出版社/メーカー: 白泉社
- 発売日: 2015/04/27
- メディア: コミック
- この商品を含むブログ (6件) を見る