これは ZOZO Advent Calendar 2025 カレンダー Vol.3 の10日目の記事です。
はじめに
「リーダブルコード」を読んだことがある人は多いものの、学んだ内容を自分のコードに落とし込むのは意外と難しいものです。
そこで生成AIを使って『あえて悪いコードを作らせ、それをレビューして改善する』という形式の読書会を実施してみました。
結果として、座学で終わらない実践的な学びが得られ、参加者のコード品質に対する意識が大きく変わる機会を得られました。
なぜ生成AIを使うのか?
リーダブルコードの学習では「悪いコード例」が極めて重要です。
しかし、毎回手作業で悪い例を作るのは手間がかかりますし、“ちょうどよく悪い”コードを書くのも意外と難しいです。それに手作業だと、「⚪︎⚪︎さんが作ったコードにどうダメ出ししよう……」と遠慮がちな指摘になってしまう懸念があります。
そこで、生成AIに次のような指示を出し、任意の言語で悪いコードを書いてもらいます。以下はリーダブルコードの1章〜3章までの内容を含むプロンプトです。
以下を意識して、準拠できていないpythonのコード例を考えて
表面上の改善(適切なコメント、blackなどのフォーマット、docstringなど)
変数名に情報を詰め込む(tmpやi, jなどの乱用をしない、変数名で何をしているかが分かる)
誤解されない名前(min_, max_などのprefixを適切に使う)
def func(l, f=10):
# 処理する
tmp = []
for i in l:
if i > f:
tmp.append(i)
min = 0
max = 0
if len(tmp) > 0:
min = tmp[0]
max = tmp[0]
for i in tmp:
if i < min:
min = i
if i > max:
max = i
res = []
for j in range(len(tmp)):
val = tmp[j]
if j % 2 == 0:
res.append(val * 2)
else:
res.append(val / 2)
return {'min': min, 'max': max, 'data': res, 'cnt': len(res)}
このように「狙ったアンチパターン」を即座に生成できるのがAI活用の最大のメリットです。
読書会の流れ
- 本を読み、できていること・できていなかったこと・学び・読んだ部分のまとめについて話す
- 読んだ部分のまとめからアンチパターンを生成するようにAIにコードを書いてもらう(上記プロンプト)
私たちのチームではGemini 2.5 Proを使用 - 出力されたコードを参加者全員でレビューする
- AIに改善後のコードを書いてもらう
レビュー後に「良いコード版」を生成し、悪い例と並べて比較する
改善後のコード
改善したバージョンを見せて
def filter_and_transform_values(values: list[float], threshold: float = 10.0) -> dict:
"""
指定された閾値より大きい値をフィルタリングし、統計情報と変換結果を返す。
偶数インデックスの値は2倍に、奇数インデックスの値は半分に変換します。
Args:
values: 処理する数値のリスト
threshold: フィルタリングの閾値(デフォルト: 10.0)
Returns:
dict: 以下のキーを含む辞書:
- min_value: フィルタリングされた値の最小値
- max_value: フィルタリングされた値の最大値
- transformed_data: 変換後のデータリスト
- count: 変換後のデータ数
"""
# 閾値より大きい値だけをフィルタリング
filtered_values = [value for value in values if value > threshold]
# 最小値と最大値の初期化
min_value = 0
max_value = 0
# フィルタリングされた値が存在する場合、最小値と最大値を計算
if filtered_values:
min_value = min(filtered_values)
max_value = max(filtered_values)
# インデックスに基づいて値を変換
transformed_data = []
for index, value in enumerate(filtered_values):
# 偶数インデックスは2倍、奇数インデックスは半分に
if index % 2 == 0:
transformed_data.append(value * 2)
else:
transformed_data.append(value / 2)
# 結果を辞書として返す
return {
'min_value': min_value,
'max_value': max_value,
'transformed_data': transformed_data,
'count': len(transformed_data)
}
geminiの考える問題点
- 表面上の改善
- 詳細なdocstringを追加(機能説明、引数、戻り値を明記)
- 意味のあるコメントを追加
- 一貫性のあるフォーマット(適切な空白行、インデント)
- 変数名の改善
- l → values
- f → threshold
- i, j → value, index
- tmp → filtered_values
- res → transformed_data
- func → filter_and_transform_values
- 誤解を招く名前の修正
- min, max → min_value, max_value
- cnt → count
- Pythonの組み込み関数を変数名として使用しない
- その他の改善
- 型ヒントの追加
- リスト内包表記の使用
- Pythonの組み込み関数 min(), max() の活用
- enumerate() の使用でインデックスと値を同時に処理
また、時間に余裕があれば改善後のコードももっと良いものならないか議論していました。
まとめ
生成AIを活用することで以下のメリットを感じました。
- 悪いコードのバリエーションが無限に作れる
人がゼロから作るより圧倒的に速い。事前準備がほぼ不要だった。 - チームのスキルに合わせた学習ができる
初心者には単純なアンチパターン、経験者にはもう少し複雑なものを生成できる。 - 実践的な学びになる
悪いコードと向き合うことで改善するための実践的なスキルが身に付く。 - 自分たちが使う言語で実施できる
Python・Ruby・JavaScript など、チームの実務に直結する形で学習できる。
もしチームでリーダブルコードを学ぶ機会があれば、ぜひこのAI活用型の読書会を試してみてください。