Spaces:
Sleeping
Sleeping
import streamlit as st | |
# --- App Configuration --- | |
st.set_page_config( | |
page_title="Basic Python Sentiment Analyzer", | |
page_icon="βοΈ", | |
layout="centered", | |
initial_sidebar_state="auto" | |
) | |
# --- Define Sentiment Keywords (Pure Python Logic) --- | |
# These are very basic lists for demonstration purposes. | |
# A real-world rule-based system would be much more extensive and nuanced. | |
POSITIVE_KEYWORDS = [ | |
"good", "great", "excellent", "amazing", "fantastic", "love", "happy", | |
"joy", "wonderful", "positive", "awesome", "beautiful", "perfect", "like", | |
"enjoy", "best", "super", "nice", "pleased", "delightful", "brilliant" | |
] | |
NEGATIVE_KEYWORDS = [ | |
"bad", "terrible", "horrible", "awful", "hate", "sad", "unhappy", | |
"poor", "negative", "disappointing", "worst", "ugly", "frustrating", | |
"dislike", "annoying", "miserable", "stressful", "difficult", "problem", | |
"fail", "ruin", "never" | |
] | |
# --- Sentiment Analysis Function (Pure Python) --- | |
def analyze_sentiment_basic(text): | |
""" | |
Performs a very basic sentiment analysis based on predefined positive and negative keywords. | |
This function does not use any external NLP models or libraries. | |
""" | |
if not text: | |
return "Neutral", 0, 0 # Return neutral if no text | |
text_lower = text.lower() | |
positive_count = 0 | |
negative_count = 0 | |
# Count positive keywords | |
for keyword in POSITIVE_KEYWORDS: | |
positive_count += text_lower.count(keyword) | |
# Count negative keywords | |
for keyword in NEGATIVE_KEYWORDS: | |
negative_count += text_lower.count(keyword) | |
# Determine sentiment | |
if positive_count > negative_count: | |
return "Positive", positive_count, negative_count | |
elif negative_count > positive_count: | |
return "Negative", positive_count, negative_count | |
else: | |
return "Neutral", positive_count, negative_count | |
# --- Streamlit UI --- | |
# Header Section | |
st.markdown( | |
""" | |
<div style="text-align: center; padding: 20px; background-color: #f0f2f6; border-radius: 10px; margin-bottom: 30px;"> | |
<h1 style="color: #333; font-size: 2.5em;">βοΈ Sentiment Analyzer</h1> | |
<p style="color: #555; font-size: 1.1em;"> | |
Discover the sentiment of your text with a simple keyword-based analysis. | |
</p> | |
</div> | |
""", | |
unsafe_allow_html=True | |
) | |
st.markdown( | |
""" | |
<p style="font-size: 1.1em; text-align: center; margin-bottom: 20px;"> | |
Enter any text below, and I'll tell you if its sentiment is positive, negative, or neutral based on a predefined list of keywords. | |
</p> | |
""", | |
unsafe_allow_html=True | |
) | |
# Text input from the user | |
user_input = st.text_area( | |
"π Enter your text here:", | |
"This is a good example, but it could be even better. I really enjoy using Streamlit!", | |
height=180, | |
key="user_text_input" # Added a key for better control | |
) | |
col1, col2 = st.columns([1, 1]) | |
with col1: | |
analyze_button = st.button("β¨ Analyze Sentiment", key="analyze_btn") | |
with col2: | |
clear_button = st.button("ποΈ Clear Text", key="clear_btn") | |
# Clear button functionality | |
if clear_button: | |
st.session_state.user_text_input = "" # Clear the text area | |
st.experimental_rerun() # Rerun to clear the output | |
# Analyze button logic | |
if analyze_button: | |
if user_input: | |
sentiment, pos_count, neg_count = analyze_sentiment_basic(user_input) | |
st.markdown("---") | |
st.subheader("π Analysis Result:") | |
# Display result with appropriate styling and icons | |
if sentiment == "Positive": | |
st.success(f"**Sentiment:** Positive π") | |
elif sentiment == "Negative": | |
st.error(f"**Sentiment:** Negative π ") | |
else: | |
st.warning(f"**Sentiment:** Neutral π") | |
st.markdown(f"<p style='font-size: 1.05em;'>Positive keyword matches: <strong>{pos_count}</strong></p>", unsafe_allow_html=True) | |
st.markdown(f"<p style='font-size: 1.05em;'>Negative keyword matches: <strong>{neg_count}</strong></p>", unsafe_allow_html=True) | |
st.markdown("---") | |
st.write(f"**Original Text:**") | |
st.markdown(f"<div style='background-color: #e9ecef; padding: 15px; border-radius: 8px; border-left: 5px solid #007bff;'><em>{user_input}</em></div>", unsafe_allow_html=True) | |
else: | |
st.warning("Please enter some text to analyze.") | |
# Custom CSS for enhanced styling | |
st.markdown( | |
""" | |
<style> | |
/* General body and font */ | |
body { | |
font-family: 'Inter', sans-serif; | |
background-color: #f8f9fa; | |
color: #343a40; | |
} | |
/* Streamlit widgets styling */ | |
.stButton>button { | |
background-color: #28a745; /* Green for analyze */ | |
color: white; | |
padding: 12px 25px; | |
border-radius: 10px; | |
border: none; | |
cursor: pointer; | |
font-size: 1.1em; | |
font-weight: bold; | |
box-shadow: 0 5px 15px rgba(40, 167, 69, 0.3); | |
transition: all 0.3s ease-in-out; | |
width: 100%; /* Make buttons full width in columns */ | |
} | |
.stButton>button:hover { | |
background-color: #218838; | |
box-shadow: 0 8px 20px rgba(40, 167, 69, 0.4); | |
transform: translateY(-2px); | |
} | |
/* Clear button specific style */ | |
.stButton[key="clear_btn"] > button { | |
background-color: #dc3545; /* Red for clear */ | |
box-shadow: 0 5px 15px rgba(220, 53, 69, 0.3); | |
} | |
.stButton[key="clear_btn"] > button:hover { | |
background-color: #c82333; | |
box-shadow: 0 8px 20px rgba(220, 53, 69, 0.4); | |
} | |
.stTextArea>div>div>textarea { | |
border-radius: 10px; | |
border: 1px solid #ced4da; | |
padding: 15px; | |
font-size: 1.05em; | |
box-shadow: inset 0 1px 3px rgba(0,0,0,0.1); | |
transition: border-color 0.3s ease-in-out; | |
} | |
.stTextArea>div>div>textarea:focus { | |
border-color: #007bff; | |
outline: none; | |
} | |
/* Streamlit message boxes */ | |
.stSuccess { | |
background-color: #d4edda; | |
color: #155724; | |
border-radius: 8px; | |
padding: 15px; | |
border: 1px solid #c3e6cb; | |
font-weight: bold; | |
} | |
.stError { | |
background-color: #f8d7da; | |
color: #721c24; | |
border-radius: 8px; | |
padding: 15px; | |
border: 1px solid #f5c6cb; | |
font-weight: bold; | |
} | |
.stWarning { | |
background-color: #fff3cd; | |
color: #856404; | |
border-radius: 8px; | |
padding: 15px; | |
border: 1px solid #ffeeba; | |
font-weight: bold; | |
} | |
.stInfo { | |
background-color: #d1ecf1; | |
color: #0c5460; | |
border-radius: 8px; | |
padding: 10px; | |
border: 1px solid #bee5eb; | |
margin-top: 10px; | |
} | |
/* Markdown styling for titles and text */ | |
h1 { | |
color: #007bff; | |
text-align: center; | |
font-weight: 700; | |
margin-bottom: 20px; | |
} | |
h2, h3, h4, h5, h6 { | |
color: #343a40; | |
margin-top: 25px; | |
margin-bottom: 15px; | |
} | |
p { | |
line-height: 1.6; | |
} | |
</style> | |
""", | |
unsafe_allow_html=True | |
) | |
# Footer | |
st.markdown( | |
""" | |
<div style="text-align: center; margin-top: 50px; padding: 20px; border-top: 1px solid #eee; color: #6c757d;"> | |
<p>Built with β€οΈ using Streamlit and pure Python.</p> | |
</div> | |
""", | |
unsafe_allow_html=True | |
) | |