import sqlite3 import gradio as gr from dog_database import get_dog_description, dog_data from breed_health_info import breed_health_info from breed_noise_info import breed_noise_info from scoring_calculation_system import UserPreferences, calculate_compatibility_score from recommendation_html_format import format_recommendation_html, get_breed_recommendations from search_history import create_history_tab, create_history_component def create_recommendation_tab(UserPreferences, get_breed_recommendations, format_recommendation_html, history_component): with gr.TabItem("Breed Recommendation"): with gr.Tabs(): with gr.Tab("Find by Criteria"): gr.HTML("""

Tell us about your lifestyle, and we'll recommend the perfect dog breeds for you!

""") with gr.Row(): with gr.Column(): living_space = gr.Radio( choices=["apartment", "house_small", "house_large"], label="What type of living space do you have?", info="Choose your current living situation", value="apartment" ) yard_access = gr.Radio( choices=["no_yard", "shared_yard", "private_yard"], label="Yard Access Type", info="Available outdoor space", value="no_yard" ) exercise_time = gr.Slider( minimum=0, maximum=180, value=60, label="Daily exercise time (minutes)", info="Consider walks, play time, and training" ) exercise_type = gr.Radio( choices=["light_walks", "moderate_activity", "active_training"], label="Exercise Style", info="What kind of activities do you prefer?", value="moderate_activity" ) grooming_commitment = gr.Radio( choices=["low", "medium", "high"], label="Grooming commitment level", info="Low: monthly, Medium: weekly, High: daily", value="medium" ) with gr.Column(): experience_level = gr.Radio( choices=["beginner", "intermediate", "advanced"], label="Dog ownership experience", info="Be honest - this helps find the right match", value="beginner" ) time_availability = gr.Radio( choices=["limited", "moderate", "flexible"], label="Time Availability", info="Time available for dog care daily", value="moderate" ) has_children = gr.Checkbox( label="Have children at home", info="Helps recommend child-friendly breeds" ) children_age = gr.Radio( choices=["toddler", "school_age", "teenager"], label="Children's Age Group", info="Helps match with age-appropriate breeds", visible=False # 默認隱藏,只在has_children=True時顯示 ) noise_tolerance = gr.Radio( choices=["low", "medium", "high"], label="Noise tolerance level", info="Some breeds are more vocal than others", value="medium" ) def update_children_age_visibility(has_children): return gr.update(visible=has_children) has_children.change( fn=update_children_age_visibility, inputs=has_children, outputs=children_age ) get_recommendations_btn = gr.Button("Find My Perfect Match! 🔍", variant="primary") # recommendation_output = gr.HTML(label="Breed Recommendations") recommendation_output = gr.HTML( label="Breed Recommendations", visible=True, # 確保可見性 elem_id="recommendation-output" # 添加唯一ID以便追蹤 ) # def on_find_match_click(*args): # try: # user_prefs = UserPreferences( # living_space=args[0], # yard_access=args[1], # exercise_time=args[2], # exercise_type=args[3], # grooming_commitment=args[4], # experience_level=args[5], # time_availability=args[6], # has_children=args[7], # children_age=args[8] if args[7] else None, # noise_tolerance=args[9], # space_for_play=True if args[0] != "apartment" else False, # other_pets=False, # climate="moderate", # health_sensitivity="medium", # barking_acceptance=args[9] # ) # recommendations = get_breed_recommendations(user_prefs, top_n=10) # history_results = [{ # 'breed': rec['breed'], # 'rank': rec['rank'], # 'overall_score': rec['final_score'], # 'base_score': rec['base_score'], # 'bonus_score': rec['bonus_score'], # 'scores': rec['scores'] # } for rec in recommendations] # history_component.save_search( # user_preferences={ # 'living_space': args[0], # 'yard_access': args[1], # 'exercise_time': args[2], # 'exercise_type': args[3], # 'grooming_commitment': args[4], # 'experience_level': args[5], # 'time_availability': args[6], # 'has_children': args[7], # 'children_age': args[8] if args[7] else None, # 'noise_tolerance': args[9], # 'search_type': 'Criteria' # }, # results=history_results # ) # return format_recommendation_html(recommendations, is_description_search=False) # except Exception as e: # print(f"Error in find match: {str(e)}") # import traceback # print(traceback.format_exc()) # return "Error getting recommendations" def on_find_match_click(*args): try: # 添加數據驗證和日誌 print("Received args:", args) # 檢查接收到的參數 user_prefs = UserPreferences( living_space=args[0], yard_access=args[1], exercise_time=args[2], exercise_type=args[3], grooming_commitment=args[4], experience_level=args[5], time_availability=args[6], has_children=args[7], children_age=args[8] if args[7] else None, noise_tolerance=args[9], space_for_play=True if args[0] != "apartment" else False, other_pets=False, climate="moderate", health_sensitivity="medium", barking_acceptance=args[9] ) # 添加日誌來檢查 user_prefs 是否正確建立 print("UserPreferences created:", vars(user_prefs)) # 檢查推薦結果 recommendations = get_breed_recommendations(user_prefs, top_n=10) print("Recommendations received:", recommendations) # 確保 recommendations 不為空 if not recommendations: return "No matching breeds found. Please adjust your criteria." # 驗證推薦結果的格式 history_results = [] for rec in recommendations: result = { 'breed': rec['breed'], 'rank': rec.get('rank', 0), # 使用 get 方法避免 KeyError 'overall_score': rec['final_score'], 'base_score': rec.get('base_score', 0), 'bonus_score': rec.get('bonus_score', 0), 'scores': rec.get('scores', {}) } history_results.append(result) # 檢查歷史記錄是否成功保存 save_success = history_component.save_search( user_preferences={ 'living_space': args[0], 'yard_access': args[1], 'exercise_time': args[2], 'exercise_type': args[3], 'grooming_commitment': args[4], 'experience_level': args[5], 'time_availability': args[6], 'has_children': args[7], 'children_age': args[8] if args[7] else None, 'noise_tolerance': args[9], 'search_type': 'Criteria' }, results=history_results ) print("History save success:", save_success) # 產生並返回 HTML html_result = format_recommendation_html(recommendations, is_description_search=False) print("HTML generation completed") return html_result except Exception as e: print(f"Detailed error in find match: {str(e)}") import traceback print(traceback.format_exc()) return f"Error getting recommendations: {str(e)}" # 返回更具體的錯誤訊息 get_recommendations_btn.click( fn=on_find_match_click, inputs=[ living_space, yard_access, exercise_time, exercise_type, grooming_commitment, experience_level, time_availability, has_children, children_age, noise_tolerance ], outputs=recommendation_output ) return { 'living_space': living_space, 'exercise_time': exercise_time, 'grooming_commitment': grooming_commitment, 'experience_level': experience_level, 'has_children': has_children, 'noise_tolerance': noise_tolerance, 'get_recommendations_btn': get_recommendations_btn, 'recommendation_output': recommendation_output, }