Spaces:
Running
on
Zero
Running
on
Zero
| 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 | |
| } | |