Spaces:
Sleeping
Sleeping
import streamlit as st | |
import requests | |
import os | |
import json | |
import pandas as pd | |
import plotly.graph_objects as go | |
import plotly.express as px | |
import time | |
from datetime import datetime, timedelta | |
import random | |
import nltk | |
from nltk.corpus import stopwords | |
from wordcloud import WordCloud | |
import matplotlib.pyplot as plt | |
from streamlit_lottie import st_lottie | |
import base64 | |
from PIL import Image | |
import io | |
# Download NLTK data | |
nltk.download('stopwords', quiet=True) | |
nltk.download('punkt', quiet=True) | |
# Set page config | |
st.set_page_config(page_title="DSEAP", page_icon="📊", layout="wide") | |
# Custom CSS for styling | |
st.markdown(""" | |
<style> | |
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;700&display=swap'); | |
.stApp { | |
background: #f0f2f6; | |
font-family: 'Roboto', sans-serif; | |
} | |
.header { | |
font-size: 42px; | |
font-weight: bold; | |
color: #1e3799; | |
text-align: center; | |
margin-bottom: 30px; | |
text-shadow: 2px 2px 4px rgba(0,0,0,0.1); | |
} | |
.subheader { | |
font-size: 28px; | |
font-weight: bold; | |
color: #3c6382; | |
text-align: center; | |
margin-bottom: 25px; | |
} | |
.section { | |
background: white; | |
padding: 25px; | |
border-radius: 15px; | |
box-shadow: 0px 8px 16px rgba(0, 0, 0, 0.1); | |
margin-bottom: 30px; | |
} | |
.footer { | |
text-align: center; | |
font-size: 14px; | |
color: #555; | |
margin-top: 30px; | |
padding: 10px; | |
border-top: 1px solid #ddd; | |
} | |
.stProgress > div > div > div > div { | |
background-image: linear-gradient(to right, #4a69bd, #6a89cc); | |
} | |
.stButton>button { | |
background-color: #4a69bd; | |
color: white; | |
font-weight: bold; | |
border-radius: 5px; | |
padding: 10px 20px; | |
transition: all 0.3s ease; | |
} | |
.stButton>button:hover { | |
background-color: #1e3799; | |
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.2); | |
} | |
.animated-div { | |
background: linear-gradient(-45deg, #4a69bd, #6a89cc, #54a0ff, #5f27cd); | |
background-size: 400% 400%; | |
animation: gradient 15s ease infinite; | |
padding: 15px; | |
border-radius: 10px; | |
margin-bottom: 15px; | |
color: white; | |
font-weight: bold; | |
} | |
@keyframes gradient { | |
0% {background-position: 0% 50%;} | |
50% {background-position: 100% 50%;} | |
100% {background-position: 0% 50%;} | |
} | |
.info-box { | |
background-color: #e3f2fd; | |
border-left: 5px solid #2196f3; | |
padding: 15px; | |
margin-bottom: 20px; | |
border-radius: 5px; | |
} | |
.warning-box { | |
background-color: #fff3e0; | |
border-left: 5px solid #ff9800; | |
padding: 15px; | |
margin-bottom: 20px; | |
border-radius: 5px; | |
} | |
</style> | |
""", unsafe_allow_html=True) | |
# Function to load Lottie animations | |
def load_lottieurl(url: str): | |
r = requests.get(url) | |
if r.status_code != 200: | |
return None | |
return r.json() | |
# Load Lottie animations | |
lottie_analytics = load_lottieurl("https://assets5.lottiefiles.com/packages/lf20_qp1q7mct.json") | |
lottie_skills = load_lottieurl("https://assets5.lottiefiles.com/private_files/lf30_wqypnpu5.json") | |
# Function to call the Together AI model | |
def call_ai_model(prompt): | |
url = "https://api.together.xyz/v1/chat/completions" | |
payload = { | |
"model": "NousResearch/Nous-Hermes-2-Yi-34B", | |
"temperature": 1.05, | |
"top_p": 0.9, | |
"top_k": 50, | |
"repetition_penalty": 1, | |
"n": 1, | |
"messages": [{"role": "user", "content": prompt}], | |
"stream_tokens": True, | |
} | |
TOGETHER_API_KEY = os.getenv('TOGETHER_API_KEY') | |
if TOGETHER_API_KEY is None: | |
raise ValueError("TOGETHER_API_KEY environment variable not set.") | |
headers = { | |
"accept": "application/json", | |
"content-type": "application/json", | |
"Authorization": f"Bearer {TOGETHER_API_KEY}", | |
} | |
try: | |
response = requests.post(url, json=payload, headers=headers, stream=True) | |
response.raise_for_status() | |
full_response = "" | |
for line in response.iter_lines(): | |
if line: | |
line_content = line.decode('utf-8') | |
if line_content.startswith("data: "): | |
line_content = line_content[6:] | |
try: | |
json_data = json.loads(line_content) | |
if "choices" in json_data: | |
delta = json_data["choices"][0]["delta"] | |
if "content" in delta: | |
full_response += delta["content"] | |
except json.JSONDecodeError: | |
continue | |
return full_response.strip() | |
except requests.exceptions.RequestException as e: | |
st.error(f"API call failed: {e}") | |
return "An error occurred while fetching AI insights." | |
# Function to generate simulated data | |
def generate_simulated_data(categories, count=5): | |
return {cat: [random.randint(1, 100) for _ in range(count)] for cat in categories} | |
# Function to create word cloud | |
def create_word_cloud(text): | |
stopwords = set(stopwords.words('english')) | |
wordcloud = WordCloud(width=800, height=400, background_color='white', stopwords=stopwords).generate(text) | |
fig, ax = plt.subplots(figsize=(10, 5)) | |
ax.imshow(wordcloud, interpolation='bilinear') | |
ax.axis('off') | |
return fig | |
# Function to create a downloadable Excel report | |
def create_excel_report(data): | |
output = io.BytesIO() | |
with pd.ExcelWriter(output, engine='xlsxwriter') as writer: | |
for sheet_name, df in data.items(): | |
df.to_excel(writer, sheet_name=sheet_name, index=False) | |
output.seek(0) | |
return output | |
# Function for animated progress bar | |
def animated_progress_bar(): | |
progress_bar = st.progress(0) | |
status_text = st.empty() | |
phrases = [ | |
"Empowering youth with digital skills...", | |
"Unlocking your potential...", | |
"Building a brighter future...", | |
"Connecting skills to opportunities...", | |
"Transforming lives through technology..." | |
] | |
for i in range(100): | |
progress_bar.progress(i + 1) | |
status_text.text(random.choice(phrases)) | |
time.sleep(0.05) | |
status_text.text("Ready to empower!") | |
time.sleep(0.5) | |
status_text.empty() | |
progress_bar.empty() | |
# Streamlit app layout | |
st.markdown('<div class="header">Digital Skills and Employment Analytics Platform (DSEAP)</div>', unsafe_allow_html=True) | |
st.markdown('<div class="subheader">Empowering Youth Through Data-Driven Insights</div>', unsafe_allow_html=True) | |
# Sidebar for navigation | |
st.sidebar.title("Navigation") | |
page = st.sidebar.radio("Go to", ["Home", "Skills Analysis", "Program Evaluation", "Barrier Identification", "Recommendations", "Reports"]) | |
if page == "Home": | |
animated_progress_bar() | |
col1, col2 = st.columns([2, 1]) | |
with col1: | |
st.markdown('<div class="section">', unsafe_allow_html=True) | |
st.subheader("Welcome to DSEAP") | |
st.write(""" | |
The Digital Skills and Employment Analytics Platform (DSEAP) is an AI-driven tool designed to enhance | |
the evaluation and improvement of digital empowerment programs in Kenya. Our platform provides comprehensive | |
insights into the demand for digital skills, the effectiveness of existing programs, and the barriers faced | |
by youth in accessing digital opportunities. **A study In cmputing and prgramming** | |
""") | |
st.markdown('</div>', unsafe_allow_html=True) | |
with col2: | |
st_lottie(lottie_analytics, height=300, key="analytics") | |
st.markdown('<div class="section">', unsafe_allow_html=True) | |
st.subheader("Key Features") | |
col1, col2, col3 = st.columns(3) | |
with col1: | |
st.markdown("### 📊 Skills Demand Analysis") | |
st.write("Analyze job market trends and identify in-demand digital skills.") | |
with col2: | |
st.markdown("### 📈 Program Effectiveness") | |
st.write("Evaluate the impact of digital empowerment programs on youth employment.") | |
with col3: | |
st.markdown("### 🚧 Barrier Identification") | |
st.write("Identify and address obstacles to digital skill acquisition and employment.") | |
st.markdown('</div>', unsafe_allow_html=True) | |
st.markdown('<div class="info-box">', unsafe_allow_html=True) | |
st.info("📌 **Tip:** Use the sidebar to navigate through different sections of the platform.") | |
st.markdown('</div>', unsafe_allow_html=True) | |
elif page == "Skills Analysis": | |
animated_progress_bar() | |
st.markdown('<div class="section">', unsafe_allow_html=True) | |
st.subheader("Digital Skills Demand Analysis") | |
col1, col2 = st.columns([3, 1]) | |
with col1: | |
skills = st.multiselect("Select skills to analyze:", | |
["Data Analysis", "Web Development", "Digital Marketing", "Cybersecurity", "Cloud Computing", "AI/Machine Learning", "Mobile App Development", "UI/UX Design"]) | |
regions = st.multiselect("Select regions:", | |
["Kisii", "Nyamira", "Nairobi", "Mombasa", "Kisumu", "Nakuru", "Eldoret", "Thika", "Malindi", "Kitale"]) | |
time_period = st.selectbox("Select time period:", ["Last 3 months", "Last 6 months", "Last year"]) | |
with col2: | |
st_lottie(lottie_skills, height=200, key="skills") | |
if st.button("Analyze Skills Demand"): | |
with st.spinner("Analyzing skills demand..."): | |
# Simulated data generation (optimized) | |
demand_data = {skill: [random.randint(1, 100) for _ in regions] for skill in skills} | |
# Plotting (single chart instead of multiple) | |
df = pd.DataFrame(demand_data, index=regions) | |
fig = px.bar(df, barmode='group', title="Digital Skills Demand by Region") | |
st.plotly_chart(fig, use_container_width=True) | |
# AI Insights (with timeout) | |
ai_prompt = f"Briefly analyze the demand for {', '.join(skills)} in {', '.join(regions)} over the {time_period}. You can be negative on some skills too, just be free. Provide key insights on trends and gaps. Each region with its analysis and use percentages sometimes" | |
try: | |
with st.spinner("Generating AI insights..."): | |
ai_insights = call_ai_model(ai_prompt) | |
st.markdown("### AI Insights") | |
st.write(ai_insights) | |
except Exception as e: | |
st.error(f"Failed to generate AI insights: {str(e)}") | |
# Word Cloud (optional) | |
if st.checkbox("Generate Word Cloud"): | |
word_cloud_text = " ".join(skills + regions + ai_insights.split()) | |
st.markdown("### Skills Demand Word Cloud") | |
st.pyplot(create_word_cloud(word_cloud_text)) | |
# Skills growth projection (simplified) | |
st.markdown("### Skills Growth Projection") | |
growth_data = {skill: [random.uniform(0, 15) for _ in range(2)] for skill in skills} | |
years = [datetime.now().year, datetime.now().year + 5] | |
df_growth = pd.DataFrame(growth_data, index=years) | |
fig_growth = px.line(df_growth, title="Projected Skills Growth (5 Year Projection)") | |
st.plotly_chart(fig_growth, use_container_width=True) | |
st.markdown('</div>', unsafe_allow_html=True) | |
elif page == "Program Evaluation": | |
animated_progress_bar() | |
st.markdown('<div class="section">', unsafe_allow_html=True) | |
st.subheader("Digital Empowerment Program Evaluation") | |
programs = st.multiselect("Select programs to evaluate:", | |
["Ajira Digital", "Remotasks", "Upwork", "Fiverr", "Andela", "Emobiles", "snaphub", "iBizAfrica"]) | |
metrics = st.multiselect("Select evaluation metrics:", | |
["Employment Rate", "Income Increase", "Skill Proficiency", "Program Completion Rate", "Job Satisfaction", "Career Advancement"]) | |
if st.button("Evaluate Programs"): | |
with st.spinner("Evaluating programs..."): | |
# Simulated data generation | |
evaluation_data = generate_simulated_data(programs) | |
# Plotting | |
df = pd.DataFrame(evaluation_data) | |
fig = px.line(df, x=df.index, y=df.columns, labels={'index': 'Time (months)', 'value': 'Performance'}, title="Program Performance Over Time") | |
fig.update_layout(legend_title_text='Programs') | |
st.plotly_chart(fig) | |
# AI Insights | |
ai_prompt = f"Evaluate the effectiveness of {', '.join(programs)} based on {', '.join(metrics)}. Provide a detailed analysis of each program's performance, strengths, weaknesses, and recommendations for improvement." | |
ai_insights = call_ai_model(ai_prompt) | |
st.markdown("### AI-Powered Evaluation Insights") | |
st.write(ai_insights) | |
# Impact Visualization | |
impact_data = {prog: random.uniform(0, 1) for prog in programs} | |
fig = px.pie(values=list(impact_data.values()), names=list(impact_data.keys()), title="Program Impact Distribution") | |
st.plotly_chart(fig) | |
# Comparative Analysis | |
st.markdown("### Comparative Analysis") | |
comp_data = pd.DataFrame({metric: [random.uniform(0, 100) for _ in programs] for metric in metrics}, index=programs) | |
fig = px.imshow(comp_data, text_auto=True, aspect="auto", title="Program Performance Heatmap") | |
st.plotly_chart(fig) | |
st.markdown('</div>', unsafe_allow_html=True) | |
elif page == "Barrier Identification": | |
animated_progress_bar() | |
st.markdown('<div class="section">', unsafe_allow_html=True) | |
st.subheader("Digital Skills Acquisition Barriers") | |
barrier_categories = ["Access to Technology", "Digital Literacy", "Financial Constraints", "Cultural Factors", "Education System", "Gender Disparity", "Infrastructure", "Language Barriers"] | |
selected_barriers = st.multiselect("Select barrier categories to analyze:", barrier_categories) | |
if st.button("Identify Barriers"): | |
with st.spinner("Analyzing barriers..."): | |
# Simulated data generation | |
barrier_data = generate_simulated_data(selected_barriers) | |
# Plotting | |
fig = go.Figure(data=[go.Scatterpolar( | |
r=[max(barrier_data[cat]) for cat in selected_barriers], | |
theta=selected_barriers, | |
fill='toself' | |
)]) | |
fig.update_layout( | |
polar=dict( | |
radialaxis=dict(visible=True), | |
), | |
showlegend=False | |
) | |
fig.update_layout(title="Barrier Intensity Analysis") | |
st.plotly_chart(fig) | |
# AI Insights | |
ai_prompt = f"with a precise answer, not so long and well structured for easy understanding. Analyze the barriers to digital skills acquisition in Kenya, focusing on {', '.join(selected_barriers)}. Provide a comprehensive breakdown of each barrier, its impact, and potential solutions." | |
ai_insights = call_ai_model(ai_prompt) | |
st.markdown("### AI-Generated Barrier Analysis") | |
st.write(ai_insights) | |
# Recommendations | |
st.markdown("### Recommended Interventions") | |
interventions = { | |
"Access to Technology": "Implement mobile learning programs and community technology centers", | |
"Digital Literacy": "Integrate digital skills into primary and secondary education curricula", | |
"Financial Constraints": "Provide scholarships and low-interest loans for digital skills training", | |
"Cultural Factors": "Develop culturally sensitive training materials and awareness campaigns", | |
"Education System": "Partner with local schools for early digital education integration", | |
"Gender Disparity": "Create women-focused digital skills programs and mentorship opportunities", | |
"Infrastructure": "Invest in rural broadband expansion and solar-powered internet kiosks", | |
"Language Barriers": "Develop multilingual digital learning resources and interfaces" | |
} | |
for barrier in selected_barriers: | |
st.write(f"- **{barrier}:** {interventions.get(barrier, 'Customized intervention based on specific barrier characteristics')}") | |
# Barrier Impact Over Time | |
st.markdown("### Projected Barrier Impact Over Time") | |
years = [datetime.now().year + i for i in range(5)] | |
impact_data = {barrier: [random.uniform(0, 100) for _ in range(5)] for barrier in selected_barriers} | |
fig = go.Figure() | |
for barrier, impact in impact_data.items(): | |
fig.add_trace(go.Scatter(x=years, y=impact, mode='lines+markers', name=barrier)) | |
fig.update_layout(title="Projected Barrier Impact (Next 5 Years)", xaxis_title="Year", yaxis_title="Impact Score") | |
st.plotly_chart(fig) | |
st.markdown('</div>', unsafe_allow_html=True) | |
elif page == "Recommendations": | |
animated_progress_bar() | |
st.markdown('<div class="section">', unsafe_allow_html=True) | |
st.subheader("Personalized Recommendations") | |
# User profile input | |
st.write("Enter your profile information to receive personalized recommendations:") | |
age = st.slider("Age", 15, 35, 25) | |
education = st.selectbox("Highest Education Level", ["High School", "Diploma", "Bachelor's", "Master's", "PhD"]) | |
current_skills = st.multiselect("Current Digital Skills", | |
["Basic Computer Use", "Office Software", "Web Browsing", "Social Media", | |
"Programming", "Data Analysis", "Graphic Design", "Digital Marketing"]) | |
career_goal = st.text_input("Career Goal") | |
location = st.selectbox("Current Location", ["Nairobi", "Mombasa", "Kisumu", "Nakuru", "Eldoret", "Kisii", "Nyamira"]) | |
if st.button("Get Recommendations"): | |
with st.spinner("Generating personalized recommendations..."): | |
# AI-generated recommendations | |
ai_prompt = f"""Generate personalized digital skills recommendations for a {age}-year-old with {education} education, | |
skills in {', '.join(current_skills)}, located in {location}, aiming for a career in {career_goal}. | |
Provide a detailed learning path, skill priorities, job market insights, and potential challenges to overcome. Well structured for easy understanding""" | |
recommendations = call_ai_model(ai_prompt) | |
st.markdown("### Your Personalized Digital Skills Roadmap") | |
st.write(recommendations) | |
# Simulated skill gap analysis | |
st.markdown("### Skill Gap Analysis") | |
all_skills = ["Data Analysis", "Web Development", "Digital Marketing", "Cybersecurity", "Cloud Computing", | |
"AI/Machine Learning", "Mobile App Development", "UI/UX Design"] | |
skill_gaps = [skill for skill in all_skills if skill not in current_skills] | |
gap_scores = [random.randint(1, 100) for _ in skill_gaps] | |
fig = go.Figure(go.Bar( | |
x=skill_gaps, | |
y=gap_scores, | |
marker_color=['#1e3799', '#4a69bd', '#6a89cc', '#54a0ff', '#48dbfb'] | |
)) | |
fig.update_layout(title="Skill Gap Analysis", xaxis_title="Skills", yaxis_title="Proficiency Gap") | |
st.plotly_chart(fig) | |
# Job market alignment | |
st.markdown("### Job Market Alignment") | |
job_matches = ["Data Analyst", "Digital Marketing Specialist", "Front-end Developer", "UX Researcher", "Cybersecurity Analyst"] | |
match_scores = [random.uniform(0.5, 1) for _ in job_matches] | |
fig = px.bar(x=job_matches, y=match_scores, labels={'x': 'Job Titles', 'y': 'Match Score'}, title="Top Job Matches") | |
st.plotly_chart(fig) | |
# Learning resources | |
st.markdown("### Recommended Learning Resources") | |
resources = [ | |
{"name": "Coursera", "type": "Online Courses", "link": "https://www.coursera.org/"}, | |
{"name": "edX", "type": "Online Courses", "link": "https://www.edx.org/"}, | |
{"name": "Udacity", "type": "Nanodegree Programs", "link": "https://www.udacity.com/"}, | |
{"name": "FreeCodeCamp", "type": "Coding Tutorials", "link": "https://www.freecodecamp.org/"}, | |
{"name": "Codecademy", "type": "Interactive Coding Lessons", "link": "https://www.codecademy.com/"} | |
] | |
for resource in resources: | |
st.write(f"- [{resource['name']}]({resource['link']}) - {resource['type']}") | |
st.markdown('</div>', unsafe_allow_html=True) | |
elif page == "Reports": | |
animated_progress_bar() | |
st.markdown('<div class="section">', unsafe_allow_html=True) | |
st.subheader("Generate Custom Reports") | |
report_type = st.selectbox("Select Report Type", ["Skills Demand", "Program Effectiveness", "Barrier Analysis"]) | |
date_range = st.date_input("Select Date Range", [datetime.now() - timedelta(days=30), datetime.now()]) | |
if st.button("Generate Report"): | |
with st.spinner("Generating report..."): | |
# Simulated report generation | |
if report_type == "Skills Demand": | |
skills = ["Data Analysis", "Web Development", "Digital Marketing", "Cybersecurity", "Cloud Computing"] | |
demand_data = pd.DataFrame({ | |
"Skill": skills, | |
"Demand Score": [random.randint(50, 100) for _ in skills], | |
"Growth Rate": [random.uniform(0.5, 15) for _ in skills] | |
}) | |
st.markdown("### Skills Demand Report") | |
st.dataframe(demand_data) | |
fig = px.scatter(demand_data, x="Demand Score", y="Growth Rate", size="Demand Score", | |
color="Skill", hover_name="Skill", size_max=60) | |
fig.update_layout(title="Skills Demand vs Growth Rate") | |
st.plotly_chart(fig) | |
elif report_type == "Program Effectiveness": | |
programs = ["Ajira Digital", "DigiTruck", "eMobilis", "KamiLimu", "Andela"] | |
metrics = ["Employment Rate", "Income Increase", "Skill Proficiency", "Program Completion Rate"] | |
effectiveness_data = pd.DataFrame({ | |
metric: [random.uniform(60, 95) for _ in programs] for metric in metrics | |
}, index=programs) | |
st.markdown("### Program Effectiveness Report") | |
st.dataframe(effectiveness_data) | |
fig = px.imshow(effectiveness_data, text_auto=True, aspect="auto", | |
title="Program Effectiveness Heatmap") | |
st.plotly_chart(fig) | |
elif report_type == "Barrier Analysis": | |
barriers = ["Access to Technology", "Digital Literacy", "Financial Constraints", "Cultural Factors"] | |
impact_data = pd.DataFrame({ | |
"Barrier": barriers, | |
"Impact Score": [random.uniform(3, 9) for _ in barriers], | |
"Affected Population (%)": [random.uniform(10, 50) for _ in barriers] | |
}) | |
st.markdown("### Barrier Analysis Report") | |
st.dataframe(impact_data) | |
fig = px.bar(impact_data, x="Barrier", y="Impact Score", color="Affected Population (%)", | |
title="Barrier Impact Analysis") | |
st.plotly_chart(fig) | |
# Generate Excel report | |
excel_data = { | |
"Report": pd.DataFrame({"Report Type": [report_type], "Date Range": [f"{date_range[0]} to {date_range[1]}"]}) | |
} | |
if report_type == "Skills Demand": | |
excel_data["Skills Demand"] = demand_data | |
elif report_type == "Program Effectiveness": | |
excel_data["Program Effectiveness"] = effectiveness_data | |
elif report_type == "Barrier Analysis": | |
excel_data["Barrier Analysis"] = impact_data | |
excel_report = create_excel_report(excel_data) | |
st.download_button( | |
label="Download Excel Report", | |
data=excel_report, | |
file_name=f"DSEAP_{report_type}_Report_{date_range[0]}_{date_range[1]}.xlsx", | |
mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" | |
) | |
st.markdown('</div>', unsafe_allow_html=True) | |
# Footer | |
st.markdown('<div class="footer">© 2024 Digital Skills and Employment Analytics Platform (DSEAP) </div>', unsafe_allow_html=True) | |
# Add a warning about simulated data | |
st.markdown('<div class="warning-box">', unsafe_allow_html=True) | |
st.warning("**Note:** This is a prototype version Developed by Teresa Abuya, COD SIST") | |
st.markdown('</div>', unsafe_allow_html=True) |