なぜシン・ゴジラはナックルウォークを経ずして二足歩行を獲得することができたのか
(この記事は明確にシン・ゴジラのネタバレを含みますので、未視聴の方は閲覧しないでください)
はじめに
現生生物で二足歩行を行う生き物といえば、真っ先に鳥類が思い浮かぶが、その二足歩行の起源については恐竜にまで遡る。鳥類の起源は恐竜の中でも、多くの種が二足歩行をしていたとされる竜盤目獣脚類とされているからだ(これはティラノサウルスを含む群になる)。そして、彼らがどのようにして二足歩行を獲得したかについては、どうやら以下の論文に目を通したかぎりははっきりとした定説はなさそうだ。
https://www.dinosaur.pref.fukui.jp/archive/memoir/memoir010-055.pdf (恐竜の共通祖先は二足歩行だと思われていたが、実は四足歩行なのではないかという議論がされている)
さて、公開中の映画シン・ゴジラでは、獣脚類によく似た見た目のゴジラが、作中で二足歩行を獲得した。この二足歩行に至る描写がとてもすんなりと頭に入ってきたので、非常に感動した(もしかしたら元ネタがあるのかもしれないけれど)。つまり要約すると、ゴジラは前足が退化していたため、四足歩行することができず、地上では二足歩行せざるを得なかったのだ。
問題意識
まず、そもそもなぜこんな疑問が生じるかについて理解できない方もいるかと思われるので、問題を共有したい。例としてヒトを挙げる。問題は、「ヒトはどうやって(直立)二足歩行を獲得したのか」。その答えは、とてもざっくりと進化論を援用して言うと、「二足歩行可能な形質をもった個体がたまたま発生し、それがたまたまその環境で生き残ったから」となる。しかし、果たして四足歩行しているサルからいきなり二足歩行する生物が生まれるのだろうか。だとしたらなぜ二足歩行の哺乳類は珍しいのだろうか。そのような疑問に答える一つの方向性として、それらの進化の隔たりを埋める中間的な形質を持つ種が存在した、と仮定することができる。それは上記の文脈で言うと、ゴリラ等が行うナックルウォーク(拳をついて歩くこと)、ということになる。樹上生活を行っていたサルが、前足を枝を握るために用いるようになる。前足の形状は歩行には適さない。その中で地上に降りたもの(ゴリラ)が、前足を握り歩行するようになる。しかしそのナックルウォークだとあまりにも移動コストが高い。そのために、森が失われ歩行が優位になる環境では、直立二足歩行というナックルウォークに比べると移動コストの低い手段を用いることのできる生物が、新たな種として固定される。...果たしてこれが明快なストーリーだろうか? 二足歩行なんて不安定な移動法を取るくらいならナックルウォークのほうがましではないのか?(少し古い記事だが、http://sicambre.at.webry.info/200710/article_17.html ナックルウォークは直立二足歩行より後という内容もある)
https://www.youtube.com/watch?v=rVlhMGQgDkY
(近年見られる四足歩行から二足歩行への進化の例)
以上のように、二足歩行について少し考えるだけで頭が混乱してくるのだが、シン・ゴジラの中では二足歩行の獲得は明快に示される。なにしろ、視聴者の目の前で得体のしれない生き物がどんどん進化していくのだ。そして、地上にでてきたそれは当初、前足はひれ状になっており、後ろ足だけが発達している。移動方法は匍匐だ。そして物語は進み、ついに、その両足で立ち上がる。あのやたらと気持ち悪い謎の生物がやっと二足歩行を獲得したのだ。
ゴジラにおける二足歩行の獲得
ゴジラは二足歩行を獲得する順序において、匍匐→四足歩行→二足歩行という脊椎動物の王道を無視し、ひとつ飛ばしに匍匐→二足歩行という進化を遂げた。こここでの進化は、「すでに退化してしまった前足を歩行用に用いる」というオプションではなく、「すでに発達している後ろ足のみでの歩行」というオプションが用いられている。おかげで、匍匐から二足歩行への中間的な形質である四足歩行(ヒトの説明で言えばナックルウォーク)をスキップしている。これは明らかに、前足が退化していたおかげである。これは二足歩行を獲得する上で非常にスマートな回答のひとつだと自分は思う。シン・ゴジラ公開前に、自分は「このゴジラ前足がちっちゃい!前足がちっちゃい!」としか思っていなかったが、その伏線が回収された瞬間が、このゴジラ立ち上がりシーンだと言える。オットセイ、アシナシイモリ、ヘビ類等に準じた退化をし(有尾類のネオテニーが可能性が高いと睨んでいるが)、十分な歩行器官の無い生物だからこその、二足歩行の獲得。それを視聴者の前でやってのける映画力、さすがだ。この映画の95%ぐらいの面白さはここに詰まっている。
最後に
この記事はゴジラが四足歩行を獲得した生物(両生類や爬虫類)から進化した、という仮定にもとづき書かれているが、「単に魚から進化しただけでは?」というつっこみにはじまり、生物学的に不適切であることが確実なため(用語も適当、"中間的な形質"、とか、進化論ではなんていうんだろう?)、不備については順次指摘されたい。また、「どうしておばあちゃんのお口はそんなに大きいの?」「それはお前を食べるためだよ」的な考察(たぶんビルで視界が塞がれるから立ち上がったんだと思うが)もしていないので、そちらについても気になっていることではある。ゴジラの二足歩行に対して専門的な意見を持っている方がもしおられれば、随時ネット上に関連記事をアップしていただけると非常にありがたい。
zsh + pretzoでdocker-composeの補完
curl -L https://raw.githubusercontent.com/docker/compose/$(docker-compose version --short)/contrib/completion/zsh/_docker-compose > ~/.zprezto/modules/completion/external/src/_docker-compose
以上です。
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件) を見る