おんがえしの blog

作ったプログラムと調べた技術情報

英語のハノンを読みながらChatGPTに質問する

少しずつ続けている英語のハノンがついに上級まで来ました。

最近試している方法で、課題を進めているときに分からないことや気になることが出てきた場合に、それを問いの形にして ChatGPT に質問する、ということをやっています。勉強中に分からないことがあるときはたとえハルシネーションのリスクがあっても何らかの回答を読みたいと感じているものですし、さらに例題や解答として出ている文が正しいことはある程度保証されているため、ただ知らないことを ChatGPT に聞くよりも安心して質問することができます。

Unit 10.6

例を挙げてみます。以下の文を It is ... that ... の強調構文に直せというものです。

Not until I graduated from college was I aware of the importance of study.

解答はこのようになります。

It wasn't until I graduated from college that I was aware of the importance of study.

書き方は分かったのですが、この2つの文をどうやって使い分ければいいのかが気になりました。ということで問いを立てて教えてもらいます。

質問

2つの文を訳して違いを教えて。

Not until I graduated from college was I aware of the importance of study.
It wasn't until I graduated from college that I was aware of the importance of study.

回答(ここは ChatGPT が生成した文)

訳:

  1. Not until I graduated from college was I aware of the importance of study.
    「大学を卒業して初めて、勉強の重要性に気づいた。」

  2. It wasn't until I graduated from college that I was aware of the importance of study.
    「大学を卒業して初めて、勉強の重要性に気づいた。」

違い:

文の意味はほぼ同じで、「大学を卒業するまで勉強の重要性に気づかなかった」という内容を表しています。ただし、文法構造ニュアンスに若干の違いがあります。

  1. Not until...構文

    • 形式的で強調された印象を与える文。
    • 倒置構文(主語と動詞の語順が入れ替わる)を用いるため、やや硬い印象。
    • 詩的または文学的な表現として使われることが多い。
  2. It wasn't until...構文

    • 日常会話や書き言葉で自然に使われる表現。
    • 「It wasn't until... that」という構造が原因と結果を明確に強調する役割を果たす。

使用場面:

  • 1番目の文はフォーマルなスピーチやエッセイで効果的。
  • 2番目の文は日常会話やカジュアルな文章で自然に使いやすい。

どちらを使うかは、文の雰囲気や場面に応じて選ぶとよいでしょう。

まとめ

倒置があるとフォーマルな印象になる、というのが今回は特に参考になりました。

ChatGPT などの LLM が質問者にとって良い回答を出せるかどうかは、問いの立て方に大きく影響されます。実際のところ、ChatGPT は確率で続きを書く機械(from 深津式プロンプト読本)です。参考書で問題を解いたり本を読んでいる際に自分が知りたくなったことをベースに問いを立てることは、問いの精度を高めるのに役立ちます。

正確な記述が本の中に含まれていること、つまり信頼できる足場がある状態から LLM と対話することが重要なのだと感じています。

ホームページを VitePress でリニューアルした

ongaeshi.me

自分のウェブサイトを VitePress でリニューアルした。 自分がやりたいことは VitePress のデフォルトテーマの機能だけで完全に賄うことができた。一通りそろっていている。起動が早いのもよい。

レポジトリはGitHubで管理されており、push すると自動で deploy されるようになっている。この辺りはほぼ VitePress 公式の設定でうまくいった。

github.com

一番の目的は Markdown で書けるようにしてウェブサイトの更新頻度を上げるためで 、これで Obsidian を使って原稿の執筆が可能になった。普段使っている Vault に https://ongaeshi.me/history.html の原稿をコピーして運用している。追記したいときは Obsidian で編集・確認後、そのままクリップボード経由で GitHub にコミット。これでモバイルからでもホームページの編集ができるようになった。

Obsidian Web Clipper がすごい

https://obsidian.md/clipper

最近リリースされたばかりの新機能。ブラウザの拡張機能として使えて、Web 上の記事を簡単に Obsidian 上に取り込むことができる。Web 上にあるたくさんのドキュメントを読むのに重宝している。

iOS からも使える

Safari の拡張機能としてもリリースされているので実はスマホからも使えるのがポイント高い。SNS で流れてきた記事をスマホでクリップして後からオフラインで読んだり、はてブや Pocket でブックマークしておいた(後で読まれることのない)記事をまとめて取り込んだりできる。

PC でまとめて取り込んで後からスマホで読む

PC の Firefox からまとめて取り込んで、後からスマホで読む。PC だとちょっと取り込んだデータが壊れていてもこっちで加工したり複数のクリップを1つにまとめたりの編集作業が簡単にできる。

PC とモバイルの Obsidian 間の同期は色々なツールがあるのでそれぞれのお気に入りを使うとよい。(私は Obsidian Sync を使っている。)

専用の valut 「scrap」

長い記事を大量に取り込むのを躊躇しないように、メインで使っている Obsidian ノート(以下 main vault)とは別の専用の vault を作ることにした。名前は「scrap」とした。

scrap valut

この vault には気になった記事やページをどんどん取り込むことができ、情報収集がスムーズに進む(購入したいものの Amazon ページとかも取り込んでいる)。フォルダ構造も専用の vault なので極力シンプルにしている。

フォルダ名 説明
Clippings Obsidian Web Clipper がデフォルトで取り込むフォルダ。
Archive 読み終わったらこっちに移動。

Obsidian Web Clipper はデフォルトだと開いている vault に対して取り込みを行うので、設定で scrap vault を直接指定して取り込むようにしている。

Obsidian Web Clipper Settings

vault を分けておくことで scrap に絞って全文検索できるようになるのも便利。

外国語の記事は翻訳したものを取り込む

原文はリンクさえ残っていれば(それは Obsidian Web Clipper がやってくれる)いつでも確認できると割り切る。

Google ウェブサイト翻訳で翻訳したページを直接取り込むようにしている。日本語だと読むスピードが全然違う。ちまちまと頑張っている英語の勉強はこの記事は面白そうかの判断に使っている。

※ 書きながらこのメソッドなら中国語だろうがドイツ語だろうが何だって読めるじゃん!と思ったが、パッと見たときに面白そうかの判断が難しいんだろうなぁ。

取り込んだ記事にメモを残す

記事を読む中で気になった箇所には==テキスト==でハイライトを付ける。自分の考えをその場でメモとして追記してしまうこともある。

能動的に読んだ方が記憶の定着率がよいので色々手を動かしながら読むと理解力が上がる感覚がある。

メインノートにスクラップ

読み終わって特に面白いと感じた記事は、ハイライト部分などを抜粋して main vault に新規ページとしてスクラップする。このプロセスによって、日常的に参照したい情報と一時的な情報を自然に分けることができ、 main vault が効率よく整備される。

実用 git 第3版を読んだ

内部実装を分かりやすく説明した2章が特に面白い。 それぞれはシンプルな blob, tree, commit の組み合わせで複雑なバージョン管理が実現できているのが分かった。

blob はBinary Large OBjectの略だということをこの本で初めて知った。

ChatGPT さんにも聞いてみる。

「blob」は「Binary Large Object」の略です。データベースやファイルシステムで、画像や動画、音声データなどの大量のバイナリデータを扱う際に使われます。構造化されていない大きなデータをそのまま保存するための形式として広く利用されています。

「.NETのクラスライブラリ設計 改訂新版」を買った

最近買った C# 系の本の中ではダントツでよい。巨大な API ライブラリを設計するときに気を付けることが具体的に書いてあって参考になる。

neuecc 氏が前書きを書いていて 2章が素晴らしいと書いてあったけどそのとおり2章が素晴らしかった。ここまででも十分におつりが来る感触はある。

以下の引用が面白かった人は購入する価値があると思います。.NET 開発者が API 設計で後悔しているところが読めるなんてそんなに知見に溢れた書籍はなかなかない。

特によかったところ

自分と同じようなユーザー向けに設計するのは簡単で、そうではない人向けに設計するのはとても難しいことです。正直に言うと、ドメインの専門家によって設計された、ドメインの専門家にしか使えないAPIが多すぎます。


1回の大規模なユーザビリティスタディの計画、設計、実施に多大な労力を費やすよりも、API開発プロセス全体で、より小さく、より範囲を絞ったスタディを何度も実施する方が、はるかに価値が高い


主流のシナリオのAPIで必要となる初期化を、最小限に抑えるように設計すべきです。理想的には、基本的なシナリオ用に設計された型を使い始めるには、既定のコンストラクター、または単一のパラメーターを持つコンストラクターのいずれかで済むようにすべきです。

フレームワーク設計原則

フレームワークは、使い方のシナリオのセットと、それらのシナリオを実装するコードサンプルから設計を始めなければならない。


単純なシナリオでは、フレームワークはドキュメントを必要とせずに使用可能でなければならない。

.NET 開発者が API 設計で後悔しているところ

この逆もまた真なりで、「ほとんど使用されない型が含まれる名前空間に、一般的に使用される型を入れてはならない」と言えるでしょう。StringBuilderは、私達が後になってSystem名前空間に含めておけばよかったと思ったものの例です。この型はSystem.Text名前空間にありますが、その名前空間にある他の型よりもはるかに高い頻度で使用されるうえ、それらの型とはあまり関係がありません。


私の「もし願いがかなうなら、やり直したいこと」トップ10のひとつは、System.Threading.Tasksにあります。私達は当初、CPUベースの並列処理に焦点を当ててこれらのAPIを設計したのですが、時がたつにつれて、その最も一般的な使い方は当初の時点よりもはるかに、I/Oベースの非同期処理に焦点を当てたものへと変わってしまいました。そして、私達が当初設定した既定値の一部は、前者の場合は非常に適切なものでしたが、後者にとっては有害なものになりました。

ブログ執筆を加速させるコマンドラインインターフェースを作成した

このブログに素早く投稿するために、個人用のコマンドラインインターフェース(CLI)を作った。

github.com

  • 内部で blogsync を使っている。
  • Ruby + Thor で作成し、runablog という名前のコマンドとして、どこからでも実行できるようにしてある。

投稿: blog new

新規記事を作成するときは new コマンドを使う。引数として URL を指定するカスタムパスを渡す。

$ blog new path/to/article
     store /Users/ongaeshi/blog/ongaeshi.hatenablog.com/entry/path/to/article.md
  • 下書きとしてはてなブログ上に空の記事が投稿される。
  • URL は https://ongaeshi.hatenablog.com/entry/path/to/article になる。
  • 対応するファイルが /Users/ongaeshi/blog/ongaeshi.hatenablog.com/entry/path/to/article.md に作成される。

blog new 直後の path/to/article.md

---
Title:
URL: https://ongaeshi.hatenablog.com/entry/path/to/article
EditURL: ...
PreviewURL: ...
Draft: true
---

(ここに記事を書いていく)

執筆: blog edit

$ blog edit
  • ブログ記事が格納された git レポジトリをVSCode で開く。
  • blog new で作成したファイルを開いて記事を書いていく。
  • 記事の執筆が終わったら draft: true の行を削除して blog commit コマンドを実行する。

投稿: blog commit

$ blog commit

または

$ blog commit -m "/path/to/article を投稿"
  • 裏で blogsync push してから git commit を行う
  • blogsync push する記事は以下のどれか
    • まだ追加されていないファイル (git status --porcelain)
    • 編集済みのファイル (git diff --name-only)
    • main に pushしていないファイル (git diff --name-only origin/main..HEAD)
  • blogsync push と git commit を同時に行うことでどちらかの実行し忘れを防ぐ。(blog コマンドを作る前はこの操作ミスが本当に多かった)

感想

ここ1か月ほど、快適にブログ執筆するためのインターフェースはどうなっているのがよいかを試行錯誤していた。 個人的には特に以下の辺りが重要だった。

  1. ブログのカスタムパスは必ず指定する。
  2. blogsync post では標準入力を受け付けずに自動で空の記事を作成する。
  3. 空の記事がデフォルトになるので必ず下書きで作成する。(オプションからは指定できないようにする。)
  4. git commit と blogsync push を1つのコマンドできるようにする

自分用コマンドを作った効果は抜群で今月だけでだけですでに7本の記事を執筆できている。 今年6月までに書いた記事が10本なので1か月で半年分を追い抜きそうなペース。

よいインターフェースには利用者の力をブーストする、もしくは最大限に発揮させる力があると改め感じた。

まとめ

blogsync に薄いラッパーを被せて自分のブログ投稿ワークフローに最適なインターフェースを作った。 ユーザーにフィットしたインターフェースをデザインすることは、個人や組織の開発効率を飛躍的に向上させる。

今や、重要な内部パーツは多くがOSSとして既に存在している、あるいはLLMによって生成できる時代になった。 そのため、様々な状況に対応できるインターフェースを作成することが、これからのプログラマにとって一層重要なスキルとなりそうな予感がする。

Spotify で5分だけ音楽を聴く

例えば5分だけ休憩したいときや集中して作業したいとき、タイマーをかけるのではなく、せっかくなら Spotify で好きな音楽をかけたくなるときがある。

ところが Spotify は自動再生機能があるため、曲が終わったらそれに関連した別の曲をどんどん流してくるので気が付くと休憩時間が伸びてしまって困る。iOS のタイマーは何故かヘッドホンに流せずスピーカーに音が出るのでこれも駄目。

自動再生をその都度切るのは面倒なので、最近は「終わりの曲」を決めて、その前に大体指定時間を満たすような曲をつなげるようになった。終わりの曲には波の音を使っている。(他の曲と明らかに違うことが分かればどんな音でもよい、自分は海の音が好きなのでこれ)

「次に再生」で好きな曲をつなげて、最後に波の音を流すとなんとなくタイマーみたいな効果があっておすすめです。