第6回までで、
- コーヒーや釣りのログを リスト+辞書 で扱い
- if文とfor文で 条件に合うログだけを抽出 し
- CSVファイルとして 外の世界に保存 する
というところまで進んできました。
ただ、実際の生活に寄せて考えると、こんな欲が出てきます。
- コーヒーを飲んだタイミングで、さっと1件入力したい
- 釣りのあと、その日の釣果をまとめて入力したい
- 「もういいかな」と思うところまで、何件でも入れられるようにしたい
そこで今回のテーマは、
「入力が終わるまで、ログを取り続ける小さなツール」を while 文で作ること。
キーワードは while文 と input()、そして break。
湖のほとりでも、自宅のデスクでも、
- スクリプトを起動する
- コーヒーや釣りの情報をちょこちょこ入力する
qを打つと終わって、CSVに保存される
そんな小さな “celestial biome ロガー” を目指していきます。
この回のゴールと全体像
第7回でできるようになってほしいことは、次の4つです。
- while文の基本形と「条件がTrueのあいだ繰り返す」というイメージが持てる
- 無限ループ+break というよくあるパターンを理解できる
- input() と while 文を組み合わせて、対話的にログを入力できる
- 入力された複数のログをCSVファイルにまとめて保存できる
ここまで来れば、
- 「自分がやめると決めるまで続くループ」
を扱えるようになります。
while文とは?「〜であるあいだずっと続ける」
while文は、
ある条件がTrueであるあいだ、処理をくり返す構文
です。
基本形はこうです。
while 条件:
繰り返したい処理
条件がTrueのあいだは、何度でも繰り返される条件がFalseになったタイミングで、while ループを抜ける
という動きになります。
シンプルな例:3回だけループする
count = 0
while count < 3:
print("count は", count, "です")
count = count + 1 # ここを忘れると無限ループ!
print("ループが終わりました")
実行結果のイメージ:
count は 0 です
count は 1 です
count は 2 です
ループが終わりました
- 最初は
count = 0 count < 3→ True なので中の処理を実行- 最後に
count = count + 1で count が 1, 2, 3… と増えていく countが 3 になったときcount < 3が False になり、ループ終了
よくあるミス は、count = count + 1 を書き忘れて、条件が永遠に変わらないこと。
そうなると、処理が終わらなくなります(無限ループ)。
あえて「無限ループ」にして、breakで抜ける書き方
さきほどは「回数」で終わりを決めましたが、
今回作りたいツールは、
- 「自分が
qと入力したら終わる」
という、回数が決まっていないくり返し です。
こういうときによく使うパターンが、
while True:
何かする
if 終了条件:
break
という形です。
while True:は、条件が常に True なので、理論上は永遠にループする- ただし、ある条件になったら
breakでループを抜ける
という「意図的な無限ループ」です。
q が入力されたら終わる簡単な例
while True:
text = input("何か入力してください(qで終了):")
if text == "q":
print("終了します。")
break
print("あなたが入力したのは:", text)
input() は、ユーザーから1行文字列を入力してもらう関数です。
- ユーザーが
qと入力したらbreakでループ終了 - それ以外なら、その文字を表示してループを続ける
という流れになっています。
コーヒーログを while+input で取り続ける
では、いよいよ本題。
「入力が終わるまでコーヒーログを取り続ける小さなツール」 を作ります。
流れとしてはこんな感じです。
- ループの外で「空のリスト」を用意
- while True で、1杯分の情報を入力してもらう
qが入力されたら break で終了- 入力されたログを、ループの外でCSVにまとめて書き出す
まずはログを集める部分から
# coffee_input.py
coffee_logs = [] # 入力されたログを貯めるリスト
while True:
name = input("コーヒー名を入力してください(終了するには q):")
if name == "q":
print("入力を終了します。")
break
roast = input("焙煎度(浅煎り・中煎り・深煎りなど):")
memo = input("ひとことメモ:")
score_str = input("スコア(0〜5の数字):")
# 入力されたスコアをfloatに変換(失敗したら3.0にするなどの簡易処理)
# 例外処理について以下の補足で解説します。
try:
score = float(score_str)
except ValueError:
print("数値に変換できなかったので、スコアを 3.0 にします。")
score = 3.0
log = {
"name": name,
"roast": roast,
"memo": memo,
"score": score
}
coffee_logs.append(log)
print("1件ログを追加しました。")
print("----------------------")
print("入力された件数:", len(coffee_logs))
ここではまだ CSVには書き込んでいません。
とりあえず while で、複数件のログをリストにためるところまでです。
ポイント:
coffee_logs = []はループの外(最初)で1回だけ作る- while の中で1件分の辞書
logを作り、それをappend()で追加 qを入力したときだけbreakで抜ける
まずはここまでを動かして、len(coffee_logs) が 0,1,2,… と増えることを確認してみてください。
補足:try / except は「エラーが出ても落とさないためのクッション」
第7回のコードの中で、初めて
try:
score = float(score_str)
except ValueError:
print("数値に変換できなかったので、スコアを 3.0 にします。")
score = 3.0
という書き方が出てきました。
これは 「try / except(トライ・エクセプト)」 と呼ばれる構文です。
ざっくりイメージだけ先に持っておくと:
try:- 「ここでエラーが出るかもしれないけど、とりあえずやってみる場所」
except エラーの種類:- 「もしそのエラーが起きたら、代わりにここを実行してね」
という クッション のようなものです。
例えば、スコア入力が数値じゃなかったら?
普通にこう書くとします。
score = float(score_str)
score_str が "4.5" みたいな 数字っぽい文字列 なら大丈夫ですが、
- 「美味しい」とか
- 空文字(何も入っていない)
が入っていると、Python は
「数値に変換できないよ!」
と怒って エラーを出して、その時点でプログラムを止めてしまいます。
そこで、
try:
score = float(score_str)
except ValueError:
print("数値に変換できなかったので、スコアを 3.0 にします。")
score = 3.0
と書いておくと、
- まず
try:の中でfloat(score_str)を試す - もし
ValueError(「変換できない」という種類のエラー)が起きたらexcept ValueError:の中に進んで- エラーメッセージを出しつつ、
score = 3.0として処理を続ける
という動きになります。
つまり、
try / except は「エラーが出ても、プログラムを落とさず、ソフトランディングさせるための仕組み」
くらいのイメージでOKです。
本格的な解説はもう少し後の回で扱う予定なので、
今のところは
「入力が変でも落ちないようにする、おまじない」
くらいで気軽に使ってみてください。
集めたログをCSVに保存する
次に、入力が終わったあとで、
集めたログを CSV に書き出してみます。
今回は、
- すでに
coffee_logs.csvがあればヘッダーなしで追記 - なければヘッダー付きで新規作成
という形にしてみます。
# coffee_input.py
import csv
import os
coffee_logs = []
while True:
name = input("コーヒー名を入力してください(終了するには q):")
if name == "q":
print("入力を終了します。")
break
roast = input("焙煎度(浅煎り・中煎り・深煎りなど):")
memo = input("ひとことメモ:")
score_str = input("スコア(0〜5の数字):")
try:
score = float(score_str)
except ValueError:
print("数値に変換できなかったので、スコアを 3.0 にします。")
score = 3.0
log = {
"name": name,
"roast": roast,
"memo": memo,
"score": score
}
coffee_logs.append(log)
print("1件ログを追加しました。")
print("----------------------")
print("入力された件数:", len(coffee_logs))
if coffee_logs:
filename = "coffee_logs.csv"
fieldnames = ["name", "roast", "memo", "score"]
file_exists = os.path.exists(filename)
with open(filename, "a", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=fieldnames)
# ファイルがまだなければヘッダーを書く
if not file_exists:
writer.writeheader()
writer.writerows(coffee_logs)
print(f"{filename} に {len(coffee_logs)} 件のログを書き込みました。")
else:
print("ログが1件も入力されなかったので、ファイルには書き込みませんでした。")
これで、
- スクリプトを起動
- 満足するまでコーヒーの情報を入力
qで終了- すべてのログが
coffee_logs.csvに追記される
という流れができました。
朝・昼・夜で何度起動しても、同じ coffee_logs.csv にログが積み上がっていきます。
釣りログ版に応用する
同じパターンで、釣りログ版も作れます。
ここでは少し項目を絞ったシンプルな例を載せておきます。
# fishing_input.py
import csv
import os
fishing_logs = []
while True:
date = input("日付を入力してください(例:2025/05/01、終了するには q):")
if date == "q":
print("入力を終了します。")
break
lake = input("場所(湖の名前など):")
fish_type = input("魚種(ブラウン・レイクなど):")
length_str = input("サイズ(cm):")
is_released_str = input("リリースしましたか?(y/n):")
try:
length = int(length_str)
except ValueError:
print("整数に変換できなかったので、サイズを 0cm とします。")
length = 0
is_released = (is_released_str.lower() == "y")
log = {
"date": date,
"lake": lake,
"fish_type": fish_type,
"fish_length_cm": length,
"is_released": is_released
}
fishing_logs.append(log)
print("1件ログを追加しました。")
print("----------------------")
print("入力された件数:", len(fishing_logs))
if fishing_logs:
filename = "fishing_logs.csv"
fieldnames = ["date", "lake", "fish_type", "fish_length_cm", "is_released"]
file_exists = os.path.exists(filename)
with open(filename, "a", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=fieldnames)
if not file_exists:
writer.writeheader()
writer.writerows(fishing_logs)
print(f"{filename} に {len(fishing_logs)} 件のログを書き込みました。")
else:
print("ログが1件も入力されなかったので、ファイルには書き込みませんでした。")
これで、釣りから帰ってきた夜に
python fishing_input.pyを起動- その日の釣果を思い出しながら何件か入力
- 入力し終わったら
q
というように、儀式のようなログタイム を持てます。
よくあるつまずきポイント(while+input 編)
無限ループから抜けられない
while True:を使うときは、必ずbreakの条件を書いておく- 条件が絶対に到達するか、コードをよく見直す
入力結果の型(文字列・数値)を混同する
input()で受け取った値は 必ず文字列- 数値として使いたい場合は
int()やfloat()で変換する - 変換に失敗する可能性も考えて
try/exceptを使うと安全
リストの初期化位置を間違える
coffee_logs = []やfishing_logs = []は while の前 で1回だけ行う- while の中で毎回
[]を作り直してしまうと、ログが1件ずつしか残らない
今日のまとめ while文で「終わりを自分で決める」ループを持つ
今回は、
- while文の基本形(条件がTrueのあいだくり返す)
- 無限ループ+break というよく使うパターン
- input() と while を組み合わせた対話的なログ入力
- 集めたログをCSVにまとめて保存する流れ
までを見てきました。
これで、
- 「何回くり返すか決まっていない処理」
を、自分のタイミングで終わらせられるようになりました。
朝のコーヒー、昼の一杯、夜の一杯。
春の中禅寺湖、夏のブラウン、秋のレイク。
それぞれの「小さな瞬間」を、
while文を使って少しずつCSVに積み上げていけます。
次回予告 関数で「よく使う処理」に名前をつけて整理する
ここまでコードを書いてくると、こんな感覚も出てきます。
- 「CSVに書き込む処理、毎回ほとんど同じことを書いてない?」
- 「ログ1件分を辞書にまとめるところも、パターンが似ているな」
この 「似たような処理をまとめたい」 という感覚は、とても大事です。
次回は、
defを使って 関数 を定義し- 「コーヒーログを書き込む関数」
- 「釣りログを書き込む関数」
のように、よく使う処理に名前をつけて整理していきます。
関数を使えるようになると、
- コードの重複が減って読みやすくなる
- 「何をしているのか」が名前から分かる
- 将来クラスや大きなアプリを作るときの土台になる
というメリットがあります。
というわけで次回は、
第8回:関数入門 ログ処理に名前をつけてスッキリさせる
を予定しています。
コーヒーと湖のログツールを、そのまま題材に進めていきましょう。




コメント