{"id":437605,"date":"2024-11-07T03:00:35","date_gmt":"2024-11-07T03:00:35","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=437605"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=437605","title":{"rendered":"<span>Telegram-\u0431\u043e\u0442 \u0434\u043b\u044f \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u0442\u0435\u043a\u0441\u0442\u0430 | \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0442\u0435\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0433\u0440\u0443\u043f\u043f<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h2>\u041f\u0440\u0435\u0434\u044b\u0441\u0442\u043e\u0440\u0438\u044f<\/h2>\n<p>\u0411\u0443\u043a\u0432\u0430\u043b\u044c\u043d\u043e \u043c\u0435\u0441\u044f\u0446 \u043d\u0430\u0437\u0430\u0434, \u043c\u044b \u0441 \u043c\u043e\u0438\u043c \u043a\u043e\u043b\u043b\u0435\u0433\u043e\u0439 \u0443\u0447\u0430\u0441\u0442\u0432\u043e\u0432\u0430\u043b\u0438 \u0432 HAKATON. \u041d\u0430\u0448\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u0432\u0437\u044f\u043b\u0430\u0441\u044c \u0437\u0430 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443 \u043e\u0442 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 \u041c\u0422\u0421: \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0442\u044b\u0441\u044f\u0447 \u043e\u043f\u0440\u043e\u0441\u043e\u0432, \u043d\u0430\u0439\u0442\u0438 \u0443\u0441\u0440\u0435\u0434\u043d\u0435\u043d\u043d\u044b\u0439 \u0441\u0438\u043d\u043e\u043d\u0438\u043c \u043a \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438 \u043e\u0442\u0432\u0435\u0442\u043e\u0432 \u0438 \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e \u0432 \u0432\u0438\u0434\u0435 \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u044b, \u043b\u0438\u0431\u043e \u043e\u0431\u043b\u0430\u043a\u0430 \u0441\u043b\u043e\u0432.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447\u0438 \u0438 \u0437\u0430\u0449\u0438\u0442\u044b \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043c\u044b \u0437\u0430\u0434\u0443\u043c\u0430\u043b\u0438\u0441\u044c:<\/p>\n<blockquote>\n<p>&#171;<em>\u0410 \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u0434\u0430\u043d\u043d\u0443\u044e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0441\u0432\u044f\u0437\u0430\u0442\u044c \u0441 \u0442\u0433 \u0431\u043e\u0442\u043e\u043c?&#187;<\/em><\/p>\n<\/blockquote>\n<p>\u041a\u0430\u043a \u0440\u0430\u0437 \u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e, \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u044d\u0442\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c.<\/p>\n<h2>\u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u0432 github<\/h2>\n<p><a href=\"https:\/\/github.com\/onevay\/Tg_Bot_Topic_Analyze\/tree\/main\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/onevay\/Tg_Bot_Topic_Analyze\/tree\/main<\/a><\/p>\n<h2>\u042d\u0442\u0430\u043f\u044b \u0440\u0430\u0431\u043e\u0442\u044b<\/h2>\n<ul>\n<li>\n<p>\u0412\u044b\u0431\u043e\u0440 \u0441\u0442\u0435\u043a\u0430<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 &#171;\u043a\u043d\u043e\u043f\u043e\u043a \u0438 \u0441\u044b\u0440\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430&#187;<\/p>\n<\/li>\n<li>\n<p>\u0411\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445<\/p>\n<\/li>\n<li>\n<p>\u0412\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u0442\u0435\u043a\u0441\u0442\u0430<\/p>\n<\/li>\n<li>\n<p>\u041e\u0444\u043e\u0440\u043c\u043b\u0435\u043d\u0438\u0435 \u0438 \u0434\u043e\u0440\u0430\u0431\u043e\u0442\u043a\u0430<\/p>\n<\/li>\n<\/ul>\n<h2>\u041a\u0440\u0430\u0442\u043a\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430<\/h2>\n<p>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u0430\u043d\u043a\u0435\u0442\u0443, \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u044e\u0442\u0441\u044f \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445. \u0414\u0430\u043b\u0435\u0435, \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c csv-\u0444\u0430\u0439\u043b \u0441 \u0431\u043e\u043b\u044c\u0448\u0438\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u0442\u0435\u043a\u0441\u0442\u0430, \u0431\u043e\u0442 \u043f\u0440\u043e\u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442 \u0438 \u043e\u0442\u0432\u0435\u0442\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442, \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0438\u0439 \u0438\u0437 \u0434\u0432\u0443\u0445 \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c:<\/p>\n<p>\u041f\u0435\u0440\u0432\u0430\u044f \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u0441\u043b\u043e\u0432\u0430 \u043a\u0430\u0436\u0434\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b, \u043e\u0442\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u043e \u0441\u0432\u043e\u0435\u0439 \u0437\u043d\u0430\u0447\u0438\u043c\u043e\u0441\u0442\u0438.\u0412\u0442\u043e\u0440\u0430\u044f \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0430 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u044d\u0442\u0438 \u0433\u0440\u0443\u043f\u043f\u044b \u0432 \u043f\u0440\u043e\u0446\u0435\u043d\u0442\u043d\u043e\u043c \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0438.<\/p>\n<p>\u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f, \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441 \u0432 chat gpt, \u0433\u0434\u0435 \u0442\u043e\u0442 \u043d\u0430\u0439\u0434\u0435\u0442 \u043a\u0430\u0436\u0434\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u0435 \u0441\u043b\u043e\u0432 \u0441\u0432\u043e\u044e \u0442\u0435\u043c\u0443.<\/p>\n<h2>\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 aiogram<\/h2>\n<p>aiogram &#8212; \u044d\u0442\u043e \u043c\u043e\u0449\u043d\u044b\u0439  \u0438 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0439 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0439 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0431\u043e\u0442\u043e\u0432 \u0432 Telegram \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 python. \u041e\u043d \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 Telegram Bot API.<\/p>\n<p><strong>\u041e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430 aiogram<\/strong>:<\/p>\n<ol>\n<li>\n<p><em>\u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0441\u0442\u044c<\/em>. \u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0431\u043e\u0442\u0443 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e, \u043d\u0435 \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0434\u0440\u0443\u0433\u0438\u0445 \u0437\u0430\u0434\u0430\u0447.<\/p>\n<\/li>\n<li>\n<p><em>\u0413\u0438\u0431\u043a\u043e\u0441\u0442\u044c.<\/em> \u041f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 \u0434\u043b\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0431\u043e\u0442\u0430.  \u041e\u043d \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439, \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u044b (inline \u0438 reply), \u043a\u043e\u043b\u043b\u0431\u044d\u043a\u0438 \u0438 \u043c\u043d\u043e\u0433\u043e\u0435 \u0434\u0440\u0443\u0433\u043e\u0435.<\/p>\n<\/li>\n<li>\n<p><em>\u041f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439 (FSM)<\/em>. \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0438\u043c\u0435\u0435\u0442 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u0443\u044e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0445 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u043e\u0432, \u0447\u0442\u043e \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u0431\u043e\u0442\u043e\u0432 \u0441 \u043c\u043d\u043e\u0433\u043e\u0448\u0430\u0433\u043e\u0432\u044b\u043c \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435\u043c \u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c.<\/p>\n<\/li>\n<li>\n<p><em>\u041c\u0438\u043d\u0438\u043c\u0430\u043b\u0438\u0437\u043c<\/em>. aiogram \u043d\u0435 \u043d\u0430\u0432\u044f\u0437\u044b\u0432\u0430\u0435\u0442 \u043b\u0438\u0448\u043d\u0438\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439, \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u0435\u0433\u043e \u043b\u0435\u0433\u043a\u0438\u043c \u0438 \u0431\u044b\u0441\u0442\u0440\u044b\u043c.<\/p>\n<\/p>\n<\/li>\n<\/ol>\n<h2>\u041d\u0430\u0447\u0430\u043b\u043e \u0440\u0430\u0431\u043e\u0442\u044b<\/h2>\n<p>\u0411\u044b\u043b\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u044b \u043c\u043e\u0434\u0443\u043b\u0438 \u0434\u043b\u044f \u0431\u043e\u043b\u0435\u0435 \u0443\u0434\u043e\u0431\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b.<\/p>\n<p><em>ha1.py<\/em><\/p>\n<pre><code class=\"python\">from aiogram import F, Router from aiogram.types import CallbackQuery, Message, ReplyKeyboardRemove, FSInputFile from aiogram import filters from aiogram.enums import ParseMode import app.db as db import topic_funcs.gensi as gn from aiogram.fsm.context import FSMContext from aiogram.fsm.state import State, StatesGroup import re import topic_funcs.vizualize as viz import topic_funcs.probably as prob import topic_funcs.textb as req from decouple import config import app.keyboard as kb<\/code><\/pre>\n<p><em>keyboard.py<\/em><\/p>\n<pre><code class=\"python\">from aiogram.types import ReplyKeyboardMarkup, \\     KeyboardButton, InlineKeyboardButton, InlineKeyboardMarkup<\/code><\/pre>\n<p><em>db.py<\/em><\/p>\n<pre><code class=\"python\">import psycopg2 from decouple import config<\/code><\/pre>\n<p><em>main.py<\/em><\/p>\n<pre><code class=\"python\">from aiogram import Bot, Dispatcher import asyncio import logging import app.db as db from decouple import config from app.ha1 import router<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f Telegram-\u0431\u043e\u0442\u0430. <\/p>\n<pre><code class=\"python\">def extract_number(text):     match = re.search(r'\\b(\\d+)\\b', text)     if match:         return int(match.group(1))     else:         return None  class UserData(StatesGroup):     name: str = State()     age: int | None = State()     aim: str = State()     gender: str | None = State()  class TopicAnalize(StatesGroup):     start_analize: str = State()     choice_rezult = State()<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0432 \u0444\u0430\u0439\u043b\u0435 <em>ha1.py<\/em> \u043c\u044b \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <strong>extract_number()<\/strong>, \u0434\u043b\u044f \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u044f \u0432\u043e\u0437\u0440\u0430\u0441\u0442\u0430 \u0438\u0437 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u0432\u0432\u043e\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u041a\u043b\u0430\u0441\u0441 <strong>UserData(StatesGroup)<\/strong> \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0434\u043b\u044f FSM, \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0449\u0435\u0433\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u043c \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0430\u043d\u043a\u0435\u0442\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c. \u041a\u043b\u0430\u0441\u0441 <strong>TopicAnalize(StatesGroup)<\/strong> \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0434\u043b\u044f FSM, \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0449\u0435\u0433\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u043c \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u0442\u0435\u043c \u0442\u0435\u043a\u0441\u0442\u0430.<\/p>\n<pre><code class=\"python\">topic_start = InlineKeyboardMarkup(     inline_keyboard=[         [InlineKeyboardButton(text='\ud83d\ude80 \u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0432\u044b\u0434\u0435\u043b\u0438\u0442\u0435\u043b\u044c \u0442\u043e\u043f\u0438\u043a\u043e\u0432', callback_data='topic_start')]     ] )  ancet_start = InlineKeyboardMarkup(inline_keyboard=[     [InlineKeyboardButton(text='\ud83d\udcdd \u041f\u0440\u043e\u0439\u0442\u0438 \u0430\u043d\u043a\u0435\u0442\u0443', callback_data='anceta')],     [InlineKeyboardButton(text='\ud83d\ude80 \u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0432\u044b\u0434\u0435\u043b\u0438\u0442\u0435\u043b\u044c \u0442\u043e\u043f\u0438\u043a\u043e\u0432', callback_data='topic_start')] ])  check_data = InlineKeyboardMarkup(     inline_keyboard=[         [InlineKeyboardButton(text=\"\u2705 \u0412\u0441\u0435 \u0432\u0435\u0440\u043d\u043e\", callback_data='correct')],         [InlineKeyboardButton(text=\"\u274c \u0417\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0441\u043d\u0430\u0447\u0430\u043b\u0430\", callback_data='incorrect')]     ] )  air_foul = InlineKeyboardMarkup(     inline_keyboard=[         [InlineKeyboardButton(text='\ud83d\ude45\u200d\u2642\ufe0f \u041d\u0435 \u0445\u043e\u0447\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c', callback_data='air_foul')]     ] )  gen_button = ReplyKeyboardMarkup(     keyboard=[         [KeyboardButton(text='\ud83d\udc69\ud83c\udffb \u0416\u0435\u043d\u0449\u0438\u043d\u0430')],         [KeyboardButton(text='\ud83d\udc68\ud83c\udffb \u041c\u0443\u0436\u0447\u0438\u043d\u0430')]     ],     resize_keyboard=True,     one_time_keyboard=True,     input_field_placeholder='\ud83e\udd14 \u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0432\u0430\u0448 \u043f\u043e\u043b' )<\/code><\/pre>\n<p>\u0412 \u0444\u0430\u0439\u043b\u0435 <em>keyboard.py<\/em> \u043a\u043e\u0434 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0431\u043e\u0442\u0430, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0432\u044b\u0431\u043e\u0440 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u043e\u043f\u0446\u0438\u0439 \u0447\u0435\u0440\u0435\u0437 &#171;\u043a\u043d\u043e\u043f\u043a\u0438&#187;.<\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043e \u0444\u0430\u0439\u043b\u0435 <em>db.py,  <\/em>\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<pre><code class=\"python\">db_url = config('DB_URL') host = config('HOST') port = config('PORT') user = config('USER') password = config('PASSWORD') database = config('DB_NAME')  conn = psycopg2.connect(dbname=database, user=user, password=password, host=host, port=port) conn.autocommit = True<\/code><\/pre>\n<p><em>host = config(&#8216;HOST&#8217;), port = config(&#8216;PORT&#8217;), user = config(&#8216;USER&#8217;), password = config(&#8216;PASSWORD&#8217;), database = config(&#8216;DB_NAME&#8217;)<\/em>: \u042d\u0442\u0438 \u0441\u0442\u0440\u043e\u043a\u0438 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u044e\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a PostgreSQL \u0438\u0437 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f: <strong>HOST, PORT, USER, PASSWORD, DB_NAME.<\/strong><\/p>\n<p><em>conn = psycopg2.connect(dbname=database, user=user, password=password, host=host, port=port):<\/em>  \u042d\u0442\u043e \u043a\u043b\u044e\u0447\u0435\u0432\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0441 \u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b, \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0435 \u043d\u0430 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u044d\u0442\u0430\u043f\u0430\u0445. <\/p>\n<p><em>conn.autocommit = True:<\/em> \u042d\u0442\u0430 \u0441\u0442\u0440\u043e\u043a\u0430 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0439.  \u042d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442, \u0447\u0442\u043e \u043a\u0430\u0436\u0434\u043e\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438.<\/p>\n<pre><code class=\"python\">def create_table():     with conn.cursor() as cursor:         cursor.execute(\"\"\"CREATE TABLE IF NOT EXISTS users (                         id INT8 NOT NULL PRIMARY KEY,                         name VARCHAR(255) NOT NULL,                         age INT8 NOT NULL,                         gender VARCHAR(255) NOT NULL,                         aim VARCHAR(255));\"\"\")  def insert(id, test_dict):     if check_primary(id):         with conn.cursor() as cursor:             cursor.execute(f\"\"\"INSERT INTO users(id, name, age, gender, aim)                         VALUES ({id},'{test_dict[\"name\"]}',                         {test_dict[\"age\"]},                         '{test_dict[\"gender\"]}',                         '{test_dict[\"aim\"]}');\"\"\")     else:         with conn.cursor() as cursor:             cursor.execute(f\"\"\"UPDATE users SET id = {id}, name = '{test_dict[\"name\"]}', age = {test_dict[\"age\"]},                         gender = '{test_dict[\"gender\"]}', aim = '{test_dict[\"aim\"]}'                         WHERE id = {id};\"\"\")<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u0434\u0432\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438. <\/p>\n<p><em>create_table()<\/em> \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445, \u0435\u0441\u043b\u0438 \u043e\u043d\u0430 \u0435\u0449\u0451 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442.  <\/p>\n<p><em>insert()<\/em> \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043b\u0438 \u0443\u0436\u0435 \u0437\u0430\u043f\u0438\u0441\u044c \u0441 \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u043c <strong>id<\/strong>, \u0438 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0432\u0441\u0442\u0430\u0432\u043a\u0443 \u0438\u043b\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435.<\/p>\n<pre><code class=\"python\">def age_procent(test_dict):     with conn.cursor() as cursor:         cursor.execute(f\"\"\"SELECT ROUND(COUNT(CASE WHEN age = {test_dict[\"age\"]}THEN 1 END) * 100.0 \/ count(*), 2) AS fraction FROM users;\"\"\")         procent_age = cursor.fetchone()[0]         return procent  def gender_procent(test_dict):     with conn.cursor() as cursor:         cursor.execute(f\"\"\"SELECT ROUND(COUNT(CASE WHEN gender = {test_dict[\"gender\"]} THEN 1 END) * 100.0 \/ COUNT(*), 2) AS fraction FROM users;\"\"\")         procent_gender = cursor.fetchone()[0]         return procent_gender<\/code><\/pre>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u0438 <em>age_procent()<\/em> \u0438 <em>gender_procent()<\/em> \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 \u0432 \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u043d\u0442\u043d\u043e\u0435 \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435, \u0441\u0440\u0435\u0434\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435.<\/p>\n<pre><code class=\"python\">def check_primary(id):     with conn.cursor() as cursor:         cursor.execute(f\"\"\"SELECT id FROM users;\"\"\")         p = cursor.fetchall()         if p == None:             return True         lst = [int(i[0]) for i in p]     return True if id not in lst else False  def delete_user(id):     with conn.cursor() as cursor:         cursor.execute(f\"\"\"DELETE FROM users WHERE id = {id}\"\"\")  def print_data(id):     with conn.cursor() as cursor:         cursor.execute(f\"\"\"SELECT name, age, gender, aim FROM users WHERE id = {id};\"\"\")         return cursor.fetchone()<\/code><\/pre>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <em>check_primary()<\/em> \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441 \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u043c <strong>id<\/strong>.<\/p>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <em>delete_used()<\/em> \u0443\u0434\u0430\u043b\u044f\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0430\u0439\u0434\u0438 \u0438\u0437 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445, \u0435\u0441\u043b\u0438 \u043e\u043d \u0436\u0435 \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u0437\u0430\u043d\u043e\u0432\u043e \u0430\u043d\u043a\u0435\u0442\u0443.<\/p>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <em>print_data()<\/em> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0441 \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u043c <strong>id<\/strong>.<\/p>\n<p>\u0412\u0435\u0440\u043d\u0435\u043c\u0441\u044f \u043a \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c\u0443 <em>ha1.py<\/em><\/p>\n<pre><code class=\"python\">@router.message(filters.CommandStart()) async def start_bot(message: Message):     await message.answer(text='\u041f\u0440\u0438\u0432\u0435\u0442!\ud83d\ude01')     await message.answer(text='\u0422\u044b, \u043d\u0430\u0432\u0435\u0440\u043d\u043e\u0435, \u0437\u043d\u0430\u0435\u0448\u044c \u0446\u0435\u043b\u0438 \u043d\u0430\u0448\u0435\u0433\u043e \u0431\u043e\u0442\u0430\ud83d\ude42,\\n'                          '||\u043d\u043e \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \/help \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e \u043c\u043e\u0436\u0435\u0442 \u0442\u0435\u0431\u0435 \u043f\u043e\u043c\u043e\u0447\u044c||')     await message.answer(text='\u041f\u0435\u0440\u0435\u0434 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0439\u0442\u0438 \u0430\u043d\u043a\u0435\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\ud83d\ude42\\n'                          '||\u041c\u044b \u043d\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435, \u043e\u043d\u0438 \u043e\u0441\u0442\u0430\u043d\u0443\u0442\u0441\u044f \u043c\u0435\u0436\u0434\u0443 \u043d\u0430\u043c\u0438 (\u0434\u043b\u044f \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438)||', reply_markup=kb.ancet_start)  @router.message(filters.Command('help')) async def help(message: Message):     await message.answer(         text='\ud83d\udcda *\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b:*  \\n\\n'              '\ud83d\udd39 \/start - *\u043d\u0430\u0447\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0431\u043e\u0442\u043e\u043c*  \\n'              '\ud83d\udd39 \/help - *\u0432\u0441\u0435 \u043e\u0431\u044a\u044f\u0441\u043d\u0438\u0442*  \\n'              '\ud83d\udd39 \/ancet_fill - *\u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0430\u043d\u043a\u0435\u0442\u0443*  \\n'              '\ud83d\udd39 \/start_topic - *\u0430\u043d\u0430\u043b\u0438\u0437 \u0442\u0435\u043a\u0441\u0442\u0430*',         parse_mode=types.ParseMode.MARKDOWN_V2     ) @router.message(filters.Command('start_topic')) async def start_topic(message: Message):     await message.answer(text='\ud83d\ude80*\u0417\u0430\u043f\u0443\u0441\u043a \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u0442\u0435\u043c\u044b!*', parse_mode=types.ParseMode.MARKDOWN_V2, reply_markup=kb.topic_start)  @router.callback_query(F.data == 'anceta') async def cl_ancet_start(callback: CallbackQuery, state: FSMContext):     await callback.message.answer(text='\ud83d\udcdd *\u0414\u0430\u0432\u0430\u0439 \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c!*\\n'                                   '\ud83e\udd14 *\u041a\u0430\u043a \u0442\u0435\u0431\u044f \u0437\u043e\u0432\u0443\u0442?*', parse_mode=types.ParseMode.MARKDOWN_V2)     await state.set_state(UserData.name)     await callback.answer()  @router.message(F.text, UserData.name) async def get_name(message: Message, state: FSMContext):     await message.answer(text=f'\u0422\u0430\u043a, {message.text}, \u0430 \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u0435\u0431\u0435 \u043b\u0435\u0442?\ud83d\ude36')     await state.update_data(name=message.text)     await state.set_state(UserData.age)  @router.message(UserData.name) async def get_name_e(message: Message):     await message.answer(         text='\u274c *\u041e\u0448\u0438\u0431\u043a\u0430!*  \\n'              '\ud83e\udd37\u200d\u2642\ufe0f *\u0422\u044b \u044f\u0432\u043d\u043e \u0442\u043a\u043d\u0443\u043b \u043d\u0435 \u0442\u0443\u0434\u0430.*  \\n'              '\ud83d\udd04 *\u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0439 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0432\u0441\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0438 \u0432\u0432\u0435\u0434\u0438 \u0441\u0432\u043e\u0435 \u0438\u043c\u044f!*',         parse_mode=types.ParseMode.MARKDOWN_V2)   @router.message(F.text, UserData.age) async def get_age(message: Message, state: FSMContext):     if extract_number(message.text):         await state.update_data(age=extract_number(message.text))         procent = db.age_procent(message.text)         await message.answer(             text=f'\ud83c\udf89 *\u041f\u043e\u0441\u0447\u0438\u0442\u0430\u043b\u0438 \u0438 \u043f\u043e\u043d\u044f\u043b\u0438!*  \\n'                  f'\ud83d\udcca *\u0412\u0430\u0448 \u0432\u043e\u0437\u0440\u0430\u0441\u0442 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0435\u0442 \u0441 {procent}% \u043d\u0430\u0448\u0438\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439.*',             parse_mode=types.ParseMode.MARKDOWN_V2         )         await message.answer(             text='\ud83e\udd14 *\u0421 \u0432\u043e\u0437\u0440\u0430\u0441\u0442\u043e\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043b\u0438\u0441\u044c, \u043d\u0435\u043f\u043b\u043e\u0445\u043e \u0431\u044b \u0435\u0449\u0435 \u0438 \u0433\u0435\u043d\u0434\u0435\u0440 \u0443\u0437\u043d\u0430\u0442\u044c.*',             reply_markup=kb.gen_button,             parse_mode=types.ParseMode.MARKDOWN_V2         )         await state.set_state(UserData.gender)     else:         await message.answer(             text='\u274c *\u041d\u0435 \u043f\u043e\u0445\u043e\u0436\u0435 \u043d\u0430 \u043f\u0440\u0430\u0432\u0434\u0443!*  \\n'                  '\ud83d\ude15 *\u041c\u043e\u0436\u0435\u0442, \u0442\u044b \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0432\u0432\u043e\u0434\u0438\u0448\u044c? \u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0439 \u0435\u0449\u0435 \u0440\u0430\u0437.*',             parse_mode=types.ParseMode.MARKDOWN_V2         ) @router.message(F.text.in_(['\ud83d\udc69\ud83c\udffb \u0416\u0435\u043d\u0449\u0438\u043d\u0430', '\ud83d\udc68\ud83c\udffb \u041c\u0443\u0436\u0447\u0438\u043d\u0430']), UserData.gender) async def get_gender(message: Message, state: FSMContext):     await state.update_data(gender=message.text[2:].lower())     procent = db.gender_procent(message.text[2:])     await message.answer(         text=f'\ud83c\udf89 *\u041a\u043b\u0430\u0441\u0441!*  \\n'              f'\ud83e\udd1d *\u0422\u0432\u043e\u0439 \u043f\u043e\u043b \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0435\u0442 \u0441 \u043f\u043e\u043b\u043e\u043c {procent}% \u043d\u0430\u0448\u0438\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439.*',         reply_markup=ReplyKeyboardRemove(),         parse_mode=types.ParseMode.MARKDOWN_V2     )     await message.answer(         text='\ud83d\udcac *\u0420\u0430\u0441\u0441\u043a\u0430\u0436\u0438, \u043f\u043e\u0447\u0435\u043c\u0443 \u0440\u0435\u0448\u0438\u043b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430\u0448\u0438\u043c \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u043c?*',         reply_markup=kb.air_foul,         parse_mode=types.ParseMode.MARKDOWN_V2     )     await state.set_state(UserData.aim)  @router.message(UserData.gender) async def get_gender_e(message: Message):     await message.answer(         text='\u274c *\u041d\u0435 \u0437\u043d\u0430\u044e \u0442\u0430\u043a\u043e\u0433\u043e \u0433\u0435\u043d\u0434\u0435\u0440\u0430!*  \\n'              '\ud83d\udc49 \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u044b\u0431\u0435\u0440\u0438 \u0438\u0437 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0433\u043e \u0441\u043f\u0438\u0441\u043a\u0430.',         parse_mode=types.ParseMode.MARKDOWN_V2     ) @router.message(F.text, UserData.aim) async def get_air(message: Message, state: FSMContext):     await state.update_data(aim=message.text)     db.insert(message.chat.id, await state.get_data())     test_dict = db.print_data(message.chat.id)     await message.answer(         text='\ud83d\udccb *\u041f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435, \u0432\u0441\u0451 \u043b\u0438 \u0432\u0435\u0440\u043d\u043e:*  \\n\\n'              f'\ud83d\udc71\ud83c\udfa4 *\u0418\u043c\u044f:* `{test_dict[0]}`  \\n'              f'\ud83d\udd52 *\u0412\u043e\u0437\u0440\u0430\u0441\u0442:* `{test_dict[1]}`  \\n'              f'\ud83d\udebb *\u041f\u043e\u043b:* `{test_dict[2]}`  \\n'              f'\ud83d\udcac *\u041f\u043e\u0447\u0435\u043c\u0443 \u0440\u0435\u0448\u0438\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f:* `{test_dict[3]}`',         reply_markup=kb.check_data,         parse_mode=types.ParseMode.MARKDOWN_V2     )     await state.clear() @router.message(UserData.aim) async def get_air_e(message: Message):     await message.answer(         text='\u274c *\u0420\u0430\u0437\u0432\u0435 \u044d\u0442\u043e \u0446\u0435\u043b\u044c?*  \\n'              '\ud83d\udcdd \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u0432\u0435\u0434\u0438 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435!',         reply_markup=kb.air_foul,         parse_mode=types.ParseMode.MARKDOWN_V2     )  @router.callback_query(F.data == 'air_foul', UserData.aim) async def air_foul(callback: CallbackQuery, state: FSMContext):     await callback.message.answer(         text='\ud83d\ude14 *\u0416\u0430\u043b\u044c, \u0447\u0442\u043e \u043d\u0435 \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0435\u0448\u044c...*  \\n'     )     await state.update_data(aim=callback.message.text)     db.insert(callback.message.chat.id, await state.get_data())     test_dict = db.print_data(callback.message.chat.id)      await callback.message.answer(         text='\ud83d\udccb *\u041f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435, \u0432\u0441\u0451 \u043b\u0438 \u0432\u0435\u0440\u043d\u043e:*  \\n\\n'              f'\ud83d\udc71\u200d\ud83c\udfa4 *\u0418\u043c\u044f:* {test_dict[0]}  \\n'              f'\ud83d\udd52 *\u0412\u043e\u0437\u0440\u0430\u0441\u0442:* {test_dict[1]}  \\n'              f'\ud83d\udebb *\u041f\u043e\u043b:* {test_dict[2]}  \\n',         reply_markup=kb.check_data,         parse_mode=types.ParseMode.MARKDOWN_V2     )     await callback.answer()     await state.clear()  @router.callback_query(F.data == 'correct') async def correct(callback: CallbackQuery):     await callback.message.answer(         text='\ud83c\udf89 *\u041a\u043b\u0430\u0441\u0441!*  \\n'              '\ud83d\ude80 *\u0421\u0430\u043c\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u043e\u043c!*',         reply_markup=kb.topic_start,         parse_mode=types.ParseMode.MARKDOWN_V2     )     await callback.answer()  @router.callback_query(F.data == 'incorrect') async def incorrect(callback: CallbackQuery, state: FSMContext):     db.delete_user(callback.message.chat.id)     await callback.message.answer(         text='\ud83d\udd04 *\u0428\u0438\u043b\u043e \u043d\u0430 \u043c\u044b\u043b\u043e... \u0422\u043e \u0435\u0441\u0442\u044c, \u0432\u0432\u0435\u0434\u0438 \u0441\u0432\u043e\u0451 \u0438\u043c\u044f:*',         parse_mode=types.ParseMode.MARKDOWN_V2     )     await state.set_state(UserData.name)     await callback.answer()  @router.callback_query(F.data == 'topic_start') async def topic_start(callback: CallbackQuery):     if not db.check_primary(callback.message.chat.id):         await callback.message.answer(             text='\ud83d\udd04 *\u041e\u0431\u043d\u043e\u0432\u0443 \u0435\u0449\u0451 \u043d\u0435 \u0437\u0430\u0432\u0435\u0437\u043b\u0438...*  \\n'                  '\ud83c\udf1f \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u0435 \u0430\u043d\u043a\u0435\u0442\u0443.',             parse_mode=types.ParseMode.MARKDOWN_V2         )     else:         await callback.message.answer(             text='\u2757\ufe0f *\u041d\u0435 \u0432\u0438\u0436\u0443 \u0430\u043d\u043a\u0435\u0442\u0443 \u043e\u0442 \u0442\u0435\u0431\u044f,*  \\n'                  '\ud83d\udcdd *\u043d\u0443\u0436\u043d\u043e \u044d\u0442\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c!*',             reply_markup=kb.ancet_start,             parse_mode=types.ParseMode.MARKDOWN_V2         )     await callback.answer() @router.message(filters.Command('ancet_fill')) async def ancet_fill(message: Message):     await message.answer(         text='\ud83d\udcdd *\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0430\u043d\u043a\u0435\u0442\u0443:*  \\n'              '\u261d*\u0421 \u043d\u0443\u043b\u044f*  \\n'              '\u270c*\u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u043d\u0435\u0439*',         reply_markup=kb.ancet_start,         parse_mode=types.ParseMode.MARKDOWN_V2     )  @router.callback_query(F.data == 'topic_start') async def topic_start(callback: CallbackQuery):     await callback.message.answer(         text='\ud83d\udcc4 *\u041e\u0442\u043f\u0440\u0430\u0432\u044c \u043c\u043d\u0435 \u0444\u0430\u0439\u043b \u0434\u043b\u044f \u0430\u043d\u0430\u043b\u0438\u0437\u0430.*  \\n'              '\u26a0\ufe0f *\u0424\u0430\u0439\u043b, \u043a\u0441\u0442\u0430\u0442\u0438, \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0432 CSV \u0444\u043e\u0440\u043c\u0430\u0442\u0435.*',         parse_mode=types.ParseMode.MARKDOWN_V2     )   @router.message(F.document, TopicAnalize.start_analize) async def analyze(message: Message, state: FSMContext):     global res, lda_model, them_count, mydict, corpus, st     if '.csv' in message.document.file_name:         await message.answer(text='\u2705 *\u041f\u0440\u0438\u043d\u044f\u043b, \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e...*')         await message.bot.download(message.document.file_id, destination='..\/TG_BOT\/tgbot\/csv.csv')          with open('..\/TG_BOT\/tgbot\/csv.csv') as f:             st1 = f.read()          res, lda_model, them_count, mydict, corpus, st = gn.start(st1)          await message.answer(text=f'\ud83d\udd0d *\u0410\u043d\u0430\u043b\u0438\u0437 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d:*  \\n{res}', reply_markup=kb.rezult_choice)         await state.set_state(TopicAnalize.choice_rezult)     else:         await message.answer(text='\u274c *\u0412\u0438\u0434\u0438\u043c\u043e, \u0444\u0430\u0439\u043b \u043d\u0435 \u0442\u043e\u0433\u043e \u0444\u043e\u0440\u043c\u0430\u0442\u0430.*  \\n'                                   '\ud83d\udcc4 *\u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0439 \u0441\u043d\u043e\u0432\u0430 \u0441 CSV \u0444\u0430\u0439\u043b\u043e\u043c!*')   @router.message(TopicAnalize.start_analize) async def analyze_e(message: Message):     await message.reply(text='\u2757\ufe0f *\u0422\u044b \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0448\u044c\u0441\u044f \u0431\u043e\u0442\u043e\u043c... \u041e\u0434\u0443\u043c\u0430\u0439\u0441\u044f!*')   @router.message(F.text.startswith('\u0414\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0430'), TopicAnalize.choice_rezult) async def show_res(message: Message):     if message.text[-1] == '1':         if them_count &lt;= 6:             viz.plot_topic_distribution(lda_model, 3)         else:             viz.plot_topic_distribution(lda_model, 4)         await message.answer_photo(photo=FSInputFile('..\/TG_BOT\/tgbot\/res1.png'),                                    caption='\ud83d\udcca *\u0417\u0434\u0435\u0441\u044c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u0441\u0430\u043c\u044b\u0435 \u0437\u043d\u0430\u0447\u0438\u043c\u044b\u0435 \u0441\u043b\u043e\u0432\u0430 \u043a\u0430\u0436\u0434\u043e\u0439 \u0441\u043c\u044b\u0441\u043b\u043e\u0432\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b.*')     else:         prob.probably_topics(lda_model, mydict, them_count)         await message.answer_photo(photo=FSInputFile('..\/TG_BOT\/tgbot\/res2.png'),                                    caption='\ud83d\udcc8 *\u0417\u043d\u0430\u0447\u0438\u043c\u043e\u0441\u0442\u044c \u043a\u0430\u0436\u0434\u043e\u0439 \u043f\u043e\u0434\u0442\u0435\u043c\u044b \u0432 \u043e\u0431\u0449\u0435\u043c \u043c\u0430\u0441\u0441\u0438\u0432\u0435 \u043e\u0442\u0432\u0435\u0442\u043e\u0432.*')   @router.message(F.text.startswith('\u041f\u043e\u043b\u043d'), TopicAnalize.choice_rezult) async def full_list(message: Message):     await message.answer(text=f'\ud83d\udcc4 *\u041f\u043e\u043b\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u0442\u0432\u043e\u0438 \u043e\u0442\u0432\u0435\u0442\u044b:*  \\n{st}')   @router.message(F.text.startswith('\u0412\u044b\u0445'), TopicAnalize.choice_rezult) async def exit_analysis(message: Message, state: FSMContext):     await message.answer(text='\ud83d\udeaa *\u0412\u044b \u0432\u044b\u0448\u043b\u0438 \u0438\u0437 \u0440\u0435\u0436\u0438\u043c\u0430 \u0430\u043d\u0430\u043b\u0438\u0437\u0430.*', reply_markup=ReplyKeyboardRemove())     await message.answer(text='\ud83d\ude0a *\u041d\u043e \u043d\u0435 \u043e\u0433\u043e\u0440\u0447\u0430\u0439\u0442\u0435\u0441\u044c, \u0432\u044b \u0432\u0441\u0435\u0433\u0434\u0430 \u043c\u043e\u0436\u0435\u0442\u0435 \u0432\u0435\u0440\u043d\u0443\u0442\u044c\u0441\u044f \u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044e!*',                          reply_markup=kb.topic_start)     await state.clear()   @router.message(TopicAnalize.choice_rezult) async def state_e(message: Message):     await message.answer(text='\u2753 *\u0414\u043b\u044f \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435  \u0438\u043b\u0438 \u0432\u044b\u0439\u0442\u0438 \u0438\u0437 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0440\u0435\u0436\u0438\u043c\u0430*')  @router.message(F.text) async def any_text(message: Message):     await message.answer(         text='\u274c *\u0422\u0430\u043a\u043e\u0435 \u044f \u043d\u0435 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e!*  \\n'              '\ud83d\udcdc *\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439 \/help, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b.*',         parse_mode=types.ParseMode.MARKDOWN_V2     )<\/code><\/pre>\n<p>\u042d\u0442\u043e\u0442 \u043a\u043e\u0434 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u043d\u0430\u0431\u043e\u0440 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u0434\u043b\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445  \u044d\u0442\u0430\u043f\u043e\u0432 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u0431\u043e\u0442\u043e\u043c: \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0430\u043d\u043a\u0435\u0442\u044b, \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445, \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043e\u0448\u0438\u0431\u043e\u043a \u0438 \u0437\u0430\u043f\u0443\u0441\u043a \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u0442\u0435\u043c. \u0411\u043e\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043d\u0430 \u0432\u0445\u043e\u0434 CSV-\u0444\u0430\u0439\u043b.<\/p>\n<h2>\u0410\u043d\u0430\u043b\u0438\u0437 \u0442\u0435\u043a\u0441\u0442\u0430<\/h2>\n<p>\u041d\u0438\u0436\u0435 \u0432 \u0444\u0430\u0439\u043b\u0435 <em>gensi.py<\/em>, \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0442\u0435\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043c\u043e\u0434\u0435\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u0435\u043a\u0441\u0442\u0430 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c LDA. <\/p>\n<pre><code class=\"python\">import gensim from topic_funcs.clean import cleaning_and_normalize, mstem, punctions_del from gensim import corpora from gensim.utils import simple_preprocess from topic_funcs.thems import thems_count  def start(answers):      answers = punctions_del(answers)     list_of_answers = mstem(answers)     list_of_answers = cleaning_and_normalize(list_of_answers)      mydict = corpora.Dictionary([simple_preprocess(line) for line in list_of_answers])     corpus = [mydict.doc2bow(simple_preprocess(line)) for line in list_of_answers]     them_count = thems_count(mydict)     lda_model = gensim.models.ldamodel.LdaModel(corpus=corpus,                                             id2word=mydict,                                             num_topics=them_count,                                             random_state=100,                                             update_every=1,                                             chunksize=30000,                                             passes=15,                                             alpha='auto',                                             per_word_topics=True)     stl = lda_model.print_topics()     st = ''     for i in range(1, them_count):         st = st + \"\u0433\u0440\u0443\u043f\u043f\u0430 \u043d\u043e\u043c\u0435\u0440: \" + str(i) + \" \"         st += stl[i][1]     lda_topics = lda_model.show_topics(num_words=5)     for topic in lda_topics:         print(topic)     return f'\u0412 \u0445\u043e\u0434\u0435 \u043e\u0434\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u0442\u0432\u0435\u0442\u043e\u0432 \u0431\u044b\u043b\u043e \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u043e {them_count} \u0442\u0435\u043c\\n\u0414\u0430\u043b\u0435\u0435 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430\u043c\u0438', lda_model, them_count, mydict, corpus, st<\/code><\/pre>\n<p>\u0418\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u043d\u0443\u0436\u043d\u044b\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438, \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u044f\u0442 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0442\u0435\u043a\u0441\u0442\u0430: \u0443\u0434\u0430\u043b\u044f\u0435\u0442 \u043f\u0443\u043d\u043a\u0442\u0443\u0430\u0446\u0438\u044e \u0438\u0437 \u043e\u0442\u0432\u0435\u0442\u043e\u0432, \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0441\u043b\u043e\u0432 \u043a \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0439 \u0444\u043e\u0440\u043c\u0435, \u0443\u0434\u0430\u043b\u044f\u0435\u0442 \u0441\u0442\u043e\u043f \u0441\u043b\u043e\u0432\u0430. \u0421\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u0441\u043b\u043e\u0432\u0430\u0440\u044c <em>mydict<\/em> \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043f\u0440\u0435\u0434\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u044b\u0445 \u043e\u0442\u0432\u0435\u0442\u043e\u0432 \u0438 \u043a\u043e\u0440\u043f\u0443\u0441 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432 corpus, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0445 \u043a\u0430\u0436\u0434\u044b\u0439 \u043e\u0442\u0432\u0435\u0442 \u0432 \u0432\u0438\u0434\u0435 \u0441\u043f\u0438\u0441\u043a\u0430 \u043f\u0430\u0440(\u0441\u043b\u043e\u0432\u043e, \u0447\u0430\u0441\u0442\u043e\u0442\u0430).<\/p>\n<p>\u0412\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <em>them_count<\/em> \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0442\u0435\u043c \u0434\u043b\u044f LDA \u043c\u043e\u0434\u0435\u043b\u0438. \u0414\u0430\u043b\u0435\u0435, \u044d\u0442\u0430 \u043c\u043e\u0434\u0435\u043b\u044c \u043e\u0431\u0443\u0447\u0430\u0435\u0442\u0441\u044f, \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0440\u043f\u0443\u0441\u0430 \u0438 \u0441\u043b\u043e\u0432\u0430\u0440\u044f.\u0412 \u043a\u043e\u043d\u0446\u0435 \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u0441\u043f\u0438\u0441\u043e\u043a \u0442\u0435\u043c \u0438 \u0438\u0445 \u0442\u043e\u043f 5 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0445 \u0441\u043b\u043e\u0432. <\/p>\n<p><em>clean.py<\/em><\/p>\n<pre><code class=\"python\">from nltk.corpus import stopwords import nltk from pymystem3 import Mystem from topic_funcs.censor import remove_russian_mat  def punctions_del(st):     punctions = \"!\\\"#$%&amp;'()*+,-.\/:;&lt;=&gt;?@[\\]^_`{|}~1234567890\"     for i in range(len(st)):         if(i &gt;= len(st)):             break         if st[i] in punctions:             st = st[:i] + st[i + 1:]     return st  def mstem(st):     m = Mystem()     return m.lemmatize(st)  nltk.download('stopwords') stop_words = stopwords.words('russian')  def cleaning_and_normalize(lst):     words = list(word for word in lst if word not in stop_words)     words = remove_russian_mat(words)     return words<\/code><\/pre>\n<p>\u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0435 \u0448\u0430\u0433\u0438 \u043f\u0440\u0435\u0434\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0442\u0435\u043a\u0441\u0442\u0430 \u0434\u043b\u044f \u0437\u0430\u0434\u0430\u0447 \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430: \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u043f\u0443\u043d\u043a\u0442\u0443\u0430\u0446\u0438\u0438, \u043b\u0435\u043c\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u044f \u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0441\u0442\u043e\u043f-\u0441\u043b\u043e\u0432<\/p>\n<h2>\u0412\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f<\/h2>\n<p>\u0427\u0442\u043e\u0431\u044b \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0430\u043d\u0430\u043b\u0438\u0437 \u0442\u0435\u043a\u0441\u0442\u0430 \u043c\u044b \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0432 \u0444\u0430\u0439\u043b\u0435 <em>probably.py<\/em> \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434:<\/p>\n<pre><code class=\"python\">import numpy as np import matplotlib.pyplot as plt import matplotlib  def probably_topics(lda_model, dictionary, num_topics):     matplotlib.use('TkAgg')     topic_probs = np.zeros(num_topics)      for word_id in range(len(dictionary)):         word_probabilities = lda_model.get_term_topics(word_id)          for topic_id, probability in word_probabilities:             topic_probs[topic_id] += probability      topic_probs \/= np.sum(topic_probs)      labels = [f'\u0422\u043e\u043f\u0438\u043a {i}' for i in range(num_topics)]     sizes = topic_probs * 100      plt.figure(figsize=(8, 8))     plt.pie(sizes, labels=labels, autopct='%1.1f%%', startangle=140)     plt.title('\u0417\u043d\u0430\u0447\u0438\u043c\u043e\u0441\u0442\u044c \u043a\u0430\u0436\u0434\u043e\u0439 \u043f\u043e\u0434\u0442\u0435\u043c\u044b \u0432 \u043e\u0431\u0449\u0435\u043c \u043c\u0430\u0441\u0441\u0438\u0432\u0435 \u043e\u0442\u0432\u0435\u0442\u043e\u0432')     plt.axis('equal')      plt.show()<\/code><\/pre>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <em>probably_topics<\/em> \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043e\u0431\u0443\u0447\u0435\u043d\u043d\u0443\u044e LDA \u043c\u043e\u0434\u0435\u043b\u044c <em>lda_model<\/em>, \u0441\u043b\u043e\u0432\u0430\u0440\u044c <em>dictionary<\/em> \u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0442\u0435\u043c <em>num_topics<\/em>. \u041e\u043d\u0430 \u0441\u0443\u043c\u043c\u0438\u0440\u0443\u0435\u0442 \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u0438 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u043e\u043f\u0438\u043a\u0430 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0441\u043b\u043e\u0432 \u0432 \u0441\u043b\u043e\u0432\u0430\u0440\u0435, \u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u044d\u0442\u0438 \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u0438 \u0438 \u0441\u0442\u0440\u043e\u0438\u0442 \u043a\u0440\u0443\u0433\u043e\u0432\u0443\u044e \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0443, \u0433\u0434\u0435 \u043a\u0430\u0436\u0434\u044b\u0439 \u0441\u0435\u0433\u043c\u0435\u043d\u0442 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0442\u0435\u043c\u0443, \u0430 \u0435\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440 \u2014 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u044c \u044d\u0442\u043e\u0439 \u0442\u0435\u043c\u044b \u0432\u043e \u0432\u0441\u0435\u043c \u043a\u043e\u0440\u043f\u0443\u0441\u0435 \u0442\u0435\u043a\u0441\u0442\u0430.<\/p>\n<p>\u0414\u043b\u044f \u0431\u043e\u043b\u0435\u0435 \u0442\u043e\u0447\u043d\u043e\u0439 \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438, \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u0442\u043e\u043b\u0431\u0447\u0430\u0442\u0443\u044e \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0443.<\/p>\n<p><em>vizualize.py<\/em><\/p>\n<pre><code class=\"python\">import matplotlib.pyplot as plt import matplotlib  def plot_topic_distribution(lda_model, num_words=10):     num_topics = lda_model.num_topics     matplotlib.use('TkAgg')      topics = []     words = []     weights = []      for topic_id in range(num_topics):         topic_terms = lda_model.show_topic(topic_id, topn=num_words)         for term, weight in topic_terms:             topics.append(f'Topic {topic_id + 1}')             words.append(term)             weights.append(weight)      import pandas as pd     df = pd.DataFrame({         'Topic': topics,         'Word': words,         'Weight': weights     })      plt.figure(figsize=(12, 6))     for topic in range(num_topics):         topic_data = df[df['Topic'] == f'Topic {topic + 1}']         plt.bar(topic_data['Word'], topic_data['Weight'], label=f'Topic {topic + 1}')      plt.title('\u0412\u0435\u0441\u043e\u043c\u044b\u0435 \u0441\u043b\u043e\u0432\u0430 \u0432 \u043a\u0430\u0436\u0434\u043e\u0439 \u0438\u0437 \u043f\u043e\u0434\u0442\u0435\u043c')     plt.xlabel('\u0421\u043b\u043e\u0432\u0430')     plt.ylabel('\u0412\u0435\u0441 \u0441\u043b\u043e\u0432\u0430')     plt.xticks(rotation=45, ha='right')     plt.legend()     plt.tight_layout()     plt.show()<\/code><\/pre>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <em>plot_topic_distribution<\/em> \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043e\u0431\u0443\u0447\u0435\u043d\u043d\u0443\u044e LDA \u043c\u043e\u0434\u0435\u043b\u044c \u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u043b\u043e\u0432 <em>num_words<\/em>, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u044c \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0442\u0435\u043c\u044b. \u041e\u043d\u0430 \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0438\u043c\u044b\u0435 \u0441\u043b\u043e\u0432\u0430 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0442\u0435\u043c\u044b \u0438\u0437 \u043c\u043e\u0434\u0435\u043b\u0438 LDA,  \u0441\u043e\u0437\u0434\u0430\u0435\u0442 <em>DataFrame<\/em> \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <em>pandas<\/em> \u0438 \u0441\u0442\u0440\u043e\u0438\u0442 \u0441\u0442\u043e\u043b\u0431\u0447\u0430\u0442\u0443\u044e \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0443, \u0433\u0434\u0435 \u043a\u0430\u0436\u0434\u0430\u044f \u0433\u0440\u0443\u043f\u043f\u0430 \u0441\u0442\u043e\u043b\u0431\u0446\u043e\u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0442\u0435\u043c\u0435, \u0430 \u0441\u0442\u043e\u043b\u0431\u0446\u044b \u0432 \u043a\u0430\u0436\u0434\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u0435 \u2014 \u0441\u043b\u043e\u0432\u0430\u043c \u044d\u0442\u043e\u0439 \u0442\u0435\u043c\u044b, \u0432\u044b\u0441\u043e\u0442\u0430 \u0441\u0442\u043e\u043b\u0431\u0446\u0430 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0432\u0435\u0441 \u0441\u043b\u043e\u0432\u0430 \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u0442\u0435\u043c\u0435.<\/p>\n<h2>\u0417\u0430\u043f\u0440\u043e\u0441 \u0432 gpt<\/h2>\n<pre><code class=\"python\">from g4f.client import Client  def get_answer(st):     client = Client()     content = f'\u0414\u0430\u0439 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0433\u0440\u0443\u043f\u043f\u0430\u043c \u0441\u043b\u043e\u0432, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u043f\u043e \u0441\u043c\u044b\u0441\u043b\u0443, \u0441\u043b\u043e\u0432\u0430 \u0443\u0436\u0435 \u0440\u0430\u0437\u0431\u0438\u0442\u044b \u043f\u043e \u0433\u0440\u0443\u043f\u043f\u0430\u043c. {st}'     response = client.chat.completions.create(     model=\"gpt-3.5-turbo\",     messages=[{\"role\": \"user\", \"content\": content}],     )     return response.to_json()['choices'][0]['message']['content']<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 \u0441\u0435\u0440\u0432\u0438\u0441\u0443, \u044d\u0442\u043e \u043d\u0435 request \u043a gpt, \u0442\u0430\u043a \u043a\u0430\u043a \u043d\u0430 \u0442\u0435\u0440\u0440\u0438\u0442\u043e\u0440\u0438\u0438 \u0420\u043e\u0441\u0441\u0438\u0438 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d \u0434\u043e\u0441\u0442\u0443\u043f, \u0430 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0445 proxy \u0441\u0440\u0430\u0437\u0443 \u0441\u043b\u0435\u0442\u0430\u044e\u0442. \u041d\u043e g4f \u043e\u0447\u0435\u043d\u044c \u0445\u043e\u0440\u043e\u0448\u0438\u0439 \u043f\u0440\u043e\u0435\u043a\u0442, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 API \u043a \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u043c\u0443 \u0431\u043e\u0442\u0443 \u0434\u0430\u0436\u0435 \u0443\u0441\u0442\u0443\u043f\u0430\u0435\u0442.<\/p>\n<h2>\u041a\u0430\u043a \u044d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0432 \u0431\u043e\u0442\u0435<\/h2>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/032\/b4d\/ef1\/032b4def181e4baa9a3a46abf5809744.png\" alt=\"\u0417\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0430\u043d\u043a\u0435\u0442\u044b\" title=\"\u0417\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0430\u043d\u043a\u0435\u0442\u044b\" width=\"622\" height=\"670\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/032\/b4d\/ef1\/032b4def181e4baa9a3a46abf5809744.png\"\/><\/p>\n<div><figcaption>\u0417\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0430\u043d\u043a\u0435\u0442\u044b<\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/be3\/815\/fc2\/be3815fc2f4b0f0128c3b80aaac0a01c.png\" alt=\"\u0417\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0430\u043d\u043a\u0435\u0442\u044b\" title=\"\u0417\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0430\u043d\u043a\u0435\u0442\u044b\" width=\"578\" height=\"596\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/be3\/815\/fc2\/be3815fc2f4b0f0128c3b80aaac0a01c.png\"\/><\/p>\n<div><figcaption>\u0417\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0430\u043d\u043a\u0435\u0442\u044b<\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/7cc\/8cc\/987\/7cc8cc987f3569d7d4a139f4a09c185e.png\" alt=\"\u0412\u044b\u0431\u043e\u0440 \u043a\u043d\u043e\u043f\u043e\u043a \u0434\u043b\u044f \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u0442\u0435\u043a\u0441\u0442\u0430\" title=\"\u0412\u044b\u0431\u043e\u0440 \u043a\u043d\u043e\u043f\u043e\u043a \u0434\u043b\u044f \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u0442\u0435\u043a\u0441\u0442\u0430\" width=\"1490\" height=\"183\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/7cc\/8cc\/987\/7cc8cc987f3569d7d4a139f4a09c185e.png\"\/><\/p>\n<div><figcaption>\u0412\u044b\u0431\u043e\u0440 \u043a\u043d\u043e\u043f\u043e\u043a \u0434\u043b\u044f \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u0442\u0435\u043a\u0441\u0442\u0430<\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/189\/1ec\/bb1\/1891ecbb1ba0f1fc5bd0f0210969ce97.png\" alt=\"\u0412\u044b\u0432\u043e\u0434 \u043f\u0435\u0440\u0432\u043e\u0439 \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u044b\" title=\"\u0412\u044b\u0432\u043e\u0434 \u043f\u0435\u0440\u0432\u043e\u0439 \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u044b\" width=\"656\" height=\"689\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/189\/1ec\/bb1\/1891ecbb1ba0f1fc5bd0f0210969ce97.png\"\/><\/p>\n<div><figcaption>\u0412\u044b\u0432\u043e\u0434 \u043f\u0435\u0440\u0432\u043e\u0439 \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u044b<\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/2a2\/7d3\/0ac\/2a27d30acc5ba5df8405a850074fb1c2.png\" alt=\"\u0412\u044b\u0432\u043e\u0434 \u0432\u0442\u043e\u0440\u043e\u0439 \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u044b\" title=\"\u0412\u044b\u0432\u043e\u0434 \u0432\u0442\u043e\u0440\u043e\u0439 \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u044b\" width=\"615\" height=\"653\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/2a2\/7d3\/0ac\/2a27d30acc5ba5df8405a850074fb1c2.png\"\/><\/p>\n<div><figcaption>\u0412\u044b\u0432\u043e\u0434 \u0432\u0442\u043e\u0440\u043e\u0439 \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u044b<\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ede\/9ec\/e11\/ede9ece11a706b142fed89c01a9e4984.png\" alt=\"\u0421\u043f\u0438\u0441\u043e\u043a \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0441\u043b\u043e\u0432 \u043a\u0430\u0436\u0434\u043e\u0439 \u0441\u043c\u044b\u0441\u043b\u043e\u0432\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b \u0438 \u0438\u0445 \u0437\u043d\u0430\u0447\u0438\u043c\u043e\u0441\u0442\u0438(\u0432\u0435\u0441)\" title=\"\u0421\u043f\u0438\u0441\u043e\u043a \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0441\u043b\u043e\u0432 \u043a\u0430\u0436\u0434\u043e\u0439 \u0441\u043c\u044b\u0441\u043b\u043e\u0432\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b \u0438 \u0438\u0445 \u0437\u043d\u0430\u0447\u0438\u043c\u043e\u0441\u0442\u0438(\u0432\u0435\u0441)\" width=\"579\" height=\"693\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ede\/9ec\/e11\/ede9ece11a706b142fed89c01a9e4984.png\"\/><\/p>\n<div><figcaption>\u0421\u043f\u0438\u0441\u043e\u043a \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0441\u043b\u043e\u0432 \u043a\u0430\u0436\u0434\u043e\u0439 \u0441\u043c\u044b\u0441\u043b\u043e\u0432\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b \u0438 \u0438\u0445 \u0437\u043d\u0430\u0447\u0438\u043c\u043e\u0441\u0442\u0438(\u0432\u0435\u0441)<\/figcaption><\/div>\n<\/figure>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/606\/bbd\/63c\/606bbd63cef9281597a3fd90baf0a0d3.png\" alt=\"Chatgpt \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 \u0438 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u0442 \u0441\u043b\u043e\u0432\u0430 \u043a\u0430\u0436\u0434\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b \u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u0443\u044e \u0442\u0435\u043c\u0443\" title=\"Chatgpt \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 \u0438 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u0442 \u0441\u043b\u043e\u0432\u0430 \u043a\u0430\u0436\u0434\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b \u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u0443\u044e \u0442\u0435\u043c\u0443\" width=\"452\" height=\"213\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/606\/bbd\/63c\/606bbd63cef9281597a3fd90baf0a0d3.png\"\/><\/p>\n<div><figcaption>Chatgpt \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 \u0438 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u0442 \u0441\u043b\u043e\u0432\u0430 \u043a\u0430\u0436\u0434\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b \u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u0443\u044e \u0442\u0435\u043c\u0443<\/figcaption><\/div>\n<\/figure>\n<h2>\u0412\u044b\u0432\u043e\u0434<\/h2>\n<p>\u0412 \u0445\u043e\u0434\u0435 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0446\u0435\u043d\u043d\u044b\u0439 \u043e\u043f\u044b\u0442 \u0432 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 Telegram-\u0431\u043e\u0442\u043e\u0432,  \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430,  \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u0431\u0430\u0437\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0442\u0435\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043c\u043e\u0434\u0435\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u0412 \u0431\u0443\u0434\u0443\u0449\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d \u0437\u0430 \u0441\u0447\u0435\u0442 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c\u0438 \u0438 \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u0432 \u0430\u043d\u0430\u043b\u0438\u0437\u0430.<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/855786\/\"> https:\/\/habr.com\/ru\/articles\/855786\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h2>\u041f\u0440\u0435\u0434\u044b\u0441\u0442\u043e\u0440\u0438\u044f<\/h2>\n<p>\u0411\u0443\u043a\u0432\u0430\u043b\u044c\u043d\u043e \u043c\u0435\u0441\u044f\u0446 \u043d\u0430\u0437\u0430\u0434, \u043c\u044b \u0441 \u043c\u043e\u0438\u043c \u043a\u043e\u043b\u043b\u0435\u0433\u043e\u0439 \u0443\u0447\u0430\u0441\u0442\u0432\u043e\u0432\u0430\u043b\u0438 \u0432 HAKATON. \u041d\u0430\u0448\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u0432\u0437\u044f\u043b\u0430\u0441\u044c \u0437\u0430 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443 \u043e\u0442 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 \u041c\u0422\u0421: \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0442\u044b\u0441\u044f\u0447 \u043e\u043f\u0440\u043e\u0441\u043e\u0432, \u043d\u0430\u0439\u0442\u0438 \u0443\u0441\u0440\u0435\u0434\u043d\u0435\u043d\u043d\u044b\u0439 \u0441\u0438\u043d\u043e\u043d\u0438\u043c \u043a \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438 \u043e\u0442\u0432\u0435\u0442\u043e\u0432 \u0438 \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e \u0432 \u0432\u0438\u0434\u0435 \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u044b, \u043b\u0438\u0431\u043e \u043e\u0431\u043b\u0430\u043a\u0430 \u0441\u043b\u043e\u0432.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447\u0438 \u0438 \u0437\u0430\u0449\u0438\u0442\u044b \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043c\u044b \u0437\u0430\u0434\u0443\u043c\u0430\u043b\u0438\u0441\u044c:<\/p>\n<blockquote>\n<p>&#171;<em>\u0410 \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u0434\u0430\u043d\u043d\u0443\u044e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0441\u0432\u044f\u0437\u0430\u0442\u044c \u0441 \u0442\u0433 \u0431\u043e\u0442\u043e\u043c?&#187;<\/em><\/p>\n<\/blockquote>\n<p>\u041a\u0430\u043a \u0440\u0430\u0437 \u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e, \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u044d\u0442\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c.<\/p>\n<h2>\u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u0432 github<\/h2>\n<p><a href=\"https:\/\/github.com\/onevay\/Tg_Bot_Topic_Analyze\/tree\/main\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/onevay\/Tg_Bot_Topic_Analyze\/tree\/main<\/a><\/p>\n<h2>\u042d\u0442\u0430\u043f\u044b \u0440\u0430\u0431\u043e\u0442\u044b<\/h2>\n<ul>\n<li>\n<p>\u0412\u044b\u0431\u043e\u0440 \u0441\u0442\u0435\u043a\u0430<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 &#171;\u043a\u043d\u043e\u043f\u043e\u043a \u0438 \u0441\u044b\u0440\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430&#187;<\/p>\n<\/li>\n<li>\n<p>\u0411\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445<\/p>\n<\/li>\n<li>\n<p>\u0412\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u0442\u0435\u043a\u0441\u0442\u0430<\/p>\n<\/li>\n<li>\n<p>\u041e\u0444\u043e\u0440\u043c\u043b\u0435\u043d\u0438\u0435 \u0438 \u0434\u043e\u0440\u0430\u0431\u043e\u0442\u043a\u0430<\/p>\n<\/li>\n<\/ul>\n<h2>\u041a\u0440\u0430\u0442\u043a\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430<\/h2>\n<p>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u0430\u043d\u043a\u0435\u0442\u0443, \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u044e\u0442\u0441\u044f \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445. \u0414\u0430\u043b\u0435\u0435, \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c csv-\u0444\u0430\u0439\u043b \u0441 \u0431\u043e\u043b\u044c\u0448\u0438\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u0442\u0435\u043a\u0441\u0442\u0430, \u0431\u043e\u0442 \u043f\u0440\u043e\u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442 \u0438 \u043e\u0442\u0432\u0435\u0442\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442, \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0438\u0439 \u0438\u0437 \u0434\u0432\u0443\u0445 \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c:<\/p>\n<p>\u041f\u0435\u0440\u0432\u0430\u044f \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u0441\u043b\u043e\u0432\u0430 \u043a\u0430\u0436\u0434\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b, \u043e\u0442\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u043e \u0441\u0432\u043e\u0435\u0439 \u0437\u043d\u0430\u0447\u0438\u043c\u043e\u0441\u0442\u0438.\u0412\u0442\u043e\u0440\u0430\u044f \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0430 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u044d\u0442\u0438 \u0433\u0440\u0443\u043f\u043f\u044b \u0432 \u043f\u0440\u043e\u0446\u0435\u043d\u0442\u043d\u043e\u043c \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0438.<\/p>\n<p>\u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f, \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441 \u0432 chat gpt, \u0433\u0434\u0435 \u0442\u043e\u0442 \u043d\u0430\u0439\u0434\u0435\u0442 \u043a\u0430\u0436\u0434\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u0435 \u0441\u043b\u043e\u0432 \u0441\u0432\u043e\u044e \u0442\u0435\u043c\u0443.<\/p>\n<h2>\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 aiogram<\/h2>\n<p>aiogram &#8212; \u044d\u0442\u043e \u043c\u043e\u0449\u043d\u044b\u0439  \u0438 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0439 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0439 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0431\u043e\u0442\u043e\u0432 \u0432 Telegram \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 python. \u041e\u043d \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 Telegram Bot API.<\/p>\n<p><strong>\u041e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430 aiogram<\/strong>:<\/p>\n<ol>\n<li>\n<p><em>\u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0441\u0442\u044c<\/em>. \u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0431\u043e\u0442\u0443 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e, \u043d\u0435 \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0434\u0440\u0443\u0433\u0438\u0445 \u0437\u0430\u0434\u0430\u0447.<\/p>\n<\/li>\n<li>\n<p><em>\u0413\u0438\u0431\u043a\u043e\u0441\u0442\u044c.<\/em> \u041f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 \u0434\u043b\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0431\u043e\u0442\u0430.  \u041e\u043d \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439, \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u044b (inline \u0438 reply), \u043a\u043e\u043b\u043b\u0431\u044d\u043a\u0438 \u0438 \u043c\u043d\u043e\u0433\u043e\u0435 \u0434\u0440\u0443\u0433\u043e\u0435.<\/p>\n<\/li>\n<li>\n<p><em>\u041f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439 (FSM)<\/em>. \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0438\u043c\u0435\u0435\u0442 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u0443\u044e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0445 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u043e\u0432, \u0447\u0442\u043e \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u0431\u043e\u0442\u043e\u0432 \u0441 \u043c\u043d\u043e\u0433\u043e\u0448\u0430\u0433\u043e\u0432\u044b\u043c \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435\u043c \u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c.<\/p>\n<\/li>\n<li>\n<p><em>\u041c\u0438\u043d\u0438\u043c\u0430\u043b\u0438\u0437\u043c<\/em>. aiogram \u043d\u0435 \u043d\u0430\u0432\u044f\u0437\u044b\u0432\u0430\u0435\u0442 \u043b\u0438\u0448\u043d\u0438\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439, \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u0435\u0433\u043e \u043b\u0435\u0433\u043a\u0438\u043c \u0438 \u0431\u044b\u0441\u0442\u0440\u044b\u043c.<\/p>\n<\/p>\n<\/li>\n<\/ol>\n<h2>\u041d\u0430\u0447\u0430\u043b\u043e \u0440\u0430\u0431\u043e\u0442\u044b<\/h2>\n<p>\u0411\u044b\u043b\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u044b \u043c\u043e\u0434\u0443\u043b\u0438 \u0434\u043b\u044f \u0431\u043e\u043b\u0435\u0435 \u0443\u0434\u043e\u0431\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b.<\/p>\n<p><em>ha1.py<\/em><\/p>\n<pre><code class=\"python\">from aiogram import F, Router from aiogram.types import CallbackQuery, Message, ReplyKeyboardRemove, FSInputFile from aiogram import filters from aiogram.enums import ParseMode import app.db as db import topic_funcs.gensi as gn from aiogram.fsm.context import FSMContext from aiogram.fsm.state import State, StatesGroup import re import topic_funcs.vizualize as viz import topic_funcs.probably as prob import topic_funcs.textb as req from decouple import config import app.keyboard as kb<\/code><\/pre>\n<p><em>keyboard.py<\/em><\/p>\n<pre><code class=\"python\">from aiogram.types import ReplyKeyboardMarkup, \\     KeyboardButton, InlineKeyboardButton, InlineKeyboardMarkup<\/code><\/pre>\n<p><em>db.py<\/em><\/p>\n<pre><code class=\"python\">import psycopg2 from decouple import config<\/code><\/pre>\n<p><em>main.py<\/em><\/p>\n<pre><code class=\"python\">from aiogram import Bot, Dispatcher import asyncio import logging import app.db as db from decouple import config from app.ha1 import router<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f Telegram-\u0431\u043e\u0442\u0430. <\/p>\n<pre><code class=\"python\">def extract_number(text):     match = re.search(r'\\b(\\d+)\\b', text)     if match:         return int(match.group(1))     else:         return None  class UserData(StatesGroup):     name: str = State()     age: int | None = State()     aim: str = State()     gender: str | None = State()  class TopicAnalize(StatesGroup):     start_analize: str = State()     choice_rezult = State()<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0432 \u0444\u0430\u0439\u043b\u0435 <em>ha1.py<\/em> \u043c\u044b \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <strong>extract_number()<\/strong>, \u0434\u043b\u044f \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u044f \u0432\u043e\u0437\u0440\u0430\u0441\u0442\u0430 \u0438\u0437 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u0432\u0432\u043e\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u041a\u043b\u0430\u0441\u0441 <strong>UserData(StatesGroup)<\/strong> \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0434\u043b\u044f FSM, \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0449\u0435\u0433\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u043c \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0430\u043d\u043a\u0435\u0442\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c. \u041a\u043b\u0430\u0441\u0441 <strong>TopicAnalize(StatesGroup)<\/strong> \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0434\u043b\u044f FSM, \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0449\u0435\u0433\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u043c \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u0442\u0435\u043c \u0442\u0435\u043a\u0441\u0442\u0430.<\/p>\n<pre><code class=\"python\">topic_start = InlineKeyboardMarkup(     inline_keyboard=[         [InlineKeyboardButton(text='\ud83d\ude80 \u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0432\u044b\u0434\u0435\u043b\u0438\u0442\u0435\u043b\u044c \u0442\u043e\u043f\u0438\u043a\u043e\u0432', callback_data='topic_start')]     ] )  ancet_start = InlineKeyboardMarkup(inline_keyboard=[     [InlineKeyboardButton(text='\ud83d\udcdd \u041f\u0440\u043e\u0439\u0442\u0438 \u0430\u043d\u043a\u0435\u0442\u0443', callback_data='anceta')],     [InlineKeyboardButton(text='\ud83d\ude80 \u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0432\u044b\u0434\u0435\u043b\u0438\u0442\u0435\u043b\u044c \u0442\u043e\u043f\u0438\u043a\u043e\u0432', callback_data='topic_start')] ])  check_data = InlineKeyboardMarkup(     inline_keyboard=[         [InlineKeyboardButton(text=\"\u2705 \u0412\u0441\u0435 \u0432\u0435\u0440\u043d\u043e\", callback_data='correct')],         [InlineKeyboardButton(text=\"\u274c \u0417\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0441\u043d\u0430\u0447\u0430\u043b\u0430\", callback_data='incorrect')]     ] )  air_foul = InlineKeyboardMarkup(     inline_keyboard=[         [InlineKeyboardButton(text='\ud83d\ude45\u200d\u2642\ufe0f \u041d\u0435 \u0445\u043e\u0447\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c', callback_data='air_foul')]     ] )  gen_button = ReplyKeyboardMarkup(     keyboard=[         [KeyboardButton(text='\ud83d\udc69\ud83c\udffb \u0416\u0435\u043d\u0449\u0438\u043d\u0430')],         [KeyboardButton(text='\ud83d\udc68\ud83c\udffb \u041c\u0443\u0436\u0447\u0438\u043d\u0430')]     ],     resize_keyboard=True,     one_time_keyboard=True,     input_field_placeholder='\ud83e\udd14 \u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0432\u0430\u0448 \u043f\u043e\u043b' )<\/code><\/pre>\n<p>\u0412 \u0444\u0430\u0439\u043b\u0435 <em>keyboard.py<\/em> \u043a\u043e\u0434 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0431\u043e\u0442\u0430, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0432\u044b\u0431\u043e\u0440 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u043e\u043f\u0446\u0438\u0439 \u0447\u0435\u0440\u0435\u0437 &#171;\u043a\u043d\u043e\u043f\u043a\u0438&#187;.<\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043e \u0444\u0430\u0439\u043b\u0435 <em>db.py,  <\/em>\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<pre><code class=\"python\">db_url = config('DB_URL') host = config('HOST') port = config('PORT') user = config('USER') password = config('PASSWORD') database = config('DB_NAME')  conn = psycopg2.connect(dbname=database, user=user, password=password, host=host, port=port) conn.autocommit = True<\/code><\/pre>\n<p><em>host = config(&#8216;HOST&#8217;), port = config(&#8216;PORT&#8217;), user = config(&#8216;USER&#8217;), password = config(&#8216;PASSWORD&#8217;), database = config(&#8216;DB_NAME&#8217;)<\/em>: \u042d\u0442\u0438 \u0441\u0442\u0440\u043e\u043a\u0438 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u044e\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a PostgreSQL \u0438\u0437 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f: <strong>HOST, PORT, USER, PASSWORD, DB_NAME.<\/strong><\/p>\n<p><em>conn = psycopg2.connect(dbname=database, user=user, password=password, host=host, port=port):<\/em>  \u042d\u0442\u043e \u043a\u043b\u044e\u0447\u0435\u0432\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0441 \u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b, \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0435 \u043d\u0430 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u044d\u0442\u0430\u043f\u0430\u0445. <\/p>\n<p><em>conn.autocommit = True:<\/em> \u042d\u0442\u0430 \u0441\u0442\u0440\u043e\u043a\u0430 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0439.  \u042d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442, \u0447\u0442\u043e \u043a\u0430\u0436\u0434\u043e\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438.<\/p>\n<pre><code class=\"python\">def create_table():     with conn.cursor() as cursor:         cursor.execute(\"\"\"CREATE TABLE IF NOT EXISTS users (                         id INT8 NOT NULL PRIMARY KEY,                         name VARCHAR(255) NOT NULL,                         age INT8 NOT NULL,                         gender VARCHAR(255) NOT NULL,                         aim VARCHAR(255));\"\"\")  def insert(id, test_dict):     if check_primary(id):         with conn.cursor() as cursor:             cursor.execute(f\"\"\"INSERT INTO users(id, name, age, gender, aim)                         VALUES ({id},'{test_dict[\"name\"]}',                         {test_dict[\"age\"]},                         '{test_dict[\"gender\"]}',                         '{test_dict[\"aim\"]}');\"\"\")     else:         with conn.cursor() as cursor:             cursor.execute(f\"\"\"UPDATE users SET id = {id}, name = '{test_dict[\"name\"]}', age = {test_dict[\"age\"]},                         gender = '{test_dict[\"gender\"]}', aim = '{test_dict[\"aim\"]}'                         WHERE id = {id};\"\"\")<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u0434\u0432\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438. <\/p>\n<p><em>create_table()<\/em> \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445, \u0435\u0441\u043b\u0438 \u043e\u043d\u0430 \u0435\u0449\u0451 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442.  <\/p>\n<p><em>insert()<\/em> \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043b\u0438 \u0443\u0436\u0435 \u0437\u0430\u043f\u0438\u0441\u044c \u0441 \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u043c <strong>id<\/strong>, \u0438 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0432\u0441\u0442\u0430\u0432\u043a\u0443 \u0438\u043b\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435.<\/p>\n<pre><code class=\"python\">def age_procent(test_dict):     with conn.cursor() as cursor:         cursor.execute(f\"\"\"SELECT ROUND(COUNT(CASE WHEN age = {test_dict[\"age\"]}THEN 1 END) * 100.0 \/ count(*), 2) AS fraction FROM users;\"\"\")         procent_age = cursor.fetchone()[0]         return procent  def gender_procent(test_dict):     with conn.cursor() as cursor:         cursor.execute(f\"\"\"SELECT ROUND(COUNT(CASE WHEN gender = {test_dict[\"gender\"]} THEN 1 END) * 100.0 \/ COUNT(*), 2) AS fraction FROM users;\"\"\")         procent_gender = cursor.fetchone()[0]         return procent_gender<\/code><\/pre>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u0438 <em>age_procent()<\/em> \u0438 <em>gender_procent()<\/em> \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 \u0432 \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u043d\u0442\u043d\u043e\u0435 \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435, \u0441\u0440\u0435\u0434\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435.<\/p>\n<pre><code class=\"python\">def check_primary(id):     with conn.cursor() as cursor:         cursor.execute(f\"\"\"SELECT id FROM users;\"\"\")         p = cursor.fetchall()         if p == None:             return True         lst = [int(i[0]) for i in p]     return True if id not in lst else False  def delete_user(id):     with conn.cursor() as cursor:         cursor.execute(f\"\"\"DELETE FROM users WHERE id = {id}\"\"\")  def print_data(id):     with conn.cursor() as cursor:         cursor.execute(f\"\"\"SELECT name, age, gender, aim FROM users WHERE id = {id};\"\"\")         return cursor.fetchone()<\/code><\/pre>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <em>check_primary()<\/em> \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441 \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u043c <strong>id<\/strong>.<\/p>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <em>delete_used()<\/em> \u0443\u0434\u0430\u043b\u044f\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0430\u0439\u0434\u0438 \u0438\u0437 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445, \u0435\u0441\u043b\u0438 \u043e\u043d \u0436\u0435 \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u0437\u0430\u043d\u043e\u0432\u043e \u0430\u043d\u043a\u0435\u0442\u0443.<\/p>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <em>print_data()<\/em> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0441 \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u043c <strong>id<\/strong>.<\/p>\n<p>\u0412\u0435\u0440\u043d\u0435\u043c\u0441\u044f \u043a \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c\u0443 <em>ha1.py<\/em><\/p>\n<pre><code class=\"python\">@router.message(filters.CommandStart()) async def start_bot(message: Message):     await message.answer(text='\u041f\u0440\u0438\u0432\u0435\u0442!\ud83d\ude01')     await message.answer(text='\u0422\u044b, \u043d\u0430\u0432\u0435\u0440\u043d\u043e\u0435, \u0437\u043d\u0430\u0435\u0448\u044c \u0446\u0435\u043b\u0438 \u043d\u0430\u0448\u0435\u0433\u043e \u0431\u043e\u0442\u0430\ud83d\ude42,\\n'                          '||\u043d\u043e \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \/help \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e \u043c\u043e\u0436\u0435\u0442 \u0442\u0435\u0431\u0435 \u043f\u043e\u043c\u043e\u0447\u044c||')     await message.answer(text='\u041f\u0435\u0440\u0435\u0434 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0439\u0442\u0438 \u0430\u043d\u043a\u0435\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\ud83d\ude42\\n'                          '||\u041c\u044b \u043d\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435, \u043e\u043d\u0438 \u043e\u0441\u0442\u0430\u043d\u0443\u0442\u0441\u044f \u043c\u0435\u0436\u0434\u0443 \u043d\u0430\u043c\u0438 (\u0434\u043b\u044f \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438)||', reply_markup=kb.ancet_start)  @router.message(filters.Command('help')) async def help(message: Message):     await message.answer(         text='\ud83d\udcda *\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b:*  \\n\\n'              '\ud83d\udd39 \/start - *\u043d\u0430\u0447\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0431\u043e\u0442\u043e\u043c*  \\n'              '\ud83d\udd39 \/help - *\u0432\u0441\u0435 \u043e\u0431\u044a\u044f\u0441\u043d\u0438\u0442*  \\n'              '\ud83d\udd39 \/ancet_fill - *\u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0430\u043d\u043a\u0435\u0442\u0443*  \\n'              '\ud83d\udd39 \/start_topic - *\u0430\u043d\u0430\u043b\u0438\u0437 \u0442\u0435\u043a\u0441\u0442\u0430*',         parse_mode=types.ParseMode.MARKDOWN_V2     ) @router.message(filters.Command('start_topic')) async def start_topic(message: Message):     await<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-437605","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/437605","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=437605"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/437605\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=437605"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=437605"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=437605"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}