Stat_2025 / app.py
fruitpicker01's picture
Update app.py
e6644f0 verified
raw
history blame
5.61 kB
import gradio as gr
import pandas as pd
import plotly.express as px
# Ссылки на CSV-файлы
URL_DASHA = "https://raw.githubusercontent.com/fruitpicker01/Storage_Dasha_2025/main/messages.csv"
URL_LERA = "https://raw.githubusercontent.com/fruitpicker01/Storage_Lera_2025/main/messages.csv"
URL_SVETA = "https://raw.githubusercontent.com/fruitpicker01/Storage_Sveta_2025/main/messages.csv"
# Функция для чтения данных, подсчёта уникальных SMS и подготовки данных для графиков
def read_and_process_data(url, user_name):
df = pd.read_csv(url, na_values=["Не выбрано"])
# Оставляем только нужные столбцы (если какие-то отсутствуют — пропускаем аккуратно)
cols = ["gender", "generation", "industry", "opf", "timestamp"]
df = df[[col for col in cols if col in df.columns]].copy()
# Убираем дубликаты по gender, generation, industry, opf
df_unique = df.drop_duplicates(subset=["gender", "generation", "industry", "opf"])
# Считаем абсолютное количество уникальных SMS
unique_count = len(df_unique)
# Готовим столбец date
if "timestamp" in df_unique.columns:
# Переводим timestamp в datetime
df_unique["timestamp"] = pd.to_numeric(df_unique["timestamp"], errors='coerce')
df_unique["date"] = pd.to_datetime(df_unique["timestamp"], unit="s", origin="unix", errors='coerce').dt.date
else:
df_unique["date"] = pd.NaT
# Группируем по дате, считаем, сколько уникальных SMS приходится на каждую дату
# (снова нужно учесть комбинацию gender, generation, industry, opf)
# Но т.к. мы уже отфильтровали уникальные, достаточно просто groupby date
df_daily = df_unique.groupby("date").size().reset_index(name="count")
df_daily["user"] = user_name # чтобы потом можно было объединить данные для всех
return unique_count, df_daily
def process_data():
# Считываем и обрабатываем все три репозитория
dasha_count, dasha_daily = read_and_process_data(URL_DASHA, "Даша")
lera_count, lera_daily = read_and_process_data(URL_LERA, "Лера")
sveta_count, sveta_daily = read_and_process_data(URL_SVETA, "Света")
# Суммарные значения
total_count = dasha_count + lera_count + sveta_count
# Считаем % (округлим до целого)
# Каждое хранилище: процент относительно 117
dasha_percent = round((dasha_count / 117) * 100) if 117 else 0
lera_percent = round((lera_count / 117) * 100) if 117 else 0
sveta_percent = round((sveta_count / 117) * 100) if 117 else 0
# Суммарный % от 702
total_percent = round((total_count / 702) * 100) if 702 else 0
# Формируем HTML с "прогресс-барами"
# Простейшая полоска: ширина = процент, внутри пишем "X SMS (Y%)"
def get_progress_bar(label, abs_val, pct):
return f"""
<div style='margin-bottom: 1em;'>
<div><strong>{label}</strong></div>
<div style='width: 100%; background-color: #ddd; text-align: left;'>
<div style='width: {pct}%; background-color: #4CAF50; padding: 5px 0;'>
&nbsp;{abs_val} SMS ({pct}%)
</div>
</div>
</div>
"""
bars_html = (
get_progress_bar("Даша", dasha_count, dasha_percent) +
get_progress_bar("Лера", lera_count, lera_percent) +
get_progress_bar("Света", sveta_count, sveta_percent) +
get_progress_bar("Всего", total_count, total_percent)
)
# Делаем один общий DataFrame для построения графика:
daily_all = pd.concat([dasha_daily, lera_daily, sveta_daily], ignore_index=True)
# Уберём строки, где date может быть NaT (если timestamp некорректный)
daily_all = daily_all.dropna(subset=["date"])
# Построим столбчатую диаграмму, показывающую, кто в какой день сколько сохранил SMS
# (уникальных по комбинации gender, generation, industry, opf)
fig = px.bar(
daily_all,
x="date",
y="count",
color="user",
title="Количество уникальных SMS по датам",
labels={"date": "Дата", "count": "Количество SMS", "user": "Пользователь"},
barmode="group"
)
return bars_html, fig
# Создаём интерфейс Gradio
with gr.Blocks() as demo:
gr.Markdown("<h2>Подсчёт уникальных SMS для Даши, Леры и Светы</h2>")
btn = gr.Button("Обновить данные и показать результат")
html_output = gr.HTML(label="Прогресс-бары (Количество SMS и %)")
plot_output = gr.Plot(label="График количества уникальных SMS по датам")
btn.click(fn=process_data, outputs=[html_output, plot_output])
if __name__ == "__main__":
demo.launch()