DawnC commited on
Commit
511f397
·
1 Parent(s): e87833c

Delete breed_comparison.py

Browse files
Files changed (1) hide show
  1. breed_comparison.py +0 -545
breed_comparison.py DELETED
@@ -1,545 +0,0 @@
1
-
2
- import gradio as gr
3
- import sqlite3
4
- from dog_database import get_dog_description
5
- from breed_health_info import breed_health_info
6
- from breed_noise_info import breed_noise_info
7
-
8
- def create_comparison_tab(dog_breeds, get_dog_description, breed_noise_info, breed_health_info):
9
- breed_display_mapping = { breed: breed.replace('_', ' ').title() for breed in dog_breeds}
10
- reversed_mapping = {v: k for k ,v in breed_display_mapping.items()}
11
-
12
- sorted_display_names = sorted(breed_display_mapping.values(), key=lambda x: x.lower())
13
-
14
- with gr.TabItem("Breed Comparison"):
15
- gr.HTML("<p style='text-align: center;'>Select two dog breeds to compare their characteristics and care requirements.</p>")
16
-
17
- with gr.Row():
18
- breed1_dropdown = gr.Dropdown(
19
- choices=sorted_display_names,
20
- label="Select First Breed",
21
- value="Golden Retriever"
22
- )
23
- breed2_dropdown = gr.Dropdown(
24
- choices=sorted_display_names,
25
- label="Select Second Breed",
26
- value="Border Collie"
27
- )
28
-
29
- compare_btn = gr.Button("Compare Breeds")
30
- comparison_output = gr.HTML(label="Comparison Results")
31
-
32
- def format_noise_data(notes):
33
- characteristics = []
34
- triggers = []
35
- noise_level = "Moderate" # 預設值
36
-
37
- if isinstance(notes, str):
38
- lines = notes.strip().split('\n')
39
- section = ""
40
- for line in lines:
41
- line = line.strip()
42
- if "Typical noise characteristics:" in line:
43
- section = "characteristics"
44
- elif "Barking triggers:" in line:
45
- section = "triggers"
46
- elif "Noise level:" in line:
47
- noise_level = line.split(':')[1].strip()
48
- elif line.startswith('•'):
49
- if section == "characteristics":
50
- characteristics.append(line[1:].strip())
51
- elif section == "triggers":
52
- triggers.append(line[1:].strip())
53
-
54
- return {
55
- 'characteristics': characteristics,
56
- 'triggers': triggers,
57
- 'noise_level': noise_level
58
- }
59
-
60
- def format_health_data(notes):
61
- considerations = []
62
- screenings = []
63
-
64
- if isinstance(notes, str):
65
- lines = notes.strip().split('\n')
66
- current_section = None
67
-
68
- for line in lines:
69
- line = line.strip()
70
- # 修正字串比對
71
- if "Common breed-specific health considerations" in line:
72
- current_section = "considerations"
73
- elif "Recommended health screenings:" in line:
74
- current_section = "screenings"
75
- elif line.startswith('•'):
76
- item = line[1:].strip()
77
- if current_section == "considerations":
78
- considerations.append(item)
79
- elif current_section == "screenings":
80
- screenings.append(item)
81
-
82
- # 只有當真的沒有資料時才返回 "Information not available"
83
- if not considerations and not screenings:
84
- return {
85
- 'considerations': ["Information not available"],
86
- 'screenings': ["Information not available"]
87
- }
88
-
89
- return {
90
- 'considerations': considerations,
91
- 'screenings': screenings
92
- }
93
-
94
- def get_comparison_styles():
95
- return """
96
- .comparison-container {
97
- display: grid;
98
- grid-template-columns: 1fr 1fr;
99
- gap: 24px;
100
- padding: 20px;
101
- }
102
-
103
- .breed-column {
104
- background: white;
105
- border-radius: 10px;
106
- padding: 24px;
107
- box-shadow: 0 2px 4px rgba(0,0,0,0.1);
108
- }
109
-
110
- .section-title {
111
- font-size: 24px;
112
- color: #2D3748;
113
- margin-bottom: 20px;
114
- padding-bottom: 10px;
115
- border-bottom: 2px solid #E2E8F0;
116
- }
117
-
118
- .info-section {
119
- display: grid;
120
- grid-template-columns: repeat(2, 1fr);
121
- gap: 16px;
122
- margin-bottom: 24px;
123
- }
124
-
125
- .info-item {
126
- position: relative;
127
- background: #F8FAFC;
128
- padding: 16px;
129
- border-radius: 8px;
130
- border: 1px solid #E2E8F0;
131
- }
132
-
133
- .info-label {
134
- display: flex;
135
- align-items: center;
136
- gap: 8px;
137
- color: #4A5568;
138
- font-size: 0.9em;
139
- margin-bottom: 4px;
140
- }
141
-
142
- .info-icon {
143
- cursor: help;
144
- background: #E2E8F0;
145
- width: 18px;
146
- height: 18px;
147
- border-radius: 50%;
148
- display: inline-flex;
149
- align-items: center;
150
- justify-content: center;
151
- font-size: 12px;
152
- color: #4A5568;
153
- margin-left: 4px;
154
- }
155
-
156
- .info-icon:hover + .tooltip-content {
157
- display: block;
158
- }
159
-
160
- .tooltip-content {
161
- display: none;
162
- position: absolute;
163
- background: #2D3748;
164
- color: #FFFFFF;
165
- padding: 8px 12px;
166
- border-radius: 6px;
167
- font-size: 14px;
168
- line-height: 1.3;
169
- width: max-content;
170
- max-width: 280px;
171
- z-index: 1000;
172
- top: 0; /* 修改位置 */
173
- left: 100%;
174
- margin-left: 10px;
175
- box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
176
- white-space: normal; /* 允許文字換行 */
177
- }
178
-
179
-
180
- .tooltip-content,
181
- .tooltip-content *,
182
- .tooltip-content strong,
183
- .tooltip-content li,
184
- .tooltip-content ul,
185
- .tooltip-content p,
186
- .tooltip-content span,
187
- .tooltip-content div {
188
- color: #FFFFFF !important;
189
- }
190
-
191
-
192
- .tooltip-content::before {
193
- content: '';
194
- position: absolute;
195
- left: -6px;
196
- top: 14px; /* 配合上方位置調整 */
197
- border-width: 6px;
198
- border-style: solid;
199
- border-color: transparent #2D3748 transparent transparent;
200
- }
201
-
202
- .tooltip-content strong {
203
- color: #FFFFFF;
204
- display: block;
205
- margin-bottom: 4px;
206
- font-weight: 600;
207
- }
208
-
209
- .tooltip-content ul {
210
- margin: 0;
211
- padding-left: 16px;
212
- color: #FFFFFF;
213
- }
214
-
215
- .tooltip-content * {
216
- color: #FFFFFF;
217
- }
218
-
219
- .tooltip-content li {
220
- margin-bottom: 2px;
221
- color: #FFFFFF;
222
- }
223
-
224
- .tooltip-content li::before {
225
- color: #FFFFFF !important;
226
- }
227
-
228
- .tooltip-content br {
229
- display: block;
230
- margin: 2px 0;
231
- }
232
-
233
- .info-value {
234
- color: #2D3748;
235
- font-weight: 500;
236
- }
237
-
238
- .characteristic-section {
239
- background: #F8FAFC;
240
- padding: 20px;
241
- border-radius: 8px;
242
- margin-bottom: 20px;
243
- }
244
-
245
- .subsection-title {
246
- font-size: 18px;
247
- color: #2D3748;
248
- margin-bottom: 16px;
249
- display: flex;
250
- align-items: center;
251
- gap: 8px;
252
- }
253
-
254
- .noise-level {
255
- background: #EDF2F7;
256
- padding: 16px;
257
- border-radius: 6px;
258
- margin: 16px 0;
259
- border: 1px solid #CBD5E0;
260
- }
261
-
262
- .level-label {
263
- color: #4A5568;
264
- font-size: 1.1em;
265
- font-weight: 500;
266
- margin-bottom: 8px;
267
- }
268
-
269
- .level-value {
270
- color: #2D3748;
271
- font-size: 1.2em;
272
- font-weight: 600;
273
- }
274
-
275
- .characteristics-grid {
276
- display: grid;
277
- grid-template-columns: repeat(2, 1fr);
278
- gap: 12px;
279
- margin-top: 12px;
280
- }
281
-
282
- .characteristic-item {
283
- background: white;
284
- padding: 12px;
285
- border-radius: 6px;
286
- border: 1px solid #E2E8F0;
287
- color: #4A5568;
288
- }
289
-
290
- .health-insights {
291
- margin-top: 24px;
292
- }
293
-
294
- .health-grid {
295
- display: grid;
296
- grid-template-columns: 1fr;
297
- gap: 8px;
298
- }
299
-
300
- .health-item {
301
- background: white;
302
- padding: 12px;
303
- border-radius: 6px;
304
- border: 1px solid #E2E8F0;
305
- color: #E53E3E;
306
- }
307
-
308
- .screening-item {
309
- background: white;
310
- padding: 12px;
311
- border-radius: 6px;
312
- border: 1px solid #E2E8F0;
313
- color: #38A169;
314
- }
315
-
316
- .learn-more-btn {
317
- display: inline-block;
318
- margin-top: 20px;
319
- padding: 12px 24px;
320
- background: linear-gradient(90deg, #4299e1, #48bb78);
321
- color: white;
322
- text-decoration: none;
323
- border-radius: 6px;
324
- transition: all 0.3s ease;
325
- text-align: center;
326
- width: 100%;
327
- font-weight: 500;
328
- box-shadow: 0 2px 4px rgba(0,0,0,0.1);
329
- }
330
-
331
- .learn-more-btn:hover {
332
- background: linear-gradient(90deg, #4299e1, #48bb78);
333
- transform: translateY(-2px);
334
- box-shadow: 0 4px 6px rgba(0,0,0,0.1);
335
- }
336
-
337
- .info-disclaimer {
338
- margin-top: 24px;
339
- padding: 16px;
340
- background: #F7FAFC;
341
- border-radius: 8px;
342
- font-size: 0.9em;
343
- color: #4A5568;
344
- line-height: 1.5;
345
- border-left: 4px solid #4299E1;
346
- }
347
-
348
- @media (max-width: 768px) {
349
- .comparison-container {
350
- grid-template-columns: 1fr;
351
- }
352
- .info-section {
353
- grid-template-columns: 1fr;
354
- }
355
- .characteristics-grid {
356
- grid-template-columns: 1fr;
357
- }
358
- }
359
- """
360
-
361
- def show_comparison(breed1_display, breed2_display):
362
- if not breed1_display or not breed2_display:
363
- return "Please select two breeds to compare"
364
-
365
- breed1 = reversed_mapping[breed1_display]
366
- breed2 = reversed_mapping[breed2_display]
367
- breed1_info = get_dog_description(breed1)
368
- breed2_info = get_dog_description(breed2)
369
- breed1_noise = breed_noise_info.get(breed1, {})
370
- breed2_noise = breed_noise_info.get(breed2, {})
371
- breed1_health = breed_health_info.get(breed1, {})
372
- breed2_health = breed_health_info.get(breed2, {})
373
-
374
- def create_info_item(label, value, tooltip_text=""):
375
- tooltip = f"""
376
- <div class="info-label">
377
- <span>{label}</span>
378
- <div class="tooltip">
379
- <span class="info-icon">i</span>
380
- <div class="tooltip-content">
381
- {tooltip_text}
382
- </div>
383
- </div>
384
- </div>
385
- """ if tooltip_text else f'<div class="info-label">{label}</div>'
386
-
387
- return f"""
388
- <div class="info-item" style="position: relative;">
389
- {tooltip}
390
- <div class="info-value">{value}</div>
391
- </div>
392
- """
393
-
394
- def create_breed_section(breed, info, noise_info, health_info):
395
- # 建立提示文字
396
- section_tooltips = {
397
- 'Size': """
398
- <strong>Size Categories:</strong><br>
399
- • Small: Under 20 pounds<br>
400
- • Medium: 20-60 pounds<br>
401
- • Large: Over 60 pounds
402
- """,
403
- 'Exercise': """
404
- <strong>Exercise Needs:</strong><br>
405
- • Low: Short walks suffice<br>
406
- • Moderate: 1-2 hours daily<br>
407
- • High: 2+ hours daily activity<br>
408
- • Very High: Intensive daily exercise
409
- """,
410
- 'Grooming': """
411
- <strong>Grooming Requirements:</strong><br>
412
- • Low: Occasional brushing<br>
413
- • Moderate: Weekly grooming<br>
414
- • High: Daily maintenance needed
415
- """,
416
- 'Children': """
417
- <strong>Compatibility with Children:</strong><br>
418
- • Yes: Excellent with kids<br>
419
- • Moderate: Good with supervision<br>
420
- • No: Better with older children
421
- """,
422
- 'Lifespan': """
423
- <strong>Average Lifespan Range:</strong><br>
424
- Typical lifespan for this breed with proper care and genetics
425
- """,
426
- 'noise': """
427
- <strong>Noise Behavior Information:</strong><br>
428
- • Noise Level indicates typical vocalization intensity<br>
429
- • Characteristics describe common vocal behaviors<br>
430
- • Triggers list common causes of barking or vocalization
431
- """,
432
- 'health': """
433
- <strong>Health Information:</strong><br>
434
- • Health considerations are breed-specific concerns<br>
435
- • Screenings are recommended preventive tests<br>
436
- • Always consult with veterinary professionals
437
- """
438
- }
439
-
440
- noise_data = format_noise_data(noise_info.get('noise_notes', ''))
441
- health_data = format_health_data(health_info.get('health_notes', ''))
442
-
443
- def create_section_header(title, icon, tooltip_text):
444
- return f"""
445
- <div class="section-header">
446
- <span>{icon}</span>
447
- <span>{title}</span>
448
- <span class="tooltip">
449
- <span class="tooltip-icon">ⓘ</span>
450
- <span class="tooltip-text">{tooltip_text}</span>
451
- </span>
452
- </div>
453
- """
454
-
455
- return f"""
456
- <div class="breed-column">
457
- <h2 class="section-title">🐕 {breed_display_mapping[breed]}</h2>
458
-
459
- <div class="info-section">
460
- {create_info_item('Size', info['Size'], section_tooltips['Size'])}
461
- {create_info_item('Exercise', info['Exercise Needs'], section_tooltips['Exercise'])}
462
- {create_info_item('Grooming', info['Grooming Needs'], section_tooltips['Grooming'])}
463
- {create_info_item('With Children', info['Good with Children'], section_tooltips['Children'])}
464
- {create_info_item('Lifespan', info['Lifespan'], section_tooltips['Lifespan'])}
465
- </div>
466
-
467
- <div class="characteristic-section">
468
- {create_section_header('Noise Behavior', '🔊', section_tooltips['noise'])}
469
- <div class="noise-level">
470
- <div class="level-label">Noise Level</div>
471
- <div class="level-value">{noise_data['noise_level'].upper()}</div>
472
- </div>
473
-
474
- <div class="subsection">
475
- <h4>Typical Characteristics</h4>
476
- <div class="characteristics-grid">
477
- {' '.join([f'<div class="characteristic-item">{char}</div>'
478
- for char in noise_data['characteristics']])}
479
- </div>
480
- </div>
481
-
482
- <div class="subsection">
483
- <h4>Barking Triggers</h4>
484
- <div class="characteristics-grid">
485
- {' '.join([f'<div class="characteristic-item">{trigger}</div>'
486
- for trigger in noise_data['triggers']])}
487
- </div>
488
- </div>
489
- </div>
490
-
491
- <div class="characteristic-section health-insights">
492
- {create_section_header('Health Insights', '🏥', section_tooltips['health'])}
493
- <div class="subsection">
494
- <h4>Health Considerations</h4>
495
- <div class="health-grid">
496
- {' '.join([f'<div class="health-item">{item}</div>'
497
- for item in health_data['considerations']])}
498
- </div>
499
- </div>
500
-
501
- <div class="subsection">
502
- <h4>Recommended Screenings</h4>
503
- <div class="health-grid">
504
- {' '.join([f'<div class="screening-item">{item}</div>'
505
- for item in health_data['screenings']])}
506
- </div>
507
- </div>
508
- </div>
509
-
510
- <a href="https://www.akc.org/dog-breeds/{breed.lower().replace('_', '-')}/"
511
- class="learn-more-btn"
512
- target="_blank">
513
- 🌐 Learn more about {breed_display_mapping[breed]} on AKC
514
- </a>
515
- </div>
516
- """
517
-
518
- html_output = f"""
519
- <div class="comparison-container">
520
- {create_breed_section(breed1, breed1_info, breed1_noise, breed1_health)}
521
- {create_breed_section(breed2, breed2_info, breed2_noise, breed2_health)}
522
- </div>
523
- <div class="info-disclaimer">
524
- <strong>Note:</strong> The health and behavioral information provided is for general reference only.
525
- Individual dogs may vary, and characteristics can be influenced by training, socialization, and genetics.
526
- Always consult with veterinary professionals for specific health advice and professional trainers for
527
- behavioral guidance.
528
- </div>
529
- <style>{get_comparison_styles()}</style>
530
- """
531
-
532
- return html_output
533
-
534
- compare_btn.click(
535
- show_comparison,
536
- inputs=[breed1_dropdown, breed2_dropdown],
537
- outputs=comparison_output
538
- )
539
-
540
- return {
541
- 'breed1_dropdown': breed1_dropdown,
542
- 'breed2_dropdown': breed2_dropdown,
543
- 'compare_btn': compare_btn,
544
- 'comparison_output': comparison_output
545
- }