コンテンツにスキップ

計算機教育に欠けている一課

本記事は MIT の講義「計算機教育に欠けている一課」を受けた僕のノートと個人的な感想をまとめたもので、講義の代替となるものではありません。

ここに 中国語の講義資料bilibili 熟肉 を添付しておきます。

パス

パスというのはまあ比較的基礎的なものですね。. は現在のディレクトリを表し、.. は一つ上のディレクトリを表します。これらは Windows でも共通です。

ただし Windows と Unix システムのパス区切り文字は異なります。Windows は \ を使用し、Unix は / を使用します。だから、Python の os.path のようなライブラリを使ってパスを処理するのがベストです。自分でパスを処理すると問題が起きやすいです。

2025-01-11 14:25:09 注意

Python の os.path は徐々に pathlib に置き換えられることが推奨されています。より現代的で、より読みやすいです

僕にとって印象深いのは LeetCode の 71 題目 です。Unix スタイルのパスを簡素化することが求められます。ぜひ皆さんもやってみてください。

Shell と Bash

このセクションの内容は実際 SSH で既に触れていますが、ここで少し補足します。

実を言うと、以前の僕は全部 Python でスクリプトを書いていました。例えば、Mercurius で APK や Windows ZIP をビルドして out フォルダに移動するスクリプトとか。でもこれって、スクリプトを使う人がみんな Python をインストールしている必要があって、明らかに良い選択とは言えませんよね。

Bash は Unix システムのデフォルトの Shell で、そのスクリプトファイルは .sh で終わります。Windows では WSL を使って Bash スクリプトを実行できます —— もちろん、Windows ではやはり PowerShell を使うべきだと思います。そのスクリプトファイルは .ps1 で終わります。もちろん、.bat.cmd という古いバッチファイルもありますね。

スクリプトを使う人全員に Python をインストールさせるわけにはいきません。

まず、Windows には PowerShell が内蔵されているし、Linux や macOS には bash が内蔵されています。システム元々のものを使えば依存が一つ減りますよね。もちろん問題もあって、.ps1.sh の二つのスクリプトファイルを用意する必要があります(実際多くのリポジトリがこうしています)。

それから Python スクリプトに必要な Python のバージョンが、システムに既存のバージョンと衝突する 可能性 があるし、一部の依存関係も既存の環境を汚染する 可能性 があります。もちろん、uv を使ってにゃん、uv を使ってありがとうにゃん。でも uv もダウンロードして使う必要があるわけで、プロジェクトが実際にこのツールを推せるかどうか、推す気があるかどうか次第です。

最後に、プロジェクト自体が多言語開発で Python が含まれているなら、それは仕方ないですね。

この講義を見ている間、僕も Termux を使っていました。最近 GitHub が調子悪くて、どのリポジトリに新しい Release があるのか全く分からなかったので、GitHub CLIjq コマンドを組み合わせて、最近の Release を取得するスクリプトを書きました。ここでは恥ずかしいので詳細は省きます。

Regex

正規表現は文字列をマッチングするためのパターンで、検索エンジン、テキストエディタ、IDE など、多くの場所で使われています。

Java を学び始めたばかりの頃、Minecraft のコマンドを模倣する Java プログラムを書いたのですが、まだ文字列の切り取りを使っていました:

Java
// コマンドをマッチング
public void match(String input) {

    int i; // コマンドのインデックス
    for (i = 0; i < Command.length; i++) { // 検索
        // 入力されたコマンドの左側がコマンドライブラリのコマンドと一致する場合
        if (input.regionMatches(0, Command[i], 0, Command[i].length())) {
            // 左側を切り取り、コマンドのインデックスと右側のスライスを toCommand 関数に渡す
            input = input.substring(Command[i].length());
            String[] splitCommand = input.split(" "); // 空白で入力されたコマンドを分割する
            toCommand(i, splitCommand);
            return;
        }
    }

    // 一致するコマンドがない場合は通知
    if (i == Command.length) {
        System.out.print("\33[31;1mNo matched command!\33[0m\n\n");
    }
}

正規表現を使えば、このプログラムはもっと簡潔になるかもしれません —— もちろん、こういったコマンドラインプログラム用のパッケージはちゃんとあります。例えば PicocliJCommander、Kotlin 専用の Clikt などです。

その後、VSCode も正規表現をサポートしていることに気づき、Python のクローラーを書くときも正規表現を使って欲しい内容を抽出しました。今では Mercurius も正規表現を使って日記の内容を検索できます。正規表現は本当に強力だと言わざるを得ません。

ただ、正規表現には時々落とし穴もあります。例えば 「熟肉」非常慢代码来自 Cloudflare, 使整个公司瘫痪 というビデオでは、小さな .*.*=.* の正規表現が Cloudflare 全体をダウンさせてしまいました。

Vim

僕は今でも VSCode を使っています。完全に Vim に移行するのはまだまだ難しいです:

  1. Vim の習得難易度が高い
  2. Vim は Shell 上で動作するので、PDF、ウェブページ、アプリなど、リアルタイムプレビューのコンテンツをどう操作すればいいのか?

マウスを捨てるのはまだ現実的ではないですが、確かに自分のコーディングスピードを上げたいとは思っています。たぶん VSCode の Vim プラグインが助けてくれるかな?

でもこれって本物の Vim とどれくらい違うんでしょうか? Vim プラグインを使う前に Vim を学ぶ必要があるんでしょうか?

セマンティックバージョニング

セマンティックバージョニングについては このリンク を参照してください。

僕が最初にバージョン番号を意識したのは、Minecraft のバージョン番号でした。1.7.2 のようなやつです。ただし Minecraft はこの規範に完全には従っておらず、Snapshot スナップショットバージョンでは別のバージョン番号形式も見られます: 24w06a。ここで 24 は 2024 年、w06 は 6 週目、a はその週の最初のスナップショットバージョンを表しています。

その具体的な形式については このリンク を参照してください。

source script.sh./script.sh の違い

うっすらと覚えているのですが、前者は「ソース化」と呼ばれていて、初めて使ったのは zsh を設定する時でした。

具体的には、前者は現在のセッションで sh ファイルを実行します。ファイル内で環境変数の設定などをした場合、実行後その設定が現在のセッションに適用されます。一方、後者はサブプロセスで実行され、外部のセッションには影響しません。

それに加えて、後者はユーザーに実行権限を要求します。chmod +x script.sh で設定する必要があります。

個人的な感想

これが「計算機教育に欠けている一課」だとすれば、僕に欠けているのは一課どころじゃないですね。

この講義は、この数年間で僕が理解した授業外の知識のほとんどを含んでいると言えます。そしてこれらの知識は 408 の四大科目 —— まあそれらも無視できないとはいえ —— と比べて、より実践的です。僕は毎日データ構造、計算機組成原理、コンピュータネットワーク、オペレーティングシステムとかいじっているわけじゃないですから。

僕は興味もとても重要だと思っています。あの四大科目の教育モデルは、完全に机上の空論で、全く興味が湧きません —— でもこの前 GFW の仕組みを勉強した時は楽しく見れたじゃないですか?

同時に、自分が学んだことがあまりにも少ないということにも気づきました。知識の範囲はそこそこ広くても、その深さは満足いくレベルには達していません。だから、今の卒業まで半年ある時間を利用して、こういった公開講座をもっと見ていきたいと思います。