酒井潤さんの教材を使って人気SNSリサーチャーロボットを作ってみた

はじめに

Pythonはそのシンプルさと強力なライブラリの存在により、さまざまなアプリケーションの開発に広く使用されています。今回は、そんなPythonの初めての教材として使わせていただいた酒井潤さんの「現役シリコンバレーエンジニアが教えるPython 3 入門 + 応用 +アメリカのシリコンバレー流コードスタイル」の中盤で学習できるロボットアプリ作成を参考に、人気SNSリサーチャーロボットを作成していきます!(酒井潤さんの教材は全て中身たっぷりで大変満足しております尊敬していますいつもありがとうございます)
※本投稿内の人気SNSリサーチャーロボットは、ユーザーの回答から人気度を測るユーザーアンケートランキングロボットです。

【1. ライブラリのインポート】

まずはじめに、必要なライブラリをインポートします。今回はcsvライブラリとosライブラリを使用します。

# csvライブラリをインポートします
import csv
# osライブラリをインポートします
import os

csvライブラリは、Pythonの標準ライブラリ(標準で備え付けられているもの)の一つで、CSVファイルの読み書きを行うためのライブラリです。
osライブラリは、オペレーティングシステム(要はコンピューターの頭脳)とやりとりするための機能を提供するライブラリで、今回はファイルの存在を確認する際に使用します。

【2. 変数の定義】

こちらは遊び心的なものですが、青色の文字を表示するための変数と、文字色をリセット(デフォルトで緑としています)するための変数を定義します。

# 青色の文字を表示するための変数を定義します
GREEN = '\033[34m'
# 文字色をリセットするための変数を定義します(デフォルト=緑)
RESET = "\033[0m"

これらの変数は、ターミナル上で色付きの文字を表示するために使用します。'\033[34m'と'\033[0m'は、エスケープシーケンスと呼ばれる特殊な文字列で、それぞれ青色とリセットを表します。

【3. SNSのアンケートランキングデータを読み込む関数の定義】

では次に、SNSのアンケートランキングデータを読み込む関数を定義します。

# SNSのアンケートランキングデータを読み込む関数(load_ranking())を定義します
def load_ranking():
    # 空の辞書(ranking_data)を用意します
    ranking_data = {}
    # SNSのアンケートランキングデータのcsvファイル("ranking.csv")が存在するか否か確認します
    if os.path.exists("ranking.csv"):
        # 上記存在した場合、csvファイルをwith openの読み込みモードで開きます
        with open("ranking.csv", "r") as csv_file:
            # DictReaderを使ってcsvファイルの内容を読み込み変数readerに格納します
            reader = csv.DictReader(csv_file)
            # 変数reader(csvファイル = "ranking.csv")を行ごとにデータを読み込みます
            for row in reader:
                # 辞書(ranking_data)にSNS名とカウント(整数)を追加します
                ranking_data[row["Name"]] = int(row["Count"])
    # 上書きされたSNSのアンケートランキングデータを返します
    return ranking_data

この関数は、まず空の辞書を作成します。
次に、"ranking.csv"という名前のCSVファイルが存在するかどうかを確認し、存在する場合、そのファイルを開き、csv.DictReaderを使用して内容を読み込みます。
そして、各行のSNS名とカウントを辞書に追加し、最後に作成した辞書を返します。

【4. SNSのアンケートランキングデータを保存する関数の定義】

続けて、SNSのアンケートランキングデータを保存する関数を定義します

# SNSのアンケートランキングデータを保存する関数(save_ranking(ranking_data))を定義します
def save_ranking(ranking_data):
    # csvファイル(ranking_data)をwith openの書き込みモードで開きます
    with open("ranking.csv", "w") as csv_file:
        # フィールド名(列の見出し、ヘッダー)を定義します
        fieldnames = ["Name", "Count"]
        # DictWriterメソッドを使用して、csvファイルに書き込む変数writerを定義します
        writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
        # 変数writerをwriteheaderメソッドを使用して、ヘッダーとして書き込みます
        writer.writeheader()
        # SNSのアンケートランキングデータを行ごとに書き込みます
        for name, count in ranking_data.items():
            writer.writerow({"Name": name, "Count": count})

この関数は、まず"ranking.csv"という名前のCSVファイルを開きます。次に、フィールド名(列の見出し、ヘッダー)を定義し、csv.DictWriterを使用してCSVファイルに書き込むwriterを定義します。
そして、writer.writeheaderメソッドを使用して、ヘッダーとして書き込み、最後にSNSのアンケートランキングデータを行ごとに書き込みます。

【5. SNSのアンケートランキングデータのロード】

そして、先ほど定義したload_ranking関数を呼び出し、その結果をranking_data変数に格納します。

# SNSのアンケートランキングデータをロードする変数をranking_dataとします
ranking_data = load_ranking()

ここまでで事前準備は完了です!
ここから、ユーザー側とのやり取り、つまりインタラクションの部分を定義し、可視化しながら確認していきます。


【6. ユーザーとのインタラクション】

まず、ユーザーの名前を取得します(以下から全てwhile文内のコードとなっております)。

while True:
    # ユーザーの名前を取得します
    user_name = input(f"{GREEN}=============================================={RESET}\n"
                      f"{GREEN}こんにちは!私は人気SNSリサーチャーロボットです。{RESET}\n"
                      f"{GREEN}次の設問以降で、あなたの一番好きなSNSを教えてください。{RESET}\n"
                      f"{GREEN}まず最初にあなたの名前を教えてください。{RESET}\n"
                      f"{GREEN}=============================================={RESET}\n"
                      f"{RESET}")
ユーザーの名前を求めるインタラクション

次に、SNSアンケートランキングデータをカウントの降順でソートします。ソートされたSNSアンケートランキングデータを順に処理し、ユーザーにおすすめのSNSをランキング順で尋ねます。
ユーザーが"Yes"を選択した場合は、ループを抜けます。
ユーザーが"No"を選択した場合は、次に人気の SNSを尋ねます。

    # SNSのアンケートランキングデータをカウントの降順でソートします
    sorted_ranking = sorted(ranking_data.items(), key=lambda x: x[1], reverse=True)

    # ユーザーの好きなSNSを見つけたか否かを追跡するフラグ変数を用意します
    found_favorite = False
    # ソートされたSNSのアンケートランキングデータを順に処理します
    for name, count in sorted_ranking:
        while True:
            # ユーザーにこれまで人気SNSをランキング順で尋ねます
            user_answer = input(f"{GREEN}=============================================={RESET}\n"
                                f"{GREEN}私のオススメのSNSは、{name}です。{RESET}\n"
                                f"{GREEN}あなたの一番好きなSNSは{name}ですか?[Yes/No]{RESET}\n"
                                f"{GREEN}=============================================={RESET}\n"
                                f"{RESET}")
            # ユーザーが"No"を選択した場合は内側のwhileループを抜けます(次に人気のSNSを尋ねます)
            if user_answer.lower() in ["no", "n"]:
                break
            # ユーザーが"Yes"を選択した場合はforループを抜けます(次の質問へいきます)
            elif user_answer.lower() in ["yes", "y"]:
                found_favorite = True
                break
            # それ以外の回答をした場合、再度同じ質問を尋ねます
            else:
                # それ以外の場合の処理(同じ質問を繰り返し表示)
                print("有効な回答ではありません。もう一度入力してください。")
        # ユーザーの好きなSNSが見つかったらループを抜けます(found_favorite = Trueによって以下構文が成り立ちます)
        if found_favorite:
            break
noで返した場合(※決して自分の意見を反映しているわけではないです汗)
yesで返した場合
yes or no 以外で返した場合

次の設問では、ユーザーの好きなSNSを尋ねます。回答を受け取ったら、ユーザーからの回答の単語毎の頭文字を大文字に変換(データを重複させない為)し、ユーザーの好きなSNSがランキングデータに存在するかチェックします。存在する場合はカウントを増やし、存在しない場合は新しい項目を作成します。
そして、ランキングデータを保存します。

    # ユーザーの好きなSNSを尋ねます
    user_like_restaurant = input(f"{GREEN}=============================================={RESET}\n"
                                 f"{GREEN}{user_name}さんは、どのSNSが好きですか?{RESET}\n"
                                 f"{GREEN}※先ほどの設問でYesを回答した場合、選択したSNS名を入力してください{RESET}\n"
                                 f"{GREEN}=============================================={RESET}\n"
                                 f"{RESET}")
    # ユーザーからの回答の単語毎の頭文字を大文字に変換します
    capitalize_user_like_restaurant = ' '.join(word.capitalize() for word in user_like_restaurant.split())

    # ユーザーの好きなSNSがSNSのアンケートランキングデータに存在するかチェックします
    if capitalize_user_like_restaurant in ranking_data:
        # 存在する場合はカウントを増やします
        ranking_data[capitalize_user_like_restaurant] += 1
    # 存在しない場合は新しい項目を作成します
    else:
        ranking_data[capitalize_user_like_restaurant] = 1
    # SNSのアンケートランキングデータを保存します
    save_ranking(ranking_data)
ユーザーの好きなSNSを入力するインタラクション

最後に、ユーザーにメッセージを表示し、プログラムを終了します。

    # ユーザーにメッセージを表示し、プログラムを終了します
    print(f"{GREEN}=============================================={RESET}\n"
          f"{GREEN}{user_name}さん、貴重な時間をありがとうございました!{RESET}\n"
          f"{GREEN}それでは、良い1日を。さようなら!{RESET}\n"
          f"{GREEN}=============================================={RESET}"
          f"{RESET}")
    break
最後にメッセージを出力し、プログラムを終了
ranking.csvの中身


【7. アプリ制作を終えて】

以上が、Pythonを使用した人気SNSリサーチャーロボット()の作成方法です。このコードは酒井潤さんの教材以外の内容も含めていること、加えて教材内容と酒井潤さんが回答として用意されているコードとは異なることをご了承ください。
本来であれば、ユーザーに既存のSNSのアンケートランキングデータから好きなSNSを聞いた際、"Yes"の回答を受け取ったら次の設問に行く必要はありません。ですので、その場合には違う回答を出してアンケートを終了するコードにする方が望ましいかもしれません。

酒井潤さんの教材は他にも購入しましたが、やるのが楽しみで仕方がありません!各教材で1アウトプットくらいできればと思いますし、それ以外でも引き続きインプットアウトプットを繰り返していきたいと思います💪

それでは!!

この記事が気に入ったらサポートをしてみませんか?