SamanthaStorm commited on
Commit
6139d49
·
verified ·
1 Parent(s): 9ab7ab9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +48 -1
app.py CHANGED
@@ -98,6 +98,47 @@ def generate_risk_snippet(abuse_score, top_label):
98
  title, summary, advice = RISK_SNIPPETS[risk_level]
99
  return f"\n\n{title}\n{summary} (Pattern: **{top_label}**)\n💡 {advice}"
100
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  # --- Escalation Quiz Questions & Weights ---
102
  ESCALATION_QUESTIONS = [
103
  ("Partner has access to firearms or weapons", 4),
@@ -150,6 +191,12 @@ def analyze_composite(msg1, msg2, msg3, *answers_and_none):
150
  out = f"Abuse Intensity: {composite_abuse}%\n"
151
  out += f"Escalation Potential: {escalation_level} ({escalation_score}/{sum(w for _,w in ESCALATION_QUESTIONS)})"
152
  out += generate_risk_snippet(composite_abuse, top_pattern)
 
 
 
 
 
 
153
  return out
154
 
155
  textbox_inputs = [
@@ -170,4 +217,4 @@ iface = gr.Interface(
170
  )
171
 
172
  if __name__ == "__main__":
173
- iface.launch()
 
98
  title, summary, advice = RISK_SNIPPETS[risk_level]
99
  return f"\n\n{title}\n{summary} (Pattern: **{top_label}**)\n💡 {advice}"
100
 
101
+ # --- DARVO Detection ---
102
+ DARVO_PATTERNS = {
103
+ "blame shifting", "projection", "dismissiveness", "guilt tripping", "contradictory statements"
104
+ }
105
+ DARVO_MOTIFS = [
106
+ "i guess i’m the bad guy", "after everything i’ve done", "you always twist everything",
107
+ "so now it’s all my fault", "i’m the villain", "i’m always wrong", "you never listen",
108
+ "you’re attacking me", "i’m done trying", "i’m the only one who cares"
109
+ ]
110
+
111
+ def detect_contradiction(message):
112
+ contradiction_flag = False
113
+ contradiction_phrases = [
114
+ (r"\b(i love you).{0,15}(i hate you|you ruin everything)", re.IGNORECASE),
115
+ (r"\b(i’m sorry).{0,15}(but you|if you hadn’t)", re.IGNORECASE),
116
+ (r"\b(i’m trying).{0,15}(you never|why do you)", re.IGNORECASE),
117
+ (r"\b(do what you want).{0,15}(you’ll regret it|i always give everything)", re.IGNORECASE),
118
+ (r"\b(i don’t care).{0,15}(you never think of me)", re.IGNORECASE),
119
+ (r"\b(i guess i’m just).{0,15}(the bad guy|worthless|never enough)", re.IGNORECASE),
120
+ ]
121
+ for pattern, flags in contradiction_phrases:
122
+ if re.search(pattern, message, flags):
123
+ contradiction_flag = True
124
+ break
125
+ return contradiction_flag
126
+
127
+ def calculate_darvo_score(patterns, sentiment_before, sentiment_after, motifs_found, contradiction_flag=False):
128
+ pattern_hits = len([p.lower() for p in patterns if p.lower() in DARVO_PATTERNS])
129
+ pattern_score = pattern_hits / len(DARVO_PATTERNS)
130
+ sentiment_shift_score = max(0.0, sentiment_after - sentiment_before)
131
+ motif_hits = len([m.lower() for m in motifs_found if m.lower() in DARVO_MOTIFS])
132
+ motif_score = motif_hits / len(DARVO_MOTIFS)
133
+ contradiction_score = 1.0 if contradiction_flag else 0.0
134
+ darvo_score = (
135
+ 0.3 * pattern_score +
136
+ 0.3 * sentiment_shift_score +
137
+ 0.25 * motif_score +
138
+ 0.15 * contradiction_score
139
+ )
140
+ return round(min(darvo_score, 1.0), 3)
141
+
142
  # --- Escalation Quiz Questions & Weights ---
143
  ESCALATION_QUESTIONS = [
144
  ("Partner has access to firearms or weapons", 4),
 
191
  out = f"Abuse Intensity: {composite_abuse}%\n"
192
  out += f"Escalation Potential: {escalation_level} ({escalation_score}/{sum(w for _,w in ESCALATION_QUESTIONS)})"
193
  out += generate_risk_snippet(composite_abuse, top_pattern)
194
+
195
+ avg_darvo = round(sum([r[3] for r in results]) / len(results), 3)
196
+ if avg_darvo > 0.25:
197
+ darvo_descriptor = "moderate" if avg_darvo < 0.65 else "high"
198
+ out += f"\n\nDARVO Score: {avg_darvo} → This indicates a **{darvo_descriptor} likelihood** of narrative reversal (DARVO), where the speaker may be denying, attacking, or reversing blame."
199
+
200
  return out
201
 
202
  textbox_inputs = [
 
217
  )
218
 
219
  if __name__ == "__main__":
220
+ iface.launch()