File size: 2,949 Bytes
32328ca
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# emotion_core.py
# Lightweight sentiment + arousal + trait inferences (no external deps)

import re

_POS = {
    "love","like","enjoy","great","good","amazing","excited","confident","proud","win",
    "focus","focused","progress","grow","learning","curious","optimistic","strong","ready",
    "grateful","hyped","calm","peace","solid","clear","vision","hungry","ambitious"
}
_NEG = {
    "hate","dislike","bad","terrible","awful","sad","angry","upset","lost","stuck",
    "tired","worried","anxious","stress","stressed","fail","failure","confused","quit",
    "overwhelmed","mad","frustrated"
}
_AROUSAL_UP = {
    "hyped","excited","now","today","urgent","fast","go","run","grind","push","shipping",
    "launch","win","attack","dominate","scale"
}
_AROUSAL_DOWN = {"calm","slow","reflect","breathe","steady","patient","peace","chill"}

TRAIT_MAP = {
    "ambition": {"keywords": {"ambitious","billionaire","build","empire","dominate","scale","win","grind","goal"}, "pos": +2, "neg": -1},
    "optimism": {"keywords": {"optimistic","confident","great","good","amazing","believe","can","possible"}, "pos": +2, "neg": -2},
    "resilience": {"keywords": {"again","retry","keep","persist","bounce","comeback","despite","even if"}, "pos": +2, "neg": 0},
    "focus": {"keywords": {"focus","focused","discipline","plan","system","consistent","daily"}, "pos": +2, "neg": -1},
    "curiosity": {"keywords": {"curious","learn","why","how","explore","research","test"}, "pos": +2, "neg": 0},
    "calm": {"keywords": {"calm","steady","patient","peace","collected"}, "pos": +2, "neg": -2},
}

def _tokens(text: str):
    return set(re.findall(r"[a-zA-Z']+", text.lower()))

class EmotionAnalyzer:
    def analyze(self, text: str):
        toks = _tokens(text)

        pos_hits = len(toks & _POS)
        neg_hits = len(toks & _NEG)
        raw = pos_hits - neg_hits
        # sentiment in [-1,1]
        sentiment = 0.0
        if raw != 0:
            sentiment = max(-1.0, min(1.0, raw / 5.0))

        # arousal in [0,1]
        arousal = 0.5
        up = len(toks & _AROUSAL_UP)
        down = len(toks & _AROUSAL_DOWN)
        arousal = max(0.0, min(1.0, 0.5 + 0.15 * (up - down)))

        # tags
        tags = []
        if sentiment > 0.25: tags.append("positive")
        if sentiment < -0.25: tags.append("negative")
        if arousal >= 0.65: tags.append("high-energy")
        if arousal <= 0.35: tags.append("low-energy")

        # trait deltas
        trait_deltas = {}
        for trait, spec in TRAIT_MAP.items():
            found = any(k in toks for k in spec["keywords"])
            if found:
                trait_deltas[trait] = spec["pos"]
            elif sentiment < -0.4 and trait in ("optimism","calm","focus"):
                trait_deltas[trait] = spec["neg"]

        return {
            "sentiment": sentiment,
            "arousal": arousal,
            "tags": tags,
            "trait_deltas": trait_deltas
        }