カマカマの雑草ブログ

個人の日記です

ごーるでんうぃーく1日目

メガごーるでんうぃーくらしいので毎日雑に書きます。

今日は家事やって髪切って後はずっとuGUIでAndroidで言うListViewの実装を写経をしてた。

ずっと積んでたこれの電子書籍版。

uGUIではじめるUnity UIデザインの教科書

uGUIではじめるUnity UIデザインの教科書

モチベーション

普段の仕事がAndroidでの開発で、ListView & Adapterのお世話になることが多い。
AndroidのListViewではListの中の各要素であるCellが画面外に出た時に、これまで表示で利用していたCellのViewが再利用される。
これはいちいち各CellのViewを生成していると、メモリを圧迫して大変なことになるのを防ぐためだった。

Unityその辺どうなってるのかなーとか思いつつuGUI流し読みしてたら、どうやら自分で作る必要がありそうだったので写経しつつどういう考えでやってるのかが知りたかった。 ちなみに苦労したくなかったらReusableなTSTableViewというのがアセットストアにある。

Asset Store

とりあえず動かしてみて

Cellがどのデータに対応するかのIndex、表示中のCellの連結リストを弄っているだけでも、描画位置の計算とかが入ってくるだけで結構しんどかった。
おそらく自分が慣れていないだけだが、UIパーツの実装はドメイン層の実装とは異なる感覚が必要そう。
慣れてきたらもうちょい区画整理できないか思案してみる。

UnityちゃんADVアセットとかあるので、最終的にチャットっぽい画面作れるといいですね。

追記

そういやHHKB手入れしてたの忘れてた。

scaffoldから学ぶあるコードの間にgenerateしたコードを注入する考え方

目的

自動生成したコードを既存のコードの末尾に追記ではなく、ある一定の判断基準をもって既存のコードの間に注入したいときにどういう考え方でやるのかが知りたい。

rails generate scaffoldから見る

railsだとgenerate系が充実しててtutorialではまずこれを使ってmodelを作ってみましょうという流れがある。

$ rails generate scaffold Micropost content:string user_id:integer
      invoke  active_record
      create    db/migrate/20160401165016_create_microposts.rb
      create    app/models/micropost.rb
      invoke    test_unit
      create      test/models/micropost_test.rb
      create      test/fixtures/microposts.yml
      invoke  resource_route
       route    resources :microposts
      invoke  scaffold_controller
      create    app/controllers/microposts_controller.rb
      invoke    erb
      create      app/views/microposts
      create      app/views/microposts/index.html.erb
      create      app/views/microposts/edit.html.erb
      create      app/views/microposts/show.html.erb
      create      app/views/microposts/new.html.erb
      create      app/views/microposts/_form.html.erb
      invoke    test_unit
      create      test/controllers/microposts_controller_test.rb
      invoke    helper
      create      app/helpers/microposts_helper.rb
      invoke      test_unit
      invoke    jbuilder
      create      app/views/microposts/index.json.jbuilder
      create      app/views/microposts/show.json.jbuilder
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/microposts.coffee
      invoke    scss
      create      app/assets/stylesheets/microposts.scss
      invoke  scss
   identical    app/assets/stylesheets/scaffolds.scss

ここのinvoke resource_routeのroute resources: microposts実行されると 以下のようにconfig/routes.rbのイイカンジの所に自動的にinjectされる。

Rails.application.routes.draw do
  resources :microposts  # <- inject at this point
  
  # Other codes
end

というわけで、どういう考え方でこれをやってるのかが知りたくなった。

code reading

invoke resource_routeの瞬間に実行されているのは以下
https://github.com/rails/rails/blob/master/railties/lib/rails/generators/rails/resource_route/resource_route_generator.rb#L15-L35

ここで生成したroute_stringから不要なスペースや改行コードを弾いてrouteへ渡している。此処が肝っぽい
https://github.com/rails/rails/blob/master/railties/lib/rails/generators/actions.rb#L236-L246

基準地点を正規表現としてルーチンの中で保持しておいて(ここでは/.routes.draw do\s*\n/m)、その基準地点の後のところにrouting_codeを差し込んでいる。 この実際の処理をしているinject_into_fileはThorというself-documenting command line utilities向けのライブラリの機能で、与えられたパスのファイルに対してdataをconfigのルールに従って注入できる。 似た機能で正規表現置換をするgsub_fileがあるらしいけど、そっちと違ってこれは元に戻せる仕組みらしい。
Method: Thor::Actions#inject_into_file — Documentation for wycats/thor (master)

Applying "Design by Contract" を読んだ

読んだやつ

Applying Design by ContractでGoogle検索して一番上に出てくるPDF

TL; DR

  • OOPについてのソフトウェアの信頼性を改善するための方法論の一つ
  • 信頼性はソフトウェアを作る上でしばしば考えるテーマ
  • 信頼性を確保するための方法としてよく"防御的プログラミング"が挙げられる
    • NPEを過剰に恐れてのif (concrete != null) とか
  • これは本来不要なコードを増やしてソフトウェアの複雑性を増すので再考の余地がある
  • 契約という考え方をソフトウェアに適用してシンプルにしてみる
  • 何かしらのタスクの実行が他のサブタスクと関連する時、呼び出し側と呼び出される側の関係をきちんと規定する
  • 各ルーチンを作るときには"precondition (事前条件)" と "postcondition (事後条件)" を含めるのが大事
    • Eiffelだと言語レベルでサポートしてるっぽい。よく論文内で出てくる
    • Eiffel - Wikipedia
  • preconditionはルーチンが正しく安全に動作するために必要な条件を示す
    • 例えば、ある木構造データに対して新たにノードを追加するput_child(new)があったとして、newはnullじゃダメですよーみたいな感じ
  • "特別なケース"(↑の例ならnewがnullなら別の処理をしたいなど)は事前条件に含める
  • preconditionの違反は呼び出し側の実装バグであることを示している
  • postconditionの違反は呼び出される側の実装バグであることを示している
  • こうしたconditionsを前提としてソフトウェアを組み上げることで不要なテストの作成を減らす
  • まあでもpreconditionもpostconditionもOOPに限った話じゃないよね
  • OOPなら"class invariants (クラスの不変性)"を考えると良さげ
  • 特定のルーチン処理を超えて全てのクラスインスタンスに適用できる不変的なプロパティ
    • 例えば、ある木構造データであるノードcurrentを基準にその左ノードがnullでないとき、左ノードのparentプロパティは暗黙的にcurrentであるみたいな感じ
  • この不変性は常に保たれている必要がある
    • クラス生成時、クラスの受け持つルーチンの実行時など、またこれに限らないall provisions of the XXX code
  • あるルーチンが継承によって拡張される場合はpreconditionはより広く、postconditionはより厳しくあるべきだとしている
    • Aのpre, postに対して、Aを継承したBのpreconditionは「original precondition or new precondition」postconditionは「original postcondition and new postcondition」の論理式が真である必要がある
    • 継承元のassertionsについては保持するべき(preconditionなら守るべきとは言っていない
  • 継承元の不変性は継承先にも適用するべき
    • 不変性は子になるに従ってより強いものになるか親と同じになる
  • 例外処理も該当のルーチンが契約に基づいて設計されているのであれば"失敗"という概念を定義できる
    • ルーチンが契約を満たせなかった時に発生する
      • ハードウェアの不具合、実装上のバグ、外部からの期待しないイベントなど
  • 失敗したらやるのは以下のどれか
    • 再試行 (resumption)
    • 失敗を呼び出し元に伝える (organized panic)
  • Eiffelの例だとrescue句つかってる
    • この例のgetintは外部機能で、こちらでコントロール出来ないもの
    • 引数が不正な場合に例外を発生させる
    • この例をRubyで書くならたぶんこんな感じ
def get_integer_from_user(n)
  failures = 0

  begin
    result = getint(n)
  rescue
    failures = failures += 1
    if failures < 5 then
        puts "Input must be an integer. Please enter again: "
        retry
    end
  end
end

ぜんぜんTL; DRじゃない

Pictures of a reasonably documented yearsやった

ネタバレ注意。雑。気になる人はすぐ終わるからやってから見ましょう。

outlands.itch.io

やろうとしたきっかけ

  • 「いったい何が起きたのか」を突き止めるシチュエーションが好き
  • 雰囲気ゲー好き
  • PC漁るこういうのはやったことがなかったから気になった
  • プレイヤー(自分)の英語力はカス
  • プレイヤー(自分)のホラー耐性はカス

結果

  • 英語バカでも分かる不穏な文章で良い。こういうの好き。以下のやつは変なつながりになってるかもしんない。

    I don’t really know how to explain it, but I feel like I owe this town something.
    I feel like it's my mission to document what's.

  • フォルダ開こうとしたらノイズ音でビビる

  • BGMが早まる動悸っぽくてビビる
  • Getting crazy.vidファイルの字面の開きたくなさ
  • 半年過ぎた辺りでもうPC漁るの怖くて嫌になる
  • 年が終わるのが怖くなる

    Things are getting worse as we approach year end.

  • オチが厳しい
    • 公式のコメント欄見てようやく分かった
    • この手の慣れてる人&英語慣れてる人はすぐ合点がいくかもしれない
  • 音楽・サウンドエフェクトのインタラクティブ感ってこの手のジャンルのゲームすごい大事だと思った
  • 完全版がたのしみ

くる年

ぼちぼち社会人3年目に突入しそうなので、クソみたいな抱負を立てておく。

基礎をつける(特にこの辺が欲しい)

  • How toは今は要らない(必要になったらやる、で良いと思ってる)
  • ネットワークプログラミング
    • ソケット・プロトコルの知識
    • Remote Procedure Control
    • 同時接続・Latencyの対策
      • 子プロセス化とかI/O多重化とかそういうの
      • 遅延については関連する隠蔽・推測手法とか(Dead Reckoningみたいな)
  • "綺麗なコード"
  • 古典に学ぶ
  • 低レイヤにもちゃんと意識を向けましょう

体力とかバイタリティつける

  • ジム通い出したので続けたい
    • 健康は損なうと辛いので自分の心身に関しては悲観的にならないようにする
  • 通院が必要になったら面倒くさがらない

考える力つけましょう

  • 脳が壊死していて人生が浅い
    • 頭脳労働なのでせめて思考力みたいなものは欲しい
  • Inputが無いと薄っぺらくなるのでは
  • 取り敢えず読書の量増やしてみる
  • SNS中毒のケがあるので意識して減らしてみる

取り敢えず読んでる

オンラインゲームを支える技術  ??壮大なプレイ空間の舞台裏 (WEB+DB PRESS plus)

オンラインゲームを支える技術  ??壮大なプレイ空間の舞台裏 (WEB+DB PRESS plus)

Game Programming Patterns ソフトウェア開発の問題解決メニュー (impress top gear)

Game Programming Patterns ソフトウェア開発の問題解決メニュー (impress top gear)

今年もよろしくお願いします。

RaspberryPiを使ったIoT向けに汎用的に使えそうなやつ書いてる

MKomiya/Lugh · GitHub

前回のエントリーでRaspberry Piの環境作って、IoT的なことやりたくて多少は汎用的に使えそうなものをGoで書き始めた。
Goでやるメリットはそんなになかったのだけれど、サンプルがRubyだったから別の言語で書きたかったのと、GoでもSPI通信をサポートできるライブラリが転がってたのと、ちょうどA Tour of Goを終えた頃だったってのがある。
今はADコンバータで変換された照度センサ(NJL7502L)の値を受け取ってGoogle App ScriptへPOSTで投げてスプレッドシートにライトが点灯した時刻を書き込むところまでは出来ている。
基本的なMCP3002の変換はこちらを参考にした 

Raspberry Piで取得したセンサーデータをリアルタイムに可視化する(センサー編) | Milkcocoa Engineers' Blog

このために書いたGASのスクリプトは本当に酷いもので、POSTされたパラメータをそのまま書き込んでいるだけで、本来なら適切なValidationを行わなければならないのだけれど、javascriptが面倒くさくてそのままにしている。Request Validationを楽に実現する仕組みは一考の余地があるかもしれない。

Handler, Actionという形で、SPI通信によって得られたセンサーからの値を感知してActionの内容を実行する、という形で、ある程度は汎用的に使えそうなところへ落とし込もうとしている。

Raspberry Pi 2 Model B買った & セットアップ

IoT (Internet of Thingsの略) が周りで流行ってたりとか、ラズパイゼロが発表されたりとか、帰ってきた時にイオンが「あっ!おかえりなさーい」って言ってくれるような何かがあると嬉しいですねみたいな話を友人としたりして、前々から気になってたラズパイを衝動買いした。

尼じゃなくて秋葉まで行って諸々セットになってるやつを買った。起動ディスク付きだったので焼きこみ周りは省略してる。 セットアップどうしたかとかどの辺参考にしたかをまとめておく。

セットアップ

こちらを参考にやった。zshのみ設定せずそのままbashにしてある。

Raspberry Pi 2の初期設定 - nagashy’s diary

ssh-copy-idはMacならHomebrewで入る。

$ brew install ssh-copy-id

無線LAN

この辺りはルーターや環境に応じて違いが大きいと思うのであくまで参考程度に。
自分は親機: WHR-G301NにWPA-PSK-AESで繋いでいる。一番安いルーター買ってそのまんまなのでいい加減買い換えたい。
無線LAN子機はこれを買った。安価なのと消費電力が低め(参考: neuralassemblyのメモ: Raspberry Piの低消費電力化を目指した話)とのこと。

挿すだけでusb認識はしてくれる

pi@raspberrypi ~ $ lsusb
略
Bus 001 Device 004: ID 04bb:094c I-O Data Device, Inc.

設定ファイル周りはこんな感じに

# eth0は省略

allow-hotplug wlan0
iface wlan0 inet static
address 192.168.11.9 
netmask 255.255.255.0
gateway 192.168.11.1
wireless-essid #自分のssid
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
iface default inet dhcp
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
        ssid="106F3F051AEB-1"
        psk=略
}

今思うとavahi-daemon入ってるしstatic ipじゃなくても良かった。 ここのnetwork={}内はwpa_passphraseコマンドで暗号化したものが生成できる。

$ wpa-passphrase #自分のSSID #パスワード

ifdown, ifupでwlan0を再起動してinet addr来てBROADCAST RUNNINGになってればOK

参考

http://yamaryu0508.hatenablog.com/entry/2014/08/15/001312

GPIOでADコンバータ介してセンサーの値とる辺りが上手くいってないのでまたこんど。