正直USキーボードの良さが分かっていない

概要 SNSを見ているとエンジニアの世界ではUSキーボードが異様に称賛されているように感じる。 自分自身は大学3年生まではJISキーボードを使っていて、研究室&1社目&2社目では支給されたUSキーボードを使っている。 どちらのキーボードも使った結果、JISキーボードの方が使いやすいと感じている。 この記事ではその理由を述べていく。 よく語られるUSキーボードの長所に対する疑問 まずは世間でよく語られるUSキーボードの長所に対する疑問を述べていく。 1. ショートカットキーが使いやすい 感じたことがない。 むしろ、後述する「かな・英数変換」のショートカットキーはとても使いにくいと感じる。 2. ホームポジションが崩れにくい 感じたことがない。 むしろ、後述する「かな・英数変換」で毎回ホームポジションが崩れる。 3. 表記がシンプルで見やすい キーボードの表記を気にしたことがない。 ただ、初学者にとっては確かに見やすいのかもしれない。 4. キーの配置が論理的で使いやすい キーの配置が論理的というのはその通りだと思う。 例えばJISキーボードでは「」は横並びで{}は縦並びだったりするが、USキーボードではどちらも横並びになっている。 ただ、キーの配置が論理的であることがメリットだとは個人的には思わない。 なぜなら我々は論理的に思考しながらキーを入力しているわけではなく、手癖でキーを入力しているからだ。 キー入力しているときに「{}は横並びだなー」なんて考えているやつはいないだろう。 もし論理的に考えながらキー入力をしているなら、研究室に入って初めてUSキーボードを使ったときにミスタイプしまくった思い出と整合性がつかない。 確かに初学者なら論理的な配置の方が覚えやすいというのはあるのかもしれないが、慣れてしまえばどちらでも同じだと思う。 USキーボードの悪いところ 1. かな入力と英数入力の切り替えが不便 正直この欠点で全ての長所は吹き飛ぶのではないかと思う。 例えばWindowsのUSキーボードだとCtrl + `というショートカットでかな入力モードと英数入力モードの切替ができるのだが、2つのキーの配置が遠すぎてめちゃくちゃ指がスカってしまう。 世間でよく語られている「ショートカットキーが使いやすい」や「ホームポジションが崩れにくい」といったUSキーボードの長所が仮に事実だったとしても、このCtrl + `という使用頻度S級にも関わらず超絶押しにくいショートカットが全てを破壊してしまう。 ちなみに、Macの^ + SpaceはCtrl + `よりはかなり押しやすいが、それでもたまにスカってしまう。 もう一つ大変なのは、Ctrl + `に冪等性がないということだ。 JISキーボードでかな入力をしたいときには、現在がどちらのモードであるかに関わらずかなキーを押しておけば良いのだが、USキーボードだと既にかな入力モードのときにCtrl + `を押してしまうと英数入力モードに切り替わってしまう。 したがってUSキーボードを使う場合は、現在のモードを常に記憶しておくか、モードの切替をする前にタスクバーを確認するという癖をつける必要がある。 これらはJISキーボードを使用しているときには意識する必要がないことだ。 USキーボードのこれらの欠点に対して、「レジストリをイジったり、『⌘英かな』のようなツールを使ってキー配置を新たに割り当てればいいじゃないか」という反論があるかもしれない。 ただ、セキュリティの要件の厳しいプロジェクトだと、レジストリをイジったり承認の無いツールを導入することができなかったりすることも多い。 そもそも、キー配置を割り当て直すことを良しとするなら、JISキーボードをUSキーボードのキー配列に変更することもOKになってしまうわけで、反論として成立しているかは微妙なところだ。 まとめ ぶっちゃけ、カッコつけでUSキーボードが良いと言っているエンジニアも多いんじゃないだろうか? 少しでも日本語を入力する機会がある人にとってはJISキーボードの方が楽なんじゃないだろうか?

2025-06-22

PyPIにパブリッシュしたら「File exceeds compression ratio of 50」というエラーが出る問題

概要 PyPIにパッケージをパブリッシュしようとしたら、以下のようなエラーが出てパブリッシュできなかった。 <html> <head> <title>400 Invalid distribution file. File exceeds compression ratio of 50</title> </head> <body> <h1>400 Invalid distribution file. File exceeds compression ratio of 50</h1> The server could not comply with the request since it is either malformed or otherwise incorrect.<br/><br/> Invalid distribution file. File exceeds compression ratio of 50 </body> </html> 間接的原因. なぜエラーが発生したのか? 解凍したときにファイルサイズが50倍以上に膨れ上がるzipファイルをアップロードしたことが原因だった。 ちなみに、解凍したらサイズが膨れ上がるようなファイルを利用してシステムをクラッシュさせるような攻撃をZip Bombと呼ぶらしい。全然知らなかった。 高圧縮ファイル爆弾 46MBが4.5PBへと膨れ上がるZIP爆弾がネット上で公開中 Zip Bombを防ぐために、PyPIでは2023年の6月頃から圧縮率50倍を超えるファイルを含むパッケージのパブリッシュを拒否するようになっているようだ。 最初は圧縮率10倍以上で弾いていたが、制限が厳しすぎるということで50倍以上に緩和されたらしい。 PyPI is now requiring wheels to be too much compressed ...

2025-06-21

Python製の麻雀ゲームの向聴数計算部分をC拡張で実装

概要 Pythonでkago-utilsという麻雀ゲームを作っている。 こいつの処理がもっさりしていたので、向聴数計算の処理をCで書き換えることによって速度を改善した。 背景 kago-utilsのゲームルーチンにバグがないかを検証するために、天鳳の牌譜を約60万半荘分流し込むという作業をしていた。 しかし、1半荘を終えるのに1秒程度かかっていたので、検証作業に非常に時間がかかっていた。 そこでyappiというツールを使って牌譜10半荘分のデータを流した時の各関数の実行時間を計測したところ、以下のようになった。 HaihuParser.runが一番外側の呼び出し関数で、これが350秒かかっている。 どうやらyappiの差し込みの処理が重いらしく、実際は10秒程度で終わっている処理に350秒程度かかってしまっているようだが、各関数の処理時間の比率自体はそこまで変わらないと想定して、どの関数がボトルネックになっているかを考えることにした。 この画像を見て分かる通り、向聴数の計算を行うcalculate_shantenに338秒かかっていて、これは全体の処理時間の96%程度を占めていることが分かる。 そこで、向聴数計算の処理だけをC拡張で実装して速度改善を図ることにした。 全部の実装をCで書き換えることができればベストなんだろうが、自分はCが書けないし、既にほぼ全てのコードを書き終えてしまっているので、今回は向聴数計算の部分だけをCで実装することで手打ちにした。 方法 正直、方法については調べればいくらでも情報は出るので、コードと細かいTipsだけを共有する。 _shanten.c Tips1. C vs C拡張 Cで実装するのにも2通りの方法がある。Cを直接呼び出す方法と、C拡張モジュールを使う方法だ。 Cを直接呼び出す方法は、ビルドしたCのコードをPythonから直接呼び出す方法だ。 そのため、PythonとCの間でデータをやり取りするためのコードを書く必要がある。 長所としては、PythonのコードとCのコードが疎結合になりやすいこと、特別な設定を必要としないことなどが挙げられる。 短所としては、PythonのデータをCのデータに変換する過程でオーバーヘッドが発生することなどが挙げられる。 C拡張モジュールを使う方法は、PythonのC APIを使ってCのコードをPythonのモジュールとしてビルドする方法だ。 長所としては、PythonのデータをほぼそのままCに渡せるので速度が早いことなどが挙げられる。 短所としては、CのコードとPythonのコードと密結合になること、Pythonから直接データを受け取るための専用の関数を覚える必要があること、Cのコードをビルドするためにsetup.pyの設定が必要になることなどが挙げられる。 今回はあまりメンテする必要がないこと、速度改善が最重要の目的であることなどからC拡張モジュールを使う方法を選択した。 Tips2. Python.hの場所 C拡張モジュールを使う場合、Python.hというヘッダーファイルをインクルードする必要がある。 ただビルドするだけならPythonが勝手にPython.hの場所を探してよしなにやってくれるのだが、もしエディタで補完の恩恵を受けたいならPython.hの場所をエディタに教えてあげる必要がある。 C拡張モジュールは専用の関数が多いので、補完が効かないと非常に不便だ。 Python.hのパスはターミナルでpython3 -c "from sysconfig import get_paths; print(get_paths()['include'])"のように実行すると取得できる。 VSCodeなら設定画面でC_Cpp.default.includePathに上記のパスを追加してやれば補完が効くようになる。ただしC/C++という拡張機能を入れておく必要がある。 Tips3. setup.pyの追加 拡張モジュールを使う場合、setup.pyというファイルを追加して、Cのコードをビルドするための設定を記述する必要がある。 自分の場合はsetup.pyのように現状ではシンプルな内容になっているが、色々なリポジトリを見て回った感じ、いくらでも複雑な構成にできそうだった。 怖いのであまり奥深くには立ち入らないことにする。 Tips4. .pyiを追加する .pyiを作成することでPythonのコードからC拡張モジュールのコードを呼び出すための型ヒントを追加することができる。 これを行うことでエディタのインテリセンスが効くようになので、やっておいて損はないだろう。 _shanten.pyi - GitHub Tips5. 【告白】 CのコードはほぼChatGPTに書かせた!!!! 自分はCが書けないので既存のPythonのコードをChatGPTに投げて、「C拡張に変換して」とお願いしたらほぼ完成形のCのコードを書いてくれた。 一部だけ修正して終了。 いい時代になった…。 結果 再度10半荘分の牌譜を流し込んで関数の処理時間を計測したところ以下のようになった。 向聴数計算が処理時間上位にランクインすることはなくなり、全体の処理時間も約13秒程度にまで短縮された。 またpytest-benchmarkの結果をGitHub ActionsでGitHub Pagesに自動デプロイの記事で解説したベンチマーク計測処理を向聴数の計算にも適用していたのだが、その結果は以下のようになった。 ...

2025-06-19

SSHログイン時にターミナルの配色を変更して本番環境でのミスを防ぐ

概要 自分はさくらのVPS上でKonbuやNBAMashのようなWebアプリを運用している。 最近、ローカルで操作しているつもりが実はVPS上で操作をしていて、うっかりコンテナを落としてしまうというミスを多発させてしまった。 そこで本番環境にSSHログインをした際にはターミナルの配色を変更して、視覚的に本番環境とローカル環境を差別化することで本番環境での誤操作を防ぐことにした。 方法 .bash_profileに以下のコードを追加した。 # ssh接続時に文字色と背景色を変更する関数 function ssh() { if [[ "$TERM_PROGRAM" == "vscode" ]]; then DEFAULT_COLOR="#CCCCCC" DEFAULT_BG_COLOR="#171717" elif [[ "$TERM_PROGRAM" == "Apple_Terminal" ]]; then DEFAULT_COLOR="#000000" DEFAULT_BG_COLOR="#FFFFFF" fi # SSH接続時に文字色と背景色を変える echo -ne "\033]10;#FFFFFF\007" echo -ne "\033]11;#330000\007" # 実際にsshを実行 command ssh "$@" # 接続終了後に元の文字色と背景色に戻す echo -ne "\033]10;${DEFAULT_COLOR}\007" echo -ne "\033]11;${DEFAULT_BG_COLOR}\007" } コードを順を追って説明する。 まずは以下のようなsshの関数を書くことで、デフォルトのsshコマンドを上書きする。 引数は$@で取得できるので、ssh 引数1 引数2 ...のように実行したら、関数の内部でもちゃんとssh 引数1 引数2 ...のように実行される。 # ssh接続時に文字色と背景色を変更する関数 function ssh() { (...中略...) # 実際にsshを実行 command ssh "$@" (...中略...) } 次にデフォルトの文字色と背景色を変数に格納する。 ...

2025-06-07

おまえのオールをまかせるな - 口出ししてくる人への対処法

概要 社会人になって気づいたのだが、会社の中には安全圏からやたらと口出しをしてくる人がいる。 自分自身は特にリスクを背負うこと無く、その場の思いつきのアイデアを他人に投げかけて、他人のリソースを消費させてしまう人がこの社会には少なくない数存在しているのだ。 この記事ではそういった人に対する対処法を紹介する。 口出しを受け入れるかどうかの判定法 まずは口出しを受け入れるかどうかの判定法を紹介する。 口出しする人は基本的に「クライアントのために〜」とか「社会への貢献を〜」のようなきれいでカッコいい言葉を使ってこちらを説得しようとしてくる。 表面上は良いことを言っているので気を抜くと説得されてしまいそうになるのだが、事前に口出しを受け入れるかどうかの基準を設けておくことによって、言葉のきれいさに惑わされることなく冷静に判断を下すことができるようになる。 自分の場合は2つの判断基準を設けている。 1つめは「口出ししてくる人が精神的な負担を背負うのかどうか」だ。 要するに、口出ししてきた人が最終的な責任を負うのかどうかということだ。 口出しによって発生したタスクであなたが失敗した時に、口出ししてきた人が矢面に立って顧客に頭を下げるのならば、その口出しは受け入れても良いと思う。 なぜなら最終的に責任を取ってくれる人の口出しは本気で現状を良くしようとしている可能性が高いからだ。 逆に放任主義で「お前のミスはお前のミス」のようなスタンスをとる上司の口出しは無視しても良いだろう。 2つめは「口出ししてくる人が物理的な負担を背負うのかどうか」だ。 口出しした本人がそれによって多少なりともリソースを消費するのであれば、先程と同様にその口出しの本気度は高くなる。 逆に口出しした本人が一切のリソースを消費しない場合は、カッコつけたくて口出ししているだけの可能性も高い。 そのような口出しは本気度が低い可能性が高いので無視しても良い。 以上が個人的な口出しを受け入れるかどうかの判定法だ。 「精神的負担」も「物理的負担」も背負ってくれない人の口出しは基本的に無視するように基準を設定している。 逆にどちらか一方でも満たす人の口出しであれば、受け入れるかどうかは一考の余地があるのではないだろうか? 口出しする人への対処法 次に上記の基準を用いて口出しを「受け入れない」と判定した場合に、どうやって対処するかを紹介する。 これも大きく2つの方法があると思う。 1つ目は「適当に返事だけしておいて無視する」という方法だ。 両方の基準を満たさないような人はその場のノリで適当にカッコつけて口出ししていることも多い。 信念のない場当たり的な口出しは本人の中でも上手く落とし込めていないことが多いので、時間の経過とともに自然と忘れてくれる可能性が非常に高い。 口出しする人が普段から適当な人なのであれば、忘れることに賭けて無視するというのは有効な手段だ。 2つ目は「相手を巻き込む」という方法だ。 つまり口出ししてきた相手に精神的負担か物理的負担を強いることで、相手を基準を満たす人間に変化させるということだ。 これは使用方法を間違えると関係が悪化しかねないが、上手く使うと効果は絶大だ。 例えば「あなたがそのタスクに本気で取り組むのなら私も手伝います」というように「あなたがやる」→「私がやる」という物理的負担の矢印を作ることで相手に圧をかけることができる。 この時点で大半の人は口出しを引っ込めてくれる。 もし相手が圧に屈せず「やってやらあ!」となった場合もどうせ長続きはしないので、事前に「あなたがやる」→「私がやる」という構図を作って置くことで、相手がサボり始めたタイミングで自分も堂々とサボってフェードアウトできるようになる。 1つだけ注意点があり、それは「一緒にやる」と言ってはいけないということである。 「一緒にやる」という構図を作ってしまうと、相手は「ちょっと今回だけ忙しいから先にやっておいて」などと言って、徐々にフェードアウトしようとしてくる。 なので「あなた」→「私」という構図はくどいほどに徹底することが重要だ。 ちなみに精神的負担を背負わせるのは難しいと思う。 「精神的負担を背負わせる」ということは大抵の場合は「最終責任を負わせる」ということを意味し、これは「あなた」→「私」という矢印を構築することが難しくなるからだ。 精神的負担を背負わせたつもりが、知らぬ間にフェードアウトされている…というオチになるのが関の山だ。 「あなたが今までの〇〇倍の契約金で案件を取ってくるならやってもよいですよ」ぐらいが精神的責任を負わせる限界だろうか。 したがって、個人的には物理的負担を背負わせるほうが成功率が高いと思う。 口出しする人がきれいでカッコいい言葉を使うタイプの場合に巻き込む手法は特に有効だ。 相手もカッコつけてしまった手前、自分が巻き込まれそうになった場合に「いや、俺は君と違って忙しいんだ…」のようなダサい言い訳で逃げることが難しくなるのだ。 面と向かって言うのは勇気が必要だと思うが、経験上この手法はかなり有効だ。 まとめ 精神的負担も物理的負担も背負っていない人の口出しは必ずしも受け入れる必要はない。 受け入れたくない場合は「分かりました」と言いながら無視するか、相手を巻き込むことで大抵の場合は面倒事を回避できる。 中島みゆきも「その船を漕いでゆけ おまえの手で漕いでゆけ 精神的にも物理的にも負担も背負わぬ者に おまえのオールをまかせるな」と歌っている。 俺達には中島みゆきがついているんだ。 勇気が出るだろう?

2025-06-06

【書評】Java言語で学ぶデザインパターン入門 第3版

概要 デザインパターンの勉強をしたいと思ったので『Java言語で学ぶデザインパターン入門 第3版』を購入した。 転職先で未経験のJavaを扱うことも決まっていたので、Javaとデザインパターンを同時に学べるのは一石二鳥だと思い即決。 今回はその感想を書いていく。 #PR Java言語で学ぶデザインパターン入門 第3版 楽天 Amazon 良かった点 1. わかりやすい 本書は説明が豊富で、章ごとに考え方のヒントやクラスの役割などが丁寧に解説されている。 特に豊富なUMLが理解を大幅に手助けしてくれた。 余談だが、自分は新卒1年目のときに『オブジェクト指向設計実践ガイド』という書籍を読んで、その内容の難しさに挫折してしまったことがある。 本書と『オブジェクト指向設計実践ガイド』は趣旨の異なる書籍だが、テクニック自体は共通している点も数多くある。 本書はかなり説明が分かりやすく、Javaの継承やインタフェースさえ理解していればスラスラと読み進めることができるので、本書を中間セーブポイントとして利用することによって『オブジェクト指向設計実践ガイド』の内容も理解できるようになるのではないかという気がしている。 また機会があれば『オブジェクト指向設計実践ガイド』にも挑戦してみたい。 #PR オブジェクト指向設計実践ガイド 楽天 Amazon 2. 演習がある 本書では各章の末尾に演習問題が用意されている。 本文を目でなぞっていただけのときには気付けなかったことに演習を通して気づくことが何度もあり、かなり学びになった。 演習内容も設定がシンプルかつ面白くて、飽きずに取り組めた。 特に第23章の演習は骨太でかなり楽しかった。 デザインパターンの難しさ 本書に対する不満点は特に無いので、ここからはデザインパターン自体の難しさについて個人的に思ったことを書いていく。 1. 使い道がわからない 「これって本当に使い道あるのか?」と思ってしまうようなデザインパターンがいくつかあった。 Wikipediaのデザインパターンの記事を見ると、本書でも紹介されているGoFによる23のデザインパターンが『Code Complete』という他のデザインパターンの書籍で紹介されているのかどうかを一覧することができる。 そして、直感的に「これって使い道あるのか?」と感じたデザインパターンの大半は『Code Complete』では紹介されていなかった。 『Code Complete』は後発の書籍なので、GoFのデザインパターンの中でも特に使用頻度が高いものだけを厳選したのだと思う。 つまり『Code Complete』で紹介されていないデザインパターンは、使用頻度が低いものだと考えても問題はないだろう。 なので、本書を使ってデザインパターンの勉強をするときは、使う頻度が多そうか少なそうかでメリハリを付けて学ぶのが良いと感じた。 2. 違いがよくわからない デザインパターンの中には違いがよくわからないものがあり、「あれ、これさっきも勉強したような…」となることがあった。 そういうときは前のページに引き返して復習すればいいんだろうが、「とはいえコード自体はスラスラ読めてちゃんと理解できているし、デザインパターンのそれぞれの違いを言語化できるレベルまで理解する必要もないか」みたいに面倒くさがっている自分も存在した。 冷静に考えると、デザインパターンの凄さというのは暗黙知に境界線を引いて「この暗黙知にはこういう名前をつけます!」とラベリングし、暗黙知をエンジニア共通の知識に変えたことにある気がするので、デザインパターンの名前と内容が紐づいていない今の自分の状態は本末転倒な気もする。 これはデザインパターンのせいと言うより自分の怠惰さの問題なのだが、とはいえそもそもデザインパターン自体がMECEではない印象があり、自分以外にも違いが曖昧になっている人はかなり多い気がする。 違いが分からなくなったときに前のページに引き返せるかどうかが、私とあなたを差別化するポイントになるのではないかと思う。 まとめ かなり分かりやすく、演習も豊富で、デザインパターンの入門書としては非常に良い書籍だった。

2025-05-24

HugoにGoogle Analyticsを導入する

概要 Hugoで作成したブログにGoogle Analyticsを導入する方法を解説する。 まずPaperModに導入する方法を紹介する。 その後にPaperModに導入した際の思考の過程を紹介することで、他のテーマにも応用できるようにする。 環境 Hugo 0.146.6 PaperMod (commit 7cf752f8644fea1fc3dc7299352718d492c55182) PaperModに導入する方法 1. Google Analyticsのスクリプトタグを取得 Google Analyticsの管理画面でスクリプトタグを取得する。 タグ発行の手順は色々な方が書いてくれていると思うので今回は省略。 2. /layouts/partials/google_analytics.htmlにスクリプトタグを追加 /layouts/partials/google_analytics.htmlに取得したスクリプトをコピペする。 /layouts/partials/google_analytics.html <!-- Google tag (gtag.js) --> <script async src="https://www.googletagmanager.com/gtag/js?id=G-HTNQ9KZXWH" ></script> <script> window.dataLayer = window.dataLayer || []; function gtag() { dataLayer.push(arguments); } gtag("js", new Date()); gtag("config", "G-HTNQ9KZXWH"); </script> <!-- End Google tag (gtag.js) --> 3. テスト 管理画面からテストボタンを実行してテストする。 緑のチェックマークが出れば成功。 以上。 思考過程 自分がどのようにして上記の手法にたどり着いたか、その思考過程を紹介する。 考え方はどのテーマでも共通していると思うので、他のテーマでGoogle Analyticsを導入する際のヒントになると思う。 1. ドキュメントを探す まず「PaperMod Google Analytics」のようなキーワードでGoogle検索をした。 PaperModの場合は適切なドキュメントを見つけることができなかったので、テンプレートをコードリーディングすることにした。 ...

2025-05-24

pytest-benchmarkの結果をGitHub ActionsでGitHub Pagesに自動デプロイ

概要 kago-utilsというPython製の麻雀OSSを作っている。 将来的にはこいつを拡張して強化学習を行うことが目標だ。 強化学習をするとなると速度は命だ。 そこでpytest-benchmarkを使って逐一ベンチマークを行い、その結果をGitHub Pagesにデプロイし、パフォーマンスを改悪するようなコミットをしてしまっていないかどうかを可視化することにした。 最終的には以下のようなGitHub Pagesができる。 Benchmarks 基本的にはgithub-action-benchmark(GitHub)に書いてある通りにやればよいのだが、意外と行間を補完する必要があって手間取ったので、この記事にまとめておく。 サンプルプロジェクト というわけで、kago-utilsにpytest-benchmarkを導入して上手くいったのだが、色々とコミットがごちゃごちゃしてしまった。 そこで今回は新しくこの記事用のリポジトリを作成したので、説明ではこちらを使う。 リポジトリは以下。 pytest-benchmark-with-github-actions-example GitHub Pages用のブランチを作成 とりあえずコードを書く前にGitHub Pages用のブランチを作成しておく。 今回はベンチマークの結果を保存するだけなので空のブランチを作成する。 空のブランチを作成する方法が以下。 git switch --orphan gh-pages git commit --allow-empty -m "Initial empty commit for gh-pages branch" git push origin gh-pages git switch main git switchやgit checkoutで新しいブランチを作成する際に--orphanオプションをつけることで空のブランチを作成できる。 通常のコミットは何らかの変更点が必要だが、--allow-emptyオプションをつけることで、変更点なしの空のコミットを作成できる。これは今回四苦八苦する中で初めて知った。 あとはプッシュして終了。 これ以降は手動でgh-pagesブランチに変更を加えることはないので、うっかりgh-pagesブランチで作業をしてしまわないようにgit switch mainでmainブランチに戻っておく。 GitHubの管理画面でGitHub Pages用の設定を行う Settings > PagesのBranchにgh-pagesを選択する。 自分の場合は自動でgh-pagesが選択されていたが念の為。 mainブランチでの作業 ディレクトリ構成 ├── Pipfile ├── Pipfile.lock ├── README.md ├── src │ ├── __init__.py │ └── prime.py └── tests ├── __init__.py └── test_prime.py Pipfileの作成 Pipfile [[source]] url = "https://pypi.org/simple" verify_ssl = true name = "pypi" [packages] [dev-packages] pytest = "*" pytest-benchmark = "*" [requires] python_version = "3.12" [scripts] test = "python -m pytest --benchmark-skip" benchmark = "python -m pytest --benchmark-only --benchmark-json output.json" 自分はPipenvに慣れているのでPipenvを使っているが、pipやpoetryやuvなど各々の環境に併せて適宜読み替えてほしい。 ...

2025-05-21

いまさら五等分の花嫁の感想

概要 いまさら『五等分の花嫁』を読んだ。 その感想を書いていく。 結論だけ先に言うと、途中まではめちゃくちゃ面白くて途中からは微妙だった。 盛大にネタバレも含むので注意。 #PR 五等分の花嫁 (1) 楽天 Amazon 1行で分かる五等分の花嫁 見た目がそっくりな五つ子のヒロイン達とその家庭教師である主人公の風太郎によるラブコメ。 途中までは面白い 途中まではかなり面白かった。具体的に言うと二乃の告白まで。 特に林間学校編と二乃の告白はすごく良かった。 林間学校編ではラブコメにミステリー要素を加えるという試みが行われていて斬新で面白いし、二乃の告白のシーンも今までのラブコメの常識をあえて破壊するものになっていて意表を突かれた。 調べてないけどこの2つは世間でも特に人気が高いエピソードなんじゃないだろうか?すごく面白かった。 後半は個人的には微妙 二乃の告白以降は無理にミステリー要素を入れようとして展開がちぐはぐになっているように感じた。 代表例としてスクランブルエッグ編がある。 スクランブルエッグ編では五つ子の誰かが五女の五月に変装して、主人公の風太郎に家庭教師をやめるように言い捨てる。 風太郎はなぜ家庭教師をやめてほしいのかその理由を問うために五月に変装していた犯人を突き止めようとする。 スクランブルエッグ編のミステリー要素は「誰が五月に変装していたのか」ということだ。 作中で読者に提示されたヒントは2つ。 偽物の五月の足にはあざがあった 長女の一花の足にもあざがあった 賢い皆さんならもう誰が偽物の五月なのかお分かりかと思う。 そう、偽物の五月の正体は〜〜〜〜? … … … 三女の三玖でした。 いや、こんなん分かるか!!! 一花が偽五月でない根拠 三玖が偽五月である根拠 この両方は特に描かれることなく、スクランブルエッグ編は終了してしまう。 百歩譲って三玖が偽五月である根拠は無くても良しとしよう。 一旦ミステリー要素を忘れてただのラブコメだと割り切れば、いちいち起こった出来事に対してその根拠など必要ないからだ。 ただ、ラブコメだと割り切ったとしても「一花が偽五月ではない根拠」は必要だろう。 これが無いと一花のあざの描写は何だったんだ?となってしまう。 批判ばかりしていても芸がないので、ここで創作の才能ゼロの自分が納得できるストーリーを提案してみよう。 風太郎が偽五月の右足にあざを発見する 風太郎が鏡越しに一花の右足にあざがあるのを発見する 風太郎が「偽五月は一花だ」と思い込む よく考えると鏡で反転してるから一花のあざは左足だと気づく どうだろうか? めちゃくちゃベタだし改善の余地は大量にあると思うが、要するにこういう描写があれば一花のあざの描写もミスリードとして許容できるということを言いたいのだ。 「偽五月にはあざがあります」 「一花にもあざがあります」 「ただし、偽五月は三玖です」 これだけだとちょっと厳しいんじゃないかなあ…。 その後もチグハグな描写は続く… 一花のあざに代表される「一見するとミステリーを解くヒントになりそうで特に意味のない描写」はこれ以降も頻繁に現れる。 二乃の告白以降は終始ミステリー要素を無理に足そうとしてちぐはぐになっている印象だ。 作者はとっくにネタ切れしているのに読者が考察要素を要求し続けた結果、こういう感じになってしまったのではないかと推察する。 こういう意味のないミスリードを楽しめる人もいるんだろうが、個人的にはノイズに感じてしまった。 いっそミステリー要素を捨てて純粋なラブコメに振り切ってくれる方が楽しめた気がする。

2025-05-17

勉強時間を記録するWebアプリを開発した

概要 最近転職をした。 転職先ではJavaを使うのだが自分のJava経験は完全に0だ。 入社まで2ヶ月ほど期間があったので、せっかくだからJavaを使った個人開発でもしてJavaの勉強をしようと思った。 というわけで勉強時間を記録するWebアプリを作ることにした。 なぜ勉強時間を記録するWebアプリかと言うと、自分が欲しいからだ。 自分は怠惰な人間なので「〇〇時間勉強する」みたいな目標をビシッと決めないと勉強をするモチベーションの維持ができない。 社会人になってからは「毎四半期〇〇時間勉強をする」と目標を立てて、そこに向かって頑張るという作戦を取っている。 今のところは上手く機能している。 今までは勉強時間の管理にExcelを使っていて、正直Excelでも十分ではあったが、「Javaの勉強にもなるし、まあいっか」という感じでWebアプリを作ってみることにした。 アプリ名 アプリはその名も「Konbu」だ。 利用したい人がいるのかどうかは甚だ疑問だが、一応URLを載せておく。 https://konbu.zurukumo.dev なぜKonbuという名前なのかというと、大学の韓国語の授業で韓国語で「勉強」は「コンブ」と言うと習って、なんか可愛いなと思ったからだ。 どんな機能があるの? 機能はめっちゃ少ない。 勉強時間を記録する 目標を立てる この2つだけ。 Excel時代も結局この2つで十分だったので、個人的にはこれでいいかなと。 レスポンシブ対応もしていない。なぜなら自分があまりスマホを使わないから。 いきなり機能を盛り沢山にしても開発のモチベーションが維持できないし、とりあえず最低限の機能だけ実装した。 万が一にもユーザー数が増えて新機能の要望が来るようなことがあればその時に機能を追加するかどうかは考えようかな。 使い方 勉強時間の記録 勉強記録のページでは画像のような感じで上部のフォームから勉強時間を記録できる。 フォームの下には記録した勉強時間の一覧が表示される。 最近はずっとKonbuを開発しているので個人開発ばっかりだ。 更新や削除もできる。 目標の設定 目標のページでは画像のような感じで上部のフォームから目標を作成できる。 目標の下には作成した目標の一覧が表示される。 更新や削除もできる。 目標の分析 目標一覧のページから個別の目標をクリックすると個別の目標分析ページに移動できる。 いろんな指標や集計されたデータを見ることができる。 コンブくん なんらかの操作をすると右下にいるコンブくんが反応してくれる。 ChatGPTに作ってもらった画像だけど、最近は普通に愛着が湧いてしまっている。 感想 機能は少ないけど逆にそこが分かりやすくて良いのかなと思っている。 プロトタイプが完成した時点でExcelからKonbuに移行したので、なんだかんだもう1ヶ月くらい使っている。 自分で言うのも何だけど、結構使いやすいんじゃないかな? 個人開発は自分のためのツールを開発するのが一番楽しいですな。 JavaやSpringの勉強にもなったので良かった。

2025-05-15