Update app.py
Browse files
app.py
CHANGED
@@ -2,265 +2,205 @@
|
|
2 |
import streamlit as st
|
3 |
from groq import Groq
|
4 |
from textblob import TextBlob
|
|
|
|
|
5 |
import re
|
6 |
-
import
|
7 |
from reportlab.lib.pagesizes import letter
|
8 |
from reportlab.pdfgen import canvas
|
9 |
import io
|
10 |
|
11 |
-
# Initialize
|
12 |
-
|
|
|
|
|
13 |
|
14 |
# Configure Streamlit
|
15 |
-
st.set_page_config(page_title="
|
16 |
|
17 |
# Custom CSS
|
18 |
st.markdown("""
|
19 |
<style>
|
20 |
-
@keyframes
|
21 |
-
0% {
|
22 |
-
|
23 |
-
|
|
|
|
|
|
|
24 |
}
|
25 |
|
26 |
-
.
|
27 |
-
animation:
|
28 |
-
font-size: 2.5em;
|
29 |
-
text-align: center;
|
30 |
}
|
31 |
|
32 |
.progress-bar {
|
33 |
height: 25px;
|
34 |
border-radius: 15px;
|
35 |
-
background: linear-gradient(90deg, #FF6B6B 0%, #
|
36 |
-
transition: width 0.8s ease-in-out;
|
37 |
-
}
|
38 |
-
|
39 |
-
.stButton>button {
|
40 |
-
background: #4CAF50 !important;
|
41 |
-
color: white !important;
|
42 |
-
border-radius: 25px !important;
|
43 |
-
padding: 10px 25px !important;
|
44 |
-
font-size: 1.1em !important;
|
45 |
}
|
46 |
</style>
|
47 |
""", unsafe_allow_html=True)
|
48 |
|
49 |
-
#
|
50 |
-
|
51 |
-
{"text": "What's your most
|
52 |
-
{"text": "How do you
|
53 |
-
{"text": "Describe your ideal
|
54 |
-
{"text": "What's
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
]
|
56 |
|
57 |
-
def
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
'absolutes': 0,
|
62 |
-
'negativity': 0
|
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 |
-
try:
|
96 |
-
if analysis['humor_score'] > 15:
|
97 |
-
report['type'] = "The Resilient Jester 🃏"
|
98 |
-
report['strengths'] = ["Stress diffuser", "Creative thinker"]
|
99 |
-
report['tips'] = [
|
100 |
-
"🎯 Use humor to reframe challenges",
|
101 |
-
"🧘♂️ Balance jokes with mindfulness",
|
102 |
-
"📅 Schedule 'serious time' daily",
|
103 |
-
"🎭 Channel creativity productively",
|
104 |
-
"🤔 Challenge 'all-or-nothing' thoughts",
|
105 |
-
"📝 Journal funny observations",
|
106 |
-
"🌅 Start day with positive affirmation",
|
107 |
-
"🎉 Reward small achievements",
|
108 |
-
"🧩 Break tasks into fun-sized chunks",
|
109 |
-
"🔄 Replace 'never' with 'sometimes'"
|
110 |
-
]
|
111 |
-
else:
|
112 |
-
report['type'] = "The Thoughtful Strategist 🧭"
|
113 |
-
report['strengths'] = ["Analytical mind", "Detail-oriented"]
|
114 |
-
report['tips'] = [
|
115 |
-
"😄 Schedule daily laughter breaks",
|
116 |
-
"🌈 Visualize positive outcomes",
|
117 |
-
"🗣️ Practice positive self-talk",
|
118 |
-
"🎯 Set micro-goals daily",
|
119 |
-
"🧘♀️ Try 5-minute mindfulness",
|
120 |
-
"📚 Read humorous content",
|
121 |
-
"🔄 Reframe 'problems' as 'challenges'",
|
122 |
-
"🎁 Reward progress, not perfection",
|
123 |
-
"🤝 Share worries with friends",
|
124 |
-
"✨ Celebrate small wins"
|
125 |
-
]
|
126 |
-
|
127 |
-
# Generate inspirational quote
|
128 |
-
quote_response = client.chat.completions.create(
|
129 |
-
model="mixtral-8x7b-32768",
|
130 |
-
messages=[{"role": "user", "content": f"Generate inspirational quote about {report['type']}"}]
|
131 |
-
)
|
132 |
-
report['quote'] = quote_response.choices[0].message.content
|
133 |
-
|
134 |
-
except Exception as e:
|
135 |
-
st.error(f"Error generating report: {str(e)}")
|
136 |
-
|
137 |
-
return report
|
138 |
-
|
139 |
-
def create_pdf_report(report):
|
140 |
-
buffer = io.BytesIO()
|
141 |
-
p = canvas.Canvas(buffer, pagesize=letter)
|
142 |
-
p.setFont("Helvetica-Bold", 16)
|
143 |
-
p.drawString(100, 750, "🌟 Your Personality Report 🌟")
|
144 |
-
|
145 |
-
y_position = 700
|
146 |
-
p.setFont("Helvetica", 12)
|
147 |
-
for line in [
|
148 |
-
f"Personality Type: {report['type']}",
|
149 |
-
"",
|
150 |
-
"Top Strengths:",
|
151 |
-
*[f"- {strength}" for strength in report['strengths']],
|
152 |
-
"",
|
153 |
-
"Growth Tips:",
|
154 |
-
*[f"{i+1}. {tip}" for i, tip in enumerate(report['tips'])],
|
155 |
-
"",
|
156 |
-
f"Inspirational Quote: {report['quote']}"
|
157 |
-
]:
|
158 |
-
p.drawString(100, y_position, line)
|
159 |
-
y_position -= 15
|
160 |
-
|
161 |
-
p.save()
|
162 |
-
buffer.seek(0)
|
163 |
-
return buffer
|
164 |
|
165 |
-
#
|
166 |
-
if 'current_q' not in st.session_state:
|
167 |
-
st.session_state.current_q = 0
|
168 |
if 'responses' not in st.session_state:
|
169 |
st.session_state.responses = []
|
170 |
-
if '
|
171 |
-
st.session_state.
|
|
|
|
|
172 |
|
173 |
# Main UI
|
174 |
-
st.title("
|
175 |
-
st.markdown("###
|
176 |
|
177 |
-
# Progress
|
178 |
-
progress = st.session_state.current_q / len(
|
179 |
st.markdown(f"""
|
180 |
-
<div style="background: #f0f2f6; border-radius: 15px; padding: 5px;
|
181 |
-
<div class="progress-bar" style="width: {progress
|
182 |
</div>
|
183 |
""", unsafe_allow_html=True)
|
184 |
|
185 |
-
#
|
186 |
-
if
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
|
199 |
-
|
200 |
-
|
201 |
-
st.session_state.
|
202 |
-
st.
|
203 |
-
|
204 |
-
|
205 |
-
st.rerun()
|
206 |
else:
|
207 |
-
#
|
208 |
-
|
209 |
-
report = generate_personality_report(analysis)
|
210 |
-
|
211 |
-
# Show report
|
212 |
st.balloons()
|
213 |
-
st.success("🎉 Personality Analysis Complete!")
|
214 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
215 |
col1, col2 = st.columns(2)
|
216 |
with col1:
|
217 |
-
st.markdown(
|
218 |
-
|
219 |
-
# {report['type']}
|
220 |
-
""")
|
221 |
-
st.markdown(f"### 💬 Inspirational Quote:")
|
222 |
-
st.info(f'"{report["quote"]}"')
|
223 |
-
|
224 |
with col2:
|
225 |
-
st.markdown("###
|
226 |
-
for
|
227 |
-
st.markdown(f"-
|
228 |
-
|
229 |
-
st.markdown("### 📈 Resilience Score")
|
230 |
-
st.metric(label="", value=f"{analysis['resilience']}/100")
|
231 |
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
# PDF Download
|
239 |
-
pdf = create_pdf_report(report)
|
240 |
-
st.download_button(
|
241 |
-
label="📥 Download Full Report",
|
242 |
-
data=pdf,
|
243 |
-
file_name="personality_report.pdf",
|
244 |
-
mime="application/pdf"
|
245 |
-
)
|
246 |
|
247 |
-
|
248 |
-
st.session_state.clear()
|
249 |
-
st.rerun()
|
250 |
|
251 |
# Sidebar
|
252 |
with st.sidebar:
|
|
|
253 |
st.markdown("""
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
4. Get 10 growth tips
|
259 |
-
5. Download/share report!
|
260 |
|
261 |
-
**
|
262 |
-
-
|
263 |
-
-
|
264 |
-
-
|
265 |
-
- 📥 PDF report download
|
266 |
""")
|
|
|
|
2 |
import streamlit as st
|
3 |
from groq import Groq
|
4 |
from textblob import TextBlob
|
5 |
+
from transformers import pipeline
|
6 |
+
import numpy as np
|
7 |
import re
|
8 |
+
import random
|
9 |
from reportlab.lib.pagesizes import letter
|
10 |
from reportlab.pdfgen import canvas
|
11 |
import io
|
12 |
|
13 |
+
# Initialize components
|
14 |
+
groq_client = Groq(api_key=st.secrets["GROQ_API_KEY"])
|
15 |
+
personality_classifier = pipeline("text-classification", model="j-hartmann/emotion-english-distilroberta-base")
|
16 |
+
big5_model = pipeline("text-classification", model="digitalepidemiologylab/bigfive-personality-traits")
|
17 |
|
18 |
# Configure Streamlit
|
19 |
+
st.set_page_config(page_title="🧠 Personality Prodigy", layout="wide", page_icon="🤖")
|
20 |
|
21 |
# Custom CSS
|
22 |
st.markdown("""
|
23 |
<style>
|
24 |
+
@keyframes rainbow {
|
25 |
+
0% { color: #ff0000; }
|
26 |
+
20% { color: #ff8000; }
|
27 |
+
40% { color: #ffff00; }
|
28 |
+
60% { color: #00ff00; }
|
29 |
+
80% { color: #0000ff; }
|
30 |
+
100% { color: #ff00ff; }
|
31 |
}
|
32 |
|
33 |
+
.personality-title {
|
34 |
+
animation: rainbow 3s infinite;
|
35 |
+
font-size: 2.5em !important;
|
|
|
36 |
}
|
37 |
|
38 |
.progress-bar {
|
39 |
height: 25px;
|
40 |
border-radius: 15px;
|
41 |
+
background: linear-gradient(90deg, #FF6B6B 0%, #4ECDC4 100%);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
42 |
}
|
43 |
</style>
|
44 |
""", unsafe_allow_html=True)
|
45 |
|
46 |
+
# Dynamic questions pool
|
47 |
+
QUESTION_BANK = [
|
48 |
+
{"text": "What's your most creative procrastination method? 🎨🛌", "trait": "openness"},
|
49 |
+
{"text": "How do you react when plans change suddenly? 🌪️🤔", "trait": "neuroticism"},
|
50 |
+
{"text": "Describe your ideal weekend vs reality 🏝️🛠️", "trait": "extraversion"},
|
51 |
+
{"text": "What's your 'guilty pleasure' productivity hack? 🍫📈", "trait": "conscientiousness"},
|
52 |
+
{"text": "How do you comfort a stressed friend? 🤗💬", "trait": "agreeableness"},
|
53 |
+
{"text": "What would you do if you were invisible for a day? 👻🎭", "trait": "openness"},
|
54 |
+
{"text": "Your reaction to unexpected criticism? 🥊💡", "trait": "neuroticism"},
|
55 |
+
{"text": "Plan a party vs enjoy quiet night? 🎉📚", "trait": "extraversion"},
|
56 |
+
{"text": "How do you handle missed deadlines? ⌛🤷", "trait": "conscientiousness"},
|
57 |
+
{"text": "Describe your perfect collaboration 👥✨", "trait": "agreeableness"}
|
58 |
]
|
59 |
|
60 |
+
def get_dynamic_questions(responses):
|
61 |
+
"""Select questions based on emerging personality patterns"""
|
62 |
+
if len(responses) == 0:
|
63 |
+
return random.sample(QUESTION_BANK, 5)
|
|
|
|
|
|
|
64 |
|
65 |
+
traits = analyze_big5("\n".join(responses))
|
66 |
+
dominant_trait = max(traits, key=traits.get)
|
67 |
+
return [q for q in QUESTION_BANK if q['trait'] == dominant_trait][:3] + random.sample(QUESTION_BANK, 2)
|
68 |
+
|
69 |
+
def analyze_big5(text):
|
70 |
+
"""Analyze Big Five personality traits using OCEAN model"""
|
71 |
+
result = big5_model(text[:512])[0]
|
72 |
+
return {label.split("_")[1].lower(): score for label, score in zip(result['label'], result['score'])}
|
73 |
+
|
74 |
+
def analyze_emotions(text):
|
75 |
+
"""Detect emotional tone using RoBERTa"""
|
76 |
+
return personality_classifier(text[:512])
|
77 |
+
|
78 |
+
def generate_quote(traits):
|
79 |
+
"""Generate personality-specific quote using Groq/Mistral"""
|
80 |
+
prompt = f"""Create a motivational quote for someone with these traits:
|
81 |
+
{traits}
|
82 |
+
Make it inspirational, funny, and include an emoji."""
|
83 |
|
84 |
+
response = groq_client.chat.completions.create(
|
85 |
+
model="mixtral-8x7b-32768",
|
86 |
+
messages=[{"role": "user", "content": prompt}],
|
87 |
+
temperature=0.7
|
88 |
+
)
|
89 |
+
return response.choices[0].message.content
|
90 |
+
|
91 |
+
def generate_tips(traits):
|
92 |
+
"""Generate evidence-based psychological tips"""
|
93 |
+
tips = []
|
94 |
+
if traits['openness'] > 0.7:
|
95 |
+
tips.extend(["🎨 Try creative cross-training (write a poem about your work)",
|
96 |
+
"🌍 Learn something new daily about different cultures"])
|
97 |
+
if traits['neuroticism'] > 0.6:
|
98 |
+
tips.extend(["🧘 Practice box breathing: 4s in, 4s hold, 4s out",
|
99 |
+
"📝 Keep a worry journal to externalize anxieties"])
|
100 |
+
return tips[:10] # Return top 10 tips
|
101 |
+
|
102 |
+
def create_personality_report(responses):
|
103 |
+
"""Generate comprehensive personality analysis"""
|
104 |
+
text = "\n".join(responses)
|
105 |
+
return {
|
106 |
+
"big5": analyze_big5(text),
|
107 |
+
"emotions": analyze_emotions(text),
|
108 |
+
"quote": generate_quote(analyze_big5(text)),
|
109 |
+
"tips": generate_tips(analyze_big5(text))
|
110 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
111 |
|
112 |
+
# Session state management
|
|
|
|
|
113 |
if 'responses' not in st.session_state:
|
114 |
st.session_state.responses = []
|
115 |
+
if 'current_q' not in st.session_state:
|
116 |
+
st.session_state.current_q = 0
|
117 |
+
if 'questions' not in st.session_state:
|
118 |
+
st.session_state.questions = get_dynamic_questions([])
|
119 |
|
120 |
# Main UI
|
121 |
+
st.title("🧠 Personality Prodigy")
|
122 |
+
st.markdown("### Your AI-Powered Mirror for Self-Discovery 🔍✨")
|
123 |
|
124 |
+
# Progress tracker
|
125 |
+
progress = st.session_state.current_q / len(st.session_state.questions)
|
126 |
st.markdown(f"""
|
127 |
+
<div style="background: #f0f2f6; border-radius: 15px; padding: 5px;">
|
128 |
+
<div class="progress-bar" style="width: {progress*100}%; height: 25px;"></div>
|
129 |
</div>
|
130 |
""", unsafe_allow_html=True)
|
131 |
|
132 |
+
# Dynamic question flow
|
133 |
+
if st.session_state.current_q < len(st.session_state.questions):
|
134 |
+
q = st.session_state.questions[st.session_state.current_q]
|
135 |
+
|
136 |
+
with st.chat_message("assistant"):
|
137 |
+
st.markdown(f"### {q['text']}")
|
138 |
+
st.markdown(f"*What's your answer?* {'🤔' if q['trait'] in ['neuroticism','conscientiousness'] else '😄'}")
|
139 |
+
|
140 |
+
user_input = st.text_input("Your response:", key=f"q{st.session_state.current_q}")
|
141 |
+
|
142 |
+
if st.button("Next ➡️"):
|
143 |
+
st.session_state.responses.append(user_input)
|
144 |
+
st.session_state.current_q += 1
|
145 |
|
146 |
+
# Update questions based on responses
|
147 |
+
if st.session_state.current_q == len(st.session_state.questions):
|
148 |
+
st.session_state.questions = get_dynamic_questions(st.session_state.responses)
|
149 |
+
st.session_state.current_q = 0
|
150 |
+
|
151 |
+
st.rerun()
|
|
|
152 |
else:
|
153 |
+
# Generate and display report
|
154 |
+
report = create_personality_report(st.session_state.responses)
|
|
|
|
|
|
|
155 |
st.balloons()
|
|
|
156 |
|
157 |
+
st.markdown(f"## <div class='personality-title'>🌟 Your Personality Report 🌟</div>", unsafe_allow_html=True)
|
158 |
+
|
159 |
+
# Big Five Traits Visualization
|
160 |
+
with st.expander("🔍 Big Five Personality Traits"):
|
161 |
+
cols = st.columns(5)
|
162 |
+
traits = report['big5']
|
163 |
+
for i, (trait, score) in enumerate(traits.items()):
|
164 |
+
cols[i].metric(label=trait.upper(), value=f"{score:.0%}",
|
165 |
+
help=f"{['Low','Moderate','High'][int(score//0.33)]} {trait}")
|
166 |
+
|
167 |
+
# Emotional Analysis
|
168 |
+
with st.expander("🎭 Emotional Tone Analysis"):
|
169 |
+
emotion = max(report['emotions'], key=lambda x: x['score'])
|
170 |
+
st.markdown(f"**Dominant Emotion**: {emotion['label']} ({emotion['score']:.0%})")
|
171 |
+
st.progress(emotion['score'])
|
172 |
+
|
173 |
+
# Personalized Content
|
174 |
col1, col2 = st.columns(2)
|
175 |
with col1:
|
176 |
+
st.markdown("### 💬 Your Personality Quote")
|
177 |
+
st.success(f'"{report["quote"]}"')
|
|
|
|
|
|
|
|
|
|
|
178 |
with col2:
|
179 |
+
st.markdown("### 🛠️ Growth Strategies")
|
180 |
+
for tip in report['tips'][:5]:
|
181 |
+
st.markdown(f"- {tip}")
|
|
|
|
|
|
|
182 |
|
183 |
+
# Downloadable Report
|
184 |
+
pdf_buffer = io.BytesIO()
|
185 |
+
p = canvas.Canvas(pdf_buffer, pagesize=letter)
|
186 |
+
p.drawString(100, 750, f"Personality Report - {datetime.now().strftime('%Y-%m-%d')}")
|
187 |
+
# ... [Add PDF content creation logic] ...
|
188 |
+
p.save()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
189 |
|
190 |
+
st.download_button("📥 Download Full Report", data=pdf_buffer, file_name="personality_report.pdf")
|
|
|
|
|
191 |
|
192 |
# Sidebar
|
193 |
with st.sidebar:
|
194 |
+
st.markdown("## 🌈 How It Works")
|
195 |
st.markdown("""
|
196 |
+
1. Answer dynamic personality questions
|
197 |
+
2. Get real-time psychological analysis
|
198 |
+
3. Receive personalized growth strategies
|
199 |
+
4. Download/share your unique report
|
|
|
|
|
200 |
|
201 |
+
**Scientific Backing:**
|
202 |
+
- Big Five Personality Model (OCEAN)
|
203 |
+
- Emotion Recognition (RoBERTa)
|
204 |
+
- Cognitive Behavioral Therapy (CBT)
|
|
|
205 |
""")
|
206 |
+
|