CHAPTER 9 ・ AIと一緒に、中級者として / Lesson 36
AIが書いたコードを点検する(中級)
エラーの握りつぶし、決め打ちの値、遅い書き方、危ない操作。中級者の目でチェックする観点です。
このレッスンが終わったら
「AIのコードは、握りつぶし・決め打ち・上書き削除・外部送信の4点で点検する。分からない部分は、AIに説明させてから採用する」と言える。
こんな場面、ありませんか?
AIが書いたコードを実行したら、エラーも出ず、数字がきれいに表示された。基礎編では、そんなときこそ「読む」「検算する」と学びました。中級になると、コードが長くなり、動いているのに、間違っている(あるいは危ない)コードに出会う場面が増えます。
次は、AIが書いた、売上CSVの合計を出すコードです。messy.csv は、表記ゆれや欠損が混ざった10行のデータです。
この欄では、サンプルファイルが使えます。実行のたびに、ファイルは最初の状態に戻ります。
▶ 実行を押すと、ここに結果が出ます
エラーはなく、「96000」と表示されました。ところが、messy.csv をExcelで開くと、金額の入った行が8行あり、足すと50万円を超えます。表示された合計は、5分の1以下です。何が起きたのでしょうか。
点検の観点を、順番に当てる
「読む」だけでなく、決まった観点で、1つずつ当てていくと、見落としが減ります。これが、AIのコードを点検(コードレビュー)するということです。
| 観点 | 見つけるサイン | 起きること |
|---|---|---|
| ① エラーの握りつぶし | except: のあとが pass、except Exception で空のデータにする | 間違いに気づけない |
| ② 決め打ち | パス、日付、列名、税率などが、コードに直接書かれている | 他のPC・他の月で壊れる |
| ③ 上書き・削除 | open(..., "w") で元のファイルを開く、os.remove | 元のデータが失われる |
| ④ 外部への送信・秘密情報 | requests.post、API_KEY = "..." | 情報が漏れる |
| ⑤ 遅い・重い書き方 | ループの中でファイルを何度も開く | 件数が増えると終わらない |
| ⑥ テストがない | 確かめる手段がない | 直したときに壊れても分からない |
先ほどのコードは、①に当たります。except: で全部のエラーを受け止め、pass で何もしないため、変換できなかった行が黙って捨てられています。この握りつぶしを外して、何が起きているのか、見える形にします。
この欄では、サンプルファイルが使えます。実行のたびに、ファイルは最初の状態に戻ります。
▶ 実行を押すと、ここに結果が出ます
8行が捨てられていました。原因の多くは、'120,000' のような桁区切りのカンマで、int() が変換できなかったためです。一方、''(空欄)と '不明' は、本当に変換できない行です。捨てるなら、何件捨てたかを必ず見えるようにする。これが、握りつぶしを避ける基本です(Lesson 09)。
怪しいコードを、読む
実際のAIのコードは、1本に複数の問題が混ざっています。次のコードから、②③④の問題点を探してみてください(動かさずに、読むだけです)。
import csv
import os
import requests
API_KEY = "sk-abc123-secret"
path = "C:\\Users\\tanaka\\Desktop\\expenses.csv"
with open(path, encoding="utf-8") as f:
rows = list(csv.DictReader(f))
total = sum(int(r["金額"]) * 1.1 for r in rows)
requests.post("https://example.com/upload", json={"total": total}, headers={"Authorization": API_KEY})
os.remove(path) # 後片付けAPI_KEY = "sk-abc123-secret"④ 秘密のキーが、コードに丸見え(環境変数に置く。Lesson 32)path = "C:\\Users\\tanaka\\..."② 田中さんのパソコンにしかない場所の、決め打ちint(r[...]) * 1.1② 税率の決め打ち。8%の商品も、10%で計算されるrequests.post(...)④ 合計額を、外部のURLに送信している。送り先と中身を確認os.remove(path)③ 元のファイルを、削除しているどの行も、1行ずつ見れば、もっともらしく見えます。観点を決めて見るから、気づけるのです。AIに点検を手伝ってもらうときは、次のように頼みます。
AIに、点検を頼むときの文章
次のPythonコードを、点検してください。問題点を、重要度の高い順に、箇条書きで挙げてください。 【見てほしい観点】 1. エラーを握りつぶしていないか(except: pass など) 2. パス・日付・列名・税率などを、決め打ちしていないか 3. 元のファイルを上書き・削除していないか 4. データを外部に送信していないか。キーやパスワードがコードに書かれていないか 5. 遅い・メモリを多く使う書き方はないか 【お願い】 - 各指摘に、該当する行と、直し方を添える。問題がない観点は「問題なし」と書く - 分からない行があれば、初心者向けに説明する 【コード】 (ここにコードを貼る)
ただし、AIの指摘も鵜呑みにしません。間違った指摘や、大げさな指摘が混ざることがあるからです。たとえば、「ファイルを close() していません」と言われたとき、コードが with open(...) を使っているなら、本当でしょうか。
この欄では、サンプルファイルが使えます。実行のたびに、ファイルは最初の状態に戻ります。
▶ 実行を押すと、ここに結果が出ます
True、つまり閉じています。with が、自動で閉じてくれるためです。指摘は、自分で確かめてから、採用する。分からない部分は、AIに説明させてから、採用しましょう。
変えて、試す
観点②(決め打ち)、③(上書き)、⑤(遅い)を、動かして確かめます。まず、②の税率です。
この欄では、サンプルファイルが使えます。実行のたびに、ファイルは最初の状態に戻ります。
▶ 実行を押すと、ここに結果が出ます
9月には、8%の商品(ミネラルウォーター)の伝票が2枚あり、10%で計算されています。小さな差でも、請求の金額が合わなくなる原因です。
次は、③の上書きです。「空欄のある行を取り除く」というコードです。
この欄では、サンプルファイルが使えます。実行のたびに、ファイルは最初の状態に戻ります。
▶ 実行を押すと、ここに結果が出ます
8行あったデータが、5行になりました。取り除いた3行は、ファイルから消えました。どの行に問題があったのか、あとから確認することもできません。保存先は、必ず別の名前にします(Lesson 29)。
最後に、⑤の遅い書き方です。売上の1行ごとに、products.csv を開き直すコードを、開いた回数で比べます。
この欄では、サンプルファイルが使えます。実行のたびに、ファイルは最初の状態に戻ります。
▶ 実行を押すと、ここに結果が出ます
明細128行で、128回開いていました。128行なら一瞬ですが、数万行になると、極端に遅くなります。最初に1回だけ読んで辞書にしておく書き方(Lesson 06)が定番です。
自分で書く
お題① 最初のコード(握りつぶし)を直します。桁区切りのカンマを取り除いて変換し、それでも変換できない行は、件数を数えて表示してください。
この欄では、サンプルファイルが使えます。実行のたびに、ファイルは最初の状態に戻ります。
▶ 実行を押すと、ここに結果が出ます
ヒントを見る
int(row["金額"].replace(",", "")) でカンマを取ります。except は ValueError にして、中で skipped += 1 と数え、最後に print(f"スキップ: {skipped}件") と表示します。skipped = 0 を、最初に作るのを忘れずに。
答えの例を見る
import csv
total = 0
skipped = 0
with open("messy.csv", encoding="utf-8") as f:
for row in csv.DictReader(f):
try:
total += int(row["金額"].replace(",", ""))
except ValueError:
skipped += 1
print("売上合計:", total)
print(f"スキップ: {skipped}件")お題② 税率の決め打ちを直します。rate_of(商品コード→税率)を使って、商品ごとの税率で、税込金額を計算してください(1円未満は切り捨て)。
この欄では、サンプルファイルが使えます。実行のたびに、ファイルは最初の状態に戻ります。
▶ 実行を押すと、ここに結果が出ます
ヒントを見る
110 のところを、その行の商品の税率にします。(100 + rate_of[r["商品コード"]]) の形です。割り算は // のままです。
答えの例を見る
import csv
with open("products.csv", encoding="utf-8") as f:
rate_of = {r["商品コード"]: int(r["税率"]) for r in csv.DictReader(f)}
with open("sales_detail.csv", encoding="utf-8") as f:
rows = [r for r in csv.DictReader(f) if r["日付"][:7] == "2025-09"]
total = sum(int(r["数量"]) * int(r["単価"]) * (100 + rate_of[r["商品コード"]]) // 100 for r in rows)
print(total)仕事ならどう使う?
理解チェックAIのコードに、except Exception: rows = [] がありました。何が問題でしょう?
理解チェックAIに点検を頼んだら、『ファイルを close() していません』と指摘されました。コードは with open(...) を使っています。どうしますか?