DawnC commited on
Commit
51398a5
1 Parent(s): bf00b71

Update breed_recommendation.py

Browse files
Files changed (1) hide show
  1. breed_recommendation.py +79 -461
breed_recommendation.py CHANGED
@@ -9,256 +9,11 @@ from scoring_calculation_system import UserPreferences, calculate_compatibility_
9
  from recommendation_html_format import format_recommendation_html, get_breed_recommendations
10
  from search_history import create_history_tab, create_history_component
11
 
12
- # def create_recommendation_tab(UserPreferences, get_breed_recommendations, format_recommendation_html, history_component):
13
-
14
- # with gr.TabItem("Breed Recommendation"):
15
- # with gr.Tabs():
16
- # with gr.Tab("Find by Criteria"):
17
- # gr.HTML("""
18
- # <div style='
19
- # text-align: center;
20
- # position: relative;
21
- # padding: 20px 0;
22
- # margin: 15px 0;
23
- # background: linear-gradient(to right, rgba(66, 153, 225, 0.1), rgba(72, 187, 120, 0.1));
24
- # border-radius: 10px;
25
- # '>
26
- # <!-- BETA 標籤 -->
27
- # <div style='
28
- # position: absolute;
29
- # top: 10px;
30
- # right: 20px;
31
- # background: linear-gradient(90deg, #4299e1, #48bb78);
32
- # color: white;
33
- # padding: 4px 12px;
34
- # border-radius: 15px;
35
- # font-size: 0.85em;
36
- # font-weight: 600;
37
- # letter-spacing: 1px;
38
- # box-shadow: 0 2px 4px rgba(0,0,0,0.1);
39
- # '>BETA</div>
40
-
41
- # <!-- 主標題 -->
42
- # <p style='
43
- # font-size: 1.2em;
44
- # margin: 0;
45
- # padding: 0 20px;
46
- # line-height: 1.5;
47
- # background: linear-gradient(90deg, #4299e1, #48bb78);
48
- # -webkit-background-clip: text;
49
- # -webkit-text-fill-color: transparent;
50
- # font-weight: 600;
51
- # '>
52
- # Tell us about your lifestyle, and we'll recommend the perfect dog breeds for you!
53
- # </p>
54
-
55
- # <!-- 提示訊息 -->
56
- # <div style='
57
- # margin-top: 15px;
58
- # padding: 10px 20px;
59
- # background: linear-gradient(to right, rgba(66, 153, 225, 0.15), rgba(72, 187, 120, 0.15));
60
- # border-radius: 8px;
61
- # font-size: 0.9em;
62
- # color: #2D3748;
63
- # display: flex;
64
- # align-items: center;
65
- # justify-content: center;
66
- # gap: 8px;
67
- # '>
68
- # <span style="font-size: 1.2em;">🔬</span>
69
- # <span style="
70
- # letter-spacing: 0.3px;
71
- # line-height: 1.4;
72
- # "><strong>Beta Feature:</strong> Our matching algorithm is continuously improving. Results are for reference only.</span>
73
- # </div>
74
- # </div>
75
- # """)
76
-
77
- # with gr.Row():
78
- # with gr.Column():
79
- # living_space = gr.Radio(
80
- # choices=["apartment", "house_small", "house_large"],
81
- # label="What type of living space do you have?",
82
- # info="Choose your current living situation",
83
- # value="apartment"
84
- # )
85
-
86
- # yard_access = gr.Radio(
87
- # choices=["no_yard", "shared_yard", "private_yard"],
88
- # label="Yard Access Type",
89
- # info="Available outdoor space",
90
- # value="no_yard"
91
- # )
92
-
93
- # exercise_time = gr.Slider(
94
- # minimum=0,
95
- # maximum=180,
96
- # value=60,
97
- # label="Daily exercise time (minutes)",
98
- # info="Consider walks, play time, and training"
99
- # )
100
-
101
- # exercise_type = gr.Radio(
102
- # choices=["light_walks", "moderate_activity", "active_training"],
103
- # label="Exercise Style",
104
- # info="What kind of activities do you prefer?",
105
- # value="moderate_activity"
106
- # )
107
-
108
-
109
- # grooming_commitment = gr.Radio(
110
- # choices=["low", "medium", "high"],
111
- # label="Grooming commitment level",
112
- # info="Low: monthly, Medium: weekly, High: daily",
113
- # value="medium"
114
- # )
115
-
116
- # with gr.Column():
117
- # experience_level = gr.Radio(
118
- # choices=["beginner", "intermediate", "advanced"],
119
- # label="Dog ownership experience",
120
- # info="Be honest - this helps find the right match",
121
- # value="beginner"
122
- # )
123
-
124
- # time_availability = gr.Radio(
125
- # choices=["limited", "moderate", "flexible"],
126
- # label="Time Availability",
127
- # info="Time available for dog care daily",
128
- # value="moderate"
129
- # )
130
-
131
- # has_children = gr.Checkbox(
132
- # label="Have children at home",
133
- # info="Helps recommend child-friendly breeds"
134
- # )
135
-
136
- # children_age = gr.Radio(
137
- # choices=["toddler", "school_age", "teenager"],
138
- # label="Children's Age Group",
139
- # info="Helps match with age-appropriate breeds",
140
- # visible=False # 默認隱藏,只在has_children=True時顯示
141
- # )
142
-
143
- # noise_tolerance = gr.Radio(
144
- # choices=["low", "medium", "high"],
145
- # label="Noise tolerance level",
146
- # info="Some breeds are more vocal than others",
147
- # value="medium"
148
- # )
149
-
150
- # def update_children_age_visibility(has_children):
151
- # return gr.update(visible=has_children)
152
-
153
- # has_children.change(
154
- # fn=update_children_age_visibility,
155
- # inputs=has_children,
156
- # outputs=children_age
157
- # )
158
-
159
- # get_recommendations_btn = gr.Button("Find My Perfect Match! 🔍", variant="primary")
160
-
161
- # recommendation_output = gr.HTML(
162
- # label="Breed Recommendations",
163
- # visible=True, # 確保可見性
164
- # elem_id="recommendation-output"
165
- # )
166
-
167
- # def on_find_match_click(*args):
168
- # try:
169
- # user_prefs = UserPreferences(
170
- # living_space=args[0],
171
- # yard_access=args[1],
172
- # exercise_time=args[2],
173
- # exercise_type=args[3],
174
- # grooming_commitment=args[4],
175
- # experience_level=args[5],
176
- # time_availability=args[6],
177
- # has_children=args[7],
178
- # children_age=args[8] if args[7] else None,
179
- # noise_tolerance=args[9],
180
- # space_for_play=True if args[0] != "apartment" else False,
181
- # other_pets=False,
182
- # climate="moderate",
183
- # health_sensitivity="medium",
184
- # barking_acceptance=args[9]
185
- # )
186
-
187
- # recommendations = get_breed_recommendations(user_prefs, top_n=10)
188
-
189
- # history_results = [{
190
- # 'breed': rec['breed'],
191
- # 'rank': rec['rank'],
192
- # 'overall_score': rec['final_score'],
193
- # 'base_score': rec['base_score'],
194
- # 'bonus_score': rec['bonus_score'],
195
- # 'scores': rec['scores']
196
- # } for rec in recommendations]
197
-
198
- # history_component.save_search(
199
- # user_preferences={
200
- # 'living_space': args[0],
201
- # 'yard_access': args[1],
202
- # 'exercise_time': args[2],
203
- # 'exercise_type': args[3],
204
- # 'grooming_commitment': args[4],
205
- # 'experience_level': args[5],
206
- # 'time_availability': args[6],
207
- # 'has_children': args[7],
208
- # 'children_age': args[8] if args[7] else None,
209
- # 'noise_tolerance': args[9],
210
- # 'search_type': 'Criteria'
211
- # },
212
- # results=history_results
213
- # )
214
-
215
- # return format_recommendation_html(recommendations, is_description_search=False)
216
-
217
- # except Exception as e:
218
- # print(f"Error in find match: {str(e)}")
219
- # import traceback
220
- # print(traceback.format_exc())
221
- # return "Error getting recommendations"
222
-
223
-
224
- # get_recommendations_btn.click(
225
- # fn=on_find_match_click,
226
- # inputs=[
227
- # living_space,
228
- # yard_access,
229
- # exercise_time,
230
- # exercise_type,
231
- # grooming_commitment,
232
- # experience_level,
233
- # time_availability,
234
- # has_children,
235
- # children_age,
236
- # noise_tolerance
237
- # ],
238
- # outputs=recommendation_output
239
- # )
240
-
241
- # return {
242
- # 'living_space': living_space,
243
- # 'exercise_time': exercise_time,
244
- # 'grooming_commitment': grooming_commitment,
245
- # 'experience_level': experience_level,
246
- # 'has_children': has_children,
247
- # 'noise_tolerance': noise_tolerance,
248
- # 'get_recommendations_btn': get_recommendations_btn,
249
- # 'recommendation_output': recommendation_output,
250
- # }
251
-
252
-
253
  def create_recommendation_tab(UserPreferences, get_breed_recommendations, format_recommendation_html, history_component):
254
- """
255
- 創建狗品種推薦頁面的主要函數
256
- 包含用戶輸入界面、推薦結果顯示和 loading 狀態
257
- """
258
  with gr.TabItem("Breed Recommendation"):
259
  with gr.Tabs():
260
  with gr.Tab("Find by Criteria"):
261
- # 頁面頂部的介紹性內容
262
  gr.HTML("""
263
  <div style='
264
  text-align: center;
@@ -319,122 +74,6 @@ def create_recommendation_tab(UserPreferences, get_breed_recommendations, format
319
  </div>
320
  """)
321
 
322
- # 添加 Loading 狀態顯示
323
- loading_html = gr.HTML("""
324
- <div id="loading-status" style="
325
- text-align: center;
326
- margin: 30px 0;
327
- opacity: 0;
328
- transition: opacity 0.3s ease-in-out;
329
- ">
330
- <div style="
331
- display: inline-flex;
332
- flex-direction: column;
333
- align-items: center;
334
- gap: 15px;
335
- padding: 25px;
336
- background: linear-gradient(to right, rgba(66, 153, 225, 0.1), rgba(72, 187, 120, 0.1));
337
- border-radius: 12px;
338
- box-shadow: 0 4px 6px rgba(0,0,0,0.1);
339
- ">
340
- <!-- 可愛的狗狗圖示 -->
341
- <div style="font-size: 40px;">🐕</div>
342
-
343
- <!-- 載入中主要訊息 -->
344
- <div style="
345
- color: #2D3748;
346
- font-size: 1.2em;
347
- font-weight: 500;
348
- margin-bottom: 5px;
349
- ">Sniffing out your perfect match...</div>
350
-
351
- <!-- 有趣的載入訊息 -->
352
- <div id="loading-message" style="
353
- color: #4A5568;
354
- font-size: 0.95em;
355
- font-style: italic;
356
- ">Checking all the good boys and girls...</div>
357
-
358
- <!-- 載入動畫 -->
359
- <div style="
360
- display: flex;
361
- gap: 8px;
362
- margin-top: 10px;
363
- ">
364
- <div class="paw" style="
365
- width: 12px;
366
- height: 12px;
367
- background: #4299e1;
368
- border-radius: 50%;
369
- animation: pawAnimation 1s infinite;
370
- animation-delay: 0s;
371
- "></div>
372
- <div class="paw" style="
373
- width: 12px;
374
- height: 12px;
375
- background: #4299e1;
376
- border-radius: 50%;
377
- animation: pawAnimation 1s infinite;
378
- animation-delay: 0.2s;
379
- "></div>
380
- <div class="paw" style="
381
- width: 12px;
382
- height: 12px;
383
- background: #4299e1;
384
- border-radius: 50%;
385
- animation: pawAnimation 1s infinite;
386
- animation-delay: 0.4s;
387
- "></div>
388
- </div>
389
- </div>
390
- </div>
391
-
392
- <style>
393
- @keyframes pawAnimation {
394
- 0% { transform: translateY(0); }
395
- 50% { transform: translateY(-10px); }
396
- 100% { transform: translateY(0); }
397
- }
398
-
399
- #loading-status {
400
- display: none;
401
- }
402
-
403
- #loading-status.visible {
404
- display: block;
405
- opacity: 1;
406
- }
407
- </style>
408
-
409
- <script>
410
- // 有趣的載入訊息列表
411
- const messages = [
412
- "Checking all the good boys and girls...",
413
- "Fetching the perfect matches...",
414
- "Calculating belly rub compatibility...",
415
- "Analyzing tail wag frequencies...",
416
- "Measuring treat enthusiasm levels...",
417
- "Evaluating walkies requirements...",
418
- "Consulting our canine experts...",
419
- "Counting tennis balls...",
420
- "Reviewing park visit preferences...",
421
- "Assessing cuddle potential..."
422
- ];
423
-
424
- // 定期更新載入訊息
425
- function updateLoadingMessage() {
426
- const messageElement = document.getElementById('loading-message');
427
- if (messageElement) {
428
- const randomMessage = messages[Math.floor(Math.random() * messages.length)];
429
- messageElement.textContent = randomMessage;
430
- }
431
- }
432
-
433
- setInterval(updateLoadingMessage, 2000);
434
- </script>
435
- """, visible=False)
436
-
437
- # 用戶輸入區域
438
  with gr.Row():
439
  with gr.Column():
440
  living_space = gr.Radio(
@@ -466,6 +105,7 @@ def create_recommendation_tab(UserPreferences, get_breed_recommendations, format
466
  value="moderate_activity"
467
  )
468
 
 
469
  grooming_commitment = gr.Radio(
470
  choices=["low", "medium", "high"],
471
  label="Grooming commitment level",
@@ -497,7 +137,7 @@ def create_recommendation_tab(UserPreferences, get_breed_recommendations, format
497
  choices=["toddler", "school_age", "teenager"],
498
  label="Children's Age Group",
499
  info="Helps match with age-appropriate breeds",
500
- visible=False
501
  )
502
 
503
  noise_tolerance = gr.Radio(
@@ -506,8 +146,7 @@ def create_recommendation_tab(UserPreferences, get_breed_recommendations, format
506
  info="Some breeds are more vocal than others",
507
  value="medium"
508
  )
509
-
510
- # 控制 children_age 顯示邏輯
511
  def update_children_age_visibility(has_children):
512
  return gr.update(visible=has_children)
513
 
@@ -517,109 +156,88 @@ def create_recommendation_tab(UserPreferences, get_breed_recommendations, format
517
  outputs=children_age
518
  )
519
 
520
- # 推薦按鈕
521
- get_recommendations_btn = gr.Button(
522
- "Find My Perfect Match! 🔍",
523
- variant="primary"
524
- )
525
-
526
- # 推薦結果顯示區域
527
  recommendation_output = gr.HTML(
528
  label="Breed Recommendations",
529
- visible=True,
530
- elem_id="recommendation-output"
531
  )
532
 
533
- def on_find_match_click(*args):
534
- """
535
- 1. 先顯示處理狀態
536
- 2. 執行推薦邏輯
537
- 3. 返回最終結果
538
- """
539
- try:
540
- # 創建用戶偏好對象
541
- user_prefs = UserPreferences(
542
- living_space=args[0],
543
- yard_access=args[1],
544
- exercise_time=args[2],
545
- exercise_type=args[3],
546
- grooming_commitment=args[4],
547
- experience_level=args[5],
548
- time_availability=args[6],
549
- has_children=args[7],
550
- children_age=args[8] if args[7] else None,
551
- noise_tolerance=args[9],
552
- space_for_play=True if args[0] != "apartment" else False,
553
- other_pets=False,
554
- climate="moderate",
555
- health_sensitivity="medium",
556
- barking_acceptance=args[9]
557
- )
558
-
559
- # 獲取推薦結果
560
- recommendations = get_breed_recommendations(user_prefs, top_n=10)
561
-
562
- # 儲存搜尋歷史
563
- history_results = [{
564
- 'breed': rec['breed'],
565
- 'rank': rec['rank'],
566
- 'overall_score': rec['final_score'],
567
- 'base_score': rec['base_score'],
568
- 'bonus_score': rec['bonus_score'],
569
- 'scores': rec['scores']
570
- } for rec in recommendations]
571
-
572
- history_component.save_search(
573
- user_preferences={
574
- 'living_space': args[0],
575
- 'yard_access': args[1],
576
- 'exercise_time': args[2],
577
- 'exercise_type': args[3],
578
- 'grooming_commitment': args[4],
579
- 'experience_level': args[5],
580
- 'time_availability': args[6],
581
- 'has_children': args[7],
582
- 'children_age': args[8] if args[7] else None,
583
- 'noise_tolerance': args[9],
584
- 'search_type': 'Criteria'
585
- },
586
- results=history_results
587
- )
588
-
589
- return format_recommendation_html(recommendations, is_description_search=False)
590
-
591
- except Exception as e:
592
- print(f"Error in find match: {str(e)}")
593
- import traceback
594
- print(traceback.format_exc())
595
- return gr.HTML("""
596
- <div style="text-align: center; padding: 20px; background: rgba(255, 0, 0, 0.1); border-radius: 10px; margin: 20px 0;">
597
- <p style="color: #d32f2f; font-size: 1.1em; margin: 0;">
598
- 🐾 抱歉出了點問題,請再試一次!
599
- </p>
600
- </div>
601
- """)
602
 
603
- # 設置按鈕點擊事件
604
- get_recommendations_btn.click(
605
- fn=on_find_match_click,
606
- inputs=[
607
- living_space,
608
- yard_access,
609
- exercise_time,
610
- exercise_type,
611
- grooming_commitment,
612
- experience_level,
613
- time_availability,
614
- has_children,
615
- children_age,
616
- noise_tolerance
617
- ],
618
- outputs=recommendation_output,
619
- show_progress="full", # 使用 Gradio 內建的進度顯示
 
 
 
 
 
 
 
 
 
620
  )
621
 
622
- # 返回頁面組件
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
623
  return {
624
  'living_space': living_space,
625
  'exercise_time': exercise_time,
 
9
  from recommendation_html_format import format_recommendation_html, get_breed_recommendations
10
  from search_history import create_history_tab, create_history_component
11
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  def create_recommendation_tab(UserPreferences, get_breed_recommendations, format_recommendation_html, history_component):
13
+
 
 
 
14
  with gr.TabItem("Breed Recommendation"):
15
  with gr.Tabs():
16
  with gr.Tab("Find by Criteria"):
 
17
  gr.HTML("""
18
  <div style='
19
  text-align: center;
 
74
  </div>
75
  """)
76
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  with gr.Row():
78
  with gr.Column():
79
  living_space = gr.Radio(
 
105
  value="moderate_activity"
106
  )
107
 
108
+
109
  grooming_commitment = gr.Radio(
110
  choices=["low", "medium", "high"],
111
  label="Grooming commitment level",
 
137
  choices=["toddler", "school_age", "teenager"],
138
  label="Children's Age Group",
139
  info="Helps match with age-appropriate breeds",
140
+ visible=False # 默認隱藏,只在has_children=True時顯示
141
  )
142
 
143
  noise_tolerance = gr.Radio(
 
146
  info="Some breeds are more vocal than others",
147
  value="medium"
148
  )
149
+
 
150
  def update_children_age_visibility(has_children):
151
  return gr.update(visible=has_children)
152
 
 
156
  outputs=children_age
157
  )
158
 
159
+ get_recommendations_btn = gr.Button("Find My Perfect Match! 🔍", variant="primary")
160
+
 
 
 
 
 
161
  recommendation_output = gr.HTML(
162
  label="Breed Recommendations",
163
+ visible=True, # 確保可見性
164
+ elem_id="recommendation-output"
165
  )
166
 
167
+ def on_find_match_click(*args):
168
+ try:
169
+ user_prefs = UserPreferences(
170
+ living_space=args[0],
171
+ yard_access=args[1],
172
+ exercise_time=args[2],
173
+ exercise_type=args[3],
174
+ grooming_commitment=args[4],
175
+ experience_level=args[5],
176
+ time_availability=args[6],
177
+ has_children=args[7],
178
+ children_age=args[8] if args[7] else None,
179
+ noise_tolerance=args[9],
180
+ space_for_play=True if args[0] != "apartment" else False,
181
+ other_pets=False,
182
+ climate="moderate",
183
+ health_sensitivity="medium",
184
+ barking_acceptance=args[9]
185
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
186
 
187
+ recommendations = get_breed_recommendations(user_prefs, top_n=10)
188
+
189
+ history_results = [{
190
+ 'breed': rec['breed'],
191
+ 'rank': rec['rank'],
192
+ 'overall_score': rec['final_score'],
193
+ 'base_score': rec['base_score'],
194
+ 'bonus_score': rec['bonus_score'],
195
+ 'scores': rec['scores']
196
+ } for rec in recommendations]
197
+
198
+ history_component.save_search(
199
+ user_preferences={
200
+ 'living_space': args[0],
201
+ 'yard_access': args[1],
202
+ 'exercise_time': args[2],
203
+ 'exercise_type': args[3],
204
+ 'grooming_commitment': args[4],
205
+ 'experience_level': args[5],
206
+ 'time_availability': args[6],
207
+ 'has_children': args[7],
208
+ 'children_age': args[8] if args[7] else None,
209
+ 'noise_tolerance': args[9],
210
+ 'search_type': 'Criteria'
211
+ },
212
+ results=history_results
213
  )
214
 
215
+ return format_recommendation_html(recommendations, is_description_search=False)
216
+
217
+ except Exception as e:
218
+ print(f"Error in find match: {str(e)}")
219
+ import traceback
220
+ print(traceback.format_exc())
221
+ return "Error getting recommendations"
222
+
223
+
224
+ get_recommendations_btn.click(
225
+ fn=on_find_match_click,
226
+ inputs=[
227
+ living_space,
228
+ yard_access,
229
+ exercise_time,
230
+ exercise_type,
231
+ grooming_commitment,
232
+ experience_level,
233
+ time_availability,
234
+ has_children,
235
+ children_age,
236
+ noise_tolerance
237
+ ],
238
+ outputs=recommendation_output
239
+ )
240
+
241
  return {
242
  'living_space': living_space,
243
  'exercise_time': exercise_time,