DawnC commited on
Commit
e15edb3
1 Parent(s): 98d657d

Update scoring_calculation_system.py

Browse files
Files changed (1) hide show
  1. scoring_calculation_system.py +157 -415
scoring_calculation_system.py CHANGED
@@ -28,207 +28,103 @@ 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:
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
  bonus = 0.0
134
  temperament = breed_info.get('Temperament', '').lower()
135
- description = breed_info.get('Description', '').lower()
136
 
137
- # 1. 壽命加分(最高0.08)- 提高上限
138
  try:
139
  lifespan = breed_info.get('Lifespan', '10-12 years')
140
  years = [int(x) for x in lifespan.split('-')[0].split()[0:1]]
141
- longevity_bonus = min(0.08, (max(years) - 10) * 0.015) # 提高係數
142
  bonus += longevity_bonus
143
  except:
144
  pass
145
 
146
- # 2. 性格特徵加分(最高0.20)- 提高上限
147
  positive_traits = {
148
- 'friendly': 0.06,
149
- 'gentle': 0.06,
150
- 'patient': 0.06,
151
- 'intelligent': 0.05,
152
- 'adaptable': 0.05,
153
- 'affectionate': 0.05,
154
- 'easy-going': 0.04,
155
- 'calm': 0.04
156
  }
157
 
158
- # 根據經驗等級調整負面特徵的影響
159
- experience_multiplier = {
160
- 'beginner': 1.3,
161
- 'intermediate': 0.8,
162
- 'advanced': 0.5 # 大幅降低進階使用者的負面特徵懲罰
163
- }.get(user_prefs.experience_level, 1.0)
164
-
165
  negative_traits = {
166
- 'aggressive': -0.08 * experience_multiplier,
167
- 'stubborn': -0.06 * experience_multiplier,
168
- 'dominant': -0.06 * experience_multiplier,
169
- 'aloof': -0.04 * experience_multiplier,
170
- 'nervous': -0.05 * experience_multiplier,
171
- 'protective': -0.04 * experience_multiplier
172
  }
173
 
174
  personality_score = sum(value for trait, value in positive_traits.items() if trait in temperament)
175
- if user_prefs.experience_level == 'advanced':
176
- personality_score *= 1.2 # 進階使用者得到更多正面特徵加分
177
  personality_score += sum(value for trait, value in negative_traits.items() if trait in temperament)
178
- bonus += max(-0.15, min(0.20, personality_score))
179
 
180
- # 3. 適應性加分(最高0.15)- 提高上限
181
  adaptability_bonus = 0.0
182
  if breed_info.get('Size') == "Small" and user_prefs.living_space == "apartment":
183
- adaptability_bonus += 0.07
184
  if 'adaptable' in temperament or 'versatile' in temperament:
185
- adaptability_bonus += 0.08
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 * experience_multiplier # 根據經驗調整懲罰
191
- elif user_prefs.yard_access == "private_yard":
192
- if "active" in description or "energetic" in description:
193
- adaptability_bonus += 0.05
194
-
195
- bonus += min(0.15, adaptability_bonus)
 
 
 
 
 
 
 
196
 
197
- # 4. 專門技能評估(最高0.15)- 提高上限和進階使用者加分
198
- skill_bonus = 0.0
199
- exercise_level = user_prefs.exercise_time / 60.0
200
 
 
 
201
  special_abilities = {
202
- 'working': 0.05 if exercise_level >= 1.5 else 0.02,
203
- 'herding': 0.05 if exercise_level >= 1.5 else 0.02,
204
- 'hunting': 0.05 if exercise_level >= 1.5 else 0.02,
205
- 'tracking': 0.04 if exercise_level >= 1.0 else 0.02,
206
- 'agility': 0.04 if exercise_level >= 1.0 else 0.02,
207
- 'sporting': 0.04 if exercise_level >= 1.2 else 0.02
208
  }
209
-
210
  for ability, value in special_abilities.items():
211
- if ability in temperament.lower() or ability in description:
212
- # 進階使用者在專門技能方面得到更多加分
213
- if user_prefs.experience_level == 'advanced':
214
- skill_bonus += value * 1.5
215
- elif user_prefs.experience_level == 'intermediate':
216
- skill_bonus += value * 1.2
217
- else:
218
- skill_bonus += value
219
-
220
- # 根據時間可用性調整技能加分
221
- time_multiplier = {
222
- 'flexible': 1.2,
223
- 'moderate': 1.0,
224
- 'limited': 0.8
225
- }.get(user_prefs.time_availability, 1.0)
226
-
227
- skill_bonus *= time_multiplier
228
- bonus += min(0.15, skill_bonus)
229
 
230
- # 最終分數範圍調整,提高上限
231
- return min(0.6, max(-0.20, bonus))
232
 
233
 
234
  @staticmethod
@@ -507,206 +403,113 @@ def calculate_compatibility_score(breed_info: dict, user_prefs: UserPreferences)
507
  return base_score
508
 
509
 
510
- # def calculate_experience_score(care_level: str, user_experience: str, temperament: str) -> float:
511
- # """
512
- # 計算使用者經驗與品種需求的匹配分數
513
-
514
- # 參數說明:
515
- # care_level: 品種的照顧難度 ("High", "Moderate", "Low")
516
- # user_experience: 使用者經驗等級 ("beginner", "intermediate", "advanced")
517
- # temperament: 品種的性格特徵描述
518
-
519
- # 返回:
520
- # float: 0.2-1.0 之間的匹配分數
521
- # """
522
- # # 基礎分數矩陣 - 更大的分數差異來反映經驗重要性
523
- # base_scores = {
524
- # "High": {
525
- # "beginner": 0.12, # 降低起始分,反映高難度品種對新手的挑戰
526
- # "intermediate": 0.65, # 中級玩家可以應付,但仍有改善空間
527
- # "advanced": 1.0 # 資深者能完全勝任
528
- # },
529
- # "Moderate": {
530
- # "beginner": 0.35, # 適中難度對新手來說仍具挑戰
531
- # "intermediate": 0.82, # 中級玩家有很好的勝任能力
532
- # "advanced": 1.0 # 資深者完全勝任
533
- # },
534
- # "Low": {
535
- # "beginner": 0.72, # 低難度品種適合新手
536
- # "intermediate": 0.92, # 中級玩家幾乎完全勝任
537
- # "advanced": 1.0 # 資深者完全勝任
538
- # }
539
- # }
540
-
541
- # # 取得基礎分數
542
- # score = base_scores.get(care_level, base_scores["Moderate"])[user_experience]
543
-
544
- # # 性格特徵評估 - 根據經驗等級調整權重
545
- # temperament_lower = temperament.lower()
546
- # temperament_adjustments = 0.0
547
-
548
- # if user_experience == "beginner":
549
- # # 新手不適合的特徵 - 更嚴格的懲罰
550
- # difficult_traits = {
551
- # 'stubborn': -0.15, # 加重固執的懲罰
552
- # 'independent': -0.12, # 加重獨立性的懲罰
553
- # 'dominant': -0.12, # 加重支配性的懲罰
554
- # 'strong-willed': -0.10, # 加重強勢的懲罰
555
- # 'protective': -0.08, # 加重保護性的懲罰
556
- # 'aloof': -0.08, # 加重冷漠的懲罰
557
- # 'energetic': -0.06 # 輕微懲罰高能量
558
- # }
559
-
560
- # # 新手友善的特徵 - 提供更多獎勵
561
- # easy_traits = {
562
- # 'gentle': 0.08, # 增加溫和的獎勵
563
- # 'friendly': 0.08, # 增加友善的獎勵
564
- # 'eager to please': 0.08, # 增加順從的獎勵
565
- # 'patient': 0.06, # 獎勵耐心
566
- # 'adaptable': 0.06, # 獎勵適應性
567
- # 'calm': 0.05 # 獎勵冷靜
568
- # }
569
-
570
- # # 計算特徵調整
571
- # for trait, penalty in difficult_traits.items():
572
- # if trait in temperament_lower:
573
- # temperament_adjustments += penalty * 1.2 # 加重新手的懲罰
574
-
575
- # for trait, bonus in easy_traits.items():
576
- # if trait in temperament_lower:
577
- # temperament_adjustments += bonus
578
-
579
- # # 品種特殊調整
580
- # if any(term in temperament_lower for term in ['terrier', 'working', 'guard']):
581
- # temperament_adjustments -= 0.12 # 加重對特定類型品種的懲罰
582
-
583
- # elif user_experience == "intermediate":
584
- # # 中級玩家的調整更加平衡
585
- # moderate_traits = {
586
- # 'intelligent': 0.05, # 獎勵聰明
587
- # 'athletic': 0.04, # 獎勵運動能力
588
- # 'versatile': 0.04, # 獎勵多功能性
589
- # 'stubborn': -0.06, # 輕微懲罰固執
590
- # 'independent': -0.05, # 輕微懲罰獨立性
591
- # 'protective': -0.04 # 輕微懲罰保護性
592
- # }
593
-
594
- # for trait, adjustment in moderate_traits.items():
595
- # if trait in temperament_lower:
596
- # temperament_adjustments += adjustment
597
-
598
- # else: # advanced
599
- # # 資深玩家能夠應對挑戰性特徵
600
- # advanced_traits = {
601
- # 'stubborn': 0.04, # 反轉為優勢
602
- # 'independent': 0.04, # 反轉為優勢
603
- # 'intelligent': 0.05, # 獎勵聰明
604
- # 'protective': 0.04, # 獎勵保護性
605
- # 'strong-willed': 0.03 # 獎勵強勢
606
- # }
607
-
608
- # for trait, bonus in advanced_traits.items():
609
- # if trait in temperament_lower:
610
- # temperament_adjustments += bonus
611
-
612
- # # 確保最終分數在合理範圍內
613
- # final_score = max(0.2, min(1.0, score + temperament_adjustments))
614
- # return final_score
615
-
616
  def calculate_experience_score(care_level: str, user_experience: str, temperament: str) -> float:
617
  """
618
- 計算使用者經驗與品種需求的匹配分數,強化進階使用者的評分
 
 
 
 
 
 
 
 
619
  """
620
- # 調整基礎分數矩陣,提高 advanced 的基本分數
621
  base_scores = {
622
  "High": {
623
- "beginner": 0.35,
624
- "intermediate": 0.75,
625
- "advanced": 0.92 # 提高上限
626
  },
627
  "Moderate": {
628
- "beginner": 0.45,
629
- "intermediate": 0.82,
630
- "advanced": 0.95
631
  },
632
  "Low": {
633
- "beginner": 0.60,
634
- "intermediate": 0.85,
635
- "advanced": 0.98
636
  }
637
  }
638
 
 
639
  score = base_scores.get(care_level, base_scores["Moderate"])[user_experience]
640
 
641
- # 性格特徵評估
642
  temperament_lower = temperament.lower()
643
  temperament_adjustments = 0.0
644
 
645
- if user_experience == "advanced":
646
- # 進階使用者的特徵評估
647
- advanced_traits = {
648
- 'intelligent': 0.08, # 提高正面特徵加分
649
- 'independent': 0.06,
650
- 'strong-willed': 0.05,
651
- 'energetic': 0.05,
652
- 'protective': 0.04,
653
- 'dominant': -0.02, # 降低負面特徵懲罰
654
- 'stubborn': -0.02,
655
- 'aggressive': -0.05
 
 
 
 
 
 
 
 
 
656
  }
657
 
658
- for trait, adjustment in advanced_traits.items():
 
659
  if trait in temperament_lower:
660
- temperament_adjustments += adjustment
 
 
 
 
661
 
 
 
 
 
662
  elif user_experience == "intermediate":
 
663
  moderate_traits = {
664
- 'intelligent': 0.05,
665
- 'adaptable': 0.04,
666
- 'easy-going': 0.04,
667
- 'stubborn': -0.06,
668
- 'independent': -0.05,
669
- 'dominant': -0.05,
670
- 'aggressive': -0.08
671
  }
672
 
673
  for trait, adjustment in moderate_traits.items():
674
  if trait in temperament_lower:
675
  temperament_adjustments += adjustment
676
-
677
- else: # beginner
678
- beginner_traits = {
679
- 'gentle': 0.05,
680
- 'friendly': 0.05,
681
- 'easy-going': 0.04,
682
- 'stubborn': -0.10,
683
- 'independent': -0.08,
684
- 'dominant': -0.08,
685
- 'aggressive': -0.12
686
  }
687
 
688
- for trait, adjustment in beginner_traits.items():
689
  if trait in temperament_lower:
690
- temperament_adjustments += adjustment
691
-
692
- # 特殊能力評估 - 對進階使用者加分
693
- if user_experience == "advanced":
694
- special_abilities = {
695
- 'working': 0.04,
696
- 'hunting': 0.04,
697
- 'herding': 0.04,
698
- 'guard': 0.03,
699
- 'agility': 0.03
700
- }
701
-
702
- for ability, bonus in special_abilities.items():
703
- if ability in temperament_lower:
704
  temperament_adjustments += bonus
705
 
706
  # 確保最終分數在合理範圍內
707
- final_score = max(0.3, min(0.98, score + temperament_adjustments))
708
  return final_score
709
 
 
710
  def calculate_health_score(breed_name: str) -> float:
711
  """計算品種健康分數"""
712
  if breed_name not in breed_health_info:
@@ -850,13 +653,6 @@ def calculate_compatibility_score(breed_info: dict, user_prefs: UserPreferences)
850
  'noise': calculate_noise_score(breed_info.get('Breed', ''), user_prefs.noise_tolerance)
851
  }
852
 
853
- breed_bonus = calculate_breed_bonus(breed_info, user_prefs)
854
- scores['breed_bonus'] = breed_bonus
855
-
856
- # 如果有小孩,加入 family_safety 分數
857
- if user_prefs.has_children:
858
- scores['family_safety'] = calculate_family_safety_score(breed_info, user_prefs.children_age)
859
-
860
 
861
  # 優化權重配置
862
  weights = {
@@ -868,91 +664,37 @@ def calculate_compatibility_score(breed_info: dict, user_prefs: UserPreferences)
868
  'noise': 0.08
869
  }
870
 
871
- if user_prefs.has_children:
872
- weights = {
873
- 'space': 0.20,
874
- 'exercise': 0.13,
875
- 'grooming': 0.08,
876
- 'experience': 0.15,
877
- 'health': 0.10,
878
- 'noise': 0.06,
879
- 'breed_bonus': 0.08,
880
- 'family_safety': 0.20 # 給予家庭安���較高權重
881
- }
882
-
883
  # 計算加權總分
884
  weighted_score = sum(score * weights[category] for category, score in scores.items())
885
 
886
- # def amplify_score(score):
887
- # """
888
- # 優化分數放大函數,確保分數範圍合理且結果一致
889
- # """
890
- # # 基礎調整
891
- # adjusted = (score - 0.35) * 1.8
892
-
893
- # # 使用 3.2 次方使曲線更平滑
894
- # amplified = pow(adjusted, 3.2) / 5.8 + score
895
-
896
- # # 特別處理高分區間,確保不超過95%
897
- # if amplified > 0.90:
898
- # # 壓縮高分區間,確保最高到95%
899
- # amplified = 0.90 + (amplified - 0.90) * 0.5
900
-
901
- # # 確保最終分數在合理範圍內(0.55-0.95)
902
- # final_score = max(0.55, min(0.95, amplified))
903
-
904
- # # 四捨五入到小數點後第三位
905
- # return round(final_score, 3)
906
-
907
- # final_score = amplify_score(weighted_score)
908
-
909
- # # 四捨五入所有分數
910
- # scores = {k: round(v, 4) for k, v in scores.items()}
911
- # scores['overall'] = round(final_score, 4)
912
-
913
- # return scores
914
-
915
  def amplify_score(score):
916
  """
917
- 優化分數放大函數,確保更合理的分數分布和品種間的差異
918
-
919
- 1. 調整基礎計算係數,使分數差異更明顯
920
- 2. 重新設計高分區間的處理
921
- 3. 確保進階使用者能獲得更高分數
922
- 4. 維持適當的分數下限
923
  """
924
- # 第一階段:基礎調整
925
- # 降低基礎調整係數,使分數變化更平滑
926
- adjusted = (score - 0.30) * 1.5
927
 
928
- # 第二階段:非線性轉換
929
- # 使用較小的指數,讓分數差異更明顯
930
- amplified = pow(adjusted, 2.8) / 4.2 + score
931
 
932
- # 第三階段:分數區間處理
933
- if amplified > 0.85:
934
- # 高分區間的處理更細緻
935
- extra = (amplified - 0.85)
936
- amplified = 0.85 + extra * 0.6
937
- elif amplified < 0.65:
938
- # 低分區間給予適當提升
939
- boost = (0.65 - amplified) * 0.3
940
- amplified += boost
941
-
942
- # 第四階段:確保分數在合理範圍內
943
- # 提高最低分數,降低最高分數
944
- final_score = max(0.60, min(0.92, amplified))
945
 
946
- # 第五階段:微調
947
- # 讓分數更容易落在中間區間
948
- if 0.75 <= final_score <= 0.85:
949
- variance = (random.random() - 0.5) * 0.02
950
- final_score += variance
951
-
952
- # 確保最終分數在絕對範圍內
953
- final_score = max(0.60, min(0.92, final_score))
954
 
 
955
  return round(final_score, 3)
 
 
 
 
 
 
 
 
956
 
957
  except Exception as e:
958
  print(f"Error details: {str(e)}")
 
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
 
403
  return base_score
404
 
405
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
406
  def calculate_experience_score(care_level: str, user_experience: str, temperament: str) -> float:
407
  """
408
+ 計算使用者經驗與品種需求的匹配分數
409
+
410
+ 參數說明:
411
+ care_level: 品種的照顧難度 ("High", "Moderate", "Low")
412
+ user_experience: 使用者經驗等級 ("beginner", "intermediate", "advanced")
413
+ temperament: 品種的性格特徵描述
414
+
415
+ 返回:
416
+ float: 0.2-1.0 之間的匹配分數
417
  """
418
+ # 基礎分數矩陣 - 更大的分數差異來反映經驗重要性
419
  base_scores = {
420
  "High": {
421
+ "beginner": 0.12, # 降低起始分,反映高難度品種對新手的挑戰
422
+ "intermediate": 0.65, # 中級玩家可以應付,但仍有改善空間
423
+ "advanced": 1.0 # 資深者能完全勝任
424
  },
425
  "Moderate": {
426
+ "beginner": 0.35, # 適中難度對新手來說仍具挑戰
427
+ "intermediate": 0.82, # 中級玩家有很好的勝任能力
428
+ "advanced": 1.0 # 資深者完全勝任
429
  },
430
  "Low": {
431
+ "beginner": 0.72, # 低難度品種適合新手
432
+ "intermediate": 0.92, # 中級玩家幾乎完全勝任
433
+ "advanced": 1.0 # 資深者完全勝任
434
  }
435
  }
436
 
437
+ # 取得基礎分數
438
  score = base_scores.get(care_level, base_scores["Moderate"])[user_experience]
439
 
440
+ # 性格特徵評估 - 根據經驗等級調整權重
441
  temperament_lower = temperament.lower()
442
  temperament_adjustments = 0.0
443
 
444
+ if user_experience == "beginner":
445
+ # 新手不適合的特徵 - 更嚴格的懲罰
446
+ difficult_traits = {
447
+ 'stubborn': -0.15, # 加重固執的懲罰
448
+ 'independent': -0.12, # 加重獨立性的懲罰
449
+ 'dominant': -0.12, # 加重支配性的懲罰
450
+ 'strong-willed': -0.10, # 加重強勢的懲罰
451
+ 'protective': -0.08, # 加重保護性的懲罰
452
+ 'aloof': -0.08, # 加重冷漠的懲罰
453
+ 'energetic': -0.06 # 輕微懲罰高能量
454
+ }
455
+
456
+ # 新手友善的特徵 - 提供更多獎勵
457
+ easy_traits = {
458
+ 'gentle': 0.08, # 增加溫和的獎勵
459
+ 'friendly': 0.08, # 增加友善的獎勵
460
+ 'eager to please': 0.08, # 增加順從的獎勵
461
+ 'patient': 0.06, # 獎勵耐心
462
+ 'adaptable': 0.06, # 獎勵適應性
463
+ 'calm': 0.05 # 獎勵冷靜
464
  }
465
 
466
+ # 計算特徵調整
467
+ for trait, penalty in difficult_traits.items():
468
  if trait in temperament_lower:
469
+ temperament_adjustments += penalty * 1.2 # 加重新手的懲罰
470
+
471
+ for trait, bonus in easy_traits.items():
472
+ if trait in temperament_lower:
473
+ temperament_adjustments += bonus
474
 
475
+ # 品種特殊調整
476
+ if any(term in temperament_lower for term in ['terrier', 'working', 'guard']):
477
+ temperament_adjustments -= 0.12 # 加重對特定類型品種的懲罰
478
+
479
  elif user_experience == "intermediate":
480
+ # 中級玩家的調整更加平衡
481
  moderate_traits = {
482
+ 'intelligent': 0.05, # 獎勵聰明
483
+ 'athletic': 0.04, # 獎勵運動能力
484
+ 'versatile': 0.04, # 獎勵多功能性
485
+ 'stubborn': -0.06, # 輕微懲罰固執
486
+ 'independent': -0.05, # 輕微懲罰獨立性
487
+ 'protective': -0.04 # 輕微懲罰保護性
 
488
  }
489
 
490
  for trait, adjustment in moderate_traits.items():
491
  if trait in temperament_lower:
492
  temperament_adjustments += adjustment
493
+
494
+ else: # advanced
495
+ # 資深玩家能夠應對挑戰性特徵
496
+ advanced_traits = {
497
+ 'stubborn': 0.04, # 反轉為優勢
498
+ 'independent': 0.04, # 反轉為優勢
499
+ 'intelligent': 0.05, # 獎勵聰明
500
+ 'protective': 0.04, # 獎勵保護性
501
+ 'strong-willed': 0.03 # 獎勵強勢
 
502
  }
503
 
504
+ for trait, bonus in advanced_traits.items():
505
  if trait in temperament_lower:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
506
  temperament_adjustments += bonus
507
 
508
  # 確保最終分數在合理範圍內
509
+ final_score = max(0.2, min(1.0, score + temperament_adjustments))
510
  return final_score
511
 
512
+
513
  def calculate_health_score(breed_name: str) -> float:
514
  """計算品種健康分數"""
515
  if breed_name not in breed_health_info:
 
653
  'noise': calculate_noise_score(breed_info.get('Breed', ''), user_prefs.noise_tolerance)
654
  }
655
 
 
 
 
 
 
 
 
656
 
657
  # 優化權重配置
658
  weights = {
 
664
  'noise': 0.08
665
  }
666
 
 
 
 
 
 
 
 
 
 
 
 
 
667
  # 計算加權總分
668
  weighted_score = sum(score * weights[category] for category, score in scores.items())
669
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
670
  def amplify_score(score):
671
  """
672
+ 優化分數放大函數,確保分數範圍合理且結果一致
 
 
 
 
 
673
  """
674
+ # 基礎調整
675
+ adjusted = (score - 0.35) * 1.8
 
676
 
677
+ # 使用 3.2 次方使曲線更平滑
678
+ amplified = pow(adjusted, 3.2) / 5.8 + score
 
679
 
680
+ # 特別處理高分區間,確保不超過95%
681
+ if amplified > 0.90:
682
+ # 壓縮高分區間,確保最高到95%
683
+ amplified = 0.90 + (amplified - 0.90) * 0.5
 
 
 
 
 
 
 
 
 
684
 
685
+ # 確保最終分數在合理範圍內(0.55-0.95)
686
+ final_score = max(0.55, min(0.95, amplified))
 
 
 
 
 
 
687
 
688
+ # 四捨五入到小數點後第三位
689
  return round(final_score, 3)
690
+
691
+ final_score = amplify_score(weighted_score)
692
+
693
+ # 四捨五入所有分數
694
+ scores = {k: round(v, 4) for k, v in scores.items()}
695
+ scores['overall'] = round(final_score, 4)
696
+
697
+ return scores
698
 
699
  except Exception as e:
700
  print(f"Error details: {str(e)}")