DawnC commited on
Commit
47e2a7c
1 Parent(s): 1887ad6

Update scoring_calculation_system.py

Browse files
Files changed (1) hide show
  1. scoring_calculation_system.py +493 -109
scoring_calculation_system.py CHANGED
@@ -28,11 +28,113 @@ class UserPreferences:
28
  self.barking_acceptance = self.noise_tolerance
29
 
30
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  @staticmethod
32
  def calculate_breed_bonus(breed_info: dict, user_prefs: 'UserPreferences') -> float:
33
- """計算品種額外加分"""
 
 
34
  bonus = 0.0
35
  temperament = breed_info.get('Temperament', '').lower()
 
36
 
37
  # 1. 壽命加分(最高0.05)
38
  try:
@@ -55,13 +157,20 @@ def calculate_breed_bonus(breed_info: dict, user_prefs: 'UserPreferences') -> fl
55
  'calm': 0.03
56
  }
57
 
 
 
 
 
 
 
 
58
  negative_traits = {
59
- 'aggressive': -0.08,
60
- 'stubborn': -0.06,
61
- 'dominant': -0.06,
62
- 'aloof': -0.04,
63
- 'nervous': -0.05,
64
- 'protective': -0.04
65
  }
66
 
67
  personality_score = sum(value for trait, value in positive_traits.items() if trait in temperament)
@@ -74,56 +183,76 @@ def calculate_breed_bonus(breed_info: dict, user_prefs: 'UserPreferences') -> fl
74
  adaptability_bonus += 0.05
75
  if 'adaptable' in temperament or 'versatile' in temperament:
76
  adaptability_bonus += 0.05
77
- bonus += min(0.1, adaptability_bonus)
78
-
79
- # 4. 家庭相容性(最高0.1)
80
- if user_prefs.has_children:
81
- family_traits = {
82
- 'good with children': 0.06,
83
- 'patient': 0.05,
84
- 'gentle': 0.05,
85
- 'tolerant': 0.04,
86
- 'playful': 0.03
87
- }
88
- unfriendly_traits = {
89
- 'aggressive': -0.08,
90
- 'nervous': -0.07,
91
- 'protective': -0.06,
92
- 'territorial': -0.05
93
- }
94
-
95
- # 年齡評估這樣能更細緻
96
- age_adjustments = {
97
- 'toddler': {'bonus_mult': 0.7, 'penalty_mult': 1.3},
98
- 'school_age': {'bonus_mult': 1.0, 'penalty_mult': 1.0},
99
- 'teenager': {'bonus_mult': 1.2, 'penalty_mult': 0.8}
100
- }
101
 
102
- adj = age_adjustments.get(user_prefs.children_age,
103
- {'bonus_mult': 1.0, 'penalty_mult': 1.0})
104
-
105
- family_bonus = sum(value for trait, value in family_traits.items()
106
- if trait in temperament) * adj['bonus_mult']
107
- family_penalty = sum(value for trait, value in unfriendly_traits.items()
108
- if trait in temperament) * adj['penalty_mult']
 
 
 
 
 
 
 
 
 
109
 
110
- bonus += min(0.15, max(-0.2, family_bonus + family_penalty))
111
 
112
-
113
- # 5. 專門技能加分(最高0.1)
114
  skill_bonus = 0.0
 
 
115
  special_abilities = {
116
- 'working': 0.03,
117
- 'herding': 0.03,
118
- 'hunting': 0.03,
119
- 'tracking': 0.03,
120
- 'agility': 0.02
 
121
  }
 
122
  for ability, value in special_abilities.items():
123
- if ability in temperament.lower():
124
- skill_bonus += value
 
 
 
 
 
 
 
 
125
  bonus += min(0.1, skill_bonus)
126
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127
  return min(0.5, max(-0.25, bonus))
128
 
129
 
@@ -205,6 +334,116 @@ def calculate_additional_factors(breed_info: dict, user_prefs: 'UserPreferences'
205
  return factors
206
 
207
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
208
  def calculate_compatibility_score(breed_info: dict, user_prefs: UserPreferences) -> dict:
209
  """計算品種與使用者條件的相容性分數的優化版本"""
210
  try:
@@ -293,88 +532,192 @@ def calculate_compatibility_score(breed_info: dict, user_prefs: UserPreferences)
293
  return base_score
294
 
295
 
296
- def calculate_experience_score(care_level: str, user_experience: str, temperament: str) -> float:
297
- """
298
- 計算使用者經驗與品種需求的匹配分數
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
299
 
300
- 參數說明:
301
- care_level: 品種的照顧難度 ("High", "Moderate", "Low")
302
- user_experience: 使用者經驗等級 ("beginner", "intermediate", "advanced")
303
- temperament: 品種的性格特徵描述
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
304
 
305
- 返回:
306
- float: 0.2-1.0 之間的匹配分數
 
 
 
 
 
307
  """
308
- # 基礎分數矩陣 - 更大的分數差異來反映經驗重要性
309
  base_scores = {
310
  "High": {
311
- "beginner": 0.12, # 降低起始分,反映高難度品種對新手的挑戰
312
- "intermediate": 0.65, # 中級玩家可以應付,但仍有改善空間
313
- "advanced": 1.0 # 資深者能完全勝任
314
  },
315
  "Moderate": {
316
- "beginner": 0.35, # 適中難度對新手來說仍具挑戰
317
- "intermediate": 0.82, # 中級玩家有很好的勝任能力
318
- "advanced": 1.0 # 資深者完全勝任
319
  },
320
  "Low": {
321
- "beginner": 0.72, # 低難度品種適合新手
322
- "intermediate": 0.92, # 中級玩家幾乎完全勝任
323
- "advanced": 1.0 # 資深者完全勝任
324
  }
325
  }
326
 
327
  # 取得基礎分數
328
  score = base_scores.get(care_level, base_scores["Moderate"])[user_experience]
329
 
330
- # 性格特徵評估 - 根據經驗等級調整權重
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
331
  temperament_lower = temperament.lower()
332
  temperament_adjustments = 0.0
333
 
334
  if user_experience == "beginner":
335
- # 新手不適合的特徵 - 更嚴格的懲罰
336
  difficult_traits = {
337
- 'stubborn': -0.15, # 加重固執的懲罰
338
- 'independent': -0.12, # 加重獨立性的懲罰
339
- 'dominant': -0.12, # 加重支配性的懲罰
340
- 'strong-willed': -0.10, # 加重強勢的懲罰
341
- 'protective': -0.08, # 加重保護性的懲罰
342
- 'aloof': -0.08, # 加重冷漠的懲罰
343
- 'energetic': -0.06 # 輕微懲罰高能量
344
  }
345
-
346
- # 新手友善的特徵 - 提供更多獎勵
347
  easy_traits = {
348
- 'gentle': 0.08, # 增加溫和的獎勵
349
- 'friendly': 0.08, # 增加友善的獎勵
350
- 'eager to please': 0.08, # 增加順從的獎勵
351
- 'patient': 0.06, # 獎勵耐心
352
- 'adaptable': 0.06, # 獎勵適應性
353
- 'calm': 0.05 # 獎勵冷靜
354
  }
355
 
356
- # 計算特徵調整
357
  for trait, penalty in difficult_traits.items():
358
  if trait in temperament_lower:
359
- temperament_adjustments += penalty * 1.2 # 加重新手的懲罰
360
 
361
  for trait, bonus in easy_traits.items():
362
  if trait in temperament_lower:
363
  temperament_adjustments += bonus
364
 
365
- # 品種特殊調整
366
- if any(term in temperament_lower for term in ['terrier', 'working', 'guard']):
367
- temperament_adjustments -= 0.12 # 加重對特定類型品種的懲罰
368
-
369
  elif user_experience == "intermediate":
370
- # 中級玩家的調整更加平衡
371
  moderate_traits = {
372
- 'intelligent': 0.05, # 獎勵聰明
373
- 'athletic': 0.04, # 獎勵運動能力
374
- 'versatile': 0.04, # 獎勵多功能性
375
- 'stubborn': -0.06, # 輕微懲罰固執
376
- 'independent': -0.05, # 輕微懲罰獨立性
377
- 'protective': -0.04 # 輕微懲罰保護性
378
  }
379
 
380
  for trait, adjustment in moderate_traits.items():
@@ -382,22 +725,43 @@ def calculate_compatibility_score(breed_info: dict, user_prefs: UserPreferences)
382
  temperament_adjustments += adjustment
383
 
384
  else: # advanced
385
- # 資深玩家能夠應對挑戰性特徵
386
  advanced_traits = {
387
- 'stubborn': 0.04, # 反轉為優勢
388
- 'independent': 0.04, # 反轉為優勢
389
- 'intelligent': 0.05, # 獎勵聰明
390
- 'protective': 0.04, # 獎勵保護性
391
- 'strong-willed': 0.03 # 獎勵強勢
392
  }
393
 
394
- for trait, bonus in advanced_traits.items():
395
  if trait in temperament_lower:
396
- temperament_adjustments += bonus
397
-
398
- # 確保最終分數在合理範圍內
399
- final_score = max(0.2, min(1.0, score + temperament_adjustments))
400
- return final_score
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
401
 
402
  def calculate_health_score(breed_name: str) -> float:
403
  """計算品種健康分數"""
@@ -542,6 +906,14 @@ def calculate_compatibility_score(breed_info: dict, user_prefs: UserPreferences)
542
  'noise': calculate_noise_score(breed_info.get('Breed', ''), user_prefs.noise_tolerance)
543
  }
544
 
 
 
 
 
 
 
 
 
545
  # 優化權重配置
546
  weights = {
547
  'space': 0.28,
@@ -552,6 +924,18 @@ def calculate_compatibility_score(breed_info: dict, user_prefs: UserPreferences)
552
  'noise': 0.08
553
  }
554
 
 
 
 
 
 
 
 
 
 
 
 
 
555
  # 計算加權總分
556
  weighted_score = sum(score * weights[category] for category, score in scores.items())
557
 
 
28
  self.barking_acceptance = self.noise_tolerance
29
 
30
 
31
+ # @staticmethod
32
+ # def calculate_breed_bonus(breed_info: dict, user_prefs: 'UserPreferences') -> float:
33
+ # """計算品種額外加分"""
34
+ # bonus = 0.0
35
+ # temperament = breed_info.get('Temperament', '').lower()
36
+
37
+ # # 1. 壽命加分(最高0.05)
38
+ # try:
39
+ # lifespan = breed_info.get('Lifespan', '10-12 years')
40
+ # years = [int(x) for x in lifespan.split('-')[0].split()[0:1]]
41
+ # longevity_bonus = min(0.05, (max(years) - 10) * 0.01)
42
+ # bonus += longevity_bonus
43
+ # except:
44
+ # pass
45
+
46
+ # # 2. 性格特徵加分(最高0.15)
47
+ # positive_traits = {
48
+ # 'friendly': 0.05,
49
+ # 'gentle': 0.05,
50
+ # 'patient': 0.05,
51
+ # 'intelligent': 0.04,
52
+ # 'adaptable': 0.04,
53
+ # 'affectionate': 0.04,
54
+ # 'easy-going': 0.03,
55
+ # 'calm': 0.03
56
+ # }
57
+
58
+ # negative_traits = {
59
+ # 'aggressive': -0.08,
60
+ # 'stubborn': -0.06,
61
+ # 'dominant': -0.06,
62
+ # 'aloof': -0.04,
63
+ # 'nervous': -0.05,
64
+ # 'protective': -0.04
65
+ # }
66
+
67
+ # personality_score = sum(value for trait, value in positive_traits.items() if trait in temperament)
68
+ # personality_score += sum(value for trait, value in negative_traits.items() if trait in temperament)
69
+ # bonus += max(-0.15, min(0.15, personality_score))
70
+
71
+ # # 3. 適應性加分(最高0.1)
72
+ # adaptability_bonus = 0.0
73
+ # if breed_info.get('Size') == "Small" and user_prefs.living_space == "apartment":
74
+ # adaptability_bonus += 0.05
75
+ # if 'adaptable' in temperament or 'versatile' in temperament:
76
+ # adaptability_bonus += 0.05
77
+ # bonus += min(0.1, adaptability_bonus)
78
+
79
+ # # 4. 家庭相容性(最高0.1)
80
+ # if user_prefs.has_children:
81
+ # family_traits = {
82
+ # 'good with children': 0.06,
83
+ # 'patient': 0.05,
84
+ # 'gentle': 0.05,
85
+ # 'tolerant': 0.04,
86
+ # 'playful': 0.03
87
+ # }
88
+ # unfriendly_traits = {
89
+ # 'aggressive': -0.08,
90
+ # 'nervous': -0.07,
91
+ # 'protective': -0.06,
92
+ # 'territorial': -0.05
93
+ # }
94
+
95
+ # # 年齡評估這樣能更細緻
96
+ # age_adjustments = {
97
+ # 'toddler': {'bonus_mult': 0.7, 'penalty_mult': 1.3},
98
+ # 'school_age': {'bonus_mult': 1.0, 'penalty_mult': 1.0},
99
+ # 'teenager': {'bonus_mult': 1.2, 'penalty_mult': 0.8}
100
+ # }
101
+
102
+ # adj = age_adjustments.get(user_prefs.children_age,
103
+ # {'bonus_mult': 1.0, 'penalty_mult': 1.0})
104
+
105
+ # family_bonus = sum(value for trait, value in family_traits.items()
106
+ # if trait in temperament) * adj['bonus_mult']
107
+ # family_penalty = sum(value for trait, value in unfriendly_traits.items()
108
+ # if trait in temperament) * adj['penalty_mult']
109
+
110
+ # bonus += min(0.15, max(-0.2, family_bonus + family_penalty))
111
+
112
+
113
+ # # 5. 專門技能加分(最高0.1)
114
+ # skill_bonus = 0.0
115
+ # special_abilities = {
116
+ # 'working': 0.03,
117
+ # 'herding': 0.03,
118
+ # 'hunting': 0.03,
119
+ # 'tracking': 0.03,
120
+ # 'agility': 0.02
121
+ # }
122
+ # for ability, value in special_abilities.items():
123
+ # if ability in temperament.lower():
124
+ # skill_bonus += value
125
+ # bonus += min(0.1, skill_bonus)
126
+
127
+ # return min(0.5, max(-0.25, bonus))
128
+
129
+
130
  @staticmethod
131
  def calculate_breed_bonus(breed_info: dict, user_prefs: 'UserPreferences') -> float:
132
+ """
133
+ 計算品種額外加分,考慮多個維度但不包含家庭相容性評分
134
+ """
135
  bonus = 0.0
136
  temperament = breed_info.get('Temperament', '').lower()
137
+ description = breed_info.get('Description', '').lower()
138
 
139
  # 1. 壽命加分(最高0.05)
140
  try:
 
157
  'calm': 0.03
158
  }
159
 
160
+ # 根據經驗等級調整負面特徵的懲罰程度
161
+ experience_multiplier = {
162
+ 'beginner': 1.3,
163
+ 'intermediate': 1.0,
164
+ 'advanced': 0.8
165
+ }.get(user_prefs.experience_level, 1.0)
166
+
167
  negative_traits = {
168
+ 'aggressive': -0.08 * experience_multiplier,
169
+ 'stubborn': -0.06 * experience_multiplier,
170
+ 'dominant': -0.06 * experience_multiplier,
171
+ 'aloof': -0.04 * experience_multiplier,
172
+ 'nervous': -0.05 * experience_multiplier,
173
+ 'protective': -0.04 * experience_multiplier
174
  }
175
 
176
  personality_score = sum(value for trait, value in positive_traits.items() if trait in temperament)
 
183
  adaptability_bonus += 0.05
184
  if 'adaptable' in temperament or 'versatile' in temperament:
185
  adaptability_bonus += 0.05
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
186
 
187
+ # 考慮更多環境適應因素
188
+ if user_prefs.yard_access == "no_yard":
189
+ if "needs space" in description or "requires yard" in description:
190
+ adaptability_bonus -= 0.05
191
+ elif user_prefs.yard_access == "private_yard":
192
+ if "active" in description or "energetic" in description:
193
+ adaptability_bonus += 0.03
194
+
195
+ # 氣候適應性
196
+ climate_terms = {
197
+ 'cold': ['thick coat', 'winter', 'cold climate'],
198
+ 'hot': ['short coat', 'warm climate', 'heat tolerant'],
199
+ 'moderate': ['adaptable', 'all climate']
200
+ }
201
+ if any(term in description for term in climate_terms[user_prefs.climate]):
202
+ adaptability_bonus += 0.02
203
 
204
+ bonus += min(0.1, adaptability_bonus)
205
 
206
+ # 4. 專門技能評估(最高0.1)
 
207
  skill_bonus = 0.0
208
+ exercise_level = user_prefs.exercise_time / 60.0 # 轉換為小時
209
+
210
  special_abilities = {
211
+ 'working': 0.03 if exercise_level >= 1.5 else 0.01,
212
+ 'herding': 0.03 if exercise_level >= 1.5 else 0.01,
213
+ 'hunting': 0.03 if exercise_level >= 1.5 else 0.01,
214
+ 'tracking': 0.03 if exercise_level >= 1.0 else 0.02,
215
+ 'agility': 0.02 if exercise_level >= 1.0 else 0.01,
216
+ 'sporting': 0.02 if exercise_level >= 1.2 else 0.01 # 新增運動犬種考量
217
  }
218
+
219
  for ability, value in special_abilities.items():
220
+ if ability in temperament.lower() or ability in description:
221
+ # 根據使用者經驗和時間可用性調整技能加分
222
+ time_multiplier = 1.2 if user_prefs.time_availability == 'flexible' else 0.8
223
+ if user_prefs.experience_level == 'advanced':
224
+ skill_bonus += value * 1.2 * time_multiplier
225
+ elif user_prefs.experience_level == 'beginner':
226
+ skill_bonus += value * 0.7 * time_multiplier
227
+ else:
228
+ skill_bonus += value * time_multiplier
229
+
230
  bonus += min(0.1, skill_bonus)
231
 
232
+ # 5. 特殊需求評估(最高0.1/-0.15)
233
+ special_needs_score = 0.0
234
+
235
+ # 檢查特殊訓練需求
236
+ if any(term in description for term in ['requires extensive training', 'needs firm training']):
237
+ if user_prefs.experience_level == 'beginner':
238
+ special_needs_score -= 0.08
239
+ elif user_prefs.experience_level == 'intermediate':
240
+ special_needs_score -= 0.04
241
+
242
+ # 檢查社交需求
243
+ if 'social needs' in description or 'requires companionship' in description:
244
+ if user_prefs.time_availability == 'limited':
245
+ special_needs_score -= 0.06
246
+ elif user_prefs.time_availability == 'flexible':
247
+ special_needs_score += 0.02
248
+
249
+ # 檢查獨立性
250
+ if 'independent' in temperament:
251
+ if user_prefs.time_availability == 'limited':
252
+ special_needs_score += 0.03
253
+
254
+ bonus += max(-0.15, min(0.1, special_needs_score))
255
+
256
  return min(0.5, max(-0.25, bonus))
257
 
258
 
 
334
  return factors
335
 
336
 
337
+ @staticmethod
338
+ def calculate_family_safety_score(breed_info: dict, children_age: str) -> float:
339
+ """
340
+ 計算品種與家庭/兒童的安全相容性分數,作為calculate_compatibility_score的一部分
341
+
342
+ 參數:
343
+ breed_info (dict): 品種資訊
344
+ children_age (str): 兒童年齡組別 ('toddler', 'school_age', 'teenager')
345
+
346
+ 返回:
347
+ float: 0.2-0.95之間的安全分數
348
+ """
349
+ temperament = breed_info.get('Temperament', '').lower()
350
+ size = breed_info.get('Size', 'Medium')
351
+
352
+ # 基礎安全分數(根據體型)
353
+ base_safety_scores = {
354
+ "Small": 0.85,
355
+ "Medium": 0.75,
356
+ "Large": 0.65,
357
+ "Giant": 0.55
358
+ }
359
+ safety_score = base_safety_scores.get(size, 0.70)
360
+
361
+ # 年齡相關的調整
362
+ age_factors = {
363
+ 'toddler': {
364
+ 'base_modifier': -0.15,
365
+ 'size_penalty': {
366
+ "Small": -0.05,
367
+ "Medium": -0.10,
368
+ "Large": -0.20,
369
+ "Giant": -0.25
370
+ }
371
+ },
372
+ 'school_age': {
373
+ 'base_modifier': -0.08,
374
+ 'size_penalty': {
375
+ "Small": -0.02,
376
+ "Medium": -0.05,
377
+ "Large": -0.10,
378
+ "Giant": -0.15
379
+ }
380
+ },
381
+ 'teenager': {
382
+ 'base_modifier': -0.05,
383
+ 'size_penalty': {
384
+ "Small": 0,
385
+ "Medium": -0.02,
386
+ "Large": -0.05,
387
+ "Giant": -0.08
388
+ }
389
+ }
390
+ }
391
+
392
+ # 應用年齡相關調整
393
+ age_adjustment = age_factors.get(children_age, age_factors['school_age'])
394
+ safety_score += age_adjustment['base_modifier']
395
+ safety_score += age_adjustment['size_penalty'].get(size, -0.10)
396
+
397
+ # 正面特徵評估
398
+ positive_traits = {
399
+ 'gentle': 0.10,
400
+ 'patient': 0.10,
401
+ 'good with children': 0.15,
402
+ 'friendly': 0.08,
403
+ 'calm': 0.08,
404
+ 'tolerant': 0.08,
405
+ 'playful': 0.05
406
+ }
407
+
408
+ # 危險特徵評估(更嚴格的懲罰)
409
+ dangerous_traits = {
410
+ 'aggressive': -0.25,
411
+ 'territorial': -0.20,
412
+ 'protective': -0.15,
413
+ 'nervous': -0.15,
414
+ 'dominant': -0.15,
415
+ 'strong-willed': -0.12,
416
+ 'independent': -0.10,
417
+ 'energetic': -0.08
418
+ }
419
+
420
+ # 計算特徵分數
421
+ for trait, bonus in positive_traits.items():
422
+ if trait in temperament:
423
+ safety_score += bonus * 0.8 # 降低正面特徵的影響力
424
+
425
+ for trait, penalty in dangerous_traits.items():
426
+ if trait in temperament:
427
+ # 對幼童加重懲罰
428
+ if children_age == 'toddler':
429
+ safety_score += penalty * 1.3
430
+ # 對青少年略微減輕懲罰
431
+ elif children_age == 'teenager':
432
+ safety_score += penalty * 0.8
433
+ else:
434
+ safety_score += penalty
435
+
436
+ # 特殊風險評估
437
+ description = breed_info.get('Description', '').lower()
438
+ if 'history of' in description:
439
+ safety_score -= 0.15
440
+ if 'requires experienced' in description:
441
+ safety_score -= 0.10
442
+
443
+ # 將分數限制在合理範圍內
444
+ return max(0.2, min(0.95, safety_score))
445
+
446
+
447
  def calculate_compatibility_score(breed_info: dict, user_prefs: UserPreferences) -> dict:
448
  """計算品種與使用者條件的相容性分數的優化版本"""
449
  try:
 
532
  return base_score
533
 
534
 
535
+ # def calculate_experience_score(care_level: str, user_experience: str, temperament: str) -> float:
536
+ # """
537
+ # 計算使用者經驗與品種需求的匹配分數
538
+
539
+ # 參數說明:
540
+ # care_level: 品種的照顧難度 ("High", "Moderate", "Low")
541
+ # user_experience: 使用者經驗等級 ("beginner", "intermediate", "advanced")
542
+ # temperament: 品種的性格特徵描述
543
+
544
+ # 返回:
545
+ # float: 0.2-1.0 之間的匹配分數
546
+ # """
547
+ # # 基礎分數矩陣 - 更大的分數差異來反映經驗重要性
548
+ # base_scores = {
549
+ # "High": {
550
+ # "beginner": 0.12, # 降低起始分,反映高難度品種對新手的挑戰
551
+ # "intermediate": 0.65, # 中級玩家可以應付,但仍有改善空間
552
+ # "advanced": 1.0 # 資深者能完全勝任
553
+ # },
554
+ # "Moderate": {
555
+ # "beginner": 0.35, # 適中難度對新手來說仍具挑戰
556
+ # "intermediate": 0.82, # 中級玩家有很好的勝任能���
557
+ # "advanced": 1.0 # 資深者完全勝任
558
+ # },
559
+ # "Low": {
560
+ # "beginner": 0.72, # 低難度品種適合新手
561
+ # "intermediate": 0.92, # 中級玩家幾乎完全勝任
562
+ # "advanced": 1.0 # 資深者完全勝任
563
+ # }
564
+ # }
565
+
566
+ # # 取得基礎分數
567
+ # score = base_scores.get(care_level, base_scores["Moderate"])[user_experience]
568
 
569
+ # # 性格特徵評估 - 根據經驗等級調整權重
570
+ # temperament_lower = temperament.lower()
571
+ # temperament_adjustments = 0.0
572
+
573
+ # if user_experience == "beginner":
574
+ # # 新手不適合的特徵 - 更嚴格的懲罰
575
+ # difficult_traits = {
576
+ # 'stubborn': -0.15, # 加重固執的懲罰
577
+ # 'independent': -0.12, # 加重獨立性的懲罰
578
+ # 'dominant': -0.12, # 加重支配性的懲罰
579
+ # 'strong-willed': -0.10, # 加重強勢的懲罰
580
+ # 'protective': -0.08, # 加重保護性的懲罰
581
+ # 'aloof': -0.08, # 加重冷漠的懲罰
582
+ # 'energetic': -0.06 # 輕微懲罰高能量
583
+ # }
584
+
585
+ # # 新手友善的特徵 - 提供更多獎勵
586
+ # easy_traits = {
587
+ # 'gentle': 0.08, # 增加溫和的獎勵
588
+ # 'friendly': 0.08, # 增加友善的獎勵
589
+ # 'eager to please': 0.08, # 增加順從的獎勵
590
+ # 'patient': 0.06, # 獎勵耐心
591
+ # 'adaptable': 0.06, # 獎勵適應性
592
+ # 'calm': 0.05 # 獎勵冷靜
593
+ # }
594
+
595
+ # # 計算特徵調整
596
+ # for trait, penalty in difficult_traits.items():
597
+ # if trait in temperament_lower:
598
+ # temperament_adjustments += penalty * 1.2 # 加重新手的懲罰
599
+
600
+ # for trait, bonus in easy_traits.items():
601
+ # if trait in temperament_lower:
602
+ # temperament_adjustments += bonus
603
+
604
+ # # 品種特殊調整
605
+ # if any(term in temperament_lower for term in ['terrier', 'working', 'guard']):
606
+ # temperament_adjustments -= 0.12 # 加重對特定類型品種的懲罰
607
+
608
+ # elif user_experience == "intermediate":
609
+ # # 中級玩家的調整更加平衡
610
+ # moderate_traits = {
611
+ # 'intelligent': 0.05, # 獎勵聰明
612
+ # 'athletic': 0.04, # 獎勵運動能力
613
+ # 'versatile': 0.04, # 獎勵多功能性
614
+ # 'stubborn': -0.06, # 輕微懲罰固執
615
+ # 'independent': -0.05, # 輕微懲罰獨立性
616
+ # 'protective': -0.04 # 輕微懲罰保護性
617
+ # }
618
+
619
+ # for trait, adjustment in moderate_traits.items():
620
+ # if trait in temperament_lower:
621
+ # temperament_adjustments += adjustment
622
+
623
+ # else: # advanced
624
+ # # 資深玩家能夠應對挑戰性特徵
625
+ # advanced_traits = {
626
+ # 'stubborn': 0.04, # 反轉為優勢
627
+ # 'independent': 0.04, # 反轉為優勢
628
+ # 'intelligent': 0.05, # 獎勵聰明
629
+ # 'protective': 0.04, # 獎勵保護性
630
+ # 'strong-willed': 0.03 # 獎勵強勢
631
+ # }
632
+
633
+ # for trait, bonus in advanced_traits.items():
634
+ # if trait in temperament_lower:
635
+ # temperament_adjustments += bonus
636
 
637
+ # # 確保最終分數在合理範圍內
638
+ # final_score = max(0.2, min(1.0, score + temperament_adjustments))
639
+ # return final_score
640
+
641
+ def calculate_experience_score(care_level: str, user_experience: str, temperament: str, has_children: bool = False) -> float:
642
+ """
643
+ 計算使用者經驗與品種需求的匹配分數,加入了更嚴格的評估標準
644
  """
645
+ # 即使是進階使用者也不應該完全無視品種難���
646
  base_scores = {
647
  "High": {
648
+ "beginner": 0.12,
649
+ "intermediate": 0.65,
650
+ "advanced": 0.85
651
  },
652
  "Moderate": {
653
+ "beginner": 0.35,
654
+ "intermediate": 0.75,
655
+ "advanced": 0.90
656
  },
657
  "Low": {
658
+ "beginner": 0.65,
659
+ "intermediate": 0.85,
660
+ "advanced": 0.92
661
  }
662
  }
663
 
664
  # 取得基礎分數
665
  score = base_scores.get(care_level, base_scores["Moderate"])[user_experience]
666
 
667
+ # 品種難度評估
668
+ breed_difficulty_penalty = 0.0
669
+ difficult_characteristics = {
670
+ 'working': 0.08,
671
+ 'guardian': 0.10,
672
+ 'primitive': 0.12,
673
+ 'independent': 0.08,
674
+ 'strong-willed': 0.07
675
+ }
676
+
677
+ for trait, penalty in difficult_characteristics.items():
678
+ if trait in temperament.lower():
679
+ # 即使是進階使用者也會受到一定程度的懲罰
680
+ if user_experience == "advanced":
681
+ breed_difficulty_penalty += penalty * 0.4
682
+ elif user_experience == "intermediate":
683
+ breed_difficulty_penalty += penalty * 0.7
684
+ else:
685
+ breed_difficulty_penalty += penalty
686
+
687
+ # 性格特徵評估
688
  temperament_lower = temperament.lower()
689
  temperament_adjustments = 0.0
690
 
691
  if user_experience == "beginner":
 
692
  difficult_traits = {
693
+ 'stubborn': -0.15,
694
+ 'independent': -0.12,
695
+ 'dominant': -0.12,
696
+ 'protective': -0.10,
697
+ 'aloof': -0.08
 
 
698
  }
 
 
699
  easy_traits = {
700
+ 'gentle': 0.08,
701
+ 'friendly': 0.08,
702
+ 'eager to please': 0.08,
703
+ 'patient': 0.06
 
 
704
  }
705
 
 
706
  for trait, penalty in difficult_traits.items():
707
  if trait in temperament_lower:
708
+ temperament_adjustments += penalty * 1.2
709
 
710
  for trait, bonus in easy_traits.items():
711
  if trait in temperament_lower:
712
  temperament_adjustments += bonus
713
 
 
 
 
 
714
  elif user_experience == "intermediate":
 
715
  moderate_traits = {
716
+ 'intelligent': 0.04,
717
+ 'athletic': 0.03,
718
+ 'versatile': 0.03,
719
+ 'stubborn': -0.06,
720
+ 'independent': -0.05
 
721
  }
722
 
723
  for trait, adjustment in moderate_traits.items():
 
725
  temperament_adjustments += adjustment
726
 
727
  else: # advanced
728
+ # 即使是進階使用者,某些特徵也應該被視為挑戰而非優勢
729
  advanced_traits = {
730
+ 'stubborn': 0.02,
731
+ 'independent': 0.02,
732
+ 'intelligent': 0.04,
733
+ 'protective': -0.02,
734
+ 'strong-willed': -0.02
735
  }
736
 
737
+ for trait, adjustment in advanced_traits.items():
738
  if trait in temperament_lower:
739
+ temperament_adjustments += adjustment
740
+
741
+ # 如果有小孩,增加額外的安全考量
742
+ if has_children:
743
+ safety_penalty = 0.0
744
+ risky_traits = {
745
+ 'protective': 0.05,
746
+ 'territorial': 0.06,
747
+ 'dominant': 0.07,
748
+ 'aggressive': 0.10,
749
+ 'strong-willed': 0.05
750
+ }
751
+
752
+ for trait, penalty in risky_traits.items():
753
+ if trait in temperament_lower:
754
+ # 即使是進階使用者,有小孩的情況下也要特別注意
755
+ if user_experience == "advanced":
756
+ safety_penalty += penalty * 0.7
757
+ else:
758
+ safety_penalty += penalty
759
+
760
+ temperament_adjustments -= safety_penalty
761
+
762
+ # 確保最終分數在合理範圍內,且有適當的上限
763
+ final_score = score - breed_difficulty_penalty + temperament_adjustments
764
+ return max(0.2, min(0.92, final_score))
765
 
766
  def calculate_health_score(breed_name: str) -> float:
767
  """計算品種健康分數"""
 
906
  'noise': calculate_noise_score(breed_info.get('Breed', ''), user_prefs.noise_tolerance)
907
  }
908
 
909
+ breed_bonus = calculate_breed_bonus(breed_info, user_prefs)
910
+ scores['breed_bonus'] = breed_bonus
911
+
912
+ # 如果有小孩,加入 family_safety 分數
913
+ if user_prefs.has_children:
914
+ scores['family_safety'] = calculate_family_safety_score(breed_info, user_prefs.children_age)
915
+
916
+
917
  # 優化權重配置
918
  weights = {
919
  'space': 0.28,
 
924
  'noise': 0.08
925
  }
926
 
927
+ if user_prefs.has_children:
928
+ weights = {
929
+ 'space': 0.20,
930
+ 'exercise': 0.13,
931
+ 'grooming': 0.08,
932
+ 'experience': 0.15,
933
+ 'health': 0.10,
934
+ 'noise': 0.06,
935
+ 'breed_bonus': 0.08,
936
+ 'family_safety': 0.20 # 給予家庭安全較高權重
937
+ }
938
+
939
  # 計算加權總分
940
  weighted_score = sum(score * weights[category] for category, score in scores.items())
941