import gradio as gr from dog_database import get_dog_description def create_comparison_tab(dog_breeds, get_dog_description): """创建品种比较标签页 Args: dog_breeds: 狗品种列表 get_dog_description: 获取品种描述的函数 """ with gr.TabItem("Breed Comparison"): gr.HTML("<p style='text-align: center;'>Select two dog breeds to compare their characteristics and care requirements.</p>") with gr.Row(): breed1_dropdown = gr.Dropdown( choices=dog_breeds, label="Select First Breed", value="Golden_Retriever" ) breed2_dropdown = gr.Dropdown( choices=dog_breeds, label="Select Second Breed", value="Border_Collie" ) compare_btn = gr.Button("Compare Breeds") comparison_output = gr.HTML(label="Comparison Results") def get_comparison_styles(): return """ /* Comparison specific styles */ .comparison-grid { display: flex; flex-direction: column; gap: 0; position: relative; } .breed-column { padding: 24px; position: relative; } .breed-column:first-child { margin-bottom: 60px; padding-bottom: 40px; } .breed-column:first-child::after { content: ''; position: absolute; bottom: -30px; left: 0; right: 0; height: 2px; background: linear-gradient( to right, transparent, #cbd5e0 10%, #cbd5e0 90%, transparent ); box-shadow: 0 1px 2px rgba(0,0,0,0.1); } .breed-column:first-child::before { content: '•••'; position: absolute; bottom: -38px; left: 50%; transform: translateX(-50%); font-size: 24px; letter-spacing: 8px; color: #94a3b8; text-align: center; background: white; padding: 0 20px; z-index: 1; } .breed-column:first-child .action-section { margin-bottom: 0; padding-bottom: 0; } @media (max-width: 768px) { .breed-column:first-child { margin-bottom: 50px; padding-bottom: 30px; } .breed-column:first-child::after { bottom: -25px; } .breed-column:first-child::before { bottom: -33px; font-size: 20px; } } .dog-info-card { background: white; position: relative; z-index: 0; } .breed-column:nth-child(2) { position: relative; margin-top: 20px; } """ def show_comparison(breed1, breed2): if not breed1 or not breed2: return "Please select two breeds to compare" # 获取所有信息 breed1_info = get_dog_description(breed1) breed2_info = get_dog_description(breed2) breed1_noise = breed_noise_info.get(breed1, {}).get('noise_notes', '').strip().split('\n') breed2_noise = breed_noise_info.get(breed2, {}).get('noise_notes', '').strip().split('\n') breed1_health = breed_health_info.get(breed1, {}).get('health_notes', '').strip().split('\n') breed2_health = breed_health_info.get(breed2, {}).get('health_notes', '').strip().split('\n') def format_noise_info(noise_data): characteristics = [] triggers = [] noise_level = "Moderate" # 默认值 in_characteristics = False in_triggers = False for line in noise_data: line = line.strip() if "Typical noise characteristics:" in line: in_characteristics = True continue elif "Barking triggers:" in line: in_triggers = True in_characteristics = False continue elif "Noise level:" in line: noise_level = line.split(':')[1].strip() continue if line.startswith('•'): if in_characteristics: characteristics.append(line[1:].strip()) elif in_triggers: triggers.append(line[1:].strip()) return { 'characteristics': characteristics, 'triggers': triggers, 'noise_level': noise_level } def format_health_info(health_data): considerations = [] screenings = [] in_considerations = False in_screenings = False for line in health_data: line = line.strip() if "Common breed-specific health considerations" in line: in_considerations = True in_screenings = False continue elif "Recommended health screenings:" in line: in_screenings = True in_considerations = False continue if line.startswith('•'): if in_considerations: considerations.append(line[1:].strip()) elif in_screenings: screenings.append(line[1:].strip()) return { 'considerations': considerations, 'screenings': screenings } def create_breed_column(breed, info, noise_data, health_data): noise_info = format_noise_info(noise_data) health_info = format_health_info(health_data) basic_info = f""" <div class="breed-column"> <h2 class="section-title"> <span class="icon">🐕</span> {breed.replace('_', ' ')} </h2> <div class="info-section"> <div class="info-item"> <span class="tooltip"> <span class="icon">📏</span> <span class="label">Size:</span> <span class="tooltip-icon">ⓘ</span> <span class="tooltip-text"> <strong>Size Categories:</strong><br> • Small: Under 20 pounds<br> • Medium: 20-60 pounds<br> • Large: Over 60 pounds </span> <span class="value">{info.get('Size', 'Not available')}</span> </span> </div> <div class="info-item"> <span class="tooltip"> <span class="icon">🏃</span> <span class="label">Exercise:</span> <span class="tooltip-icon">ⓘ</span> <span class="tooltip-text"> <strong>Exercise Needs:</strong><br> • Low: Short walks<br> • Moderate: 1-2 hours daily<br> • High: 2+ hours daily </span> <span class="value">{info.get('Exercise Needs', 'Not available')}</span> </span> </div> <div class="info-item"> <span class="tooltip"> <span class="icon">✂️</span> <span class="label">Grooming:</span> <span class="tooltip-icon">ⓘ</span> <span class="tooltip-text"> <strong>Grooming Requirements:</strong><br> • Low: Occasional brushing<br> • Moderate: Weekly grooming<br> • High: Daily maintenance </span> <span class="value">{info.get('Grooming Needs', 'Not available')}</span> </span> </div> <div class="info-item"> <span class="tooltip"> <span class="icon">👨👩👧👦</span> <span class="label">With Children:</span> <span class="tooltip-icon">ⓘ</span> <span class="tooltip-text"> <strong>Child Compatibility:</strong><br> • Yes: Excellent with kids<br> • Moderate: Good with older children<br> • No: Better for adult households </span> <span class="value">{info.get('Good with Children', 'Not available')}</span> </span> </div> <div class="info-item"> <span class="tooltip"> <span class="icon">⏳</span> <span class="label">Lifespan:</span> <span class="tooltip-icon">ⓘ</span> <span class="tooltip-text"> <strong>Average Lifespan:</strong><br> • Short: 6-8 years<br> • Average: 10-15 years<br> • Long: 12-20 years </span> <span class="value">{info.get('Lifespan', 'Not available')}</span> </span> </div> </div> """ # Noise Section noise_section = f""" <div class="noise-section"> <h3 class="section-header"> <span class="icon">🔊</span> Noise Behavior <span class="tooltip"> <span class="tooltip-icon">ⓘ</span> <span class="tooltip-text">Information about typical barking patterns and noise levels</span> </span> </h3> <div class="noise-info"> <div class="noise-details"> <h4 class="section-header">Typical noise characteristics:</h4> <div class="characteristics-list"> {' '.join([f'<div class="list-item">{item}</div>' for item in noise_info['characteristics']]) or '<div class="list-item">Information not available</div>'} </div> <div class="noise-level-display"> <h4 class="section-header">Noise level:</h4> <div class="level-indicator"> <span class="level-text">{noise_info['noise_level']}</span> </div> </div> <h4 class="section-header">Barking triggers:</h4> <div class="triggers-list"> {' '.join([f'<div class="list-item">{item}</div>' for item in noise_info['triggers']]) or '<div class="list-item">Information not available</div>'} </div> </div> </div> </div> """ # Health Section health_section = f""" <div class="health-section"> <h3 class="section-header"> <span class="icon">🏥</span> Health Insights <span class="tooltip"> <span class="tooltip-icon">ⓘ</span> <span class="tooltip-text"> Health information is compiled from multiple sources including veterinary resources, breed guides, and international canine health databases. </span> </span> </h3> <div class="health-info"> <div class="health-details"> <h4 class="section-header">Common health considerations:</h4> <div class="health-grid"> {' '.join([f'<div class="health-item">{item}</div>' for item in health_info['considerations']]) or '<div class="health-item">Information not available</div>'} </div> <h4 class="section-header">Recommended screenings:</h4> <div class="health-grid"> {' '.join([f'<div class="health-item screening">{item}</div>' for item in health_info['screenings']]) or '<div class="health-item screening">Information not available</div>'} </div> </div> </div> </div> <div class="action-section"> <a href="https://www.akc.org/dog-breeds/{breed.lower().replace('_', '-')}/" target="_blank" class="akc-button"> <span class="icon">🌐</span> Learn More about {breed.replace('_', ' ')} on AKC </a> </div> </div> """ return basic_info + noise_section + health_section html_output = f""" <div class="dog-info-card"> <div class="comparison-grid"> {create_breed_column(breed1, breed1_info, breed1_noise, breed1_health)} {create_breed_column(breed2, breed2_info, breed2_noise, breed2_health)} </div> <style> {get_comparison_styles()} </style> </div> """ return html_output compare_btn.click( show_comparison, inputs=[breed1_dropdown, breed2_dropdown], outputs=comparison_output ) return { 'breed1_dropdown': breed1_dropdown, 'breed2_dropdown': breed2_dropdown, 'compare_btn': compare_btn, 'comparison_output': comparison_output }