04:28. 昨日は YT でぼんやり時間を溶かさず就寝できた。
- Problem – 1716A – Codeforces
- 問題の名前を <title> にいれるとか、そういう基本的なことが色々できてない competition サイトの皆さま。
- Solving https://codeforces.com/problemset/problem/1716/A
- 何も考えず DP して失敗するという、いかにも Leet の方からきたダメプログラマ的行為をしてしまった・・・
04:28. 昨日は YT でぼんやり時間を溶かさず就寝できた。
04:55. 耳垢掃除薬の適用に時間がかかってしまった・・・
Kattis に挫けたので今日からは Codeforces. なお Topcoder も見たけどまったく使い方がわからなかった。10 年前くらいにいちど使ったことあるはずなのだが・・・。Codeforces は解答 (Tutorial) もあるし新しい Kotlin もサポートしてるしで、そこそこ期待している。Scala は 2.x はあるけど 3 はなくて、ほんと流行ってねーな Scala 3. まあ自分は Kotlin でいいです。
一年少し前くらいから、気晴らしで Hacker News でカルマを稼ごうと思い立ち活動を始め、昨日めでたくカルマが 1000 になった。
これはインターネットで時間を溶かしている証左でしかないが、ではどのくらい溶かしているのかというと、活動は主にコメントで、270 コメントくらいしたらしい。二日に一回よりちょっと多いくらいのペース。例のごとく HN の公開データセットで計算してみると、これはコメントをしたユーザ全体の上位 2.5% のコメント数らしい。つまり、かなりヒマをつぶしている。しかも HN とか 2011 年くらいからあって自分は 2021 参加の新参者なわけだから、それにしてはコメントしすぎである。なお 20k / 800k みたいな規模感です。
コメント一つあたりの平均カルマはだいたい 3-4 くらい。つまり特にウィットの効いたコメントができているわけではない。じっさい単一コメントだと 20-30 くらいが限度。これはコメントが数十個程度のマイナーなスレッドだと一番上にくるようなイメージ。Mediocre ですね。はい。気の利いたコメントができる人なら同コメント数で 10x くらいカルマを稼げそうだが、まあいいです。当初は HN でカルマを稼ぐコツについて書きたいと思っていたが、こんな mediocre じゃ書くこともないね。コメント以外だと Ask HN も一回やったことがある。リンクの投稿は数回。
書いたコメントに返信がついたりするとインターネットしてる感じがして割とうれしい。こういう感じ、久しく味わってなかったなと思う。言語バリアのおかげで emotional burden が若干低めなので、それもよいです。時間のムダであることに変わりはないけれど。
LeetCode に金を払い続けるのも癪に思えてきたので他を探したら Kattis というのがあったので冷やかす。
ただテストデータは見えないので、間違えたときに何が間違ってるかはわからないのだね。これだとバグがあるときに詰んでしまう。むかし Topcoder 試したときはそれがフラストレーションで続かったなかったのだよなあ。(スコアを競い合う)競技プログラミングの性質と答えの開示は相反するので仕方ないけど、テストケースが見えないの直しようがなくね?まあ甘えなのだろうけど、こういうスタイルだと無限に時間が解けてしまうか、ギブアップして何もわからないまま終了にするしかなくて、一日 30 分くらいだけパズル脳を訓練したい自分とは相性が悪い。ヒマな人向けで残念。
もう一問くらいやるか。
Tridgell: The rsync algorithm – Google Scholar
How Dolt Stores Table Data | DoltHub Blog から noms/intro.md at master · attic-labs/noms を理解するために読んだが、この肝心の Prolly-Tree はまだ理解していない。
04:38. さて Leet をやって、今日は家の用事を片付けなくてはなりません。
04:04. さて今朝は家賃を振込、Leet して、久しぶりにお手紙活動しますかね。
子が日本語補習校なので土曜は謎の時間があります。土曜まで学校とか気の毒だが、それはさておき読んでくぞ。
$ bazel-bin/zetasql/tools/execute_query/execute_query "select (select 1 + 1) + 1"
+---+
| |
+---+
| 3 |
+---+
Resolved AST をダンプしてみよう。
$ bazel-bin/zetasql/tools/execute_query/execute_query --mode=resolve "select (select 1 + 1) + 1"
QueryStmt
+-output_column_list=
| +-$query.$col1#2 AS `$col1` [INT64]
+-query=
+-ProjectScan
+-column_list=[$query.$col1#2]
+-expr_list=
| +-$col1#2 :=
| +-FunctionCall(ZetaSQL:$add(INT64, INT64) -> INT64)
| +-SubqueryExpr
| | +-type=INT64
| | +-subquery_type=SCALAR
| | +-subquery=
| | +-ProjectScan
| | +-column_list=[$expr_subquery.$col1#1]
| | +-expr_list=
| | | +-$col1#1 :=
| | | +-FunctionCall(ZetaSQL:$add(INT64, INT64) -> INT64)
| | | +-Literal(type=INT64, value=1)
| | | +-Literal(type=INT64, value=1)
| | +-input_scan=
| | +-SingleRowScan
| +-Literal(type=INT64, value=1)
+-input_scan=
+-SingleRowScan
Subquery が “SCALAR” であるという事実は静的に判定されている。複数の row を返すようなケースではどう resolve されるのだろうか・・・。なんとかテーブルをつっこむ必要があるな。この BUILD ファイル に CSV を食わせる方法がひっそり書いてあるので試すと動いた(が、コピペでは動かなかった。あとで bug をファイルすべし。)
$ bazel-bin/zetasql/tools/execute_query/execute_query --table_spec="data=csv:$(pwd)/sample.csv" "select * from data"
+---+-----+----+
| a | b | c |
+---+-----+----+
| 5 | 1.2 | r1 |
| 6 | 1.5 | r2 |
| 7 | 3.3 | r3 |
+---+-----+----+
さて query のネストをしてみましょう。
$ bazel-bin/zetasql/tools/execute_query/execute_query --table_spec="data=csv:$(pwd)/sample.csv" "select (select CAST(a AS INT64) from data) + 1"
ERROR: OUT_OF_RANGE: More than one element [type.googleapis.com/zetasql.execute_query.ParserErrorContext='\n.select (select CAST(a AS INT64) from data) + 1']
EXPLAIN すると…
morrita@noisia:~/src/zetasql$ bazel-bin/zetasql/tools/execute_query/execute_query --table_spec="data=csv:$(pwd)/sample.csv" --mode=explain "select (select CAST(a AS INT64) from data) + 1"
RootOp(
+-input: ComputeOp(
+-map: {
| +-$col1.2 := Add(SingleValueExpr(
| +-value: $col1,
| +-input: ComputeOp(
| +-map: {
| | +-$col1 := Cast($a, ConstExpr(false))},
| +-input: EvaluatorTableScanOp(
| +-a#0
| +-b#1
| +-c#2
| +-table: data))), ConstExpr(1))},
+-input: EnumerateOp(ConstExpr(1))))
“ParserErrorContext” といっていたが、EXPLAIN はできている。つまり実行時エラーである。実際 subquery を LIMIT 1 すると成功する。というわけで実行結果が vector か scalar かというのは型の一部ではない、と言えそう。
一方 string と int を + しようとすると・・・
$ bazel-bin/zetasql/tools/execute_query/execute_query --mode=resolve --table_spec="data=csv:$(pwd)/sample.csv" "select (select a from data LIMIT 1) + 1"
ERROR: INVALID_ARGUMENT: No matching signature for operator + for argument types: STRING, INT64. Supported signatures: INT64 + INT64; UINT64 + UINT64; DOUBLE + DOUBLE; NUMERIC + NUMERIC; BIGNUMERIC + BIGNUMERIC; DATE + INT64; INT64 + DATE; TIMESTAMP + INTERVAL; INTERVAL + TIMESTAMP; DATE + INTERVAL; INTERVAL + DATE; DATETIME + INTERVAL; INTERVAL + DATETIME; INTERVAL + INTERVAL [at 1:8] [type.googleapis.com/zetasql.execute_query.ParserErrorContext='\n\'select (select a from data LIMIT 1) + 1']
Resolve に失敗する。というわけで + の評価には型が存在する as expected. なお parse には成功する。
$ bazel-bin/zetasql/tools/execute_query/execute_query --mode=parse --table_spec="data=csv:$(pwd)/sample.csv" "select (select a from data LIMIT 1) + 1"
QueryStatement [0-39]
Query [0-39]
Select [0-39]
SelectList [7-39]
SelectColumn [7-39]
BinaryExpression(+) [7-39]
ExpressionSubquery [7-35]
Query [8-34]
Select [8-26]
SelectList [15-16]
SelectColumn [15-16]
PathExpression [15-16]
Identifier(a) [15-16]
FromClause [17-26]
TablePathExpression [22-26]
PathExpression [22-26]
Identifier(data) [22-26]
LimitOffset [27-34]
IntLiteral(1) [33-34]
IntLiteral(1) [38-39]
昨晩遅かったので朝は走るだけ、と思ったら雨。コード読むかな。
// Resolve a parsed ASTStatement to a ResolvedStatement.
// This fails if the statement is not of a type accepted by
// LanguageOptions.SupportsStatementKind().
// <sql> contains the text at which the ASTStatement points.
absl::Status ResolveStatement(
absl::string_view sql, const ASTStatement* statement,
std::unique_ptr<const ResolvedStatement>* output);
といったところで時間ぎれ。execute_query がいまいちだったので心配していたが、ライブラリ本体はなかなかクリーンぽくて安心。
次回以降への疑問:
ちょっとばかし ZetaSQL のコードを読んでみるターン。DuckDB しか知らないと Duck 活動してもいまいち自分の SQL 力が高まらないなということで、ガチ勢の SQL パーサを読んでみる。ZetaSQL は Google 社内の SQL 方言をすべて駆逐した本気の二周目 SQL 実装である。これを読めば SQL への理解も高まるというものでしょう。オープンソースへのコードダンプがどのくらいちゃんとしているのかは怪しいが、それは見ればわかるでしょうということで。
$ find zetasql/ -type f | xargs wc
...
852658 2684718 30878589 total
$ find zetasql/ -type f -name "*.test" | xargs wc
...
408165 1213844 13169468 total
$ find zetasql/ -type f -name "*_test.cc" | xargs wc
...
100019 276858 4024329 total
04:32. 目が覚めてダラダラインターネットして、コーヒーは今日はやめといて、そろそろやってくかな。
htl.html`<svg viewBox="0 0 ${width} ${height}" style="max-width: ${width}px; font: 10px sans-serif;">
<g fill="steelblue">
${fruits.map(d => htl.svg`<rect y="${y(d.name)}" x="${x(0)}" width="${x(d.count) - x(0)}" height="${y.bandwidth()}"></rect>`)}
</g>
<g fill="white" text-anchor="end" transform="translate(-6,${y.bandwidth() / 2})">
${fruits.map(d => htl.svg`<text y="${y(d.name)}" x="${x(d.count)}" dy="0.35em">${d.count}</text>`)}
</g>
${d3.select(htl.svg`<g transform="translate(0,${margin.top})">`)
.call(d3.axisTop(x))
.call(g => g.select(".domain").remove())
.node()}
${d3.select(htl.svg`<g transform="translate(${margin.left},0)">`)
.call(d3.axisLeft(y))
.call(g => g.select(".domain").remove())
.node()}
</svg>`
はー・・・。感想:
Python や R で EDA するとは違って D3 の可視化はウェブフロントエンドのニッチなのだろうな。たとえばデータサイエンティスト連れてきてほらこれで可視化しろよ、とかいってもできるとは思えない。
D3 の可視化は誰かが何らかの発見をして結論を出した後、その発見・結論を示せる JSON とかを事前に用意しておいて、そいつをかっこよく表示してあげるというもの。インタラクティビティも作者の意図を読者に伝えるためのギミック。
仮に D3 を EDA に使おうと思ったらデータソースをつなぎこむ必要があるので、そういうシステムを作る必要がある。大仕事。(Observable はそういうのを一定程度やってくれるっぽいが。)
自分には Colab で EDA しているときに Altair に足りない機能を D3 で補いたい期待があったが、それは難しそうに見える。できなくはないだろうけど・・・。もう一つの期待は社内 dashboard のしょぼさをドメイン固有なフロントエンドを用意して補う路線で、そっちのほうが(自分のフロントエンド力の無さを差し引けば)現実的かな。
いずれにせよ次にやるべきことは D3 をつかって E2E でなんらかのウェブアプリなりサイトなりを作ることだろうね。あまりアイデアがないなあ。保留しつつそのうち考えます。
というわけで ggplot2 論文。これは…素晴らしいね。本家 GOG で曖昧だった部分をすべて明らかにしたのみならず(たとえば transformation のよくわからなかった部分は丁寧に解説されている)、整理しなおし拡張している。そして可視化の best practice のようなものにも言及している (ex. “In practice, many plots have (at least) three layers: the data, context for the data, and a statistical summary of the data.”)。コードもある。
一方、当然なら本家 GOG を参照しているのであれを読んでいないと割と意味不明ではある。そういう意味で GOG は Hadley のこの論文を読むための税金だったのだと思えば許せる。
そして読んでいて気付いたが、ggplot2 にあるのに Altair にない機能が普通にあるね。Contour とかないじゃん。これ超欲しいんですけど。
これに限らず、Hadley の可視化に関する知見を学ぶためにこの人の書いた本を読むのは意味がある気がする。
心の積読にしておこう。
さて、これで星空日記から始まった可視化入門の旅は終わった。次にやることを考えないとな。まあ dashboard の本は読むとして、あれだけだと若干退屈なのでもうちょっと他にないか考えようではないか。イメージとしては dashboard の本は私用 laptop にアクセスできない会社の昼休みとかで読み、家ではもうちょっと手を動かす感じにできないかなあ。まあ無理に手を動かさなくてもいいんだけど、画面でないとできない活動、同じ読むでもコード読みとか、そういうかんじの何かをやりたい。Notion にでも書き出して考えるべし。
Message Passing 書き終わり。そのほかお手紙に返事など。
Windows には最近は scoop という便利インストーラがあると教わり入れてみる。(参考: MacOS ユーザが WSL では無い Windows のコンソール環境を整える – A Day in the Life)
お、いいじゃんと勢い余って duckdb を Windows native でビルドしようとしてみるが、なんかいろいろ足りず挫折。また今度・・・。そして Windows ネイティブ開発しようとするとダウンロードサイズがでかい。つぎ laptop 買うときはでかめの SSD が欲しいかもしれないなあ。
参考リンク
さて家賃を払わねばならぬ・・・そういえば引っ越して一年たったけど家賃更新なかったな。COVID の影響で禁止されているのだろうか。軽く探した感じ何も見つからなかったが。そういえば東京で一人暮らししていた 10 年間くらい、一度も家賃を引き上げられたことなかったな。今思えばすごい話だね。
銀行ついでに総資産を冷やかすと・・・減ってるね。そういえば株価下がってるというニュースを見た気がする。自国で百万人死んでも株価は上がり続けるのに、遠いユーラシアで戦争になると下がるの、資本主義のろくでもなさを突き付けられる感。
家計簿振り分け。ためなければ一瞬であります。
お手紙返事活動。
さて Message Passing のターンが来たので書くぞ。
昼間コーヒー飲んだせいか気が付いたら 23 時。今日はここまで。
お手紙活動に返事がきて、M1 Mac は Docker 動くしいいですよ、とのこと。ふーんとおもって適当にぐぐると、Docker Mac は仮想化のデフォルトが QEMU だという Reddit の発言を見かける。SO も。マイクロサービシズ!みたいな仕事は開発環境含め全部 Docker に入れてしまえば Mac だろうがなんだろうが好きなのを使えばよいということなのかねえ。
しかしこの話を書いていて WSL2 は Android Studio を使えない(限りなく無理) なことに気がついてしまった。うっかり Bazel とかを使おうとした日には積んでしまうな。Mac でも同程度にダメな予感もするが・・・。
IntelliJ なら最近は JetBrain Gateway というのがあって VSCode Remote 的に JetBrain 製品を使えるようになるっぽいが、Android Studio は当然のように未対応。これが動くとハッピーなのだけどねえ。そのうち対応してくんないかな。
来週の grocery 注文作業。子が生まれる前は一週間のメニューを考えてそれに合わせて買うとかやってたなあ。今は適当に買ってあるものを作るようになったが、適当に作るスキルの高まりにより割と困っていない。Imperfect Foods はイマイチなところもあるが、全体としては納得のできるサービスといえる。
家計簿。しかし前回から transaction が一件しかない。インポートが遅れてるな。
珍しく弟から電話。雑談。長男が中学受験だよ、など。自分の日本の友達でも子が中学受験とか言ってたし、昔と比べ一般化してるのだろうか。自分の卒業した都立高校も少しまえから中高一貫校になったという。そこには知らない日本がある。
少し前、自分の子に見せようと昔の日本の様子の動画(映画の切り貼り)を見たら不思議な気分になった。人々の恰好は古いが、街並みは案外変わっていない、というと誇張だけれど、多くが共通している気がする。しかし自分の脳内日本映像の解像度もだいぶ荒く、ただしく比較できない。
明日は朝から水族館にいくのでさっさと起きて弁当を作らねばならぬ。寝るべし。
Stolte: Polaris: A system for query, analysis, and… – Google Scholar
久々に出社し、タダで使えるプリンタがあるのを思い出したので星空日記で積み残していた Tableau の元となった論文を読む。
しかしその後の Tableau の発展はアカデミアに還元されることはなかったのだった・・・と書こうと思ったら Tableau Research というのがあり、論文わりと面白そうじゃないですか。タイトルで選んで記録:
可視化は自分の関心が高まってるせいもあってどの論文も面白そうでよい。
あと Polaris の被引用リストを見ていたら The Grammar Of Graphics の論文バージョン 2012 を発見したので、書籍 Grammar Of Graphics じゃなくてこっちを読もうかな。
長いことブログというものを表立って書いていなかった。なにもインターネットに存在感がないのは寂しいのでまた書いてみる。
人々に言いたいことは今のところ特にないので、かわりにしばらくは自分が余暇の時間にやっている読んだり書いたりの活動を記録していこうと思う。森田が報告・連絡・相談するので法蓮草の森。連絡と相談はたぶんしないけど、語呂優先です。