Spaces:
Sleeping
Sleeping
File size: 5,171 Bytes
8038e76 022d9b4 8038e76 022d9b4 8038e76 022d9b4 8038e76 022d9b4 8038e76 022d9b4 8038e76 | 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 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | import gradio as gr
from transformers import pipeline
# Load a sentiment analysis model (works on free CPU)
analyzer = pipeline("sentiment-analysis", model="distilbert-base-uncased-finetuned-sst-2-english")
# --- Visual Mood Gauge using gr.HTML ---
GAUGE_HTML = """
<div class="mood-gauge">
<div class="gauge-title">Mood Reading</div>
<div class="gauge-track">
<div class="gauge-fill" style="width: ${value.percent}%; background: ${value.color};"></div>
</div>
<div class="gauge-labels">
<span class="label-neg">NEGATIVE</span>
<span class="label-pos">POSITIVE</span>
</div>
<div class="gauge-result" style="color: ${value.color};">
<span class="gauge-emoji">${value.emoji}</span>
<span class="gauge-label">${value.label}</span>
</div>
<div class="gauge-confidence">${value.confidence}</div>
<div class="gauge-hint">${value.hint}</div>
</div>
"""
GAUGE_CSS = """
.mood-gauge {
font-family: 'Segoe UI', system-ui, sans-serif;
max-width: 480px;
margin: 0 auto;
padding: 28px 24px;
text-align: center;
}
.gauge-title {
font-size: 13px;
text-transform: uppercase;
letter-spacing: 2px;
color: #888;
margin-bottom: 20px;
}
.gauge-track {
height: 28px;
background: #e8e8e8;
border-radius: 14px;
overflow: hidden;
position: relative;
box-shadow: inset 0 2px 4px rgba(0,0,0,0.1);
}
.gauge-fill {
height: 100%;
border-radius: 14px;
transition: width 0.8s ease, background 0.8s ease;
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
}
.gauge-labels {
display: flex;
justify-content: space-between;
margin-top: 6px;
font-size: 10px;
letter-spacing: 1px;
color: #aaa;
}
.gauge-result {
margin-top: 24px;
display: flex;
align-items: center;
justify-content: center;
gap: 12px;
}
.gauge-emoji {
font-size: 48px;
line-height: 1;
}
.gauge-label {
font-size: 28px;
font-weight: 700;
letter-spacing: 1px;
}
.gauge-confidence {
margin-top: 8px;
font-size: 18px;
color: #666;
}
.gauge-hint {
margin-top: 16px;
font-size: 13px;
color: #999;
font-style: italic;
min-height: 20px;
}
"""
GAUGE_JS = """
// Animate the fill bar on load
const fill = element.querySelector('.gauge-fill');
if (fill) {
const target = fill.style.width;
fill.style.width = '0%';
requestAnimationFrame(() => {
requestAnimationFrame(() => {
fill.style.width = target;
});
});
}
"""
# Default state (before any analysis)
DEFAULT_STATE = {
"percent": 50,
"color": "#ccc",
"emoji": "...",
"label": "",
"confidence": "Paste some text and click Submit",
"hint": "",
}
def check_mood(text, gauge_state):
if not text or not text.strip():
return DEFAULT_STATE
result = analyzer(text)[0]
label = result["label"]
score = result["score"]
# Map to a 0-100 gauge: 0 = fully negative, 100 = fully positive
if label == "POSITIVE":
percent = 50 + (score * 50)
color = "#2ecc71" if score > 0.9 else "#82c91e"
emoji = "\U0001f60a" if score > 0.9 else "\U0001f642"
else:
percent = 50 - (score * 50)
color = "#e74c3c" if score > 0.9 else "#e67e22"
emoji = "\U0001f622" if score > 0.9 else "\U0001f610"
# Confidence hint for students
if score > 0.95:
hint = "The model is very sure about this one."
elif score > 0.8:
hint = "Pretty confident, but not 100%. Do you agree?"
else:
hint = "The model isn't sure. This text might be ambiguous!"
return {
"percent": round(percent),
"color": color,
"emoji": emoji,
"label": label,
"confidence": f"Confidence: {score:.0%}",
"hint": hint,
}
# --- Build the app with gr.Blocks ---
with gr.Blocks(title="Mood Meter") as demo:
gr.Markdown("# Mood Meter")
gr.Markdown(
"Paste any text and this AI will tell you whether it feels **POSITIVE** or **NEGATIVE** "
"— and how confident it is. Does the model agree with how YOU feel about the text?"
)
text_input = gr.Textbox(
lines=6,
placeholder="Paste any text here — a song lyric, a diary entry, a text from a friend...",
label="Your text",
)
submit_btn = gr.Button("Check the Mood", variant="primary")
gauge = gr.HTML(
value=DEFAULT_STATE,
html_template=GAUGE_HTML,
css_template=GAUGE_CSS,
js_on_load=GAUGE_JS,
)
submit_btn.click(fn=check_mood, inputs=[text_input, gauge], outputs=gauge)
gr.Examples(
examples=[
"I can't believe how lucky I am to have friends like you. Every day feels like an adventure and I wouldn't trade it for anything in the world.",
"I don't know why I even bother anymore. Nothing I do seems to matter and nobody notices when I try my hardest.",
"Dear future me, I hope you figured it out. I hope you're not still lying awake at 2am wondering if you made the right choice.",
"Walking into school on the first day felt like stepping onto another planet. Everyone already knew each other and I just stood there holding my backpack straps.",
],
inputs=[text_input],
)
demo.launch()
|