【第6回】CSVファイル入門:コーヒー&釣りログをファイルに残す

Python入門

第4回・第5回までで、

  • コーヒーや釣りの 1件分のログ を辞書で表現して
  • それを リストでまとめて管理 して
  • if文とfor文で「自分にとって意味のあるログだけ」を絞り込む

ところまで進んできました。

ここまででもかなり“自分ログ”っぽくなっていますが、
ひとつ大事なポイントが残っています。

Pythonを終了すると、せっかくのログが消えてしまう。

ノートなら閉じても中身は残りますが、コードの中に直接書いたログは、
毎回書き直さない限り増えていきません。

そこで今回のテーマは、

  • CSVファイル にログを書き出す
  • CSVファイルからログを読み込む

という「外の世界とのやり取り」です。

今回のゴールは、

コーヒー&釣りログをCSVファイルとして保存し、あとからPythonで読み返せるようになること。

これができると、

  • シーズンの釣りログをスプレッドシートで眺めたり
  • コーヒーログを別ツールで分析したり

といった“データの旅”ができるようになります。


この回のゴールと全体像

この第6回で目指すのは、次の4つです。

  1. CSVファイルとは何か、ざっくりイメージが持てる
  2. Pythonの標準ライブラリ csv で、ログをCSVに書き出せる
  3. 既存のCSVに「1件だけ追記」できる
  4. CSVからログを読み込んで、if × for で絞り込みや簡単な集計ができる

すべて、コーヒー&釣りログを題材に進めていきます。

CSVファイルとは? 表のようなテキストファイル

CSV(Comma-Separated Values)は、

カンマ区切りのテキストで表を表現するファイル形式

です。

例えば、コーヒーログを3件CSVで書くと、こういうイメージになります。

date,name,roast,memo,score
2025/05/01,エチオピア浅煎り,浅煎り,フルーティーで朝の湖に合う,4.5
2025/05/02,グアテマラ中煎り,中煎り,ナッツのような香りで落ち着く,4.0
2025/05/03,ケニア深煎り,深煎り,夜の読書に合うしっかりした苦味,4.2
  • 1行目が「ヘッダー行」(列の名前)
  • 2行目以降がデータ

になっています。

Excel や Googleスプレッドシートでも開ける、
とてもシンプルで扱いやすい形式です。

準備 コーヒーログのサンプルデータを作る

まずは、Python側でいつものようにリスト+辞書でログを用意します。
coffee_csv_write.py というファイルを作って、次のように書いてみましょう。

# coffee_csv_write.py

coffee_logs = [
    {
        "date": "2025/05/01",
        "name": "エチオピア浅煎り",
        "roast": "浅煎り",
        "memo": "フルーティーで朝の湖に合う",
        "score": 4.5
    },
    {
        "date": "2025/05/02",
        "name": "グアテマラ中煎り",
        "roast": "中煎り",
        "memo": "ナッツのような香りで落ち着く",
        "score": 4.0
    },
    {
        "date": "2025/05/03",
        "name": "ケニア深煎り",
        "roast": "深煎り",
        "memo": "夜の読書に合うしっかりした苦味",
        "score": 4.2
    }
]

これは第4回で扱ったような、辞書のリストです。
ここから coffee_logs.csv というファイルを作っていきます。

csv.DictWriterでCSVに書き出す

Pythonには、CSVを扱うための標準ライブラリ csv があります。
ここでは、辞書のリスト → CSV に変換しやすい DictWriter を使います。

# coffee_csv_write.py

import csv

coffee_logs = [
    {
        "date": "2025/05/01",
        "name": "エチオピア浅煎り",
        "roast": "浅煎り",
        "memo": "フルーティーで朝の湖に合う",
        "score": 4.5
    },
    {
        "date": "2025/05/02",
        "name": "グアテマラ中煎り",
        "roast": "中煎り",
        "memo": "ナッツのような香りで落ち着く",
        "score": 4.0
    },
    {
        "date": "2025/05/03",
        "name": "ケニア深煎り",
        "roast": "深煎り",
        "memo": "夜の読書に合うしっかりした苦味",
        "score": 4.2
    }
]

fieldnames = ["date", "name", "roast", "memo", "score"]

with open("coffee_logs.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.DictWriter(f, fieldnames=fieldnames)

    # 1行目にヘッダーを書き込む
    writer.writeheader()

    # 辞書のリストをまとめて書き込む
    writer.writerows(coffee_logs)

print("coffee_logs.csv を書き出しました。")

ここでのポイント

  • import csv:標準ライブラリの読み込み
  • open()
    • "w":書き込みモード(上書き)
    • newline="":余計な空行が入るのを防ぐおまじない
    • encoding="utf-8":日本語を含めるための文字コード指定
  • csv.DictWriter(f, fieldnames=...)
    辞書のキー名とCSVの列名を対応させる
  • writeheader():ヘッダー行(1行目)を書く
  • writerows():辞書のリストをまとめて書き出す

ターミナルでこのファイルを実行します。

python3 coffee_csv_write.py

同じフォルダに coffee_logs.csv ができていれば成功です。


1件だけ追記する(appendモード)

次に、「その日の新しいコーヒーログを1件だけ追加したい」
という場面を考えます。

その場合は、open() のモードを "a"(append:追記)にします。

# coffee_csv_append.py

import csv

fieldnames = ["date", "name", "roast", "memo", "score"]

new_log = {
    "date": "2025/05/04",
    "name": "コロンビア中深煎り",
    "roast": "中深煎り",
    "memo": "しっかりしたコクで夕方の湖に合う",
    "score": 4.3
}

with open("coffee_logs.csv", "a", newline="", encoding="utf-8") as f:
    writer = csv.DictWriter(f, fieldnames=fieldnames)
    writer.writerow(new_log)

print("新しいコーヒーログを1件追記しました。")

ここで注意したいのは、

  • writeheader()呼ばない(2回目以降にヘッダーを書いてしまうと、CSVの途中にヘッダーが混ざる)

という点です。

最初に coffee_csv_write.py でヘッダー付きCSVを作っておき、
それ以降は coffee_csv_append.py のようなスクリプトで追記していく、
という運用がシンプルです。

CSVから読み込んで、お気に入りコーヒーだけを表示する

次は、CSVファイルからデータを読み込みます。
DictReader を使うと、1行ずつ「辞書」として扱えます。

# coffee_csv_read_favorites.py

import csv

with open("coffee_logs.csv", "r", newline="", encoding="utf-8") as f:
    reader = csv.DictReader(f)

    print("スコア4.0以上のお気に入りコーヒー")
    print("================================")

    for row in reader:
        # CSVから読み込んだ値は文字列なので、scoreをfloatに変換
        score = float(row["score"])

        if score >= 4.0:
            print("日付:", row["date"])
            print("名前:", row["name"])
            print("焙煎度:", row["roast"])
            print("メモ:", row["memo"])
            print("スコア:", score)
            print("----------------")

ここでのポイント

  • csv.DictReader(f)
    • 各行を {"date": "...", "name": "...", ...} のような辞書として扱える
    • ヘッダー行は、自動的に「キー名」として使われる
  • row["score"] は文字列なので、float() で数値に変換してから比較

釣りログもCSVにしておく

コーヒーと同じように、釣りログもCSVにしておくと後々便利です。
まずはデータと書き出しスクリプトを作ります。

# fishing_csv_write.py

import csv

fishing_logs = [
    {
        "date": "2025/04/29",
        "lake": "中禅寺湖",
        "fish_type": "ブラウントラウト",
        "fish_length_cm": 48,
        "weather": "晴れ",
        "is_released": True
    },
    {
        "date": "2025/05/01",
        "lake": "中禅寺湖",
        "fish_type": "ブラウントラウト",
        "fish_length_cm": 52,
        "weather": "くもり時々晴れ",
        "is_released": True
    },
    {
        "date": "2025/05/05",
        "lake": "中禅寺湖",
        "fish_type": "レイクトラウト",
        "fish_length_cm": 60,
        "weather": "くもり",
        "is_released": False
    }
]

fieldnames = [
    "date", "lake", "fish_type", "fish_length_cm", "weather", "is_released"
]

with open("fishing_logs.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.DictWriter(f, fieldnames=fieldnames)
    writer.writeheader()
    writer.writerows(fishing_logs)

print("fishing_logs.csv を書き出しました。")

CSVから50cm以上の魚だけを読み込んで表示する

# fishing_csv_read_50up.py

import csv

with open("fishing_logs.csv", "r", newline="", encoding="utf-8") as f:
    reader = csv.DictReader(f)

    print("50cm以上の魚だけを表示")
    print("======================")

    for row in reader:
        length = int(row["fish_length_cm"])

        if length >= 50:
            print("日付:", row["date"])
            print("場所:", row["lake"])
            print("魚種:", row["fish_type"])
            print("サイズ:", length, "cm")
            print("天気:", row["weather"])
            print("リリース?:", row["is_released"])
            print("----------------")

ここでも、row["fish_length_cm"] は文字列なので int() で整数に変換しています。


おまけ – CSVから平均スコアを計算してみる

最後に、CSVから「コーヒーの平均スコア」を出してみましょう。
第5回の if & for と同じノリで書けます。

# coffee_csv_average_score.py

import csv

total_score = 0.0
count = 0

with open("coffee_logs.csv", "r", newline="", encoding="utf-8") as f:
    reader = csv.DictReader(f)

    for row in reader:
        score = float(row["score"])
        total_score += score
        count += 1

if count > 0:
    average = total_score / count
    print("コーヒーログ件数:", count)
    print("平均スコア:", round(average, 2))
else:
    print("ログがありません。")

こんなふうに、
「ファイル → Python → if / for / 計算」
という流れで、趣味ログからシンプルな集計ができるようになります。

フォルダ構成の一例

ここまでのスクリプトとCSVファイルをまとめると、こんなフォルダ構成になります。

python-playground/
  coffee_csv_write.py
  coffee_csv_append.py
  coffee_csv_read_favorites.py
  coffee_csv_average_score.py
  fishing_csv_write.py
  fishing_csv_read_50up.py
  coffee_logs.csv
  fishing_logs.csv

だんだん「小さなプロジェクト」っぽくなってきました。
あとで関数やクラスを学ぶときに、この構成がそのまま題材として使えます。

よくあるつまずきポイント(CSV編)

ファイルが見つからない (FileNotFoundError)

  • 実行している場所と、ファイルがある場所が違う
  • 対策:python を実行するときに、スクリプトと同じフォルダにいるか確認

日本語が文字化けする

  • encoding="utf-8" を付けているか確認
  • Excel側で開くときに文字コード指定が必要な場合もある

行間が空く(空行が挟まる)

  • open()newline="" を付けているか確認
  • 付けないと、環境によっては空行が入ることがある

今日のまとめ ログが「ファイル」として残り始める

今回は、

  • CSVのイメージ(カンマ区切りのテキスト表)
  • csv.DictWriter で辞書のリストをCSVに書き出す
  • appendモードで1件だけ追記する
  • csv.DictReader でCSVからログを読み込み、if × for で絞り込む
  • CSVから簡単な平均値を計算する

ところまで進みました。

これで、あなたの

  • コーヒーの記憶
  • 湖でのブラウンやレイクとの出会い

が、「ファイル」として静かに積み上がっていく状態になりました。

ノート・Python・CSVの3つを組み合わせるだけで、
かなり“自分だけのデータ基盤”っぽくなってきます。

次回予告 while文で「終わりの決まっていないループ」をつくる

ここまでのログ管理は、

  • あらかじめコードの中にデータを書いておく
  • あるいは、すでにあるCSVを読み込んで眺める

というスタイルでした。

次回は、もう一歩だけリアルに近づけてみます。

「自分で入力するのが終わるまで、ログを取り続ける」

そんな小さなツールを、Pythonで作ってみます。

キーワードは while文

  • 何回くり返すか、あらかじめ決まっていない
  • 「そろそろ終わりにしようかな」と自分が決める

そんなループを作るのに向いている構文です。

次回扱う予定のトピックは、例えばこんな感じ:

  • while文の基本形:「〜であるあいだ、ずっと続ける」
  • input() と組み合わせて、コーヒーログを対話的に入力する
  • q が入力されたらループを抜けて、CSVにまとめて保存する
  • 釣りログ版に応用してみる(その日の釣果をその場で入力)

つまり、

  • 朝のコーヒーを飲みながら python coffee_input.py を起動して
  • 飲んだら1件入力して、気が済んだら q で終了

みたいな、「日常のリズムに溶け込む小さなスクリプト」を目指します。

湖畔でも部屋でも、
キーボードを数回叩くだけで、その日のログがCSVに静かに積もっていく——
そんな while文の使い方を、一緒に育てていきましょう。

コメント