🩺

Pythonで診断アプリを作ろう!

に公開

🔮 【プログラミング初心者向け】Streamlit で作る楽しい診断アプリ

プログラミングで何かを作ってみたいけれど、何から始めればいいかわからない...そんな方に朗報です!今回は、Python の Streamlit を使って、実際に使える診断アプリを作成します。

性格診断、天気診断、食べ物診断、ゲーム診断まで含む本格的なアプリを、初心者でも理解できるように詳しく解説していきます。

🌟 この記事を読めば...

if/else 文の使い方を楽しく学べます 🎯

この記事では、単なる診断アプリを作るだけでなく、プログラミングの基本である条件分岐(if/else 文)を徹底的に学べます。例えば:

  • 複数の条件を組み合わせた診断ロジック
  • ユーザーの選択に応じた動的な質問表示
  • 診断結果の履歴管理と統計情報

プログラミングを楽しみながら条件分岐の概念を身に着けましょう!

📁 フォルダとファイルの作成

1. フォルダ構造

diagnosis-project/
├── diagnosis.py
└── requirements.txt

2. 必要なライブラリをインストール

まず、requirements.txtファイルに以下を書きます:

streamlit>=1.28.0
random>=3.12.0

これで、プロジェクトの準備が整いました!

🔮 診断アプリを作ってみよう

さっそく、diagnosis.py にコードを書いていきましょう!

📱 アプリの基本設定

まずは、アプリの基本設定から始めます。

# 必要なライブラリをインポート
import streamlit as st  # Webアプリ作成用
import random  # ランダム選択用

# ページ設定
st.set_page_config(
    page_title="診断アプリ",  # ブラウザのタブに表示されるタイトル
    page_icon="🔮",          # ブラウザのタブに表示されるアイコン
    layout="centered"        # レイアウトを中央寄せに設定
)

# タイトルとヘッダー
st.title("🔮 あなたの診断アプリ")  # メインタイトル
st.markdown("---")  # 区切り線
st.markdown("### if/else文で作る楽しい診断!")  # サブタイトル

cursor のターミナルで以下のコマンドを実行して画面表示を確認しましょう!

python -m streamlit run diagnosis.py

📊 診断履歴の管理システム

次に、診断結果を保存する仕組みを準備します。

# ===== 診断履歴を保存する仕組み =====
# 'diagnosis_history'がsession_stateに存在しない場合(初回アクセス時)の処理
if 'diagnosis_history' not in st.session_state:
    st.session_state.diagnosis_history = []  # 空のリストで初期化

# ===== 診断タイプの選択 =====
st.subheader("🎯 診断タイプを選んでね")
diagnosis_type = st.radio(
    "どの診断をしますか?",
    ("🌟 性格診断", "🌤️ 天気診断", "🍕 食べ物診断", "🎮 ゲーム診断")
)

📝 プログラミング構文の詳細説明:

  • st.radio() - ラジオボタンを作成

    • ユーザーが複数の選択肢から 1 つのみを選べる機能
    • 例:st.radio("質問", ("選択肢1", "選択肢2", "選択肢3"))
    • 戻り値:選択された選択肢の文字列
  • st.session_state - ページを更新してもデータを保持する仕組み

    • 通常の変数はページを更新すると消える
    • session_stateを使うと、ページを更新してもデータが保持される
    • 履歴管理に最適

画面が以下のようになるはずです!

🚀 動的な質問システムの実装

診断タイプに応じて質問を変更する機能を実装します。これが if/else 文の最初の実用例です。

# ===== 診断の質問と回答 =====
st.markdown("---")  # 区切り線
st.subheader("📝 質問に答えてね")

# 診断タイプに応じて質問を変更
if diagnosis_type == "🌟 性格診断":
    st.write("あなたの性格を診断します!")

    # 質問1:
    question1 = st.selectbox(
        "休日はどう過ごす?",
        ("家でゆっくり", "友達と遊ぶ", "運動する", "勉強する")
    )

    # 質問2:
    question2 = st.selectbox(
        "好きな色は?",
        ("青", "赤", "緑", "ピンク", "紫")
    )

    # 質問3:
    # 1-10の数字を入力するフィールドを作成(最小値: 1, 最大値: 10, デフォルト値: 5)
    question3 = st.number_input("1-10の数字を選んで", min_value=1, max_value=10, value=5)

elif diagnosis_type == "🌤️ 天気診断":
    st.write("あなたに合う天気を診断します!")

    # 質問1:
    question1 = st.selectbox(
        "今の気分は?",
        ("元気", "落ち込み", "リラックス", "やる気満々")
    )

    # 質問2:
    question2 = st.selectbox(
        "好きな季節は?",
        ("春", "夏", "秋", "冬")
    )

    # 質問3:
    question3 = st.number_input("1-10の数字を選んで", min_value=1, max_value=10, value=5)

elif diagnosis_type == "🍕 食べ物診断":
    st.write("あなたに合う食べ物を診断します!")

    # 質問1:
    question1 = st.selectbox(
        "好きな味は?",
        ("甘い", "辛い", "酸っぱい", "しょっぱい")
    )

    # 質問2:
    question2 = st.selectbox(
        "好きな食事の時間は?",
        ("朝食", "昼食", "夕食", "夜食")
    )

    # 質問3:
    question3 = st.number_input("1-10の数字を選んで", min_value=1, max_value=10, value=5)

elif diagnosis_type == "🎮 ゲーム診断":
    st.write("あなたに合うゲームを診断します!")

    # 質問1:
    question1 = st.selectbox(
        "どんなゲームが好き?",
        ("アクション", "パズル", "RPG", "シミュレーション")
    )

    # 質問2:
    question2 = st.selectbox(
        "ゲームをプレイする時間は?",
        ("短時間", "中程度", "長時間", "超長時間")
    )

    # 質問3:
    question3 = st.number_input("1-10の数字を選んで", min_value=1, max_value=10, value=5)

📝 条件分岐の詳細説明:

  • if-elif-else - 条件に応じて処理を分岐

    • if 条件1: - 最初の条件が真(True)の場合の処理
    • elif 条件2: - 条件 1 が偽(False)で、条件 2 が真の場合の処理
    • else: - すべての条件が偽の場合の処理
  • 比較演算子 - 値を比較する記号

    • == - 等しい(例:diagnosis_type == "🌟 性格診断"
    • != - 等しくない
    • > - より大きい
    • < - より小さい
    • >= - 以上
    • <= - 以下
  • st.selectbox() - ドロップダウンメニューを作成

    • ユーザーが選択肢から 1 つを選べる機能
    • 戻り値:選択された選択肢の文字列
  • st.number_input() - 数値入力欄を作成

    • min_value - 最小値
    • max_value - 最大値
    • value - デフォルト値

💡 条件分岐をわかりやすく図解化

🎯 診断ロジックの実装

診断実行ボタンと、複雑な条件分岐を使った診断ロジックを実装します。

# ===== 診断実行ボタン =====
if st.button("🔮 診断開始!", type="primary"):
    try:
        # ===== 診断ロジック(if/else文の実演) =====
        if diagnosis_type == "🌟 性格診断":
            # 性格診断のロジック
            if question1 == "家でゆっくり" and question2 == "青":
                result = "🧘 あなたは静かで落ち着いた性格です。一人の時間を大切にするタイプ!"
            elif question1 == "友達と遊ぶ" and question2 == "赤":
                result = "🎉 あなたは社交的で明るい性格です。みんなの人気者タイプ!"
            elif question1 == "運動する" and question2 == "緑":
                result = "🏃 あなたは活動的で健康的な性格です。スポーツ好きタイプ!"
            elif question3 >= 7:
                result = "⭐ あなたは積極的でチャレンジ精神旺盛な性格です!"
            elif question3 >= 4:
                result = "😊 あなたはバランスの取れた性格です。安定感があります!"
            else:
                result = "🤔 あなたは慎重で思慮深い性格です。じっくり考えるタイプ!"

        elif diagnosis_type == "🌤️ 天気診断":
            # 天気診断のロジック
            if question1 == "元気" and question2 == "夏":
                result = "☀️ あなたに合う天気は晴れ!太陽のような明るさを持っています!"
            elif question1 == "落ち込み" and question2 == "秋":
                result = "🌧️ あなたに合う天気は雨。心を癒す時間が必要かもしれません。"
            elif question1 == "リラックス" and question2 == "春":
                result = "🌸 あなたに合う天気は春の陽気。心地よい風が似合います!"
            elif question3 >= 8:
                result = "🌈 あなたに合う天気は虹!特別な日を運んでくれます!"
            else:
                result = "🌤️ あなたに合う天気は曇り。落ち着いた雰囲気が似合います!"

        elif diagnosis_type == "🍕 食べ物診断":
            # 食べ物診断のロジック
            if question1 == "甘い" and question2 == "朝食":
                result = "🍰 あなたに合う食べ物はケーキ!甘いもので幸せを感じるタイプ!"
            elif question1 == "辛い" and question2 == "夕食":
                result = "🌶️ あなたに合う食べ物はカレー!スパイシーな刺激が好き!"
            elif question1 == "酸っぱい" and question2 == "昼食":
                result = "🍋 あなたに合う食べ物はレモン料理!爽やかな酸味が似合います!"
            elif question3 >= 6:
                result = "🍕 あなたに合う食べ物はピザ!みんなで楽しめる料理が好き!"
            else:
                result = "🍜 あなたに合う食べ物はラーメン!温かくて安心できる料理が好き!"

        elif diagnosis_type == "🎮 ゲーム診断":
            # ゲーム診断のロジック
            if question1 == "アクション" and question2 == "短時間":
                result = "⚡ あなたに合うゲームは格闘ゲーム!短時間でスリルを楽しむタイプ!"
            elif question1 == "パズル" and question2 == "中程度":
                result = "🧩 あなたに合うゲームはパズルゲーム!じっくり考えるのが好き!"
            elif question1 == "RPG" and question2 == "長時間":
                result = "🗡️ あなたに合うゲームはRPG!物語を楽しむのが好き!"
            elif question3 >= 7:
                result = "🎯 あなたに合うゲームはシューティングゲーム!正確性が求められるゲームが得意!"
            else:
                result = "🏠 あなたに合うゲームはシミュレーションゲーム!じっくりと世界を作るのが好き!"

📝 診断ロジックで使用する構文の詳細説明:

  • and演算子 - 両方の条件が真の場合のみ真

    • 例:question1 == "家でゆっくり" and question2 == "青"
    • 両方の条件が真の場合のみ、その処理が実行される
  • >=演算子 - 以上(その値以上)

    • 例:question3 >= 7 - question3 が 7 以上の場合
    • 数値の範囲による診断に使用
  • ネストした if 文 - if 文の中に if 文を入れる

    • 複雑な条件分岐を実現
    • 診断タイプ → 具体的な条件 → 結果という階層構造

💡 診断ロジックの流れを図解化

診断タイプ選択
    ↓
質問表示(if/elif/else)
    ↓
診断実行ボタン
    ↓
診断ロジック(if/elif/else)
    ↓
結果表示

✨ 結果表示と履歴管理

診断結果を美しく表示し、履歴に保存する機能を実装します。

        # ===== 結果表示 =====
        st.markdown("---")  # 区切り線
        st.subheader("✨ 診断結果")  # サブヘッダー
        st.success(result)  # 診断結果を表示

        # ランダムなアドバイス
        advice_list = [
            "💡 この結果を参考に、自分をより深く知ってみましょう!",
            "🌟 診断結果はあくまで参考程度。自分らしさを大切に!",
            "🎯 新しい発見があったら、それを活かしてみてください!",
            "🌈 毎日少しずつ成長していくことが大切です!"
        ]
        st.info(f"💭 {random.choice(advice_list)}") # ランダムに表示

        # 履歴に追加
        st.session_state.diagnosis_history.append(f"{diagnosis_type}: {result}")

        st.toast("🎉 診断完了!")  # 一時的な通知メッセージ

    except Exception as e:  # エラーが発生した場合の処理
        st.error(f"❌ エラーが発生しました: {str(e)}")

📝 結果表示で使用する構文の詳細説明:

  • st.success()/info()/error() - 文を色つきで表示

    • success 👉 緑(成功・結果表示)
    • info 👉 青(情報・アドバイス表示)
    • error 👉 赤(エラー表示)
  • random.choice()関数 - リストからランダムに 1 つの要素を選択

    • 例:
      advice_list = ["アドバイス1", "アドバイス2", "アドバイス3"]
      random.choice(advice_list)  # → "アドバイス2"
      
  • append()メソッド - リストの末尾に要素を追加

    • 例:
      history = ["診断1", "診断2"]
      history.append("診断3")
      print(history)  # ["診断1", "診断2", "診断3"]
      
  • f-string - 文字列内に変数を埋め込む

    • 例:f"💭 {random.choice(advice_list)}"
    • {}の中に変数や式を入れることで、動的な文字列を作成

問題なく診断処理できているか、画面を動かして確認しましょう!

📊 履歴表示機能

診断履歴を表示し、統計情報も含める機能を実装します。

# ===== 履歴表示 =====
st.markdown("---")  # 区切り線
st.subheader("📜 診断履歴")  # サブヘッダー

if st.session_state.diagnosis_history:  # 履歴が空でない場合
    # 履歴を表示
    # enumerate()関数で履歴リストの要素とインデックスを同時に取得(開始番号を1に設定)
    # i: 履歴番号、diagnosis: 診断内容
    for i, diagnosis in enumerate(st.session_state.diagnosis_history, 1):
        st.write(f"{i}. {diagnosis}")  # 「番号. 診断内容」の形式で表示

    # 統計情報(len()でリストの要素数を取得)
    st.info(f"📊 診断回数: {len(st.session_state.diagnosis_history)}回")
else:  # 履歴が空の場合
    st.write("まだ診断していません。上で診断してみましょう!")

# ===== 履歴クリアボタン =====
if st.session_state.diagnosis_history:  # 履歴が存在する場合のみクリアボタンを表示
    if st.button("🗑️ 履歴をクリア"):
        st.session_state.diagnosis_history = []  # 履歴を空のリストに初期化
        st.rerun()  # ページを再読み込みして表示を更新

📝 履歴処理で使用する関数の詳細説明:

  • enumerate()関数 - リストの要素とインデックスを同時に取得

    • 例:
      fruits = ["りんご", "みかん", "ぶどう"]
      for i, fruit in enumerate(fruits, 1):
          print(f"{i}. {fruit}")
      # 出力:
      # 1. りんご
      # 2. みかん
      # 3. ぶどう
      
  • len()関数 - リストの要素数を取得

    • 例:
      history = ["診断1", "診断2", "診断3"]
      count = len(history)  # → 3
      

履歴が表示されるか複数の診断を行って確認しましょう!

🎉 完成!

おめでとうございます!

今回出来上がった画面はこちらです 👇

実際に様々な診断を実行して動作確認してみましょう!!

🎯 まとめ:診断アプリで学んだこと

今回作成した診断アプリは、以下のような多くの重要な概念が含まれています:

  • 条件分岐(if/else 文) - プログラミングの基本
  • ユーザー入力処理 - インタラクティブなアプリの作成
  • データ管理 - 履歴の保存と表示
  • エラー処理 - 安全なアプリの作成
  • ランダム処理 - 動的なコンテンツの生成

今回の診断アプリの特徴:

  • 4 種類の診断 - 性格、天気、食べ物、ゲーム診断
  • 動的な質問 - 診断タイプに応じて質問が変化
  • 履歴管理 - 過去の診断結果を保存・表示
  • 統計情報 - 診断回数の自動カウント
  • エラー対策 - 予期しないエラーの安全対策

🚀 次のステップ

今回学んだ if/else 文を応用して、以下のような機能を追加してみましょう:

  1. 新しい診断タイプの追加 - 恋愛診断、職業診断など
  2. より複雑な条件分岐 - 3 つ以上の条件を組み合わせる
  3. 診断結果の詳細化 - より具体的なアドバイスを表示
  4. データの可視化 - 診断結果をグラフで表示

プログラミングは、このように少しずつ機能を追加していくことで、どんどん面白くなります!今回学んだ if/else 文は、プログラミングの基本中の基本なので、しっかりと理解しておきましょう!


🎓 プログラミング学習におすすめ

プログラミング未経験の方には CyTech(サイテック) がおすすめです!

CyTech は、未経験から IT エンジニアを目指す人向けのオンライン学習プラットフォームで、基礎から実務レベルのスキルを最短 10 ヶ月で習得できるカリキュラムを提供しています。
HTML/CSS/JavaScript/PHP/SQL/Git などのプログラミング言語に加え、デザイン、英語なども学べる総合的なプラットフォームです。
今後随時学習できるプログラミング言語増加予定!
エンジニア学習にお困りの方はまずは CyTech 無料カウンセリングでお悩み解消!

Discussion