// Package scale holds exploration-test scoring helpers. package scale // ScoreMajority picks the most frequent answer key and maps to a label set. func ScoreMajority(answers map[string]string, labels map[string]string, defaultLabel string) (styleKey, label string) { counts := map[string]int{} for _, v := range answers { counts[v]++ } best, bestN := "", -1 for k, n := range counts { if n > bestN { best, bestN = k, n } } if best == "" { return "", defaultLabel } label = labels[best] if label == "" { label = defaultLabel } return best, label } // CommunicationLabels for communication-style scale. func CommunicationLabels() map[string]string { return map[string]string{ "A": "理性澄清型", "B": "感受连接型", "C": "节奏尊重型", } } // EmotionLabels for emotion-pattern scale. func EmotionLabels() map[string]string { return map[string]string{ "A": "觉察表达型", "B": "安抚稳定型", "C": "行动调节型", } } // ScoreMBTI tallies E/I · S/N · T/F · J/P and returns a 4-letter type code + Chinese label. func ScoreMBTI(answers map[string]string) (typeCode, label string) { count := func(a, b string) (na, nb int) { for _, v := range answers { switch v { case a: na++ case b: nb++ } } return } pick := func(a, b string, na, nb int) string { if nb > na { return b } return a } e, i := count("E", "I") s, n := count("S", "N") t, f := count("T", "F") j, p := count("J", "P") code := pick("E", "I", e, i) + pick("S", "N", s, n) + pick("T", "F", t, f) + pick("J", "P", j, p) return code, MBTILabel(code) } // MBTILabel maps 4-letter exploration code to a lexicon-safe Chinese label. func MBTILabel(code string) string { if l, ok := mbtiLabels[code]; ok { return l } return "平衡探索型" } var mbtiLabels = map[string]string{ "INTJ": "战略建构者", "INTP": "概念探路者", "ENTJ": "目标推动者", "ENTP": "灵感挑战者", "INFJ": "愿景洞察者", "INFP": "价值守护者", "ENFJ": "共鸣召集者", "ENFP": "热情启发者", "ISTJ": "稳健执行者", "ISFJ": "细致守护者", "ESTJ": "秩序统筹者", "ESFJ": "温暖协调者", "ISTP": "务实拆解者", "ISFP": "感受体验者", "ESTP": "当下行动者", "ESFP": "活力分享者", }