NKessler commited on
Commit
a841cfc
·
verified ·
1 Parent(s): e610257

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +6 -18
app.py CHANGED
@@ -44,7 +44,6 @@ def analyze_article(text: str) -> dict:
44
  "sentiment_score": A float between -1.0 (highly negative) and 1.0 (highly positive).
45
  "primary_tone": The single dominant emotion.
46
  "dynamic_topic": A 3-to-5 word summary of the article's specific angle or frame.
47
- "key_entities": A dictionary of the top 3 entities (people, groups, concepts) mentioned, and a 1-to-2 word description of how they are portrayed (e.g., {{"Tech Leaders": "Victims", "Government": "Aggressor"}}).
48
  "tone_scores": A dictionary scoring THESE EXACT 6 EMOTIONS from 0.0 to 1.0: {{"anger": 0.0, "fear": 0.0, "joy": 0.0, "sadness": 0.0, "surprise": 0.0, "trust": 0.0}}.
49
  "framing_words": A list of dictionaries containing the 5 to 8 most emotionally charged or biased words, and the specific emotion they evoke. Format: [{{"word": "draconian", "emotion": "fear"}}, {{"word": "titans", "emotion": "awe"}}].
50
  "subjectivity_score": A float between 0.0 (completely objective/factual) and 1.0 (highly opinionated/subjective).
@@ -77,7 +76,6 @@ def analyze_article(text: str) -> dict:
77
  "sentiment_score": llm_data.get("sentiment_score", 0.0),
78
  "primary_tone": llm_data.get("primary_tone", "neutral"),
79
  "dynamic_topic": llm_data.get("dynamic_topic", "Unclear Topic"),
80
- "key_entities": llm_data.get("key_entities", {}),
81
  "tone_scores": standard_tones,
82
  "framing_words": llm_data.get("framing_words", []),
83
  "subjectivity_score": llm_data.get("subjectivity_score", 0.0),
@@ -166,7 +164,9 @@ def _highlight_framing_words(text: str, target_words: list) -> str:
166
 
167
  if len(word) > 2:
168
  pattern = r'\b(' + re.escape(word) + r')\b'
169
- replacement = rf"<span style='background-color: #fef08a; color: #854d0e; font-weight: 600; padding: 0.1rem 0.2rem; border-radius: 4px;'>\1 <span style='font-size: 0.65em; background: #854d0e; color: white; padding: 2px 4px; border-radius: 3px; margin-left: 2px; vertical-align: middle;'>{emotion}</span></span>"
 
 
170
  highlighted_text = re.sub(pattern, replacement, highlighted_text, flags=re.IGNORECASE)
171
 
172
  return highlighted_text
@@ -379,15 +379,9 @@ if st.session_state.results_a and st.session_state.results_b:
379
 
380
  st.plotly_chart(_create_sentiment_gauge(r_a["sentiment_score"], "Sentiment Bias"), use_container_width=True, key="gauge_a")
381
 
382
- st.markdown("**Entities Portrayed:**")
383
- entities = r_a.get('key_entities', {})
384
- if entities:
385
- entities_html = "".join([f"<span style='background:#f1f5f9; border: 1px solid #cbd5e1; padding:4px 8px; border-radius:6px; margin-right:8px; font-size:0.85em; display: inline-block; margin-bottom: 4px;'><b>{k}</b>: <i>{v}</i></span>" for k, v in entities.items()])
386
- st.markdown(f"<div style='margin-bottom: 1rem;'>{entities_html}</div>", unsafe_allow_html=True)
387
-
388
  st.markdown("**Key Framing Language:**")
389
  annotated_text = _highlight_framing_words(user_article_a, r_a['framing_words'])
390
- st.markdown(f"<div style='background-color: #f8fafc; padding: 1rem; border-radius: 8px; border: 1px solid #e2e8f0;'>{annotated_text}</div>", unsafe_allow_html=True)
391
 
392
  # Render Column B
393
  with res_col2:
@@ -400,14 +394,8 @@ if st.session_state.results_a and st.session_state.results_b:
400
  m3.metric("Dynamic Topic", str(r_b['dynamic_topic']).title())
401
  m4.metric("Reading Ease", f"{r_b['reading_ease']:.1f}", help="0-30 is college graduate level, 60-70 is 8th grade.")
402
 
403
- st.plotly_chart(_create_sentiment_gauge(r_b["sentiment_score"], "Sentiment Bias"), use_container_width=True, key="gauge_a")
404
-
405
- st.markdown("**Entities Portrayed:**")
406
- entities = r_b.get('key_entities', {})
407
- if entities:
408
- entities_html = "".join([f"<span style='background:#f1f5f9; border: 1px solid #cbd5e1; padding:4px 8px; border-radius:6px; margin-right:8px; font-size:0.85em; display: inline-block; margin-bottom: 4px;'><b>{k}</b>: <i>{v}</i></span>" for k, v in entities.items()])
409
- st.markdown(f"<div style='margin-bottom: 1rem;'>{entities_html}</div>", unsafe_allow_html=True)
410
 
411
  st.markdown("**Key Framing Language:**")
412
  annotated_text = _highlight_framing_words(user_article_b, r_b['framing_words'])
413
- st.markdown(f"<div style='background-color: #f8fafc; padding: 1rem; border-radius: 8px; border: 1px solid #e2e8f0;'>{annotated_text}</div>", unsafe_allow_html=True)
 
44
  "sentiment_score": A float between -1.0 (highly negative) and 1.0 (highly positive).
45
  "primary_tone": The single dominant emotion.
46
  "dynamic_topic": A 3-to-5 word summary of the article's specific angle or frame.
 
47
  "tone_scores": A dictionary scoring THESE EXACT 6 EMOTIONS from 0.0 to 1.0: {{"anger": 0.0, "fear": 0.0, "joy": 0.0, "sadness": 0.0, "surprise": 0.0, "trust": 0.0}}.
48
  "framing_words": A list of dictionaries containing the 5 to 8 most emotionally charged or biased words, and the specific emotion they evoke. Format: [{{"word": "draconian", "emotion": "fear"}}, {{"word": "titans", "emotion": "awe"}}].
49
  "subjectivity_score": A float between 0.0 (completely objective/factual) and 1.0 (highly opinionated/subjective).
 
76
  "sentiment_score": llm_data.get("sentiment_score", 0.0),
77
  "primary_tone": llm_data.get("primary_tone", "neutral"),
78
  "dynamic_topic": llm_data.get("dynamic_topic", "Unclear Topic"),
 
79
  "tone_scores": standard_tones,
80
  "framing_words": llm_data.get("framing_words", []),
81
  "subjectivity_score": llm_data.get("subjectivity_score", 0.0),
 
164
 
165
  if len(word) > 2:
166
  pattern = r'\b(' + re.escape(word) + r')\b'
167
+
168
+ replacement = rf"""<span style='background-color: #f8fafc; border: 1px solid #cbd5e1; border-radius: 6px; padding: 0.15rem 0.3rem; font-weight: 600; color: #0f172a; box-shadow: 0 1px 2px rgba(0,0,0,0.02); margin: 0 0.1rem;'>\1 <span style='font-size: 0.65rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: #ffffff; background-color: #475569; padding: 0.15rem 0.4rem; border-radius: 12px; margin-left: 4px; vertical-align: text-bottom;'>{emotion}</span></span>"""
169
+
170
  highlighted_text = re.sub(pattern, replacement, highlighted_text, flags=re.IGNORECASE)
171
 
172
  return highlighted_text
 
379
 
380
  st.plotly_chart(_create_sentiment_gauge(r_a["sentiment_score"], "Sentiment Bias"), use_container_width=True, key="gauge_a")
381
 
 
 
 
 
 
 
382
  st.markdown("**Key Framing Language:**")
383
  annotated_text = _highlight_framing_words(user_article_a, r_a['framing_words'])
384
+ st.markdown(f"<div style='background-color: #ffffff; padding: 1.5rem; border-radius: 12px; border: 1px solid #e2e8f0; line-height: 1.8; font-size: 1.05rem; box-shadow: 0 1px 3px rgba(0,0,0,0.05);'>{annotated_text}</div>", unsafe_allow_html=True)
385
 
386
  # Render Column B
387
  with res_col2:
 
394
  m3.metric("Dynamic Topic", str(r_b['dynamic_topic']).title())
395
  m4.metric("Reading Ease", f"{r_b['reading_ease']:.1f}", help="0-30 is college graduate level, 60-70 is 8th grade.")
396
 
397
+ st.plotly_chart(_create_sentiment_gauge(r_b["sentiment_score"], "Sentiment Bias"), use_container_width=True, key="gauge_b")
 
 
 
 
 
 
398
 
399
  st.markdown("**Key Framing Language:**")
400
  annotated_text = _highlight_framing_words(user_article_b, r_b['framing_words'])
401
+ st.markdown(f"<div style='background-color: #ffffff; padding: 1.5rem; border-radius: 12px; border: 1px solid #e2e8f0; line-height: 1.8; font-size: 1.05rem; box-shadow: 0 1px 3px rgba(0,0,0,0.05);'>{annotated_text}</div>", unsafe_allow_html=True)