Androidアプリ開発に入門してみた

サーバサイドのアプリケーションやコマンドラインツールは作ったことがあるけれど、考えてみるとモバイルアプリというものは作ったことがなかった。何事も経験ということでやってみる。なぜAndroidかというと、普段使っているのがAndroidであるため。

環境構築

プライベートではWSLで開発しているので、以下の記事を参考にさせていただいた。

zenn.dev

usbipdのインターフェイスは少し変わっているようで、上記の記事通りにやると怒られた。

$ usbipd: error: The 'wsl' subcommand has been removed. Learn about the new syntax at https://learn.microsoft.com/windows/wsl/connect-usb#attach-a-usb-device.

最初にWSLと共有可能なように設定し、その後バインドという流れになるようだ。共有可能とするには管理者権限が必要。sudoが欲しい!!!

$ usbipd bind -b 2-1
$ usbipd attach --busid=2-1 --wsl

インストーラの表示がまあまあグリッチしていて不穏。後でWSLをアップデートしたら治ったので一安心である。しかし、どうにも動きがもっさりだし、うまくデバイスを認識してくれている様子がない。心配。バッテリーも心もとなくなってきたので、Hello, worldするには至らなかった。

何を作るか

環境構築をしながらつらつら考えてみる。自分は何かを作るときには日常のお困りを解決するグッズを作ってみることにしているのだが、いまいち思い浮かばない。正確に言うと思い浮かばないは嘘なのだけど、サーバサイドとの連携が必要なアイディアしかなかった。それはそれで悪くないのだけど、初手でやることではないな、と思った。 要するに、スマートフォンに何ができるのかよくわかってないのだな。

今後すること

  • やっぱりこのノートPCでは限界がありそう。家のデスクトップPCとかでやる必要があるのではないか
  • 最初の一冊的な本を見つける
  • モバイルアプリの特徴は、端末にくっついている様々な機能を使えることだと思うので、どんなものがあるか調べる

この関数を使われるんですか? はい、それでしたらまず関数利用申込書を記入いただいて……

世の中には、軽々に使ってほしくないメソッドというものがありますよね。通常のフローと異なる経路でデータを削除するメソッドとか。 手っ取り早くdeprecatedにしてしまえればいいんですけれど、何かしら理由があれば許可し続けたいものもあるんですよね。

同僚がこういうことで困っていて、ジャストアイディアを口にしたら参考になったと喜んで貰えたのでメモっておきます。

TL,DR;

  # 緊急時に通常のバリデーション等を無視して削除するメソッド
  # 理由なしに緊急削除をしようとしたら実行時エラー
  #
  # 引数なしにおける関数定義
  # 引数がなければ実行時エラーする
  @spec emergency_delete :: none
  def emergency_delete do
    "Do not use this without a reason!" |> raise
  end

  # 理由があるなら許すよ
  # でも空文字列は許さん
  @spec emergency_delete(String.t()) :: :ok
  def emergency_delete(reason) when is_bitstring(reason) and byte_size(reason) > 0 do
    "Deletion completed without any validation!"
    |> IO.puts
  end

思いついた背景

紙の書類などの文化で、「例外的な手続きをするので書類のここに理由を書いてね」みたいなものがよくある気がする。これをコードで素直に表現してしまえ。

コメントと比べて何が嬉しいの?

  • コメントを見ずにうっかり使った人を確実に弾ける
  • コードレビューする側としても、呼び出し先のコメントを見に行くより気付きやすい
  • lintツールが十分整備されていない状況でも使える
  • 型に依存しないので、動的型付け言語でも使える

課題

  • 実行時エラーなのがイマイチ。コンパイルエラーやlintなどで落としたいですよね
  • コードの中に長い自然言語が現れるので頻出するとノイジーかも

(おまけ)なんでテストコードがElixirなの?

同僚がElixirわからんと言っていたので、ついでに話題にしたかった。一旦どの辺がわからないのか、などの叩き台にしたいので、自分が特徴的だと思う部分を雑に話題にしておく。Supervisorがどうのという話もあるけれど、今は一旦構文の話をしておく。

  • |>はパイプライン演算子で、左辺の評価結果を右辺にある関数の第一引数に代入する
  • 同じ名前の関数を複数定義した場合は上から順にパターンマッチを試していって、マッチした関数が適用される
    • パターンマッチは引数の数意外にも細々条件が付けられる
  • 何一つマッチしなければFunctionClauseErrorが発生する
  • Erlangのモジュールはセミコロンを先頭に付けた形で呼び出す(例: :rand.uniform(n))
  • @spec... で型を註釈することで静的解析してくれる

GitHub CoplilotとMermaidの組み合わせが結構便利っぽい

皆さん、図はお好きですか。作るのは好きなんですが、途中で「この図は本当にわかりやすいのか?」ということが気になってしまいがちなvilagiaです。

個人的にMermaidで作図をしていたんですが、GitHub Copilotを動かしたVSCodeでやっていたら案外と便利だったのでメモがてら書いておきます。

結論

  • GitHub Copilotはインデントされた箇条書きをそれなりに補完してくれる
  • GitHub Copilotは開いているファイルもネタ元にして補完してくれているらしい
    • 成果物を書きながら「この辺って図にまとめるとどうなってるんだっけ?」をMermaidで描き始めると、大項目に対応した中小項目を100点満点中60点くらいの感じで出力してくれる
  • もう少し詳しく

あくまでイメージだけれど、例えば以下のような入力をしたとする

mindmap
root((推理小説))
    探偵
    事件
    

すると、こんな感じのサジェストをしてくれる。

mindmap
root((推理小説))
    探偵
    事件
        犯人
        被害者
        証拠

GitHub Copilotの動作例。推理小説の構造をMermaidによって記述しようとしている。

もちろん人間がやりたいことと違うこともあるけれど、そこは適宜ツッコミを入れつつ直していけばよい。自分が予期していなかった有用な切り口の項目が一つでも出てくれば儲けものである。

Mermaidである必要なくない?

それはそう。ただ、human readableな書式であるからこそ良い感じの補完が効きやすいのではないかなー。そして、超凄いオートコンプリートによってにょきにょき図が生えていくのは楽しい。便利なVSCode拡張があるので導入も楽。お勧めです。皆さんもお試しあれ。

感想

こういうものが普及してくると、便利なオートコンプリート機能を持つシステム(例えばGitHub)にあらゆる情報を集約した方が便利という話になってきそう。軽量なメモツールとかが不利になってくるのかもしれないなぁ。それはそれでなんだか残念なので、うまく生き残ってほしい気がする。

音声認識を使い倒すと言う試み

最近家にあるいい感じの安楽いすにタブレットアームをつけた。これは結構良いのだが、文字入力がめんどくさいと言う問題があった。また、自分は何か考え事をする時、テキストにまとめたりするのだけれど、整った文章を書こうと言う意識に引きずられて考えの内容のほうに意識が向いていないなと思うことがままある。

これらの問題をいちどに解決するのに、音声認識機能で文字起こしをすることが有効なのではないか。そう考えて昨日あたりから試し始めている。この試みは7割程度うまくいっているように感じる。キーボードを叩いたりするのではなく、考えている対象について意識を向けながら目の前に表示される自分の考えを反芻する。どうせ完璧な文章は、このやり方では作れないので、つらつらと発散的な考えを行うのには余分な神経の使い方をせずに済んでいる。

じゃぁ残りの3割は何なのかと言うと、多分この文章を読んだ人にはある程度わかっているのではないだろうか。この文章はほぼ口述に基づいて書かれていて、キーボードを使っていない。見ての通り大変散漫な文章である。下書き、あるいは下書きの下書きを作るために、自分の中にあるものを一旦ダンプする場合には、これは問題にならない。しかしiPadの自動文字起こし機能はおばかである。ちょっと難しい語彙を出すとすぐに全然違う変換をしてしまう。機械学習マルコフ連鎖か何かそういう技術を使っていて、この話の流れならこの単語が出るだろうと言うようなものが文字起こし処理の中で使われているように感じられる。結果として、いくらはっきりと言い直したとしても、iPadが信じる自然な流れに反する単語が登場した場合、かたくなに変換結果を変えようとしないことがある。今出した語彙という言葉も、最初は全然違う単語として変換されていた。こういうところに神経を使っていると、一旦集中が削がれてしまって、ダンプ処理が妨げられてしまっているような気がする。

7割はうまくいっているので、このやり方はもうしばらく続けてみたいと思っている。けれど、残り3割の欠点は結構大きいので、そのうち嫌になってやめてしまうかもしれない。そうなる前に劇的なバージョンアップが入って、これらの欠点がいちどに解消してしまえば嬉しいのになぁ。これは願望です。

技術でなんとかするならば、この文章を生成AIに丸投げして編集や構成を勝手にやってもらえたら便利そうである。しかしガーベッジインガーベッジアウトであるから、変換等がガタガタなものが入力されてしまえば生成AIも結構困るのではないか。まぁこんなことをうだうだ言っているよりさっさと試してみろと言うのはもっともな話なので、気が向いたらやってみようと思う。

おまけ

使っている安楽いすは、IKEAで売られている以下の製品だ。お値段の割にすわり心地が良いのでお勧め。ただし長く使っているとだんだんボルトが緩んでくるので適宜増し締めをするという注意は必要。この辺は値段なりだなと思う。

https://www.ikea.com/jp/ja/p/poaeng-armchair-birch-veneer-knisa-light-beige-s19240788/

YAPC::Kyoto 2023と同人イベントと蒼い惑星

滅茶苦茶楽しい体験でした。以下、自分の好きなものに引きつけて何かを語りがちです。

参加するまで

物理的なカンファレンスの類にほとんど参加したことのない自分にとって、大きなカンファレンスに参加するということはそれなりに敷居の高いことでした。 話だけ面白く聞いて帰り、あっインターネットでは人々が出合いに盛り上がっておるな……ってなったら悲しいので……。

そんな内なる後藤ひとり*1を制するにあたり、「会社の人たくさんいそうだし」というのは大きな理由の一つ*2でした。

参加してみて

全体の印象として、同人イベントと同じ楽しさがあるなと思いました。自分は同人のオタクなので、イベントの中で何が好きって同人イベントが好きです。 この印象はあくまで印象なので、もう少し自分の中で共通項を括り出してみたい。

  • イベントの営利性が薄い
  • 新たな人・かつてすれ違った人との出会いの場である
  • 自分の興味・関心を深める場である
  • 打ち上げがある

それぞれ、もう少しブレークダウンしてみます。

イベントの営利性が薄い

ここはあくまで「そういうもの」なので、具体的なエピソード、みたいな話にはならないです。また、営利性の有無は優劣と特に関係ないですし、企業が関わっている以上は営利性が一切ないとは言えない*3です。ただ、なんとなくスタッフの方との距離が近い雰囲気はイベントの営利性の薄さと関係があるのかな〜。くらいのふわっとした印象と思ってください。

新たな人との出会いの場である

朝、KRP前で気配を感じ振り返ったら会社の人がいた。そう思って挨拶をしたら完全に違う人で、大変気まずい思いをしました。このままだと面白エピソード以上のものにはならんなと思った私は袖振り合うも多生の縁という言葉を思い出し、名刺交換をしたり多少雑談をしたりすることができました。

あるいは、以前の職場で一緒だったことのある人を見かけることもありました。明らかに雰囲気が似ていて、名札からも同一人物っぽいと判断してお声をかけたところ、やはり本人。お互いの近況を話したりできました*4

こうした偶然性からの出会いはやはりリアルイベントが強いな〜という気持ちがあります。同人イベントでも同窓会状態になったりそれ経由で新しい人と知り合うことが醍醐味の一つだと思っているので、この点も似ていそう。

自分の興味・関心を深める場である

これはイベントの性質上当然、ではあります。話題の多様性・量・質、目移りしてしまうくらいだったので、YouTubeでの配信もあるのがありがたすぎます。リスクや手間を考えると配信しない判断もあったと思うので、それらを踏まえてやってくださったことには感謝しかない。

まとめ

概観してみると、愉快な人々と一緒に偶然性を伴った情報の奔流に身を置けるというのが楽しさだなと感じました。しかも、自分の関心分野真正面ばかりでない。あ、かすってると思ったら自分はこういうのも好きなんだ、という発見があったりするのもよい。やはり同人イベントに引き付けていうと、大規模イベントで自分の関心真正面じゃない島を流している時のような楽しさと言えば伝わるかもしれません。個別具体的なセッションの話題などには触れませんでしたが、後日もしかしたら何か書くかもしれません。

ジャストアイディア

イベント前後に会話した人の一人が、口頭での発表に苦手意識があるのでブログなどでの発表に軸足を置いているという話をされていました。この文脈のリアルイベントだと技術書典がありそうというのを前提として、口頭発表イベントとテキストを発表するイベントをうまく融合できたら楽しそうだな〜と思いました。何も具体的な考えはありませんが……。

最後に

同人イベント的文化によれば、イベントはスタッフ・サークル参加者・一般参加者全ての協力によって成功するもの*5。スタッフの皆さん、発表者や出展者の皆さん、そして参加したすべての皆さん、お疲れ様でした。また次回も集まりましょう。

*1:アニメ化もされた大人気漫画「ぼっち・ざ・ろっく!」の主人公。マイナス思考のループにとらわれてドロドロの液体になったりすることで有名

*2:あと、趣味の関係で京都旅行を無限にしており、京都は何度行ってもいいという思想を心に刻まれているという理由もある

*3:同人イベントだって企業が出展するのは普通。主催している例だってある

*4:休憩時間の都合上少ししか会話できなかったのは残念

*5:一番大変なのがスタッフ、というのは多分同人イベントもこの種のイベントも一緒だと思います。ありがとうございます本当に

おうちサーバー構築日誌

我が家にはRaspberry Pi 4があり、常時稼働させたいお仕事はこれにやらせていた。けれど、思うところあってこれを中古PCにやらせてみている。

なぜ更新したいか

既存サーバには以下のような問題があった。

  1. なんだかんだ今でもArmで走らせるには一手間二手間掛かるケースが散見され、しょっちゅう困っていた
  2. GPIOなどサーバとして使うなら別に要らない機能が沢山ある。別の用途を考えてあげたい気持ちが増してきた
  3. ビルドなどの重いタスクをやらせると重い(それはそう)

結果として稼働はしてるがほぼ使ってないという問題があった。これらの問題からサーバを新たに用意したいという気持ちが増していたとき、アキバでいい感じの中古PCを見かけたので確保した。

何に更新したのか

Z2 mini G3

  • CPU: Xeon E3 1225 v5
  • GPU: Quadro M620
  • メインメモリ: 8GB
  • ストレージ: SSD 256GB
  • 消費電力
    • アイドル: 20W
    • 過負荷: 140W

選定の軸は以下のあたり。

  1. 小型であること(HP Prodesk miniなどのサイズ感)
  2. USB端子などが十分あって一定の拡張性を有すること
  3. 消費電力は大きくない方がよい
  4. ゲーム開発や画像自動生成、リアルタイム動画編集などの例外を除き、個人がごく少人数向けのサービスを複数稼働させる程度であれば不自由しない程度の計算リソースを持つこと
  5. 安い方がよい(1~2万円程度)

2017年ごろのモデルなのでXeonQuadroとはいえ型落ち甚だしいけれど、上記の評価軸からすると十分だろう。一応CUDAにも対応しているので機械学習ごっこくらいならやれそうである。お値段は3万くらいでやや予算オーバーだけど、中途半端なやつを買って二台体制にするよりは結果として安く上がるであろう。

環境構築の様子(記憶が曖昧なのであっさり目)

OS選定

Windows 10 Pro for Workstationsという面白OSが入っていた。調べてみたら、Windows Server用のリッチなファイルシステムが使えたりするらしい。興味はあったけど、別にWindows鯖を作りたいわけではなかったので他を考えた。あまり深い考えなくUbuntuにすることにした。ディストリビューションに凝るのはサーバ用途としては微妙かなと思ったのと、ラズパイと同じDebian系にしたい、くらいの気持ち。

インストールはほぼ問題なく進んだ。ファームウェアをアップデートしたらSecure Bootが怒り始めたので無効化(あんまりよくない。なんとかしたいけど……)

CUDAを使えるようにする

これもドキュメント読んでたらほぼすんなり終わった。 Failed to start nvidia-powerd service. というエラーが出てるのが気になるけど、とりあえず爆発したりはしてないから後で様子を見ましょう。

それから

Rustコードのビルドなども爆速であり大満足です。

その後microk8sを入れたりして遊んでいる。kubernetesははじめて触るので、ああ、業務で触るECSは思想的にはこういうものを更に抽象化したものなのかな、みたいな感想を抱きつつある。 やや脱線した。このサーバでどう遊ぶか、みたいな話はまた今度。

いろいろな調理器具が洗えてなくて困った

まな板も包丁も洗えてなかった。

仕事でやや失敗をしてしまった週の木曜日、晩ご飯を作ろうと思ったらいろいろな調理器具が洗えてなくて困った。食べようと思ってたネギと春菊と手羽先。どうしよう。もうおしまいだ。なーんて慌てることもなくて、馬鹿だな自分、と思いながらキッチンばさみを取り出して事なきを得た。

料理はレシピ通りに作れ、とよく言われる。料理酒がないからといって代わりにウォッカを使ったり、味噌がないからといって味噌汁のレシピから味噌を抜くような馬鹿なことはやめろ、というわけだ。これはだいたい正しいと思うけど、思えば自分はレシピ通りに作ったことがほとんどない。だいたい勢いで作っているし、想定レシピ通りに作ろうとしたら何かが不足していて作れない、というようなこともよくある。じゃあ自分の料理の評判が悪いかというとそうでもない。 考えてみると、レシピのアレンジ方法はさっき例示したようなものとは違う。味噌がないから塩気は醤油で取るとして、そうすると想定よりかなりさっぱりめな味になるはず。ならばその性質を生かして小ネギでも散らせばそれっぽい料理になるのではないか、みたいな考え方をしている。

巧みに事前計画するスキルを伸ばすことも大切だけど、こっちも大事だな、と思った。

もう少しブレークダウンするとこういうことになる

計画通りに事態が進行しなかったとき、扱っている対象について十分理解しているなら*1、適切な代替案を選択して素早く対処していくことができる。もし、対象への理解が不十分ならば、代替案の選択は往々にして場当たり的となり、結果として完成するものの品質を低下させる。

まあ結局「守破離」的月並みな結論ではある。けれど、今回した仕事の失敗というのはまあ、そういう話だと思っているので、反省も兼ねてここに書き記しておきたい。

対象への理解をどう深めていくかという方法論も結構難しいのだよなぁ。経験で慣れればいいというのはそうだけど、なるべく素早く慣れていきたい。

*1:もちろん、この条件が満たされていれば事前計画の精度も上がるはずだ。その予想を外れた場合のリカバリーも的確にできるのだから良いことずくめに感じる