Created
April 5, 2025 21:45
-
-
Save hakkm/b676b056594a1a7a84b18cf402f08bdb to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import streamlit as st | |
import requests | |
import pandas as pd | |
import matplotlib.pyplot as plt | |
from textblob import TextBlob | |
from datetime import datetime | |
from io import BytesIO | |
from fpdf import FPDF | |
# --- CONFIGURATION --- | |
OPENWEATHER_API_KEY = "YOUR_API_KEY" # Remplace avec ta clé OpenWeatherMap | |
# --- FONCTIONS --- | |
def get_air_quality(city): | |
url = f"http://api.openweathermap.org/data/2.5/air_pollution?appid={OPENWEATHER_API_KEY}&q={city}" | |
geocode_url = f"http://api.openweathermap.org/geo/1.0/direct?q={city}&limit=1&appid={OPENWEATHER_API_KEY}" | |
geo_res = requests.get(geocode_url).json() | |
if not geo_res: | |
return None | |
lat, lon = geo_res[0]['lat'], geo_res[0]['lon'] | |
air_url = f"http://api.openweathermap.org/data/2.5/air_pollution?lat={lat}&lon={lon}&appid={OPENWEATHER_API_KEY}" | |
res = requests.get(air_url) | |
if res.status_code == 200: | |
return res.json()['list'][0] | |
return None | |
def fake_social_comments(city): | |
return [ | |
f"The air in {city} is terrible today!", | |
f"I love how walkable {city} is.", | |
f"Too much traffic in downtown {city}...", | |
f"Great use of solar energy in {city}!", | |
f"{city} needs more bike lanes." | |
] | |
def analyze_sentiment(comments): | |
results = [] | |
for comment in comments: | |
blob = TextBlob(comment) | |
sentiment = blob.sentiment.polarity | |
results.append({"comment": comment, "sentiment": sentiment}) | |
return results | |
def summarize_report(air_data, sentiment_data): | |
avg_sentiment = sum(d['sentiment'] for d in sentiment_data) / len(sentiment_data) | |
quality_index = air_data['main']['aqi'] if air_data else 'Unknown' | |
if avg_sentiment > 0.3: | |
mood = "Generally positive social feedback." | |
elif avg_sentiment < -0.3: | |
mood = "Widespread dissatisfaction in social media." | |
else: | |
mood = "Mixed or neutral sentiments." | |
report = f"Air Quality Index: {quality_index}\nSocial Sentiment Score: {avg_sentiment:.2f}\nAnalysis: {mood}" | |
return report | |
def generate_sentiment_chart(data): | |
df = pd.DataFrame(data) | |
fig, ax = plt.subplots() | |
df['sentiment'].plot(kind='bar', color='skyblue', ax=ax) | |
ax.set_title("Sentiment Score per Comment") | |
ax.set_xticks(range(len(df))) | |
ax.set_xticklabels([f"{i+1}" for i in range(len(df))]) | |
ax.set_ylabel("Sentiment Polarity") | |
st.pyplot(fig) | |
def generate_pdf_report(city, air_data, sentiment_data, summary): | |
pdf = FPDF() | |
pdf.add_page() | |
pdf.set_font("Arial", size=12) | |
pdf.cell(200, 10, txt=f"Ville Durable Report - {city}", ln=True, align='C') | |
pdf.ln(10) | |
pdf.set_font("Arial", 'B', 12) | |
pdf.cell(200, 10, txt="Résumé de l'analyse:", ln=True) | |
pdf.set_font("Arial", size=11) | |
pdf.multi_cell(0, 10, summary) | |
pdf.ln(5) | |
pdf.set_font("Arial", 'B', 12) | |
pdf.cell(200, 10, txt="Commentaires sociaux:", ln=True) | |
pdf.set_font("Arial", size=11) | |
for item in sentiment_data: | |
pdf.multi_cell(0, 10, f"{item['comment']} (Score: {item['sentiment']:.2f})") | |
buffer = BytesIO() | |
pdf.output(buffer) | |
buffer.seek(0) | |
return buffer | |
# --- STREAMLIT APP --- | |
st.set_page_config(page_title="Ville Durable Dashboard", layout="centered") | |
st.title("🌍 Ville Durable Dashboard") | |
city = st.text_input("Entrez le nom d'une ville:", value="Paris") | |
if st.button("Analyser"): | |
with st.spinner("Collecte des données..."): | |
air_data = get_air_quality(city) | |
comments = fake_social_comments(city) | |
sentiment_data = analyze_sentiment(comments) | |
summary = summarize_report(air_data, sentiment_data) | |
st.subheader("📋 Rapport Résumé") | |
st.code(summary) | |
st.subheader("📊 Graphique des sentiments") | |
generate_sentiment_chart(sentiment_data) | |
st.subheader("💬 Commentaires sociaux analysés") | |
for d in sentiment_data: | |
st.write(f"{d['comment']} (Sentiment: {d['sentiment']:.2f})") | |
pdf = generate_pdf_report(city, air_data, sentiment_data, summary) | |
st.download_button( | |
label="📥 Télécharger le rapport PDF", | |
data=pdf, | |
file_name=f"rapport_{city.lower()}.pdf", | |
mime="application/pdf" | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment