MakiAi's picture
Update app.py
2daabb0 verified
import gradio as gr
import time
import pandas as pd
# 和水(WA-SUI)テーマの作成
def create_wa_sui_theme():
return gr.Theme(
primary_hue="blue",
secondary_hue="cyan",
neutral_hue="slate",
text_size="md",
spacing_size="lg",
radius_size="sm",
font=[
"Hiragino Sans",
"Noto Sans JP",
"Yu Gothic",
"system-ui",
"sans-serif"
],
font_mono=[
"SF Mono",
"Monaco",
"monospace"
]
).set(
# 和水カラーパレット
body_background_fill="#ffffff", # 純白の背景
body_text_color="#025159", # WA-from-above-4: 深海の静寂
button_primary_background_fill="#03658C", # WA-from-above-2: 深い海
button_primary_background_fill_hover="#025159", # WA-from-above-4: より深い海
button_primary_text_color="#ffffff", # WA-from-above-1: 水面の輝き
button_secondary_background_fill="#03A6A6", # WA-from-above-5: ティールの調和
button_secondary_background_fill_hover="#037F8C", # WA-from-above-3: 中間の深さ
button_secondary_text_color="#ffffff", # WA-from-above-4: 深海
input_background_fill="#ffffff", # 純白
input_border_color="#03A6A6", # WA-from-above-5: ティール
input_border_color_focus="#03658C", # WA-from-above-2: フォーカス時
block_background_fill="#ffffff", # 純白
block_border_color="#037F8C", # WA-from-above-3: 境界
panel_background_fill="#ffffff", # 純白
panel_border_color="#037F8C", # WA-from-above-3: パネル境界
slider_color="#03658C", # WA-from-above-2: スライダー
checkbox_label_text_color="#ffffff", # チェックボックスの文字色を白に
)
# 豊富なUIコンポーネントのデモ
def create_comprehensive_demo():
theme = create_wa_sui_theme()
# データ用のサンプル
sample_data = pd.DataFrame({
"商品名": ["碧海ラテ", "水面煎茶", "深海玄米茶", "潮風ほうじ茶"],
"価格": [450, 300, 280, 320],
"在庫": [15, 25, 8, 12],
"評価": [4.8, 4.5, 4.2, 4.6]
})
# 関数定義
def greet(name, mood, age, subscribe, hobbies_selected, prefecture_selected, satisfaction_level):
if not name:
return "名前を入力してください。"
age_msg = f"({age}歳)" if age else ""
subscribe_msg = "ニュースレターの購読ありがとうございます!" if subscribe else ""
hobbies_msg = f"趣味: {', '.join(hobbies_selected)}" if hobbies_selected else "趣味: 未選択"
prefecture_msg = f"出身: {prefecture_selected}"
# 満足度のNone値を処理
if satisfaction_level is None:
satisfaction_msg = "満足度: 未設定"
else:
satisfaction_msg = f"満足度: {int(satisfaction_level)}/10"
greetings = {
"🌊 爽やか": f"{name}さん{age_msg}、今日は海のように爽やかですね!🌊",
"💧 静寂": f"こんにちは、{name}さん{age_msg}。水のように静かな一日ですね。",
"🏖️ 穏やか": f"{name}さん{age_msg}、穏やかな波のような心地よい日ですね。🏖️"
}
result = greetings.get(mood, f"こんにちは、{name}さん{age_msg}。")
result += f"\n{hobbies_msg}"
result += f"\n{prefecture_msg}"
result += f"\n{satisfaction_msg}"
if subscribe_msg:
result += f"\n{subscribe_msg}"
return result
def generate_haiku(season, style):
haikus = {
("🌊 海", "古典"): "青い海\n波音響きて\n心澄む",
("🌊 海", "現代"): "海見つめ\nインスタ映えする\n青い空",
("💧 雨", "古典"): "雨滴りて\n水面に広がる\n静寂かな",
("💧 雨", "現代"): "雨の日は\nカフェで海を\n眺めつつ",
("🌙 月", "古典"): "月影が\n水面に映りて\n揺らめけり",
("🌙 月", "現代"): "月夜には\n海カフェでまったり\nティータイム",
("❄️ 雪", "古典"): "雪降りて\n海も静寂に\n包まれん",
("❄️ 雪", "現代"): "雪景色\n海と空とが\n一つなり"
}
return haikus.get((season, style), "季語なし\n心に響きて\n句となりぬ")
def process_data(data, filter_price):
if data is None:
return sample_data
df = pd.DataFrame(data)
if filter_price:
df = df[df['価格'] >= filter_price]
return df
def add_chat_message(message, history):
if message:
responses = [
"海のように深いご質問ですね!",
"波のようにゆったりと考えてみましょう。",
"なるほど、潮の満ち引きのように理解できます。",
"水面に映る月のように美しい発想ですね!",
"一緒に海風を感じながら考えてみましょう。"
]
import random
response = random.choice(responses)
history.append([message, response])
return history, ""
# クリア機能の修正
def clear_all_inputs():
return [
"", # name_input
25, # age_input
"💧 静寂", # mood_selector
False, # subscribe_check
[], # hobbies
"神奈川県", # prefecture
8, # satisfaction
"", # hobbies_debug
"神奈川県, 満足度: 8", # status_debug
"8 (type: int)", # satisfaction_debug
"" # result_output
]
# 趣味選択の変更を監視する関数
def update_hobbies_debug(selected_hobbies):
if selected_hobbies:
return ", ".join(selected_hobbies)
else:
return "未選択"
# 都道府県と満足度の変更を監視する関数
def update_status_debug(prefecture_val, satisfaction_val):
if satisfaction_val is None:
return f"{prefecture_val}, 満足度: 未設定"
else:
return f"{prefecture_val}, 満足度: {int(satisfaction_val)}"
# 満足度の変更を監視する関数(専用)
def update_satisfaction_debug(satisfaction_val):
if satisfaction_val is None:
return "None (未設定)"
else:
return f"{satisfaction_val} (type: {type(satisfaction_val).__name__})"
with gr.Blocks(theme=theme, title="WA-SUI 和水") as demo:
# ヘッダー
gr.HTML("""
<div style='text-align: center; margin-bottom: 2rem; padding: 2rem; background: linear-gradient(135deg, #03658C 0%, #AED3F2 100%); color: white; border-radius: 12px; box-shadow: 0 8px 32px rgba(3, 101, 140, 0.3);'>
<h1 style='font-size: 3rem; margin-bottom: 0.5rem; text-shadow: 2px 2px 4px rgba(2, 81, 89, 0.5); color: white;'>WA-SUI 和水</h1>
<p style='font-size: 1.2rem; margin: 0; opacity: 0.9; color: white;'>〜 水の流れのような調和とデザイン 〜</p>
</div>
""")
with gr.Tabs():
# 基本入力コンポーネント
with gr.Tab("🌊 基本入力"):
gr.Markdown("### 様々な入力コンポーネント")
with gr.Row():
with gr.Column():
name_input = gr.Textbox(
label="🌊 お名前",
placeholder="海野太郎",
info="フルネームを入力してください"
)
age_input = gr.Number(
label="🎂 年齢",
minimum=0,
maximum=120,
value=25
)
mood_selector = gr.Radio(
choices=["🌊 爽やか", "💧 静寂", "🏖️ 穏やか"],
label="🎭 今日の気分",
value="💧 静寂"
)
subscribe_check = gr.Checkbox(
label="📧 海のお便りを購読する",
value=False
)
with gr.Column():
hobbies = gr.CheckboxGroup(
choices=["🏄‍♂️ サーフィン", "🐠 釣り", "🌊 海水浴", "🏃‍♂️ ジョギング", "🍵 茶道", "🎨 水彩画"],
label="趣味(複数選択可)",
value=["🐠 釣り"],
interactive=True
)
prefecture = gr.Dropdown(
choices=["北海道", "神奈川県", "静岡県", "愛知県", "三重県", "沖縄県"],
label="🗾 都道府県(海に近い県)",
value="神奈川県",
interactive=True
)
satisfaction = gr.Slider(
minimum=1,
maximum=10,
value=8,
step=1,
label="🌊 満足度(波の高さで表現:1-10)",
interactive=True,
show_label=True
)
# デバッグ用:選択された趣味を表示
hobbies_debug = gr.Textbox(
label="🔍 選択中の趣味(デバッグ用)",
interactive=False,
value="🐠 釣り"
)
# デバッグ用:都道府県と満足度を表示
status_debug = gr.Textbox(
label="🔍 都道府県・満足度(デバッグ用)",
interactive=False,
value="神奈川県, 満足度: 8"
)
# デバッグ用:満足度の生の値を表示
satisfaction_debug = gr.Textbox(
label="🔍 満足度の生の値(デバッグ用)",
interactive=False,
value="8"
)
with gr.Row():
submit_btn = gr.Button("🌊 情報を送信", variant="primary", size="lg")
clear_btn = gr.Button("🗑️ クリア", variant="secondary")
result_output = gr.Textbox(
label="💌 結果",
interactive=False,
lines=4
)
# イベントハンドラーの修正
submit_btn.click(
fn=greet,
inputs=[name_input, mood_selector, age_input, subscribe_check, hobbies, prefecture, satisfaction],
outputs=result_output
)
# クリアボタンの修正
clear_btn.click(
fn=clear_all_inputs,
inputs=None,
outputs=[name_input, age_input, mood_selector, subscribe_check,
hobbies, prefecture, satisfaction, hobbies_debug, status_debug, satisfaction_debug, result_output]
)
# 趣味選択の変更を監視
hobbies.change(
fn=update_hobbies_debug,
inputs=[hobbies],
outputs=[hobbies_debug]
)
# 都道府県と満足度の変更を監視
prefecture.change(
fn=update_status_debug,
inputs=[prefecture, satisfaction],
outputs=[status_debug]
)
satisfaction.change(
fn=update_status_debug,
inputs=[prefecture, satisfaction],
outputs=[status_debug]
)
# 満足度専用の監視
satisfaction.change(
fn=update_satisfaction_debug,
inputs=[satisfaction],
outputs=[satisfaction_debug]
)
# 俳句生成
with gr.Tab("🎋 海の俳句工房"):
gr.Markdown("### AI海洋俳句生成システム")
with gr.Row():
with gr.Column():
season_selector = gr.Radio(
choices=["🌊 海", "💧 雨", "🌙 月", "❄️ 雪"],
label="🌊 季語を選択",
value="🌊 海"
)
style_selector = gr.Radio(
choices=["古典", "現代"],
label="🎨 スタイル",
value="古典"
)
haiku_btn = gr.Button("🌊 俳句を作る", variant="primary", size="lg")
with gr.Column(scale=2):
haiku_result = gr.Textbox(
label="📜 生成された俳句",
interactive=False,
lines=5,
placeholder="ここに美しい海の俳句が表示されます...",
)
gr.Markdown("""
**俳句の説明:**
- **古典**: 伝統的な海の表現スタイル
- **現代**: 現代的な海の言葉遣い
""")
haiku_btn.click(
fn=generate_haiku,
inputs=[season_selector, style_selector],
outputs=haiku_result
)
# データ表示
with gr.Tab("📊 海のデータ"):
gr.Markdown("### データ表示コンポーネント")
with gr.Row():
with gr.Column():
price_filter = gr.Slider(
minimum=200,
maximum=500,
value=300,
step=50,
label="💰 最低価格フィルター"
)
refresh_btn = gr.Button("🔄 データ更新", variant="secondary")
# JSON表示
json_data = gr.JSON(
value={
"店舗名": "海風カフェ 碧",
"営業時間": "9:00-21:00",
"定休日": "火曜日",
"メニュー数": 15,
"人気商品": ["碧海ラテ", "海風スイーツセット"]
},
label="📋 店舗情報(JSON)"
)
with gr.Column(scale=2):
# データフレーム表示
data_display = gr.DataFrame(
value=sample_data,
label="🌊 海のメニューデータ",
interactive=True,
wrap=True
)
# ラベル表示
label_display = gr.Label(
value={
"海の見える店": 0.95,
"潮風感じる": 0.88,
"青い空気": 0.75,
"波音聞こえる": 0.62
},
label="🏆 海のカフェ評価スコア"
)
refresh_btn.click(
fn=process_data,
inputs=[data_display, price_filter],
outputs=data_display
)
# チャットボット
with gr.Tab("💬 海のチャットボット"):
gr.Markdown("### 海風AIアシスタントと会話")
with gr.Row():
with gr.Column(scale=2):
chatbot = gr.Chatbot(
value=[["こんにちは!", "こんにちは!海風カフェ碧のAIアシスタントです。海のようにゆったりとお手伝いさせていただきます🌊"]],
label="🤖 海風AIアシスタント",
height=400
)
with gr.Row():
chat_input = gr.Textbox(
placeholder="波のようにメッセージを入力してください...",
label="",
scale=4
)
send_btn = gr.Button("🌊 送信", variant="primary", scale=1)
# クイック返信ボタン
with gr.Row():
quick1 = gr.Button("☕ 海のメニューは?", size="sm")
quick2 = gr.Button("🕐 営業時間は?", size="sm")
quick3 = gr.Button("📍 海までの道は?", size="sm")
with gr.Column():
gr.Markdown("### 💡 海の便利機能")
gr.Markdown("""
**質問例:**
- 海を眺められるメニュー
- 潮風を感じる営業時間
- 海辺へのアクセス方法
- 海の見える席の予約
- 海風イベント情報
""")
# アコーディオン
with gr.Accordion("🔧 詳細設定", open=False):
temperature = gr.Slider(
minimum=0.1,
maximum=2.0,
value=0.7,
step=0.1,
label="🌡️ 応答の流動性(波の動き)"
)
max_tokens = gr.Slider(
minimum=50,
maximum=500,
value=150,
step=25,
label="📏 最大応答長(潮の満ち引き)"
)
# チャット機能の実装
send_btn.click(
fn=add_chat_message,
inputs=[chat_input, chatbot],
outputs=[chatbot, chat_input]
)
chat_input.submit(
fn=add_chat_message,
inputs=[chat_input, chatbot],
outputs=[chatbot, chat_input]
)
# クイック返信の修正
def quick_reply_1(history):
new_history = history + [["海のメニューは?", "碧海ラテと海風スイーツセットが人気です!季節限定の潮風もちもおすすめです。🌊"]]
return new_history
def quick_reply_2(history):
new_history = history + [["営業時間は?", "海の見える時間、9:00-21:00で営業しています。定休日は火曜日です。🌅🌅"]]
return new_history
def quick_reply_3(history):
new_history = history + [["海までの道は?", "JR東海道線「大磯駅」から徒歩5分です。海岸線沿いの青い建物が目印です。🏖️"]]
return new_history
quick1.click(
fn=quick_reply_1,
inputs=[chatbot],
outputs=[chatbot]
)
quick2.click(
fn=quick_reply_2,
inputs=[chatbot],
outputs=[chatbot]
)
quick3.click(
fn=quick_reply_3,
inputs=[chatbot],
outputs=[chatbot]
)
# テーマ設定
with gr.Tab("🌊 WA-SUI設定"):
gr.Markdown("### WA-SUI(和水)テーマの哲学")
# カラーパレット表示
gr.HTML("""
<div style='display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 1rem; margin: 2rem 0;'>
<div style='padding: 1.5rem; background: #ffffff; border: 2px solid #037F8C; border-radius: 12px; text-align: center; transition: transform 0.2s; box-shadow: 0 4px 12px rgba(174, 211, 242, 0.3);'>
<h4 style='color: #025159; margin-top: 0;'>🤍 純白の背景</h4>
<div style='width: 100%; height: 60px; background: #ffffff; border: 2px solid #AED3F2; border-radius: 8px; margin: 1rem 0; box-shadow: 0 4px 8px rgba(0,0,0,0.1);'></div>
<p style='font-size: 0.9rem; color: #025159; margin: 0;'>#ffffff - メイン背景</p>
</div>
<div style='padding: 1.5rem; background: #ffffff; border: 2px solid #037F8C; border-radius: 12px; text-align: center; transition: transform 0.2s; box-shadow: 0 4px 12px rgba(174, 211, 242, 0.3);'>
<h4 style='color: #025159; margin-top: 0;'>🌊 水面の輝き</h4>
<div style='width: 100%; height: 60px; background: #AED3F2; border-radius: 8px; margin: 1rem 0; box-shadow: 0 4px 8px rgba(0,0,0,0.1);'></div>
<p style='font-size: 0.9rem; color: #025159; margin: 0;'>#AED3F2 - アクセント</p>
</div>
<div style='padding: 1.5rem; background: #ffffff; border: 2px solid #037F8C; border-radius: 12px; text-align: center; transition: transform 0.2s; box-shadow: 0 4px 12px rgba(3, 101, 140, 0.3);'>
<h4 style='color: #025159; margin-top: 0;'>🌀 深い海</h4>
<div style='width: 100%; height: 60px; background: #03658C; border-radius: 8px; margin: 1rem 0; box-shadow: 0 4px 8px rgba(0,0,0,0.1);'></div>
<p style='font-size: 0.9rem; color: #025159; margin: 0;'>#03658C - プライマリ</p>
</div>
<div style='padding: 1.5rem; background: #ffffff; border: 2px solid #037F8C; border-radius: 12px; text-align: center; transition: transform 0.2s; box-shadow: 0 4px 12px rgba(3, 127, 140, 0.3);'>
<h4 style='color: #025159; margin-top: 0;'>🌊 中間の深さ</h4>
<div style='width: 100%; height: 60px; background: #037F8C; border-radius: 8px; margin: 1rem 0; box-shadow: 0 4px 8px rgba(0,0,0,0.1);'></div>
<p style='font-size: 0.9rem; color: #025159; margin: 0;'>#037F8C - ボーダー</p>
</div>
<div style='padding: 1.5rem; background: #ffffff; border: 2px solid #037F8C; border-radius: 12px; text-align: center; transition: transform 0.2s; box-shadow: 0 4px 12px rgba(1, 80, 89, 0.3);'>
<h4 style='color: #025159; margin-top: 0;'>🕳️ 深海の静寂</h4>
<div style='width: 100%; height: 60px; background: #025159; border-radius: 8px; margin: 1rem 0; box-shadow: 0 4px 8px rgba(0,0,0,0.1);'></div>
<p style='font-size: 0.9rem; color: #025159; margin: 0;'>#025159 - テキスト</p>
</div>
<div style='padding: 1.5rem; background: #ffffff; border: 2px solid #037F8C; border-radius: 12px; text-align: center; transition: transform 0.2s; box-shadow: 0 4px 12px rgba(3, 165, 165, 0.3);'>
<h4 style='color: #025159; margin-top: 0;'>💎 ティールの調和</h4>
<div style='width: 100%; height: 60px; background: #03A6A6; border-radius: 8px; margin: 1rem 0; box-shadow: 0 4px 8px rgba(0,0,0,0.1);'></div>
<p style='font-size: 0.9rem; color: #025159; margin: 0;'>#03A6A6 - セカンダリ</p>
</div>
</div>
""")
gr.Markdown("""
### 🌊 WA-SUI(和水)デザイン哲学
**流(りゅう)- Flow**
- 水の自然な流れを表現
- 要素間の滑らかな遷移
- ユーザーの操作における流動性
**調(ちょう)- Harmony**
- 純白の背景: 清潔で読みやすい基盤
- 水面の輝き: 美しいアクセントカラー
- 深い海: 信頼感のある主要アクション
- 中間の深さ: バランスの取れた境界
- 深海の静寂: 読みやすいテキスト
- ティールの調和: 優美なセカンダリアクション
**透(とう)- Transparency**
- 直感的で透明な操作性
- 水のような清らかさ
- 心地よいユーザー体験
- 海の広がりのような開放感
**和(わ)- Japanese Harmony**
- 日本の美意識との融合
- 水と技術の調和
- 現代と伝統の共存
- 心の安らぎを与える設計
""")
# デモコンポーネント
gr.Markdown("### 🛠️ WA-SUI コンポーネント実装")
with gr.Row():
demo_slider = gr.Slider(0, 100, 50, label="🌊 波の高さ")
demo_checkbox = gr.Checkbox(True, label="☑️ 海風を感じる")
demo_radio = gr.Radio(["凪", "波", "嵐"], label="📻 海の状態", value="波")
with gr.Row():
demo_dropdown = gr.Dropdown(["深海", "浅瀬", "潮だまり"], label="📋 海の深さ")
demo_number = gr.Number(label="🔢 波の数", value=108)
demo_textbox = gr.Textbox(label="📝 海への想い", placeholder="海のように広い心で...")
# ボタンバリエーション
gr.Markdown("### 🔘 WA-SUI アクション")
with gr.Row():
gr.Button("🌊 波を起こす", variant="primary")
gr.Button("💧 静寂にする", variant="secondary")
gr.Button("⛔ 嵐を止める", variant="stop")
# 海の音効果(デモ用)
gr.Markdown("### 🎵 海の音効果")
with gr.Row():
wave_sound = gr.Audio(label="🌊 波の音", interactive=False)
rain_sound = gr.Audio(label="☔ 雨の音", interactive=False)
gr.Markdown("""
### 📚 WA-SUI 使用ガイド
**適用シーン:**
- 🏖️ 海辺のカフェ・レストラン
- 🏊‍♂️ フィットネス・スパアプリ
- 🧘‍♀️ 瞑想・リラクゼーションアプリ
- 🌊 海洋関連の教育アプリ
- 💧 水質管理システム
**デザイン原則:**
- 流れるような操作感
- 海の深さを表現した階層
- 水の透明感を活かしたレイアウト
- 日本的な美意識の組み込み
""")
return demo
# アプリケーションの実行
if __name__ == "__main__":
print("WA-SUI(和水)- 海と水のテーマ UIコンポーネント集")
print("=" * 60)
app = create_comprehensive_demo()
app.launch(
share=True,
server_name="0.0.0.0",
server_port=7860,
show_error=True
)