Останні пвідмленн

#1
Python / Порівняння Threading, Multipro...
Останй допис від Tuvze - ер. 30, 2026, 02:20 PM
У Python concurrency (паралелізм) може значно підвищити продуктивність в I/O-інтенсивних або CPU-інтенсивних завданнях. Однак через обмеження GIL (Global Interpreter Lock) у Python важливо вибрати правильний підхід. У цій статті ми порівняємо підходи threading, multiprocessing та asyncio і покажемо сценарії, де кожен з них є найбільш підходящим, з реальним прикладом застосування.

1. Threading (Потоки)
  • Підходить для I/O-bound завдань (мережеві запити, читання/запис файлів).
  • Через GIL не забезпечує справжній паралелізм у CPU-bound завданнях.
  • Легкі та швидко запускаються.

Основний приклад:
import threading
import time

def dosya_indir(url):
    print(f"Шу url завантажується...")
    time.sleep(2)  # Симуляція мережевого запиту
    print(f"Шу url завершено.")

urls = ["site1.com", "site2.com", "site3.com", "site4.com"]
threads = []
for url in urls:
    t = threading.Thread(target=dosya_indir, args=(url,))
    threads.append(t)
    t.start()
for t in threads:
    t.join()
print("Усі завантаження завершено.")

2. Multiprocessing (Багатопроцесність)
  • Забезпечує справжній паралелізм для CPU-bound завдань (GIL не впливає).
  • Кожен процес використовує окремий простір пам'яті → більше споживання пам'яті.
  • Для обміну даними потрібні структури, такі як Queue, Pipe, Manager.

Приклад CPU-інтенсивного завдання:
from multiprocessing import Process, cpu_count
import time

def hesapla(n):
    toplam = 0
    for i in range(n):
        toplam += i ** 2
    print(f" {n} для результату: {toplam}")

if __name__ == "__main__":
    sayilar = [10_000_000] * cpu_count()
    processes = []
    for sayi in sayilar:
        p = Process(target=hesapla, args=(sayi,))
        processes.append(p)
        p.start()
    for p in processes:
        p.join()
    print("Усі обчислення завершено.")

3. Asyncio (Асинхронне програмування)
  • Сучасний і найпотужніший підхід (особливо в Python 3.7+).
  • Керує тисячами паралельних завдань в одному потоці.
  • Найефективніший метод для I/O-bound завдань (мережа, бази даних, виклики API).

Реалістичний приклад asyncio: Паралельне отримання даних з кількох API.
import asyncio
import aiohttp
import time

async def api_cagir(session, url):
    async with session.get(url) as response:
        data = await response.json()
        print(f"{url} -> {len(data)} елементів отримано")
        return data

async def ana():
    urls = [
        "https://jsonplaceholder.typicode.com/posts",
        "https://jsonplaceholder.typicode.com/comments",
        "https://jsonplaceholder.typicode.com/albums",
        "https://jsonplaceholder.typicode.com/photos"
    ]
    async with aiohttp.ClientSession() as session:
        gorevler = [api_cagir(session, url) for url in urls]
        sonuclar = await asyncio.gather(*gorevler)
        print(f"Всього {sum(len(s) for s in sonuclar)} елементів зібрано")

if __name__ == "__main__":
    basla = time.time()
    asyncio.run(ana())
    print(f"Загальний час: {time.time() - basla:.2f} секунд")

Який підхід використовувати коли? (Порівняння)
  • Найкраще використання: Для threading - I/O-bound; для multiprocessing - CPU-bound; для asyncio - I/O-bound (високий обсяг).
  • Справжній паралелізм: Для threading - Ні (GIL); для multiprocessing - Так; для asyncio - Ні (один потік).
  • Споживання пам'яті: Для threading - Низьке; для multiprocessing - Високе; для asyncio - Дуже низьке.
  • Вартість запуску: Для threading - Низька; для multiprocessing - Висока; для asyncio - Дуже низька.
  • Складність коду: Для threading - Середня; для multiprocessing - Висока; для asyncio - Середня-Висока.
  • Найпопулярніші бібліотеки: Для threading - requests + ThreadPoolExecutor; для multiprocessing - concurrent.futures; для asyncio - aiohttp, httpx, aiomysql.

Практичні рекомендації
  • Для невеликих-середніх I/O-завдань → asyncio (стандарт майбутнього).
  • Для важкої математики/обчислень → multiprocessing або concurrent.futures.ProcessPoolExecutor.
  • Для простих скриптів і швидких рішень → threading + ThreadPoolExecutor.

У нашому форумі ви можете поділитися своїми проектами concurrency, обговорити, який метод найкраще підходить для вашого сценарію використання.
#2
Python / Обробка даних в реальному часі...
Останй допис від Tuvze - ер. 06, 2026, 02:48 PM
Вступ
У 2026 році додатки, орієнтовані на дані, вже не можуть бути пакетними, вони мусять працювати в реальному часі. У цьому посібнику ми створимо з нуля Панель приладів для відстеження цін на криптовалюти в реальному часі:
  • FastAPI backend: Трансляція цін у реальному часі через WebSocket
  • Redis Pub/Sub: Керування потоком даних
  • Streamlit frontend: Інтерактивна панель приладів, що оновлюється миттєво
  • Plotly для професійних графіків
  • Pandas для швидкої обробки даних
  • Симульоване джерело даних (у реальності можна використовувати API Binance, CoinGecko)

Проект пропонує production-ready основу: масштабовану, чисту та сучасну.

Вимоги
Python 3.11+, Redis (легко з docker: docker run -p 6379:6379 redis)
pip install fastapi uvicorn redis websockets streamlit pandas plotly httpx py
1. Структура проекту
Цитувати(Тут оригінал не має детального опису структури, але зображення показує дерево файлів:
real-time-crypto-dashboard/
├── backend/
│  ├── main.py  # FastAPI app
│  ├── ws_manager.py  # WebSocket connection manager
│  ├── price_simulator.py
├── frontend/
│  ├── dashboard.py  # Streamlit app
└── requirements.txt
)

2. Backend: FastAPI + WebSockets + Redis
backend/ws_manager.py
from fastapi import WebSocket
from typing import List
import asyncio
import json

class ConnectionManager:
    def __init__(self):
        self.active_connections: List[WebSocket] = []

    async def connect(self, websocket: WebSocket):
        await websocket.accept()
        self.active_connections.append(websocket)

    def disconnect(self, websocket: WebSocket):
        self.active_connections.remove(websocket)

    async def broadcast(self, message: str):
        for connection in self.active_connections:
            await connection.send_text(message)

backend/price_simulator.py (симуляція замість реального API – якщо бажаєте, переведіть на WebSocket Binance)
import asyncio
import random
import json
from datetime import datetime

async def simulate_price_stream(manager: ConnectionManager, redis_client):
    symbols = ["BTCUSDT", "ETHUSDT", "SOLUSDT"]
    while True:
        for symbol in symbols:
            price = round(
                random.uniform(20000, 100000) if symbol == "BTCUSDT" else
                random.uniform(1000, 5000) if symbol == "ETHUSDT" else
                random.uniform(50, 300), 2
            )
            data = {
                "symbol": symbol,
                "price": price,
                "timestamp": datetime.utcnow().isoformat()
            }
            # Публікувати в Redis (інші сервіси можуть прослуховувати)
            await redis_client.publish("crypto_prices", json.dumps(data))
            # Пряма трансляція через WebSocket
            await manager.broadcast(json.dumps(data))
        await asyncio.sleep(1)  # Оновлення кожну 1 секунду

backend/main.py
from fastapi import FastAPI, WebSocket, WebSocketDisconnect
from fastapi.responses import HTMLResponse
import asyncio
import redis.asyncio as redis
from ws_manager import ConnectionManager
from price_simulator import simulate_price_stream
import os
from dotenv import load_dotenv

load_dotenv()

app = FastAPI()
manager = ConnectionManager()
redis_client = redis.from_url("redis://localhost:6379/0")

@app.on_event("startup")
async def startup_event():
    asyncio.create_task(simulate_price_stream(manager, redis_client))

@app.websocket("/ws/prices")
async def websocket_endpoint(websocket: WebSocket):
    await manager.connect(websocket)
    try:
        while True:
            await websocket.receive_text()  # Ми не хочемо повідомлень від клієнта, але
    except WebSocketDisconnect:
        manager.disconnect(websocket)

@app.get("/")
async def root():
    return {"message": "Backend панелі приладів криптовалют в реальному часі працює"}

3. Frontend: Streamlit Dashboard
frontend/dashboard.py
import streamlit as st
import pandas as pd
import plotly.graph_objects as go
import asyncio
import json
import websockets
from datetime import datetime
import threading

st.set_page_config(page_title="Панель приладів криптовалют в реальному часі 2026", layout="wide")

# Зберігання даних
if "price_data" not in st.session_state:
    st.session_state.price_data = {sym: pd.DataFrame(columns=["timestamp", "price"]) for sym in ["BTCUSDT", "ETHUSDT", "SOLUSDT"]}

async def listen_websocket():
    uri = "ws://localhost:8000/ws/prices"
    async with websockets.connect(uri) as websocket:
        while True:
            try:
                message = await websocket.recv()
                data = json.loads(message)
                symbol = data["symbol"]
                price = data["price"]
                ts = pd.to_datetime(data["timestamp"])
                new_row = pd.DataFrame({"timestamp": [ts], "price": [price]})
                st.session_state.price_data[symbol] = pd.concat([st.session_state.price_data[symbol], new_row], ignore_index=True).tail(300)  # Зберігати останні 300 записів
                # Тригер перезапуску Streamlit (не thread-safe, але для простої демо)
                st.rerun()
            except Exception as e:
                print(f"Помилка WebSocket: {e}")
                await asyncio.sleep(5)

# Запуск прослуховувача WebSocket у фоновому потоці
if "ws_thread" not in st.session_state:
    st.session_state.ws_thread = threading.Thread(
        target=lambda: asyncio.run(listen_websocket()), daemon=True
    )
    st.session_state.ws_thread.start()

st.title("Панель приладів криптовалют в реальному часі (2026)")

col1, col2 = st.columns(2)

for symbol in st.session_state.price_data:
    df = st.session_state.price_data[symbol]
    if not df.empty:
        with (col1 if symbol == "BTCUSDT" else col2):
            st.subheader(f"{symbol} - Остання ціна: ${df['price'].iloc[-1]:,.2f}")
            fig = go.Figure()
            fig.add_trace(go.Scatter(
                x=df["timestamp"],
                y=df["price"],
                mode='lines+markers',
                name=symbol,
                line=dict(color='royalblue' if symbol == "BTCUSDT" else 'orange')
            ))
            fig.update_layout(
                title=f"{symbol} Останні 5 хвилин",
                xaxis_title="Час",
                yaxis_title="Ціна (USDT)",
                height=400,
                template="plotly_dark" if st.get_option("theme.base") == "dark" else "plotly"
            )
            st.plotly_chart(fig, use_container_width=True)

st.markdown("---")
st.caption("Backend: FastAPI + WebSockets + Redis | Frontend: Streamlit | Версія: 1.0.0")

4. Запуск
Термінал 1: Запустіть Redis (з docker)
Термінал 2:
cd backend
uvicorn main:app --reload --port 8000

Термінал 3:
cd frontend
streamlit run dashboard.py

5. Поради для просунутих (2026)
• Реальні дані: Інтегруйте WebSocket з ccxt або binance-python
• Замість Redis: Масштабуйте з Kafka / RabbitMQ
• Замість Streamlit: Taipy або Solara (більш професійний UI)
• Docker Compose: Підніміть весь стек однією командою
• Аутентифікація: JWT + FastAPI Users
• Деплой: Render / Railway / Fly.io (є безкоштовні рівні)
#3
Python / Аналіз даних та візуалізація з...
Останй допис від Tuvze - Груд. 12, 2025, 06:56 PM
У 2025 році в Туреччині ніхто більше не створює зведені таблиці в Excel. Pandas + Plotly стали стандартом.

У цьому посібнику ми попрактикуємося з реальними даними про продажі (дані про електронну комерцію в Туреччині за 2020–2025 роки):
  • Очищення та аналіз даних за допомогою Pandas 2.2
  • Інтерактивні графіки за допомогою Plotly
  • Створення живого дашборду за 5 хвилин за допомогою Streamlit
  • Безкоштовне розгортання на Railway / Streamlit Cloud
  • Сумісність з мобільними пристроями + темний режим

1. Встановлення (найактуальніші пакети 2025 року)

python -m venv veri-dashboard
cd veri-dashboard
Scripts\activate
pip install pandas==2.2.2 plotly==5.22 streamlit==1.38 openpyxl python-dotenv

2. Приклад даних (satislar_2025.xlsx)
Приклад таблиці Excel:

[th]Дата[/th]
[th]Продукт[/th]
[th]Категорія[/th]
[th]Кількість[/th]
[th]Ціна[/th]
[th]Місто[/th]
[th]Оплата[/th]
2025-01-15iPhone 16Електроніка245000СтамбулКредит
2025-01-16СветрОдяг5850АнкараГотівка
.....................

3. Аналіз даних – analysis.py
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
from datetime import datetime
import locale

# Встановлення локалі для Туреччини 2025
locale.setlocale(locale.LC_TIME, 'tr_TR.UTF-8')

# Завантаження даних
df = pd.read_excel("satislar_2025.xlsx", parse_dates=["Tarih"])

# Очищення
df["Toplam"] = df["Adet"] * df["Fiyat"]
df["Ay"] = df["Tarih"].dt.strftime("%Y-%m")
df["Gün"] = df["Tarih"].dt.day_name(locale='tr_TR')

print("Загальний дохід:", f"₺{df['Toplam'].sum():,}")
print("Найпопулярніша категорія:", df.groupby("Kategori")["Adet"].sum().idxmax())

4. Інтерактивний дашборд – app.py (Streamlit)
import streamlit as st
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
from pathlib import Path

st.set_page_config(page_title="Дашборд продажів 2025", layout="wide", page_icon="📊")

# Темний режим
st.markdown("""
<style>
.css-1d391kg {padding-top: 1rem; padding-bottom: 3rem;}
.css-18e3th9 {padding-top: 1rem;}
</style>
""", unsafe_allow_html=True)

@st.cache_data
def load_data():
    df = pd.read_excel("satislar_2025.xlsx", parse_dates=["Tarih"])
    df["Toplam"] = df["Adet"] * df["Fiyat"]
    df["Ay"] = df["Tarih"].dt.strftime("%Y-%m")
    df["Ay Adı"] = df["Tarih"].dt.strftime("%B %Y")
    return df

df = load_data()

st.title("Дашборд продажів електронної комерції в Туреччині - 2025")
st.markdown("---")

# KPI
col1, col2, col3, col4 = st.columns(4)
total_revenue = df["Toplam"].sum()
total_orders = len(df)
avg_basket = total_revenue / total_orders if total_orders > 0 else 0
top_city = df["Şehir"].value_counts().index[0]

col1.metric("Загальний оборот", f"₺{total_revenue:,.0f}")
col2.metric("Загальна кількість замовлень", f"{total_orders:,}")
col3.metric("Середній чек", f"₺{avg_basket:,.0f}")
col4.metric("Найпопулярніше місто", top_city)

st.markdown("---")

# Тренд продажів за місяцями
col1, col2 = st.columns(2)
with col1:
    monthly = df.groupby("Ay")["Toplam"].sum().reset_index()
    template = "plotly_dark" if st.checkbox("Темний режим", True) else "plotly"
    fig = px.line(monthly, x="Ay", y="Toplam", title="Тренд обороту за місяцями", markers=True, template=template)
    fig.update_yaxes(title="Оборот (TL)", tickprefix="₺")
    st.plotly_chart(fig, use_container_width=True)

with col2:
    category = df.groupby("Kategori")["Toplam"].sum().reset_index()
    fig2 = px.pie(category, values="Toplam", names="Kategori", title="Розподіл продажів за категоріями")
    st.plotly_chart(fig2, use_container_width=True)

# Продажі за містами
st.subheader("Продажі за містами")
city_sales = df.groupby("Şehir")["Toplam"].sum().reset_index()
fig3 = px.bar(city_sales.sort_values("Toplam", ascending=False).head(10), x="Şehir", y="Toplam", title="Топ-10 міст за продажами")
st.plotly_chart(fig3, use_container_width=True)

# Таблиця + фільтри
st.subheader("Детальна таблиця продажів")
kategori_sec = st.multiselect("Оберіть категорію", df["Kategori"].unique(), default=df["Kategori"].unique())
sehir_sec = st.multiselect("Оберіть місто", df["Şehir"].unique(), default=df["Şehir"].unique())
filtered = df[df["Kategori"].isin(kategori_sec) & df["Şehir"].isin(sehir_sec)]
st.dataframe(filtered, use_container_width=True)

# Експорт в Excel
csv = filtered.to_csv(index=False).encode('utf-8')
st.download_button("Завантажити Excel", csv, "satislar_filtreli.csv", "text/csv")

5. Запуск


streamlit run app.py
# http://localhost:8501


6. Безкоштовне розгортання (2 варіанти)
Варіант 1: Streamlit Cloud (30 секунд)

git init
git add .
git commit -m "first"
# streamlit.io → New app → Підключіть репозиторій GitHub → Deploy
# https://satis-dashboard-2025.streamlit.app


Варіант 2: Railway.app

railway login
railway init
railway up
# Автоматичне розгортання

7. Продуктивність (2025)

[th]Інструмент[/th]
[th]Час розгортання[/th]
[th]Сумісність з мобільними[/th]
[th]Інтерактивність[/th]
[th]Вартість[/th]
Power BI10+ хвилинСередняСередня$10/міс
Tableau15+ хвилинГарнаГарна$70/міс
Streamlit + Plotly30 секундВідміннаВідміннаБезкоштовно

Висновок
Цей дашборд пропонує:
  • Фільтрацію в реальному часі
  • Сумісність з мобільними та десктопними пристроями
  • Експорт в Excel
  • Темний режим
  • Живий за 5 хвилин
  • Готовий для презентації керівництву!

Повний вихідний код (працюючий):
https://github.com/kullanicin/veri-dashboard-2025

Жива демонстрація:
https://satis-dashboard-2025.streamlit.app
#4
Delphi / Підручник з Delphi: Перевірка ...
Останй допис від Tuvze - Mar 03, 2025, 05:11 PM
#5
Delphi / Підручник з Delphi: Постійні З...
Останй допис від Tuvze - Mar 03, 2025, 05:10 PM
#6
Delphi / Підручник з Delphi: як викорис...
Останй допис від Tuvze - Mar 03, 2025, 05:10 PM
#7
Delphi / Підручник з Delphi: основні ма...
Останй допис від Tuvze - Mar 03, 2025, 05:09 PM
#8
Flutter / Посібник Flutter: вирівнювання...
Останй допис від Tuvze - Mar 03, 2025, 05:07 PM
#9
Flutter / Підручник Flutter: колонка (Ві...
Останй допис від Tuvze - Mar 03, 2025, 05:07 PM
#10
Perl / Підручник з Perl: оператори пр...
Останй допис від Tuvze - Mar 03, 2025, 05:04 PM