Spaces:
Sleeping
Sleeping
Update app.py
Browse files
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 |
-
|
|
|
|
|
|
|
| 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: #
|
| 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="
|
| 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: #
|
|
|
|
| 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)
|