Python | 1 日 90 分 × 7 日アプリ学習:ファイルを読み込むアプリ(初級編)

Web APP Python
スポンサーリンク

4日目のゴール

4日目のテーマは
「ファイルの中から“欲しい行だけ”を抜き出して表示できるようになること」 です。

ここまでであなたは、

ファイル全体を読む
1行ずつ読む
先頭だけ・末尾だけ読む

というところまで来ています。

4日目ではここから一歩進んで、

特定のキーワードを含む行だけ表示する
大文字・小文字の違いを気にせず検索する
「見つかった行が何行目か」も一緒に表示する

ここを目指します。


「検索する」という発想をコードに落とす

ファイルを“行の集まり”として見る

まず、頭の中のイメージを整理します。

ファイルを 1 行ずつ読むとき、
実はこう考えることができます。

「この行は、表示したい行か?」
「この行は、スキップしたい行か?」

つまり、
「行ごとに Yes / No を判定して、Yes だけ表示する」
という発想です。

検索とは、
「キーワードを含む行だけ Yes にする」
ということです。


キーワードを含む行だけ表示する基本形

in 演算子で「含まれているか」を調べる

Python では、
文字列に別の文字列が含まれているかどうかを
in で調べられます。

"error" in "this is an error message"  # True
"error" in "this is ok"                # False
Python

これをファイルの各行に対して使えば、
「キーワードを含む行だけ表示する」
ということができます。

def search_in_file(filename, keyword):
    try:
        with open(filename, "r", encoding="utf-8") as f:
            for index, line in enumerate(f, start=1):
                if keyword in line:
                    print(f"{index:4}: {line.strip()}")

    except FileNotFoundError:
        print(f"{filename} が見つかりません。")
Python

ここでの重要ポイントは、

1行ずつ読みながら
その行に keyword が含まれているかを判定し
含まれていれば行番号付きで表示する

という流れになっていることです。


大文字・小文字を区別せずに検索する

lower() で両方を小文字にそろえる

ログやテキストでは、
「Error」「ERROR」「error」など、
大文字・小文字が混ざっていることがあります。

それを全部「同じもの」として扱いたいときは、
両方を小文字に変換してから比較します。

line_lower = line.lower()
keyword_lower = keyword.lower()

if keyword_lower in line_lower:
    ...
Python

これをさっきの関数に組み込むと、こうなります。

def search_in_file_case_insensitive(filename, keyword):
    try:
        with open(filename, "r", encoding="utf-8") as f:
            for index, line in enumerate(f, start=1):
                line_lower = line.lower()
                keyword_lower = keyword.lower()

                if keyword_lower in line_lower:
                    print(f"{index:4}: {line.strip()}")

    except FileNotFoundError:
        print(f"{filename} が見つかりません。")
Python

ここでの深掘りポイントは、

ファイルの中身そのものは変えていない
比較するときだけ「小文字版」を作っている

ということです。


検索結果が1件もなかったときの扱い

「見つからなかった」もちゃんと伝える

検索しても何も表示されないと、
「本当に動いているのか?」と不安になります。

そこで、
「1件もヒットしなかった場合はメッセージを出す」
という工夫を入れます。

def search_in_file_with_message(filename, keyword):
    try:
        found = False

        with open(filename, "r", encoding="utf-8") as f:
            for index, line in enumerate(f, start=1):
                if keyword in line:
                    print(f"{index:4}: {line.strip()}")
                    found = True

        if not found:
            print(f"「{keyword}」を含む行は見つかりませんでした。")

    except FileNotFoundError:
        print(f"{filename} が見つかりません。")
Python

ここでの重要ポイントは、

found というフラグを用意して
ヒットしたら True にして
最後に「一度も True にならなかったか」を見る

という、
「結果がゼロ件だったかどうかを自分で管理する」
という考え方です。


4日目のミニアプリ:キーワード検索付きファイルビューア

今日の学びを全部入れたコード

def search_in_file(filename, keyword):
    try:
        found = False

        with open(filename, "r", encoding="utf-8") as f:
            for index, line in enumerate(f, start=1):
                if keyword in line:
                    print(f"{index:4}: {line.strip()}")
                    found = True

        if not found:
            print(f"「{keyword}」を含む行は見つかりませんでした。")

    except FileNotFoundError:
        print(f"{filename} が見つかりません。")


def search_in_file_case_insensitive(filename, keyword):
    try:
        found = False

        with open(filename, "r", encoding="utf-8") as f:
            for index, line in enumerate(f, start=1):
                line_lower = line.lower()
                keyword_lower = keyword.lower()

                if keyword_lower in line_lower:
                    print(f"{index:4}: {line.strip()}")
                    found = True

        if not found:
            print(f"「{keyword}」を含む行は見つかりませんでした。")

    except FileNotFoundError:
        print(f"{filename} が見つかりません。")


def main():
    print("ファイル読み込みアプリ(4日目)")
    filename = input("読み込むファイル名を入力してください: ")
    keyword = input("検索したいキーワードを入力してください: ")

    print("検索方法を選んでください。")
    print("1: 大文字・小文字を区別して検索")
    print("2: 大文字・小文字を区別せずに検索")
    choice = input("番号: ")

    if choice == "1":
        search_in_file(filename, keyword)
    elif choice == "2":
        search_in_file_case_insensitive(filename, keyword)
    else:
        print("不正な入力です。1 か 2 を選んでください。")


main()
Python

このアプリは、こう動きます。

ファイル名を入力する
検索したいキーワードを入力する
検索方法(区別する/しない)を選ぶ
ヒットした行だけ、行番号付きで表示される
ヒットしなければ「見つかりません」と表示される

「読む」だけだったアプリが、
「探す」ことができるアプリ に進化しました。


関数ごとの役割を日本語で言い切る

自分の言葉で説明できるかが勝負

search_in_file
「ファイルを1行ずつ読み、キーワードを含む行だけ行番号付きで表示する。1件もなければ“見つからない”と表示する。」

search_in_file_case_insensitive
「行とキーワードを両方小文字に変換してから比較し、大文字・小文字を区別せずに検索する。」

main
「ファイル名とキーワード、検索方法を入力してもらい、選ばれた方法で検索関数を呼び出す。」

ここまで言えれば、
readfor line in f
「ただ読むための道具」ではなく
「条件に合う行だけを取り出すための道具」

として使えている状態です。


4日目のまとめ:今日つかんでほしい感覚

今日の本質は、これです。

ファイルは「全部読む」だけでなく、「条件に合う行だけ読む」ことができる。
検索とは、「各行に対して Yes / No を判定し、Yes だけ表示する」こと。
in で「含まれているか」を調べられる。
大文字・小文字を無視したいときは、両方を lower() でそろえてから比較する。
「1件もヒットしなかった」という状況も、自分でフラグを持てばきちんと扱える。

ここまで来ていれば、
5日目以降の「複数条件で絞り込む」「行の一部だけを抜き出す」といった
さらに一段賢いファイル読み込みアプリにも、自然に進んでいけます。

タイトルとURLをコピーしました