モノを減らす

もし修士を取って予定通りに就職するとなると、今の家を引き払うことになる。これを機会に必要のないものを捨てるのはもちろんだが、それ以前にゴミは捨てねばならない。とは言うものの、片付けは苦手だし早朝のごみ捨てはもっと苦手だ。

月曜日は資源ごみの回収日だ。さっき缶と紙を捨ててきた。缶はだいぶ貯めてしまっていたのですごい量だった。回収場所に行ってみるとかごが既にいっぱいだったので一つずつ潰して小さくしていれなければならなかった。片付けというのは難しい。

実験募集が終わったので隠していたブログメニューを復活させ、過去の記事を見やすく戻した。ブログが異様に重いのもなんとかしたい。たぶん同じサーバー上で動かしているMastodonを落とせばいいんだけど、それをやってしまうのは寂しい。純粋に感情の問題だ。

そういえば昨日紹介した『Hand Simulator』だが、Steamの設定からSteam Playのバージョンを最新版であるProton3.16-5 Betaにしたところ問題なくプレイできた。操作が難しい。Steamで面白いゲームがあったら紹介してください。普段はDota2ばっかりやってます。

LMMSでLinuxDTM

好きな曲を耳コピして遊ぶことがある。Windowsを使っていた頃はDominoを使っていたが、Linuxでどのソフトが適任かわかりかねていた。現状の結論としてはLMMSが良い。

LMMSはaptで入る。

sudo apt install lmms

特別最新版にこだわる理由がなければこれでよい。

LMMS初心者がつまづくのは音源だ。LMMSのデフォルト音源はよくない。なぜか入力と音高がズレているし、単純に音が悪い。プラグインのsf2 Playerを使ってフリー音源を読み込む。僕はFluidSynthとSGM-V2.01を入れた。

ググればそれぞれの.sf2ファイルが見つかるので、ダウンロードして~/lmms/samples/soundfontsに置いておく。

左端のバーからInstrumental pluginsを開き、sf2 Playerをソングエディタにドラッグする。するとトラックが追加されるのでクリックしてプロパティを開く。

FILEの右にあるフォルダマークをクリックし、先ほどダウンロードした.sf2ファイルをインポートする。その後PATCHの右のスパナのマークをクリックして音色を選択する。ソングエディタの黒い四角が並んでいるエリアをダブルクリックするとピアノロールが開き、後はDominoと同じ感覚で入力する。弱点はピアノロールに複数のトラックを表示できないことだ。

WindowsでできていたことのほとんどはLinuxでもできるが、DTMだけはできていなかった。しかしLMMSはきちんと使いこなせばDominoと同等のことはできそうだ。

なんでもかんでもLinuxでやるおじさんの次の目標はSteamゲーム『Hand Simulator』をやることだ。脳による身体のコントロールはそれなりに学んできたので、その過程を全部バラして自分の体を動かすことがどれだけ難しいかを再体験するゲームとして興味を持っている。

Steam Playを有効化すれば起動は可能なのだが、おそらくフォントの問題で文字が全く表示されず、ゲームを開始できない。

あと一歩のところまで来ている感じはする。以前は起動前のオプション画面ですら文字がなかったが、今は表示されるようになっているので改善も進んでいるようだ。

Linuxの未来は明るい。

 

修論がいよいよ切羽詰まってきて昨日までは随分と焦っていたが、今日は起きてからずっと平穏な気持ちだ。修論の切迫感も友人との世間話もどこか遠くの世界のものに感じられた。奇妙だ。覚悟ができたとか諦めがついたとかそういう見方もできるだろうし、あまりにヤバすぎて脳が感情にストップをかけているという見方もある。今こうしてブログを書いている僕にしてみれば苦しみが和らいでいるという事実が大事で、理屈はどちらでもいい。

グラフをmatplotlibで作っている。ExcelやLibreOfficeなどのGUIソフトで作るのも直感的で悪くないが、様々な形式のデータに対してグラフのフォーマットを一定に保つという点ではmatplotlibが向いている。むしろGUIソフトはマウス捌き次第で違うものが出来上がってしまうという点で苦手だ。

さすがにもう実験はやらないので実験用にしていたディスプレイを防音室から出して作業用にした。このディスプレイはWQHDだが、普段使うノートPCの外部出力はFHDまでしか対応していないので以前は画面中央のFHD分だけ使われていた。今日久しぶりに接続したときにもそうなると思っていたら、なんとWQHDが全面使えた。不思議だ。調べてみるとノートPCの仕様書には外部出力はFHDまでと書いてあるが、iGPUのIntel HD Graphics 4000はWQHDに対応している。

むしろ酷いのはノートPCの内蔵液晶だ。1366x768では今どき大した作業はできない。2013年に使い始めた頃は不便に思ったことはなかったが、今では全く不十分だ。PC環境を整える上で最も優先すべきは人間と直接ふれあう部分、具体的にはマウス・キーボード・ディスプレイだと思う。ここのストレスは処理能力のストレスに比べて影響が大きいからだ。

ノートPCは大学入学時に入手したもので、スペックは以下のとおりだ。

  • Core i5-3210M
  • 16GB RAM(自分でフル増設した)
  • 128GB SSD(光学ドライブを抜いて増設した)
    • 幸いにも光学ドライブはSATA3接続だったのでSSDを刺してもボトルネックは生じない
  • 500GB HDD(最初に入っていたのが壊れたので取り替えた)

読んでわかるように相当の愛着がある。しかし前述のディスプレイの狭さに加えてバッテリーが経年劣化によりフル充電からでも30分程度しか保たない、重い(2.5kg)、デカい(リュックに入らない)などの欠点もある。来年には新しいノートPCを購入するだろう。メーカーに特にこだわりはないがThinkPadのキーボードは打ち心地が素晴らしいのでLenovoかなあ。

JavaScript+Hyperappで心理学実験プログラムを作った

これです(github)。

僕の学科では学生が実験に参加しつつその実験についてレポートを書くという授業が多く行われている。そこで行う実験は古典的なものが多いのだが、大昔に書かれた実験プログラムがメンテナンスされずに使われ続けているということがある。

今回書いた記憶実験のプログラムもそうで、誰がいつどうやって作ったかわからないexeファイルが受け継がれ使われ続けてきた。しかし内部の処理がわからないので細かい仕様がわからず、いろいろ試してみて推測することしかできない状態だった。さらにいつ動かなくなるかもわからない。

そこでこのプログラムを移植(ソースコードがないので移植と言うかは微妙だが)しようという話になった。当初はPythonが候補に上がっていたが、多数の学生に授業中に同時に行わせるにあたり、Pythonをexeに固めたものは容量が大きくなりすぎダウンロードが長引く懸念があった(経験的には数十MB)。そこでJavaScriptでの制作を提案した。サンプルを作って披露したところゴーサインが出たので制作した。

動作は単純で

  1. x桁のランダム数列を3秒間表示
  2. 数列を消し5秒間待つ
  3. 参加者が数列を思い出して回答する
  4. 正誤を3秒間表示
  5. 桁数を変更し、1に戻る

というものだ。5の桁数変更のアルゴリズムには上下法や恒常法などがある。

上下法は正解すれば次は1段階難しく、不正解なら次は1段階簡単にするというアルゴリズムだ。これによって参加者の正解できる限界の桁数に収束する。メリットは試行数が少なく済むこと。

恒常法は一定の範囲の桁数をランダムな順番で課し、桁数を横軸に、正解率を縦軸にプロットすることで正解率を桁数を結びつける関数を得る。そして正解率50%(任意の値)に相当する桁数をその人の限界とする。メリットは関数そのものが得られるため多様な分析が可能であること。

心理学の実験は基本的にはwebではやらない。それは参加者の環境が統一できないからだ。MATLAB+Psychtoolboxが主流で、Python+Psychopy(pygame)もある。しかしポータビリティは低い。GUIを使うプログラムはDockerで動かすのは不便で、できてもパフォーマンスに不安がある。

そこまで環境にこだわらない実験や、今回のように同じ部屋で多くのPCで実験を行うときにはポータビリティの高いwebプログラミングによる実験は便利だ。そもそもGUIを扱うノウハウやライブラリという点ではJavaScript、というよりブラウザという環境が優れている。

寛容

※この記事は『Asahi クリアセブン』を飲みながら書かれた。

↑まずい。

今日はクソ酷いミスをして人に迷惑をかけてしまったのだが、さらりと許してもらえた。僕もそういう人間でありたいと思う。食堂の給茶機の順番待ちに割り込まれても笑顔でいられるようになりたい。

これまでaptで入れていたChromeを公式debから入れ直したことでバージョンが70になった。タブのデザインが変わり当たり判定が増えたのもそうだが、何より素晴らしいのは拡張機能のSpeedDialが正常に機能するようになったことだ。これまでは4列に設定するとなぜか右にスペースができてしまってとても気持ち悪かったのだが、それがなくなりきちんと中央に配置されるようになった。

Hyperappのプログラムをいじっていたのだが、actionは引数を1つしかとれないということを学んだ。そういうプログラムになっているのはそうとして、そうしている理由はなんなのだろう。

Actions

The only way to change the state is via actions. An action is a unary function (accepts a single argument) expecting a payload. The payload can be anything you want to pass into the action.

カフェインとMastodon2.5.1リレー機能

カフェイン

授業とミーティングを終えてコーヒーを飲んだら、飲んでいる最中は何もなかったのに立ち上がってから酷いめまいに襲われた。低血圧なので立ちくらみはよくあるが、立ちくらみのときは視界が白くなる。今回は純粋に平衡感覚だけが狂うというはじめての経験だった。友人に肩を借りてなんとか研究室まで戻り、やらなきゃならない仕事を片付けてからすぐに帰宅した。おそらく季節による体調変動とカフェインの刺激が重なったのだろう。

カフェインと言えば、緑茶にも多く含まれる。私の出身地は茶の産地であり、小学校の総合学習では茶について学ぶ。学んだことを発表するまで含めて総合学習なのだが、茶の効能を歌にするグループがあったような気がする。「カッテキン\カフェイン/カッテキン\カフェイン/」というリズムを今でも覚えている。

僕は24歳だ。(なぜか)まだ学生だし世間的には若者だろうが、一方で身体機能は既にピークを超えたものもある。たとえば大食いは20歳ごろがピークだった。という話は以前もしたような気がする。

Mastodonを立て直した

自分の変更点を残しつつ最新版に追従しようとしたらgitの闇に飲まれてわけがわからなくなったのでリセットボタンポチーした。何回ぶっ壊してもいいVPSとかいうおもちゃ最高。そうまでしてv2.5.1にバージョンアップした理由はリレー機能だ。

マストドン、「連合リレー」対応の2.5.0公開

Activity Pubを受け取って登録済みのインスタンスにそのまま流すリレーサーバーが開発されており、Mastodon側からも対応したとのことだ。管理画面でリレーのURLを入力するだけで接続できる。これを使うと何もしなくても連合TLに同じリレーに属するインスタンスの投稿が流れてきて、賑やかになる。

自分のインスタンスを立てて痛感したのは初速の重要さだ。小規模インスタンスの場合登録しても結局他のインスタンスの知り合いや有名人をフォローしに行くことになり、Mastodonの特徴であるごった煮高速TLを楽しむことができない。リレー機能はここに一石を投じるものだと思う。

今日のUI心理学

5.6は視覚探索の話。視野のたくさんの図形から1つの目標図形を探すとする。このとき目標図形をターゲット、それ以外をディストラクタと呼ぶ。素朴に考えれば私達は図形を一つ一つ見て確認していくはずだ。ターゲットを何番目に見るかの期待値はディストラクタの数の半分なので、見つけるまでにかかる時間はディストラクタ数が増えるに従って線形に増加するはずだ。以下のような画像から「右上を向いた赤」を探すときは実際にそうなり、右のほうが長くかかる。

しかしこれには例外がある。以下の画像から「右上を向いたもの」を探すときや

以下の画像から「緑」を探すとき。

このようなときはディストラクタの数に関係なく一瞬で見つかる。この現象を「ポップアウト」と呼ぶ。脳内の情報処理で「色」や「方位」それぞれのマップを作って探すときは全体を一瞬で処理できるが、複数種類の特徴を統合して判断する処理は一箇所ずつしかできないと考えられている。詳しく知りたい人は「特徴統合理論」でググって。

参考文献:『視覚科学』横澤一彦

Hyperappでhtml要素の真偽属性を操作する

※この記事は『金麦 RICH MALT』を飲みながら書かれた。

hyperappのviewはh関数で作る。これは公式サイトのサンプルだ。

const view = (state, actions) =>
  h("div", {}, [
    h("h1", {}, state.count),
    h("button", { onclick: () => actions.down(1) }, "-"),
    h("button", { onclick: () => actions.up(1) }, "+")
  ])

h関数は3つの引数をとる。1つ目はタグ名、2つ目は属性を列挙したハッシュ、3つ目は子要素だ。ここで属性はハッシュなので、キーとバリューのペアが必要だ。しかし全ての属性がキーとバリューのセットで用いられるわけではない。たとえばreadonlyは値をセットする必要がなく、存在することによって機能する。

ここでHTML5の真偽属性の仕様を確認する。

checkedおよびdisabledとなるチェックボックスの例を示す。checkedおよびdisabled属性は真偽属性である。

<label><input type=checkbox checked name=cheese disabled> Cheese</label>

これは次に書かれるものと等価であるべきである:

<label><input type=checkbox checked=checked name=cheese disabled=disabled> Cheese</label>

スタイルを混在させることもできる。以下は依然として等価である:

<label><input type='checkbox' checked name=cheese disabled=""> Cheese</label>

どういうことかというと、以下の3つはどれでもいい(参考)。

  • disabled
  • disabled=disabled
  • disabled=""

つまり真偽属性を変化させたいときは以下のように書きわけることができる。

h("input", {readonly=""}, "")
h("input", {not-readonly=""}, "")

これをhyperappの枠組みで考えるとこうなる。

const state = {
  readonly: "readonly"
}

const actions = {
  writable: () => state => ({ readonly: "not-readonly" })
}

const view = state => h("input", { [state.readonly]: "" }, "")

viewのh関数の第2引数のハッシュで、ブラケット記法を用いてキーの方を変更する。バリューはなんでもいい。

Mastodonに自動ハッシュタグ機能をつけた

アニメ実況時は同じハッシュタグで継続的にツイートする。よってハッシュタグを保持し自動的に付加し続けてくれる機能は便利だ。作った。

やたらとトゥートの反映が遅いのはサーバーがイマイチだからかな…

この機能追加はReact+Reduxの処理階層を知っていれば全然難しくない。まずハッシュタグ入力欄と、そこへの入力を処理するaction, reducer, stateを作る(全部compose-formのコピー)。さらにCtrl+Enterによるトゥートを処理するhandleKeyDownにShift+Enterによって発火する別ルートのトゥート投稿処理を追加する。これもトゥートボタンによって発火する処理をほとんどコピー。そのルートの最後にあるのがこれ。

const status = getState().getIn(['compose', 'text'], '') + ' ' + getState().getIn(['compose', 'preservedHashtag']);

これだけが実質的に意味のあるコードだ。興味のある方はコミットログをどうぞ。

1年前のドワンゴインターンではJavaScriptが全然わからず(わからなかったのはJavaScriptだけではないが)チームメンバーに教えてもらっていたが、今では自力で触れるようになった。

Mastodonでハッシュタグ補完すると1文字目が勝手に確定する問題

Mastodon(v2.5.0rc1)でトゥート入力時にペーストでハッシュタグを入力すると、ハッシュタグ補完機能でハッシュタグの候補が表示される。それをEnterやクリックで確定して投稿すると、次のトゥートを入力するときに日本語入力を有効にしていても1文字目が勝手に確定される。

1文字目が勝手に確定されるという現象は割とよくあるやつで、slackでもTwitter公式でも発生した事例はある。しかし今回はハッシュタグ補完時のみという条件があるので、もしかしたらハッシュタグ補完が発生したときにはトゥート投稿時の投稿欄の情報リセット忘れがあるのかもしれない。現在ソースコードを確認中だ。

なおfriends.nicoでも同様の現象が起きることを確認済み。OSはUbuntu18.04で日本語入力はmozcだ。書いてて思ったが変換の方で何か悪さをしている可能性は十分ある。あるいはデスクトップ環境かも知れないし、ブラウザかも知れない。なかなか手強そうだ。