Spaces:
Running
Running
Delete breed_comparison.py
Browse files- breed_comparison.py +0 -369
breed_comparison.py
DELETED
@@ -1,369 +0,0 @@
|
|
1 |
-
import gradio as gr
|
2 |
-
import sqlite3
|
3 |
-
from dog_database import get_dog_description
|
4 |
-
from breed_health_info import breed_health_info
|
5 |
-
from breed_noise_info import breed_noise_info
|
6 |
-
|
7 |
-
|
8 |
-
def create_comparison_tab(dog_breeds, get_dog_description):
|
9 |
-
|
10 |
-
with gr.TabItem("Breed Comparison"):
|
11 |
-
gr.HTML("<p style='text-align: center;'>Select two dog breeds to compare their characteristics and care requirements.</p>")
|
12 |
-
|
13 |
-
with gr.Row():
|
14 |
-
breed1_dropdown = gr.Dropdown(
|
15 |
-
choices=dog_breeds,
|
16 |
-
label="Select First Breed",
|
17 |
-
value="Golden_Retriever"
|
18 |
-
)
|
19 |
-
breed2_dropdown = gr.Dropdown(
|
20 |
-
choices=dog_breeds,
|
21 |
-
label="Select Second Breed",
|
22 |
-
value="Border_Collie"
|
23 |
-
)
|
24 |
-
|
25 |
-
compare_btn = gr.Button("Compare Breeds")
|
26 |
-
comparison_output = gr.HTML(label="Comparison Results")
|
27 |
-
|
28 |
-
def get_comparison_styles():
|
29 |
-
return """
|
30 |
-
/* Comparison specific styles */
|
31 |
-
.comparison-grid {
|
32 |
-
display: flex;
|
33 |
-
flex-direction: column;
|
34 |
-
gap: 0;
|
35 |
-
position: relative;
|
36 |
-
}
|
37 |
-
|
38 |
-
.breed-column {
|
39 |
-
padding: 24px;
|
40 |
-
position: relative;
|
41 |
-
}
|
42 |
-
|
43 |
-
.breed-column:first-child {
|
44 |
-
margin-bottom: 60px;
|
45 |
-
padding-bottom: 40px;
|
46 |
-
}
|
47 |
-
|
48 |
-
.breed-column:first-child::after {
|
49 |
-
content: '';
|
50 |
-
position: absolute;
|
51 |
-
bottom: -30px;
|
52 |
-
left: 0;
|
53 |
-
right: 0;
|
54 |
-
height: 2px;
|
55 |
-
background: linear-gradient(
|
56 |
-
to right,
|
57 |
-
transparent,
|
58 |
-
#cbd5e0 10%,
|
59 |
-
#cbd5e0 90%,
|
60 |
-
transparent
|
61 |
-
);
|
62 |
-
box-shadow: 0 1px 2px rgba(0,0,0,0.1);
|
63 |
-
}
|
64 |
-
|
65 |
-
.breed-column:first-child::before {
|
66 |
-
content: '•••';
|
67 |
-
position: absolute;
|
68 |
-
bottom: -38px;
|
69 |
-
left: 50%;
|
70 |
-
transform: translateX(-50%);
|
71 |
-
font-size: 24px;
|
72 |
-
letter-spacing: 8px;
|
73 |
-
color: #94a3b8;
|
74 |
-
text-align: center;
|
75 |
-
background: white;
|
76 |
-
padding: 0 20px;
|
77 |
-
z-index: 1;
|
78 |
-
}
|
79 |
-
|
80 |
-
.breed-column:first-child .action-section {
|
81 |
-
margin-bottom: 0;
|
82 |
-
padding-bottom: 0;
|
83 |
-
}
|
84 |
-
|
85 |
-
@media (max-width: 768px) {
|
86 |
-
.breed-column:first-child {
|
87 |
-
margin-bottom: 50px;
|
88 |
-
padding-bottom: 30px;
|
89 |
-
}
|
90 |
-
|
91 |
-
.breed-column:first-child::after {
|
92 |
-
bottom: -25px;
|
93 |
-
}
|
94 |
-
|
95 |
-
.breed-column:first-child::before {
|
96 |
-
bottom: -33px;
|
97 |
-
font-size: 20px;
|
98 |
-
}
|
99 |
-
}
|
100 |
-
|
101 |
-
.dog-info-card {
|
102 |
-
background: white;
|
103 |
-
position: relative;
|
104 |
-
z-index: 0;
|
105 |
-
}
|
106 |
-
|
107 |
-
.breed-column:nth-child(2) {
|
108 |
-
position: relative;
|
109 |
-
margin-top: 20px;
|
110 |
-
}
|
111 |
-
"""
|
112 |
-
|
113 |
-
def show_comparison(breed1, breed2):
|
114 |
-
if not breed1 or not breed2:
|
115 |
-
return "Please select two breeds to compare"
|
116 |
-
|
117 |
-
# 获取所有信息
|
118 |
-
breed1_info = get_dog_description(breed1)
|
119 |
-
breed2_info = get_dog_description(breed2)
|
120 |
-
breed1_noise = breed_noise_info.get(breed1, {}).get('noise_notes', '').strip().split('\n')
|
121 |
-
breed2_noise = breed_noise_info.get(breed2, {}).get('noise_notes', '').strip().split('\n')
|
122 |
-
breed1_health = breed_health_info.get(breed1, {}).get('health_notes', '').strip().split('\n')
|
123 |
-
breed2_health = breed_health_info.get(breed2, {}).get('health_notes', '').strip().split('\n')
|
124 |
-
|
125 |
-
def format_noise_info(noise_data):
|
126 |
-
characteristics = []
|
127 |
-
triggers = []
|
128 |
-
noise_level = "Moderate" # 默认值
|
129 |
-
|
130 |
-
in_characteristics = False
|
131 |
-
in_triggers = False
|
132 |
-
|
133 |
-
for line in noise_data:
|
134 |
-
line = line.strip()
|
135 |
-
if "Typical noise characteristics:" in line:
|
136 |
-
in_characteristics = True
|
137 |
-
continue
|
138 |
-
elif "Barking triggers:" in line:
|
139 |
-
in_triggers = True
|
140 |
-
in_characteristics = False
|
141 |
-
continue
|
142 |
-
elif "Noise level:" in line:
|
143 |
-
noise_level = line.split(':')[1].strip()
|
144 |
-
continue
|
145 |
-
|
146 |
-
if line.startswith('•'):
|
147 |
-
if in_characteristics:
|
148 |
-
characteristics.append(line[1:].strip())
|
149 |
-
elif in_triggers:
|
150 |
-
triggers.append(line[1:].strip())
|
151 |
-
|
152 |
-
return {
|
153 |
-
'characteristics': characteristics,
|
154 |
-
'triggers': triggers,
|
155 |
-
'noise_level': noise_level
|
156 |
-
}
|
157 |
-
|
158 |
-
def format_health_info(health_data):
|
159 |
-
considerations = []
|
160 |
-
screenings = []
|
161 |
-
|
162 |
-
in_considerations = False
|
163 |
-
in_screenings = False
|
164 |
-
|
165 |
-
for line in health_data:
|
166 |
-
line = line.strip()
|
167 |
-
if "Common breed-specific health considerations" in line:
|
168 |
-
in_considerations = True
|
169 |
-
in_screenings = False
|
170 |
-
continue
|
171 |
-
elif "Recommended health screenings:" in line:
|
172 |
-
in_screenings = True
|
173 |
-
in_considerations = False
|
174 |
-
continue
|
175 |
-
|
176 |
-
if line.startswith('•'):
|
177 |
-
if in_considerations:
|
178 |
-
considerations.append(line[1:].strip())
|
179 |
-
elif in_screenings:
|
180 |
-
screenings.append(line[1:].strip())
|
181 |
-
|
182 |
-
return {
|
183 |
-
'considerations': considerations,
|
184 |
-
'screenings': screenings
|
185 |
-
}
|
186 |
-
|
187 |
-
def create_breed_column(breed, info, noise_data, health_data):
|
188 |
-
noise_info = format_noise_info(noise_data)
|
189 |
-
health_info = format_health_info(health_data)
|
190 |
-
|
191 |
-
basic_info = f"""
|
192 |
-
<div class="breed-column">
|
193 |
-
<h2 class="section-title">
|
194 |
-
<span class="icon">🐕</span> {breed.replace('_', ' ')}
|
195 |
-
</h2>
|
196 |
-
|
197 |
-
<div class="info-section">
|
198 |
-
<div class="info-item">
|
199 |
-
<span class="tooltip">
|
200 |
-
<span class="icon">📏</span>
|
201 |
-
<span class="label">Size:</span>
|
202 |
-
<span class="tooltip-icon">ⓘ</span>
|
203 |
-
<span class="tooltip-text">
|
204 |
-
<strong>Size Categories:</strong><br>
|
205 |
-
• Small: Under 20 pounds<br>
|
206 |
-
• Medium: 20-60 pounds<br>
|
207 |
-
• Large: Over 60 pounds
|
208 |
-
</span>
|
209 |
-
<span class="value">{info.get('Size', 'Not available')}</span>
|
210 |
-
</span>
|
211 |
-
</div>
|
212 |
-
<div class="info-item">
|
213 |
-
<span class="tooltip">
|
214 |
-
<span class="icon">🏃</span>
|
215 |
-
<span class="label">Exercise:</span>
|
216 |
-
<span class="tooltip-icon">ⓘ</span>
|
217 |
-
<span class="tooltip-text">
|
218 |
-
<strong>Exercise Needs:</strong><br>
|
219 |
-
• Low: Short walks<br>
|
220 |
-
• Moderate: 1-2 hours daily<br>
|
221 |
-
• High: 2+ hours daily
|
222 |
-
</span>
|
223 |
-
<span class="value">{info.get('Exercise Needs', 'Not available')}</span>
|
224 |
-
</span>
|
225 |
-
</div>
|
226 |
-
<div class="info-item">
|
227 |
-
<span class="tooltip">
|
228 |
-
<span class="icon">✂️</span>
|
229 |
-
<span class="label">Grooming:</span>
|
230 |
-
<span class="tooltip-icon">ⓘ</span>
|
231 |
-
<span class="tooltip-text">
|
232 |
-
<strong>Grooming Requirements:</strong><br>
|
233 |
-
• Low: Occasional brushing<br>
|
234 |
-
• Moderate: Weekly grooming<br>
|
235 |
-
• High: Daily maintenance
|
236 |
-
</span>
|
237 |
-
<span class="value">{info.get('Grooming Needs', 'Not available')}</span>
|
238 |
-
</span>
|
239 |
-
</div>
|
240 |
-
<div class="info-item">
|
241 |
-
<span class="tooltip">
|
242 |
-
<span class="icon">👨👩👧👦</span>
|
243 |
-
<span class="label">With Children:</span>
|
244 |
-
<span class="tooltip-icon">ⓘ</span>
|
245 |
-
<span class="tooltip-text">
|
246 |
-
<strong>Child Compatibility:</strong><br>
|
247 |
-
• Yes: Excellent with kids<br>
|
248 |
-
• Moderate: Good with older children<br>
|
249 |
-
• No: Better for adult households
|
250 |
-
</span>
|
251 |
-
<span class="value">{info.get('Good with Children', 'Not available')}</span>
|
252 |
-
</span>
|
253 |
-
</div>
|
254 |
-
<div class="info-item">
|
255 |
-
<span class="tooltip">
|
256 |
-
<span class="icon">⏳</span>
|
257 |
-
<span class="label">Lifespan:</span>
|
258 |
-
<span class="tooltip-icon">ⓘ</span>
|
259 |
-
<span class="tooltip-text">
|
260 |
-
<strong>Average Lifespan:</strong><br>
|
261 |
-
• Short: 6-8 years<br>
|
262 |
-
• Average: 10-15 years<br>
|
263 |
-
• Long: 12-20 years
|
264 |
-
</span>
|
265 |
-
<span class="value">{info.get('Lifespan', 'Not available')}</span>
|
266 |
-
</span>
|
267 |
-
</div>
|
268 |
-
</div>
|
269 |
-
"""
|
270 |
-
|
271 |
-
# Noise Section
|
272 |
-
noise_section = f"""
|
273 |
-
<div class="noise-section">
|
274 |
-
<h3 class="section-header">
|
275 |
-
<span class="icon">🔊</span> Noise Behavior
|
276 |
-
<span class="tooltip">
|
277 |
-
<span class="tooltip-icon">ⓘ</span>
|
278 |
-
<span class="tooltip-text">Information about typical barking patterns and noise levels</span>
|
279 |
-
</span>
|
280 |
-
</h3>
|
281 |
-
<div class="noise-info">
|
282 |
-
<div class="noise-details">
|
283 |
-
<h4 class="section-header">Typical noise characteristics:</h4>
|
284 |
-
<div class="characteristics-list">
|
285 |
-
{' '.join([f'<div class="list-item">{item}</div>' for item in noise_info['characteristics']]) or '<div class="list-item">Information not available</div>'}
|
286 |
-
</div>
|
287 |
-
|
288 |
-
<div class="noise-level-display">
|
289 |
-
<h4 class="section-header">Noise level:</h4>
|
290 |
-
<div class="level-indicator">
|
291 |
-
<span class="level-text">{noise_info['noise_level']}</span>
|
292 |
-
</div>
|
293 |
-
</div>
|
294 |
-
|
295 |
-
<h4 class="section-header">Barking triggers:</h4>
|
296 |
-
<div class="triggers-list">
|
297 |
-
{' '.join([f'<div class="list-item">{item}</div>' for item in noise_info['triggers']]) or '<div class="list-item">Information not available</div>'}
|
298 |
-
</div>
|
299 |
-
</div>
|
300 |
-
</div>
|
301 |
-
</div>
|
302 |
-
"""
|
303 |
-
|
304 |
-
# Health Section
|
305 |
-
health_section = f"""
|
306 |
-
<div class="health-section">
|
307 |
-
<h3 class="section-header">
|
308 |
-
<span class="icon">🏥</span> Health Insights
|
309 |
-
<span class="tooltip">
|
310 |
-
<span class="tooltip-icon">ⓘ</span>
|
311 |
-
<span class="tooltip-text">
|
312 |
-
Health information is compiled from multiple sources including veterinary resources,
|
313 |
-
breed guides, and international canine health databases.
|
314 |
-
</span>
|
315 |
-
</span>
|
316 |
-
</h3>
|
317 |
-
<div class="health-info">
|
318 |
-
<div class="health-details">
|
319 |
-
<h4 class="section-header">Common health considerations:</h4>
|
320 |
-
<div class="health-grid">
|
321 |
-
{' '.join([f'<div class="health-item">{item}</div>' for item in health_info['considerations']]) or '<div class="health-item">Information not available</div>'}
|
322 |
-
</div>
|
323 |
-
|
324 |
-
<h4 class="section-header">Recommended screenings:</h4>
|
325 |
-
<div class="health-grid">
|
326 |
-
{' '.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>'}
|
327 |
-
</div>
|
328 |
-
</div>
|
329 |
-
</div>
|
330 |
-
</div>
|
331 |
-
|
332 |
-
<div class="action-section">
|
333 |
-
<a href="https://www.akc.org/dog-breeds/{breed.lower().replace('_', '-')}/"
|
334 |
-
target="_blank"
|
335 |
-
class="akc-button">
|
336 |
-
<span class="icon">🌐</span>
|
337 |
-
Learn More about {breed.replace('_', ' ')} on AKC
|
338 |
-
</a>
|
339 |
-
</div>
|
340 |
-
</div>
|
341 |
-
"""
|
342 |
-
|
343 |
-
return basic_info + noise_section + health_section
|
344 |
-
|
345 |
-
html_output = f"""
|
346 |
-
<div class="dog-info-card">
|
347 |
-
<div class="comparison-grid">
|
348 |
-
{create_breed_column(breed1, breed1_info, breed1_noise, breed1_health)}
|
349 |
-
{create_breed_column(breed2, breed2_info, breed2_noise, breed2_health)}
|
350 |
-
</div>
|
351 |
-
<style>
|
352 |
-
{get_comparison_styles()}
|
353 |
-
</style>
|
354 |
-
</div>
|
355 |
-
"""
|
356 |
-
return html_output
|
357 |
-
|
358 |
-
compare_btn.click(
|
359 |
-
show_comparison,
|
360 |
-
inputs=[breed1_dropdown, breed2_dropdown],
|
361 |
-
outputs=comparison_output
|
362 |
-
)
|
363 |
-
|
364 |
-
return {
|
365 |
-
'breed1_dropdown': breed1_dropdown,
|
366 |
-
'breed2_dropdown': breed2_dropdown,
|
367 |
-
'compare_btn': compare_btn,
|
368 |
-
'comparison_output': comparison_output
|
369 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|