(ch01-learn-python-with-ai)= # 第1章 AIと一緒にPythonを学ぶ この章では、本書の進め方を決めます。 使う道具、AI に任せる範囲、読者自身が確かめる範囲、そして最後に何ができあがるのかを先に共有します。 手を動かすのは次の章からです。 ここではまず全体像を見ます。 ## 1.1 この本で学ぶこと 本書で学ぶのは、次の4つを組み合わせてプログラムを作る手順です。 - **Ubuntu の端末**: コマンドを打ってコンピュータに指示を出す場所です。 - **AI 開発エージェント**: 端末の中で動き、ファイルを作ったり書き換えたりする AI です。 - **uv**: Python 本体とパッケージをまとめて管理する道具です。 - **Python**: 本書で書くプログラミング言語です。 **Ubuntu** は、Windows や macOS と同じ基本ソフト(OS)の仲間です。 Linux と呼ばれる種類のひとつで、無料で使えます。 新しいパソコンを買う必要はありません。用意のしかたは 1.6 と第2章で扱います。 図1-1が、4つの関係です。 ```{d2} :alt: フロントマシン(Windows / macOS)の端末アプリから Ubuntu につなぎ、その中で AI 開発エージェントがコードを書き、uv が用意した Python がそれを動かすという関係の図。 :width: 60% :align: center direction: down front: "フロントマシン\nWindows / macOS" { style.fill: "#f1f3f4" term: "端末アプリ" { style.fill: "#ffffff" } } ubuntu: "Ubuntu(基本ソフト)" { style.fill: "#e8f0fe" agent: "AI 開発エージェント\nコードを書く" { style.fill: "#fef7e0" } uv: "uv\nPython と道具を用意する" { style.fill: "#fef7e0" } py: "Python\nプログラムを動かす" { style.fill: "#e6f4ea" } } front.term -> ubuntu: "つないで操作する" ubuntu.uv -> ubuntu.py: "用意する" ubuntu.agent -> ubuntu.py: "コードを書く" ``` {.caption-center} 図1-1: 本書で使う4つの道具の関係 この4つは、それぞれ第2章から第5章で順に用意します。 いまは名前だけ見えていれば十分です。 学ぶ内容の中心にあるのは、Python の文法そのものではありません。 文法は必要な分だけ第2部で扱います。 本書が繰り返し練習するのは、**AI が書いたコードを自分で確かめて、自分で変える手順**です。 読み終えたときの到達点は、次の状態です。 - 端末で Python のプログラムを作って実行できる - AI に依頼して生成されたコードを、行ごとに何をしているか説明できる - エラーが出たときに、原因の場所を自分で見つけられる - 自分で決めた仕様を、小さく分けて AI に依頼できる - 端末で動くテキストのゲームをひとつ完成させ、自分で機能を足せる 最後には、端末の中で動くゲームがひとつ完成します。 どんなゲームかは 1.5 で見ます。 ## 1.2 AI時代にPythonの基礎を学ぶ意味 AI がコードを書けるのに、なぜ基礎を学ぶのでしょうか。 理由は、コードが正しいかどうかを決めるのは実行結果であり、その実行結果を読む役目が読者の側に残るからです。 短い例を見てみます。 「1 と入力したら探索、それ以外なら休む」という、ごく簡単なプログラムです。 ```{literalinclude} ../../../src/ch01/wrong_choice.py :language: python ``` {.caption-center} リスト1-1: wrong_choice.py このプログラムは、エラーを出しません。 実行すると、最後まで動きます。 ```text 1か2を入力してください > 1 休みます ``` 1 と入力したのに「休みます」と表示されました。 `input()` が受け取る値は文字列の `"1"` で、比較している `1` は数値です。 別のものを比べているので、条件は成立しません。 `input()` は、何を入力されても常に文字列を返します。 そのため、この比較はどんな入力に対しても成立しません。 文字列の `"1"` と数値の `1` の違いは、第7章と第9章で扱います。 この事故のしくみを図1-2に示します。 ```{d2} :alt: 1 と入力しても input() が返すのは文字列の「1」なので、「1」と数値の 1 の比較が不成立になって else が実行され、エラーが出ないまま意図と違う結果になる流れの図。 :width: 55% :align: center direction: down inp: "1 と入力する" { style.fill: "#f1f3f4" } val: "input() が返すのは\n文字列の \"1\"" { shape: rectangle style.fill: "#e8f0fe" } cmp: "\"1\" == 1 か" { shape: diamond style.fill: "#fef7e0" } out: "休みます\n(else が実行される)" { style.fill: "#fce8e6" } err: "エラーは出ない" { style.fill: "#f1f3f4" style.stroke-dash: 3 } inp -> val val -> cmp cmp -> out: "不成立(文字列と数値は別もの)" out -> err: "だから気付けるのは\n結果を読んだ人だけ" ``` {.caption-center} 図1-2: エラーにならないまま意図と違う動きをする ここで見てほしいのは、文法の話そのものではありません。 **エラーが出ないまま、意図と違う動きをするコードが存在する**という事実です。 AI が生成したコードにも、これは起こります。 そして、エラーが出ない以上、それを見つけられるのは実行結果を読んだ人だけです。 コードが読めると、次の3つができるようになります。 - 実行結果を見て、意図と違う箇所に気付ける - AI に「どこがおかしいのか」を具体的に質問できる - 直った理由を確認してから、次に進める 逆に読めないままだと、動かないときに打つ手がなくなります。 AI に「直して」と繰り返し頼み、変わっていくコードを眺めるしかありません。 基礎を学ぶ目的は、AI を使わないためではなく、AI に何をどう頼めばよいかを自分で決められるようにするためです。 ## 1.3 AIに任せることと自分で確認すること 本書では、AI にコードを書かせます。 ただし、任せる作業と自分で行う作業を分けます。 その区分を表1-1にまとめました。 ```{list-table} 表1-1: 役割の分担 :header-rows: 1 :widths: 45 55 * - AI に任せてよいこと - 読者が自分で行うこと * - コードを書く、書き換える - 何を作るかを決める * - 文法や関数の意味を説明する - コードを読んで意味を確かめる * - エラーメッセージの原因を説明する - 実行して結果を見る * - テストケースの案を出す - テストを実行して結果を読む * - 名前や構成の案を複数出す - どの案を採用するかを決める ``` 境目を図1-3に示します。 ```{d2} :alt: 左に AI へ任せてよいこと(コードを書く、文法やエラーの説明、テストや名前の案)、右に読者が自分で行うこと(何を作るかを決める、コードを読む、実行して結果を読む、案を選ぶ)を並べ、あいだに「手元でしか確かめられない」という境目を置いた図。 :width: 80% :align: center direction: right ai: "AI に任せてよいこと" { style.fill: "#e8f0fe" a1: "コードを書く・書き換える" a2: "文法やエラーの意味を説明する" a3: "テストや名前の案を出す" } me: "読者が自分で行うこと" { style.fill: "#e6f4ea" b1: "何を作るかを決める" b2: "コードを読んで意味を確かめる" b3: "実行して結果を読む" b4: "どの案を採るかを決める" } border: "手元でしか確かめられない" { style.fill: "#fef7e0" style.stroke-dash: 3 } ai -> border -> me ``` {.caption-center} 図1-3: 任せる側と、自分で行う側の境目 分け方の根拠は単純です。 右側の列はどれも、**読者の手元でしか確認できないこと**を扱っています。 どんなゲームにしたいのか、いま画面に何が出たのか、それが望んだ結果かどうか。 これらは読者にしか判断できません。 左側の列は、書き方の知識があれば済む作業です。 ここは AI が得意で、しかも速い分野です。 この分担は、本書のハンズオン問題でも守ります。 問題文には「AI に依頼する場合」の依頼文を載せますが、そのあとに必ず「確認」の手順を置きます。 生成されたコードを自分で実行するところまでが一問です。 ## 1.4 生成・読解・実行・検証のサイクル 本書の作業は、ひとつの流れの繰り返しです。 図1-4がその流れです。 ```{d2} :alt: 目的を決める、AIに依頼する、生成されたコードを読む、uv で実行する、結果を確認する、自分で変更する、の6段階が輪になって次の目的へ戻るサイクルの図。 :width: 45% :align: center direction: down a: "1. 目的を決める" b: "2. AIに依頼する" c: "3. 生成されたコードを読む" d: "4. uv で実行する" e: "5. 結果を確認する" f: "6. 自分で変更する" a -> b -> c -> d -> e -> f f -> a: "次の目的を決める" ``` {.caption-center} 図1-4: 本書で繰り返す学習のサイクル 各段階でやることは、次のとおりです。 1. **目的を決める**: 「メニューに終了を追加する」のように、1文で言える大きさにします。 2. **AI に依頼する**: 目的と制約を書いて渡します。依頼文の書き方は第3章で扱います。 3. **コードを読む**: 行ごとに、何をしている行かを声に出せる状態を目指します。 4. **実行する**: `uv run python ファイル名` で動かします。 5. **結果を確認する**: 出た結果が、決めた目的を満たしているかを見ます。 6. **変更する**: 自分の手で1か所だけ変えて、また実行します。 3番目と4番目のあいだに、もうひとつ習慣づけたいことがあります。 実行する前に、画面に何が出るかを予想してください。 予想と結果が一致すれば、理解が深まっている目安になります。 一致しなければ、そこに学ぶべきものがあります。 一周を小さく保つことが、この流れをうまく回すこつです。 一度の依頼で機能を5つ頼むと、動かなかったときにどこが原因か絞れません。 ひとつ頼み、動かし、確かめてから次へ進みます。 ## 1.5 本書で作るターミナル探検RPG 本書で完成させるのは、端末の中で動く**ターミナル探検RPG**です。 画面はすべて文字で、操作は数字の入力だけです。 実際に遊んだところを見てみます。 `>` の右側が、キーボードから入力した文字です。 ```text ================================ ターミナル探検RPG ================================ 冒険者の名前を入力してください > テト テト の冒険がはじまる! 1: 探索する 2: ステータス 3: どうぐを使う 4: ショップ 5: セーブする 6: 冒険をやめる > 1 あたりを探索した…… 6G を拾った! 1: 探索する 2: ステータス 3: どうぐを使う 4: ショップ 5: セーブする 6: 冒険をやめる > 1 あたりを探索した…… ゴブリン があらわれた! テト: 30/30 ゴブリン: 18 1: たたかう 2: にげる > 1 テト の攻撃! ゴブリン に 4 のダメージ。 ゴブリン の攻撃! テト は 5 のダメージを受けた。 テト: 25/30 ゴブリン: 14 1: たたかう 2: にげる > 1 テト の攻撃! ゴブリン に 5 のダメージ。 ゴブリン の攻撃! テト は 5 のダメージを受けた。 テト: 20/30 ゴブリン: 9 1: たたかう 2: にげる > 1 テト の攻撃! ゴブリン に 5 のダメージ。 ゴブリン の攻撃! テト は 5 のダメージを受けた。 テト: 15/30 ゴブリン: 4 1: たたかう 2: にげる > 1 テト の攻撃! ゴブリン に 4 のダメージ。 ゴブリン をたおした! 経験値 12 と 16G を手に入れた。 レベルが上がった! Lv.2 になった。 ``` 完成版に入っている機能は、次のとおりです。 - 探索して、敵と出会ったり、どうぐや金貨を拾ったりする - 敵と戦う。攻撃するか、逃げるかを選ぶ - 経験値をためてレベルを上げる - 拾ったどうぐを使う。ショップで買う - 冒険の記録をファイルに保存し、次回に読み込む これをいきなり作るわけではありません。 第2部で表示や条件分岐といった部品を作り、第3部でエラーとテストの扱いを身につけ、第4部で組み立てます。 第5部では、完成したゲームを書き直しながら、Python が持っている機能をひととおり使えるようにします。 第6部では、ほかの人の環境でも同じように動かせる形に整え、最後は自分で決めた機能を追加します。 画面に出ている日本語は、プログラムの中に日本語のまま書いてあります。 Python では、表示する文字に日本語をそのまま使えます。 ゲームを題材にする理由は、結果が画面に出るからです。 思ったとおりに動いたかどうかを、その場で目で確かめられます。 ## 1.6 本書で使用する開発環境 作業は、大きく2つの役割に分かれます。 いま使っているパソコン(本書では **フロントマシン** と呼びます)では、文字を打つための端末アプリだけを動かします。 Windows でも macOS でもかまいません。 Python を動かすのは **Ubuntu** の側です。 本書では、次の3つのどれかで用意します。 - **WSL**: Windows の中で Ubuntu を動かす - **OrbStack**: macOS の中で Ubuntu を動かす - **ssh 接続**: 別の場所にある Ubuntu につなぐ。Windows も macOS も、標準の端末アプリから接続できます WSL と OrbStack は、いま使っている環境とは切り離された場所に Ubuntu を用意します。 Windows や macOS の設定を書き換えるものではありませんし、使わなくなったら消せます。 3つのどれを選んでも、第3章から先の手順は変わりません。 用意のしかたは第2章で扱います。 Ubuntu の中で使う道具は3つです。 - **AI 開発エージェント**: 文字だけの画面で動く AI です。 チャットの画面ではなく、端末の中でファイルを作ったり書き換えたりします。 Claude Code や Gemini CLI といった製品があります。第3章で扱います。 - **uv**: Python 本体とパッケージをまとめて管理する道具です。 `uv run python ファイル名` のように、コマンドの名前としても使います。第4章でインストールします。 - **Python**: 本書の執筆時点では 3.12 を使います。 別のバージョンへの切り替えも uv でできます。uv が用意するので、先に入れておく必要はありません。 インターネット接続も必要です。 uv のインストールと、AI 開発エージェントの利用で使います。 **本書は Ubuntu のデスクトップ画面を使いません**。 操作はすべて文字で行います。 理由は 2.1 で説明します。 AI 開発エージェントには複数の製品があり、本書はそのどれかひとつに手順を固定しません。 本文では「AI 開発エージェントを起動し、次の依頼を入力します」という書き方をします。 製品ごとに違う部分は、第3章で補足としてまとめます。 AI 開発エージェントを用意できない場合でも、本書は読み進められます。 本書に載せたコードを書き写して進める形になります。 その場合の進め方は 3.10 で扱います。 ## 1.7 本書の読み進め方 読み進めるときに守ってほしいことが3つあります。 **手を動かす**。 本文に出てくるコマンドとコードは、読むだけでなく実際に打ってください。 画面に出る文字を見た経験が、あとでエラーを読むときの手がかりになります。 **予測してから実行する**。 実行結果を載せている箇所では、まず自分で結果を予想してから実行してください。 予想が外れたときが、いちばん学べる瞬間です。 最初はまったく予想できなくてもかまいません。確かめていくうちに、少しずつ当たるようになります。 **自分の言葉で説明する**。 節がひとつ終わったら、そこで作ったコードが何をしているかを声に出してみてください。 説明できない行が残っていたら、その行を AI に質問します。 第2章から第40章の終わりには、ハンズオン問題があります。 本文を読み終えてから取り組んでください。 問題には実行コマンドと実行例が付いているので、自分の結果と見比べられます。 「AI に依頼する場合」の依頼文も載せていますが、そのまま貼って終わりにせず、生成されたコードを読んでから実行してください。 本文の表記の約束は、次のとおりです。 - 端末に入力するコマンドは、次の形で示します。 ```bash uv run python hello.py ``` - プログラムの実行結果は、次の形で示します。 行頭の `>` は入力を待っている印で、その右側が入力した文字です。 ```text 1: 探索 2: 休む > 1 探索を開始します ``` - 本書に載せるコードには、`リスト7-1` のような番号を付けています。 同じ番号のファイルを、読者のプロジェクトにも作ります。 うまく動かないときは、まず第13章「エラーを読む」を参照してください。 環境そのものが動かないときは、第4章の 4.7 と第5章に戻ります。 次の章では、その環境の入り口である端末を開きます。