<?xml version="1.0" encoding="utf-8" ?><rss version="2.0" xmlns:tt="http://teletype.in/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>Xacker_Name_new</title><generator>teletype.in</generator><description><![CDATA[Xacker_Name_new]]></description><image><url>https://img2.teletype.in/files/9b/cd/9bcd29bc-07b9-4287-ac8b-540336b493c1.png</url><title>Xacker_Name_new</title><link>https://teletype.in/@xacker_name_new</link></image><link>https://teletype.in/@xacker_name_new?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=xacker_name_new</link><atom:link rel="self" type="application/rss+xml" href="https://teletype.in/rss/xacker_name_new?offset=0"></atom:link><atom:link rel="next" type="application/rss+xml" href="https://teletype.in/rss/xacker_name_new?offset=10"></atom:link><atom:link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></atom:link><pubDate>Sat, 02 May 2026 08:12:02 GMT</pubDate><lastBuildDate>Sat, 02 May 2026 08:12:02 GMT</lastBuildDate><item><guid isPermaLink="true">https://teletype.in/@xacker_name_new/XGXxVf7NbPH</guid><link>https://teletype.in/@xacker_name_new/XGXxVf7NbPH?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=xacker_name_new</link><comments>https://teletype.in/@xacker_name_new/XGXxVf7NbPH?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=xacker_name_new#comments</comments><dc:creator>xacker_name_new</dc:creator><title>Обучение #5</title><pubDate>Fri, 20 Oct 2023 19:42:24 GMT</pubDate><media:content medium="image" url="https://img2.teletype.in/files/50/e3/50e31141-824f-4f69-8473-ed3aa0599887.png"></media:content><category>Обучение Python+aiogram+MySQL</category><description><![CDATA[<img src="https://img4.teletype.in/files/3a/72/3a720c74-3487-46cc-ac94-4ec752d144cc.png"></img>Обучение #5]]></description><content:encoded><![CDATA[
  <h3 id="9m4T" data-align="center">Хочу сразу извиниться за то что задержал урок, была срочная работа, думаю такого больше не повториться🥺</h3>
  <p id="S1uj"></p>
  <p id="PkGH">Сегодня мы научимся работать с API сайта 365sms.org (Новый домен 365sms.ru)</p>
  <p id="btqN">Давайте попробуем понять зачем нам это.</p>
  <ol id="SBqI">
    <li id="fBQH">Это для того что-бы мы в бота смогли пихать любые сервисы которые дают нам API для связи с ними (и не только в ботов)</li>
    <li id="S8An">Для автоматизации процессов</li>
  </ol>
  <p id="l1u3">Использовать будем такую библиотеку как <a href="https://pypi.org/project/requests/" target="_blank">requests</a></p>
  <pre id="EEgB">pip install requests</pre>
  <p id="4jA6">Переходим на сайт &quot;<a href="https://365sms.ru/api365" target="_blank">https://365sms.ru/api365</a>&quot;</p>
  <p id="wbIi">и читаем документацию...</p>
  <p id="Utku">Что нам это дало?</p>
  <figure id="ZESk" class="m_original">
    <img src="https://img2.teletype.in/files/5e/12/5e1292cf-44c0-48b5-b706-46deed6fc7e8.png" width="223" />
  </figure>
  <p id="DQeK">Есть несколько разделов в api документации<br />Давайте разберём каждый по порядку:</p>
  <ol id="eOuD">
    <li id="9YHx"><strong>Описание протокола API</strong> - это нам не особо интересно, разве что строка описывающая какие запросы нам нужны &quot;Все запросы (<strong>только GET</strong>) должны идти на данный адрес&quot;</li>
    <li id="W2lV"><strong>Запрос количества доступных номеров getNumbersStatus</strong> - описан примерный запрос к сайту для получения кол-во доступных номеров<br /><code>https://365sms.org/stubs/handler_api.php?api_key=APIKEY&amp;action=getNumbersStatus&amp;country=COUNTRY&amp;operator=OPERATOR</code><br /><br />А так же предоставлены переменные которые нужно будет заменить:<br /><strong>APIKEY </strong>- ключ обеспечивает доступ к оплаченным услугам<br /><strong>COUNTRY </strong>- Страна номера<br /><strong>OPERATOR </strong>- Оператор номера. Если параметр не задан, будет задействован случайный оператор<br /><br />Ну и ответ от сервиса после сделанного запроса в формате json (позже к нему перейдём)<br /><strong><code>{&quot;vk_0&quot;:890,&quot;ok_0&quot;:192,&quot;wa_0&quot;:146,&quot;vi_0&quot;:199,&quot;tg_0&quot;:101,&quot;wb_0&quot;:103,&quot;go_0&quot;:467,&quot;av_0&quot;:177,&quot;fb_0&quot;:132,&quot;tw_0&quot;:479}</code></strong></li>
    <li id="mNXV"><strong>Запрос баланса getBalance</strong> - Получаем текущий баланс аккаунта на сайте</li>
    <li id="Lprv"><strong>Заказ номера getNumber</strong> - с помощью этого метода будем запрашивать номер</li>
    <li id="tl2F"><strong>Изменить статус setStatus</strong> - этот метод нам позволит менять статус номера<br />Статусы:</li>
    <ol id="zbuc">
      <li id="XxZV"><em>3</em> - <strong>необходимо повторно смс</strong></li>
      <li id="V2ds"><em>6</em> - <strong>активация успешно завершена</strong></li>
      <li id="MAbf"><em>8</em> - <strong>отменить активацию</strong></li>
    </ol>
    <li id="sxuJ"><strong>Получить статус getStatus</strong> - с помощью данного метода мы получим статус номера (Статусы описаны выше)</li>
    <li id="uNI7"><strong>Запросить все цены getPrices</strong> - этот метод вернёт нам json объект со всеми ценами сервисов по ID страны<br /></li>
  </ol>
  <p id="NLFI">Давайте перейдём к методам запросов модуля requests</p>
  <p id="FbSy">Метод <strong>POST</strong>:</p>
  <blockquote id="5FNH"><em>Используется для отправки данных на сервер</em></blockquote>
  <p id="eFHP">Метод <strong>GET</strong>:</p>
  <blockquote id="Z52D"><em>Используется для получения данных с сервера</em></blockquote>
  <p id="pzgr"><strong>Использовать будем метод <em>GET</em></strong></p>
  <p id="hY92">Создаём папку bot_requests_365</p>
  <p id="XfR2">В папке создаём файлы:</p>
  <ol id="NTt9">
    <li id="g6R0">main.py - В нём будем писать весь код бота</li>
    <li id="2SUL">class_db.py - Скопируем в него модуль из предыдущих уроков</li>
    <li id="pwja">test.py - В нём будут клавиатуры</li>
    <li id="uWnw">config.py - В него будем записывать все данные (токены, id админов и т.п.)</li>
  </ol>
  <p id="Rann">И так у нас получилась папка с содержанием:</p>
  <figure id="BQK8" class="m_original">
    <img src="https://img1.teletype.in/files/c6/ef/c6efb7e8-eee2-4136-8a41-df664ceefcbb.png" width="657" />
  </figure>
  <p id="TXlG">Код для файла class_db.py:</p>
  <pre id="lReH" data-lang="python">import pymysql #Импортируем модуль pymysql который установили в первом уроке

class work_db:
	def __init__(self, host, port, user, password, database): #Функция для иницилизирования переменных в класс, запускать её не надо
		self.host = host
		self.port = port
		self.user = user
		self.password = password
		self.database = database

	def connect_db(self): #Функция для конекта к базе данных
		try:
			connection = pymysql.connect(
				host = self.host,
				port = self.port,
				user = self.user,
				password = self.password,
				database = self.database,
				cursorclass = pymysql.cursors.DictCursor
			)
			return connection #Если конект прошёл успешно, возвращаем переменную connection, для дальнейшей работы
		except Exception as eror:
			print(eror) #Если произошла ошибка, выводим её в консоль
			return False #Если произошла ошибка, возвращаем False

	def connect_close(self, connection): #Передаём переменную connection если в коде подключились, после каждого подключения к базе данных и выполнения какого-либо когда, нужно закрывать подключение
		try:
			connection.close() #Закрываем подключение к базе данных
			return True #Если успешно закрыли подключение к базе, возвращаем True
		except Exception as eror:
			print(eror) #Если произошла ошибка, выводим её в консоль
			return False #Если произошла ошибка, возвращаем False

	def create_table(self, connection, creat): #Функция для создания таблице в базе данных, в creat будем передавать текст запроса
		try:
			with connection.cursor() as cursor:
				cursor.execute(creat)
			connection.commit()
			return True
		except Exception as eror:
			print(eror) #Если произошла ошибка, выводим её в консоль
			return False #Если произошла ошибка, возвращаем False

	def edit_table(self, connection, zapros, values):
		try:
			with connection.cursor() as cursor:
				cursor.execute(zapros, values)
			connection.commit()
			return True
		except Exception as eror:
			print(eror) #Если произошла ошибка, выводим её в консоль
			return False #Если произошла ошибка, возвращаем False

	def info_table(self, connection, info, values): #Функция для получения данных из таблицы, в info будем передавать текст запроса
		try:
			with connection.cursor() as cursor:
				cursor.execute(info, values)
			return cursor.fetchall() #Возвращаем всё что нашли
		except Exception as eror:
			print(str(eror)+&#x27;\n\n&#x27;) #Если произошла ошибка, выводим её в консоль
			return False #Если произошла ошибка, возвращаем False

	def insert_table(self, connection, zapros, values):
		try:
			with connection.cursor() as cursor:
				a = cursor.execute(zapros, values)
			connection.commit()
			return a
		except Exception as eror:
			print(eror) #Если произошла ошибка, выводим её в консоль
			return False #Если произошла ошибка, возвращаем False

	def delete_from_table(self, connection, delete_, values): #Функция для редактирования данных в таблице, в delete_ будем передавать текст запроса
		try:
			with connection.cursor() as cursor:
				cursor.execute(delete_, values)
			connection.commit()
			return True
		except Exception as eror:
			print(eror) #Если произошла ошибка, выводим её в консоль
			return False #Если произошла ошибка, возвращаем False</pre>
  <p id="3PRv">И так создадим ещё 1 файл для удобно работы с api сайта <a href="https://365sms.ru/" target="_blank">365sms.ru</a></p>
  <p id="t2XI">Название файла: module_sms.py</p>
  <p id="L2vb">Напишем для этого файла следующий код:</p>
  <pre id="vInI" data-lang="python">import requests

class main_sms:
	def __init__(self, token):
		self.token = token #Токен будем передавать в класс
		self.link = &#x27;https://365sms.ru/stubs/handler_api.php&#x27; #Ссылка для работы с api берём с сайта


	def get_balanse(self): #Функция для получения текущего баланса на сайте
		balans = requests.get(f&#x27;{self.link}?api_key={self.token}&amp;action=getBalance&#x27;) #Делаем get апрос для получения данных
		if &#x27;ACCESS_BALANCE&#x27; in balans.text: #если мы успешно получили баланс то возращаем его
			spisok = balans.text.split(&#x27;:&#x27;) #Сплитуем(разделяем) текст по : который получили в ответе от сайта
			return spisok[1] #Возращаем баланс
		else:
			return balans.text #В ином случае возращаем весь текст который получили, для дальнейшей обработки


	def new_number(self, servis, strana, operator=None): #Функия для получения номера телефона
		if operator == None: #Если мы не передали оператор, то сайт нам выдаст рандомного оператора
			number = requests.get(f&#x27;{self.link}?api_key={self.token}&amp;action=getNumber&amp;service={servis}&amp;country={strana}&#x27;) #Делаем гет запрос без учёта оператора
		else: #В ином случае мы передаём в запрос ещё и оператора
			number = requests.get(f&#x27;{self.link}?api_key={self.token}&amp;action=getNumber&amp;service={servis}&amp;operator={operator}&amp;country={strana}&#x27;)#Делаем гет запрос с учётом оператора
		return number.text #Возращаем всё что получили в ответ от сайта

	def new_status(self, idi, status): #Функция для изменения статуса номера
		stat = requests.get(f&#x27;{self.link}?api_key={self.token}&amp;action=setStatus&amp;status={status}&amp;id={idi}&#x27;) #Делаем гет запрос
		return stat.text #Возращаем всё что получили в ответ от сайта

	def get_status(self, idi): #Получаем статус номера по его id
		stat = requests.get(f&#x27;{self.link}?api_key={self.token}&amp;action=getStatus&amp;id={idi}&#x27;) #Делаем гет запрос
		return stat.text #Возращаем всё что получили в ответ от сайта

	def get_all_price(self, strana, servis=None):
		if servis == None: #Если не передали сервис
			spisok = requests.get(f&#x27;{self.link}?api_key={self.token}&amp;action=getPrices&amp;country={strana}&#x27;) #Делаем гет запрос без учёта сервиса
		else: #В ином случае при передаче сервиса
			spisok = requests.get(f&#x27;{self.link}?api_key={self.token}&amp;action=getPrices&amp;service={servis}&amp;country={strana}&#x27;) #Делаем гет запрос с учётом сервиса
		return spisok.json() #Возращаем всё что получили в ответ от сайта в формате json</pre>
  <p id="Cl8G">Давайте перейдём к файлу test.py:</p>
  <p id="glC9">И напишем в него код с клавиатурой (для начала напишем 1 текстовую кнопку):</p>
  <pre id="XjHI" data-lang="python">from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton, KeyboardButton, ReplyKeyboardMarkup


mainy = [[&#x27;Получить баланс&#x27;]]
mark_menu = ReplyKeyboardMarkup(mainy, resize_keyboard=True)</pre>
  <p id="au2E">Клавиатура создана, перейдём к файлу config.py:</p>
  <pre id="nO2O" data-lang="python">token_bot = &#x27;Токен вашего бота&#x27;
admin = Ваш id телеграма в формате 123
token_sms = &#x27;Токен с сайта 365sms.ru/account&#x27;
#Данные для подключения к базе данных
host = &#x27;localhost&#x27;
port = 8080
user = &#x27;root&#x27;
password = &#x27;password&#x27;
database = &#x27;database_sms&#x27;</pre>
  <p id="2YSa">Токен бота берём в <a href="https://t.me/BotFather" target="_blank">@BotFather</a></p>
  <p id="qqSG">ID берём из <a href="https://t.me/Bsc_Black_Secret_Club_bot" target="_blank">@Bsc_Black_Secret_Club_bot</a> -&gt; Профиль</p>
  <p id="AaZJ">Токен смс берём с <a href="https://365sms.ru/account" target="_blank">365sms.ru/account</a></p>
  <figure id="0hnX" class="m_custom">
    <img src="https://img1.teletype.in/files/46/6e/466e21d0-f465-48ff-83a3-37bf28324e96.png" width="1059" />
    <figcaption>Берём из этого поля</figcaption>
  </figure>
  <p id="WgFW">Перейдём к самому интересному, к файлу main.py:</p>
  <p id="WBoM">Импортируем нужные нам модули:</p>
  <pre id="8IF7" data-lang="python">from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton, KeyboardButton, ReplyKeyboardMarkup, BotCommand, WebAppInfo
from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.contrib.fsm_storage.memory import MemoryStorage
from aiogram import Bot, Dispatcher, executor, types
from aiogram.dispatcher import FSMContext
import config as c
import test as bb
import asyncio
import pymysql
from class_db import work_db
from module_sms import main_sms</pre>
  <p id="HhAL">Давайте напишем все экземпляры классов которые нам понадобятся:</p>
  <pre id="7tJr" data-lang="python">bot = Bot(token=c.token_bot, parse_mode=types.ParseMode.HTML) #Берём токен бота из файла config.py который импортировали ранее в переменную c
dp = Dispatcher(bot, storage=MemoryStorage())
db_work = work_db(c.host, c.port, c.user, c.password, c.database) #Создаём экземпляр класса для работы с базой данных, передав все нужные параметры из конфига
work_sms = main_sms(c.token_sms) #Создаём экземпляр класса для работы с сервисом смс</pre>
  <p id="8Act">Напишем обработчик всего текста, в который напишем обработку команды /start и текстовой кнопки &quot;Получить баланс&quot;:</p>
  <pre id="jvRP" data-lang="python">@dp.message_handler(content_types=[&#x27;text&#x27;])
async def text(message: types.Message):
    id_user = message.from_user.id #Записываем id пользователя (Ранее писали message.chat.id)
    if message.text == &#x27;/start&#x27;:
    	await bot.send_message(id_user, &#x27;Хай, вы попали в смс бота для работы с сайтом 365sms.ru&#x27;, reply_markup=bb.mark_menu) #При команде старт отправляем приветственное сообщение и рассказываем о себе, и выводим клавиатуру
    elif message.text == &#x27;Получить баланс&#x27;:
    	balanse_sms = work_sms.get_balanse() #Запрашиваем баланс с сайта по api
    	await bot.send_message(id_user, f&#x27;Текущий баланс: {balanse_sms}₽&#x27;) #Пока выводим то что получили от сайта</pre>
  <p id="ox9K">У нас получился такой код:</p>
  <pre id="0gvA" data-lang="python">from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton, KeyboardButton, ReplyKeyboardMarkup, BotCommand, WebAppInfo
from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.contrib.fsm_storage.memory import MemoryStorage
from aiogram import Bot, Dispatcher, executor, types
from aiogram.dispatcher import FSMContext
import config as c
import test as bb
import asyncio
import pymysql
from class_db import work_db
from module_sms import main_sms



bot = Bot(token=c.token_bot, parse_mode=types.ParseMode.HTML) #Берём токен бота из файла config.py который импортировали ранее в переменную c
dp = Dispatcher(bot, storage=MemoryStorage())
db_work = work_db(c.host, c.port, c.user, c.password, c.database) #Создаём экземпляр класса для работы с базой данных, передав все нужные параметры из конфига
work_sms = main_sms(c.token_sms) #Создаём экземпляр класса для работы с сервисом смс



@dp.message_handler(content_types=[&#x27;text&#x27;])
async def text(message: types.Message):
    id_user = message.from_user.id #Записываем id пользователя (Ранее писали message.chat.id)
    if message.text == &#x27;/start&#x27;:
    	await bot.send_message(id_user, &#x27;Хай, вы попали в смс бота для работы с сайтом 365sms.ru&#x27;, reply_markup=bb.mark_menu) #При команде старт отправляем приветственное сообщение и рассказываем о себе, и выводим клавиатуру
    elif message.text == &#x27;Получить баланс&#x27;:
    	balanse_sms = work_sms.get_balanse() #Запрашиваем баланс с сайта по api
    	await bot.send_message(id_user, f&#x27;Текущий баланс: {balanse_sms}₽&#x27;) #Пока выводим то что получили от сайта



if __name__ == &quot;__main__&quot;:
    executor.start_polling(dp, skip_updates=True)</pre>
  <p id="D7in">Запускаем и проверяем работоспособность:</p>
  <figure id="TKFT" class="m_original">
    <img src="https://img4.teletype.in/files/b4/aa/b4aada72-23fe-4aa4-95c9-d9c1e7b24657.png" width="511" />
  </figure>
  <p id="vLAT">Работает, отлично, теперь давайте сделаем обработчик ошибок:</p>
  <p id="liGG">Возможные ошибки у метода гет баланс:</p>
  <figure id="JhnF" class="m_original">
    <img src="https://img1.teletype.in/files/84/4d/844d37fa-ef6b-4e8a-8dd7-32c0249a9236.png" width="402" />
  </figure>
  <p id="m12r">И так у нас получился такой код:</p>
  <pre id="QPE6" data-lang="python">elif message.text == &#x27;Получить баланс&#x27;:
    	balanse_sms = work_sms.get_balanse() #Запрашиваем баланс с сайта по api
    	try:
    		await bot.send_message(id_user, f&#x27;Текущий баланс: {float(balanse_sms):.2f}₽&#x27;) #Пока выводим то что получили от сайта
    	except:
    		if &#x27;BAD_KEY&#x27; in balanse_sms:
    			await bot.send_message(id_user, &#x27;Не правильный токен для запроса, проверьте и обновите его!&#x27;) #Если указали не верный токен
    		elif &#x27;ERROR_SQL&#x27; in balanse_sms:
    			await bot.send_message(id_user, &#x27;Ошибка на стороне сайта поопробуйте позже!&#x27;) #Если на сайте произошла ошибка
    		else:
    			await bot.send_message(id_user, &#x27;Ваш запрос был составлен не правильно!&#x27;) #Если мы не правильно составили запрос (в уроке такого не будет)</pre>
  <p id="4maR">Давайте впишем не правильный токен в конфиг -&gt; токен смс</p>
  <figure id="14Le" class="m_original">
    <img src="https://img4.teletype.in/files/7f/97/7f97e6b3-efab-406c-bbc6-8d279045d255.png" width="174" />
  </figure>
  <p id="ruuf">Запускаем и проверяем обработку ошибок:</p>
  <p id="M0oh">Всё работает, мы молодцы!</p>
  <figure id="Lw84" class="m_original">
    <img src="https://img2.teletype.in/files/54/9a/549a1583-b6e9-4a27-a9e0-773174d9e133.png" width="497" />
  </figure>
  <p id="XGIv">Давайте добавим инлайн кнопку к сообщению с балансом (обновить)</p>
  <p id="dcTQ">Сделаем интересную систему и добавим время к сообщению:</p>
  <p id="EuSF">Добавим импорты модулей для работы со временем:</p>
  <pre id="CsFO" data-lang="python">from datetime import datetime
import pytz</pre>
  <p id="0GTC">Создадим функцию которая поможет нам получать время в Москве (в формате Часы:Минуты:Секунды):</p>
  <pre id="BiEs" data-lang="python">def time_Moscow():
	# Устанавливаем часовой пояс Москвы
	moscow_tz = pytz.timezone(&#x27;Europe/Moscow&#x27;)

	# Получаем текущее время в часовом поясе Москвы
	moscow_time = datetime.now(moscow_tz)

	# Форматируем время в часы:минуты:секунды
	formatted_time = moscow_time.strftime(&#x27;%H:%M:%S&#x27;)
	return str(formatted_time) #Возвращаем строку с временем</pre>
  <p id="2B65">Обновим обработчик кнопки получить баланс:</p>
  <pre id="koZd" data-lang="python">elif message.text == &#x27;Получить баланс&#x27;:
    	balanse_sms = work_sms.get_balanse() #Запрашиваем баланс с сайта по api
    	time_msk = time_Moscow() #Получаем время мск
    	try:
    		await bot.send_message(id_user, f&#x27;&lt;b&gt;[{time_msk}]&lt;/b&gt; Текущий баланс: {float(balanse_sms):.2f}₽&#x27;, reply_markup=InlineKeyboardMarkup(row_width=1).add(
    		InlineKeyboardButton(text=&#x27;Обновить&#x27;, callback_data=&#x27;new_balance&#x27;))) #Пока выводим то что получили от сайта
    	except:
    		if &#x27;BAD_KEY&#x27; in balanse_sms:
    			await bot.send_message(id_user, &#x27;Не правильный токен для запроса, проверьте и обновите его!&#x27;) #Если указали не верный токен
    		elif &#x27;ERROR_SQL&#x27; in balanse_sms:
    			await bot.send_message(id_user, &#x27;Ошибка на стороне сайта поопробуйте позже!&#x27;) #Если на сайте произошла ошибка
    		else:
    			await bot.send_message(id_user, &#x27;Ваш запрос был составлен не правильно!&#x27;) #Если мы не правильно составили запрос (в уроке такого не будет)</pre>
  <p id="epFT">Добавлено:</p>
  <ol id="yUpx">
    <li id="7oqW">Получение времени в Москве</li>
    <li id="jbsG">Вывод времени и баланса c кнопкой обновить</li>
  </ol>
  <pre id="QgRm" data-lang="python">await bot.send_message(id_user, f&#x27;&lt;b&gt;[{time_msk}]&lt;/b&gt; Текущий баланс: {float(balanse_sms):.2f}₽&#x27;, reply_markup=InlineKeyboardMarkup(row_width=1).add(
    		InlineKeyboardButton(text=&#x27;Обновить&#x27;, callback_data=&#x27;new_balance&#x27;))) #Пока выводим то что получили от сайта</pre>
  <p id="3K8O">Давайте напишем обработчик инлайн кнопок и напишем обработку нажатия кнопки обновить:</p>
  <pre id="MTJc" data-lang="python">@dp.callback_query_handler(lambda call: True, state=&#x27;*&#x27;)
async def callback_inline(call, state: FSMContext):
    id_user = call.from_user.id
    if call.data == &#x27;new_balance&#x27;:
    	time_msk = time_Moscow() #Получаем время мск
    	balanse_sms = work_sms.get_balanse() #Запрашиваем баланс с сайта по api
    	await bot.edit_message_text(chat_id=id_user, message_id=call.message.message_id, text=f&#x27;{call.message.html_text}\n&lt;b&gt;[{time_msk}]&lt;/b&gt; Текущий баланс: {float(balanse_sms):.2f}₽&#x27;, reply_markup=InlineKeyboardMarkup(row_width=1).add(
    		InlineKeyboardButton(text=&#x27;Обновить&#x27;, callback_data=&#x27;new_balance&#x27;)))</pre>
  <ol id="Zq3h">
    <li id="fTcZ">edit_message_text - с помощью этого метода у бота, мы будем редактировать сообщение</li>
  </ol>
  <p id="bPoA">Давайте проверим как это работает:</p>
  <figure id="bLJS" class="m_original">
    <img src="https://img1.teletype.in/files/87/ba/87ba4794-0153-4e7d-9232-72ed4ab92eaa.png" width="326" />
  </figure>
  <p id="eQDO">Время работает, а что на счёт кнопки обновить?</p>
  <figure id="mvEa" class="m_original">
    <img src="https://img3.teletype.in/files/67/a5/67a5570e-5b6b-4ef0-b3a7-4cc928197b3c.png" width="332" />
  </figure>
  <p id="BIaB">Тоже работает, отлично!</p>
  <p id="zwPZ">Давайте добавим кнопку получить номер?</p>
  <p id="qq21">Конечно давайте, я вас не буду спрашивать а просто напишу)</p>
  <blockquote id="sVEw">Признайся, улыбнулся?)</blockquote>
  <p id="vOxh">В файл test.py меняем код на:</p>
  <pre id="jLGm" data-lang="python">mainy = [[&#x27;Получить баланс&#x27;, &#x27;Получить номер&#x27;]]
mark_menu = ReplyKeyboardMarkup(mainy, resize_keyboard=True)</pre>
  <p id="1k8p">Напишем обработчик новой кнопки:</p>
  <pre id="o5UF" data-lang="python">elif message.text == &#x27;Получить номер&#x27;:
    	#Будем получать номер для вк без оператора и регистрироваться через бота (Страну возьмём индонезию потому что дёшево ID: 6)
    	number = work_sms.new_number(servis=&#x27;vk&#x27;, strana=6)
    	#Обработаем ошибки:
    	if number == &#x27;NO_NUMBERS&#x27;: #Если пришёл ответ что нет номеров
    		await bot.send_message(id_user, &#x27;Нет номеров с заданными параметрами, попробуйте позже, или поменяйте оператора, страну&#x27;, reply_markup=bb.mark_menu)
    	elif number == &#x27;NO_BALANCE&#x27;: #Если на балансе не хватает денег на номер телефона
    		await bot.send_message(id_user, &#x27;Закончились деньги на аккаунте&#x27;, reply_markup=bb.mark_menu)
    	elif number == &#x27;WRONG_SERVICE&#x27;: #Если не правильно указали &quot;servis&quot;
    		await bot.send_message(id_user, &#x27;Неверный идентификатор сервиса&#x27;, reply_markup=bb.mark_menu)
    	else: #Если номер упешно получен
    		#В ответе будет такой формат: ACCESS_NUMBER:ID:NUMBER - Пример: ACCESS_NUMBER:234242:79123456789
    		#Делим ответ на список:
    		info_number = number.split(&#x27;:&#x27;)
    		#Итоговый список будет выглядеть так: [&#x27;ACCESS_NUMBER&#x27;, &#x27;ID&#x27;, &#x27;NUMBER&#x27;] - Пример: [&#x27;ACCESS_NUMBER&#x27;, &#x27;234242&#x27;, &#x27;79123456789&#x27;]
    		#Индексы списка начинаються с 0
    		#т.е с индексом 0 - &#x27;ACCESS_NUMBER&#x27;, c индексом 1 - &#x27;ID&#x27;, c индексом 2 - &#x27;NUMBER&#x27;
    		#Отправляем данные пользователю:
    		await bot.send_message(id_user, f&#x27;ID номера: {info_number[1]}\nНомер: &lt;code&gt;{info_number[2]}&lt;/code&gt;&#x27;, reply_markup=InlineKeyboardMarkup(row_width=1).add(
    			InlineKeyboardButton(text=&#x27;Изменить статус&#x27;, callback_data=f&#x27;new_status_{info_number[1]}&#x27;))) #Передаём id номера в callback_data</pre>
  <p id="QkNR">Давайте добавим кнопки к последнему сообщению для работы с номером, например сделаем кнопку для <a href="#tl2F">обновления статуса:</a></p>
  <pre id="7JiO" data-lang="python">await bot.send_message(f&#x27;ID номера: {info_number[1]}\nНомер: &lt;code&gt;{info_number[2]}&lt;/code&gt;&#x27;, reply_markup=InlineKeyboardMarkup(row_width=1).add(
    			InlineKeyboardButton(text=&#x27;Изменить статус&#x27;, callback_data=f&#x27;new_status_{info_number[1]}&#x27;))) #Передаём id номера в callback_data</pre>
  <p id="UEWm">Давайте напишем обработчик нажатия этой кнопки:</p>
  <pre id="l1cl" data-lang="python">elif &#x27;new_status_&#x27; in call.data: #В call.data содержиться callback_data
    	id_number = int(call.data.replace(&#x27;new_status_&#x27;, &#x27;&#x27;)) #С момощью этого кода мы получим число типа int, удалив из call.data не нужное нам
		#Грубыми словами с помощью replace мы заменяем new_status_ на ничего
		#Отправим клавиатуру с дальнейшими статусами, перед этим проверив текущий статус номера</pre>
  <p id="XmX4">Сейчас нам нужно проверить текущий статус номера:</p>
  <pre id="CIe0" data-lang="python">elif &#x27;new_status_&#x27; in call.data: #В call.data содержиться callback_data
    	id_number = int(call.data.replace(&#x27;new_status_&#x27;, &#x27;&#x27;)) #С момощью этого кода мы получим число типа int, удалив из call.data не нужное нам
    	#Грубыми словами с помощью replace мы заменяем new_status_ на ничего
    	#Отправим клавиатуру с дальнейшими статусами, перед этим проверив текущий статус номера
    	status_number = work_sms.get_status(idi=id_number)
    	#Давайте в зависимости от статуса выведем клавиатуру:
    	if status_number == &#x27;STATUS_WAIT_CODE&#x27;: #Данный статус будет после получения номера он означает &quot;Ожидание смс&quot;
    		await call.answer(&#x27;Текущий статус: Ожидает смс&#x27;, show_alert=True) #Выводим табличку с текущим статусом (show_alert позваляет вывести табличку с кнопко &quot;ОК&quot;)
    	elif status_number == &#x27;STATUS_CANCEL&#x27;: #Данный статус будет после отмены номера он означает &quot;Активация отменена&quot;
    		await call.answer(&#x27;Текущий статус: Активация отменена&#x27;, show_alert=True) #Выводим табличку с текущим статусом (show_alert позваляет вывести табличку с кнопко &quot;ОК&quot;)
    	else: #Т.к. больше статусов которые может вернуть сайт нет, будем обабатывать успешное получение смс
    		#Делим полученное сообение на список с помощью split
    		kode_aktivate = status_number.split(&#x27;:&#x27;) #Получили список [&quot;STATUS_OK&quot;, &quot;CODE&quot;]
    		await call.answer(f&#x27;Текущий статус: Смс получено\nКод: {kode_aktivate[1]}&#x27;, show_alert=True)</pre>
  <p id="l2qK">Давайте обозначим каждый статус своей цифрой:</p>
  <pre id="KA0Q" data-lang="python">elif &#x27;new_status_&#x27; in call.data: #В call.data содержиться callback_data
    	id_number = int(call.data.replace(&#x27;new_status_&#x27;, &#x27;&#x27;)) #С момощью этого кода мы получим число типа int, удалив из call.data не нужное нам
    	#Грубыми словами с помощью replace мы заменяем new_status_ на ничего
    	#Отправим клавиатуру с дальнейшими статусами, перед этим проверив текущий статус номера
    	status_number = work_sms.get_status(idi=id_number)
    	#Давайте в зависимости от статуса выведем клавиатуру:
    	if status_number == &#x27;STATUS_WAIT_CODE&#x27;: #Данный статус будет после получения номера он означает &quot;Ожидание смс&quot;
    		int_status = 0 #Поставим 0 будет означать что номер только что получен
    		await call.answer(&#x27;Текущий статус: Ожидает смс&#x27;, show_alert=True) #Выводим табличку с текущим статусом (show_alert позваляет вывести табличку с кнопко &quot;ОК&quot;)
    	elif status_number == &#x27;STATUS_CANCEL&#x27;: #Данный статус будет после отмены номера он означает &quot;Активация отменена&quot;
    		int_status = 1 #Поставим 1 будет означать что номер больше не активен (отменён)
    		await call.answer(&#x27;Текущий статус: Активация отменена&#x27;, show_alert=True) #Выводим табличку с текущим статусом (show_alert позваляет вывести табличку с кнопко &quot;ОК&quot;)
    	else: #Т.к. больше статусов которые может вернуть сайт нет, будем обабатывать успешное получение смс
    		#Делим полученное сообение на список с помощью split
    		kode_aktivate = status_number.split(&#x27;:&#x27;) #Получили список [&quot;STATUS_OK&quot;, &quot;CODE&quot;]
    		int_status = 2 #Поставим 2 будет означать что смс получен
    		await call.answer(f&#x27;Текущий статус: Смс получено\nКод: {kode_aktivate[1]}&#x27;, show_alert=True)</pre>
  <p id="mt3q">Статусы обозначили, теперь давайте под каждый статус сделаем свою клавиатуру:</p>
  <pre id="c2Yh" data-lang="python">elif &#x27;new_status_&#x27; in call.data: #В call.data содержиться callback_data
    	id_number = int(call.data.replace(&#x27;new_status_&#x27;, &#x27;&#x27;)) #С момощью этого кода мы получим число типа int, удалив из call.data не нужное нам
    	#Грубыми словами с помощью replace мы заменяем new_status_ на ничего
    	#Отправим клавиатуру с дальнейшими статусами, перед этим проверив текущий статус номера
    	status_number = work_sms.get_status(idi=id_number)
    	#Давайте в зависимости от статуса выведем клавиатуру:
    	if status_number == &#x27;STATUS_WAIT_CODE&#x27;: #Данный статус будет после получения номера он означает &quot;Ожидание смс&quot;
    		int_status = 0 #Поставим 0 будет означать что номер только что получен
    		await call.answer(&#x27;Текущий статус: Ожидает смс&#x27;, show_alert=True) #Выводим табличку с текущим статусом (show_alert позваляет вывести табличку с кнопко &quot;ОК&quot;)
    	elif status_number == &#x27;STATUS_CANCEL&#x27;: #Данный статус будет после отмены номера он означает &quot;Активация отменена&quot;
    		int_status = 1 #Поставим 1 будет означать что номер больше не активен (отменён)
    		await call.answer(&#x27;Текущий статус: Активация отменена&#x27;, show_alert=True) #Выводим табличку с текущим статусом (show_alert позваляет вывести табличку с кнопко &quot;ОК&quot;)
    	else: #Т.к. больше статусов которые может вернуть сайт нет, будем обабатывать успешное получение смс
    		#Делим полученное сообение на список с помощью split
    		kode_aktivate = status_number.split(&#x27;:&#x27;) #Получили список [&quot;STATUS_OK&quot;, &quot;CODE&quot;]
    		int_status = 2 #Поставим 2 будет означать что смс получен
    		await call.answer(f&#x27;Текущий статус: Смс получено\nКод: {kode_aktivate[1]}&#x27;, show_alert=True)
    	#Сделаем стандартную клавиатуру с дефолтной нопкой:
    	klawa = InlineKeyboardMarkup(row_width=1).add(InlineKeyboardButton(text=&#x27;Узнать статус&#x27;, callback_data=f&#x27;new_status_{id_number}&#x27;))
    	if int_status == 0:
    		klawa.add(InlineKeyboardButton(text=&#x27;Отменить активацию&#x27;, callback_data=f&#x27;cancel_akt_{id_number}&#x27;))
    	elif int_status == 1:
    		klawa.add(InlineKeyboardButton(text=&#x27;Получить новый номер&#x27;, callback_data=&#x27;new_number&#x27;))
    	else:
    		klawa.add(InlineKeyboardButton(text=&#x27;Подтвердить SMS-код и завершить активацию&#x27;, callback_data=f&#x27;true_aktiv_{id_number}&#x27;),
    			InlineKeyboardButton(text=&#x27;Запросить еще одну смс&#x27;, callback_data=f&#x27;dop_sms_{id_number}&#x27;))
    	await bot.edit_message_text(chat_id=id_user, message_id=call.message.message_id, text=call.message.html_text, reply_markup=klawa)</pre>
  <p id="b6Ra">Создали и отредактировали сообщение, теперь сделаем проверку try except, т.к. aiogram не позволяет редактировать сообщение на тот же самый текст что и был (что и с кнопками):</p>
  <pre id="4T9z" data-lang="python">elif &#x27;new_status_&#x27; in call.data: #В call.data содержиться callback_data
    	id_number = int(call.data.replace(&#x27;new_status_&#x27;, &#x27;&#x27;)) #С момощью этого кода мы получим число типа int, удалив из call.data не нужное нам
    	#Грубыми словами с помощью replace мы заменяем new_status_ на ничего
    	#Отправим клавиатуру с дальнейшими статусами, перед этим проверив текущий статус номера
    	status_number = work_sms.get_status(idi=id_number)
    	#Давайте в зависимости от статуса выведем клавиатуру:
    	if status_number == &#x27;STATUS_WAIT_CODE&#x27;: #Данный статус будет после получения номера он означает &quot;Ожидание смс&quot;
    		int_status = 0 #Поставим 0 будет означать что номер только что получен
    		await call.answer(&#x27;Текущий статус: Ожидает смс&#x27;, show_alert=True) #Выводим табличку с текущим статусом (show_alert позваляет вывести табличку с кнопко &quot;ОК&quot;)
    	elif status_number == &#x27;STATUS_CANCEL&#x27;: #Данный статус будет после отмены номера он означает &quot;Активация отменена&quot;
    		int_status = 1 #Поставим 1 будет означать что номер больше не активен (отменён)
    		await call.answer(&#x27;Текущий статус: Активация отменена&#x27;, show_alert=True) #Выводим табличку с текущим статусом (show_alert позваляет вывести табличку с кнопко &quot;ОК&quot;)
    	else: #Т.к. больше статусов которые может вернуть сайт нет, будем обабатывать успешное получение смс
    		#Делим полученное сообение на список с помощью split
    		kode_aktivate = status_number.split(&#x27;:&#x27;) #Получили список [&quot;STATUS_OK&quot;, &quot;CODE&quot;]
    		int_status = 2 #Поставим 2 будет означать что смс получен
    		await call.answer(f&#x27;Текущий статус: Смс получено\nКод: {kode_aktivate[1]}&#x27;, show_alert=True)
    	#Сделаем стандартную клавиатуру с дефолтной нопкой:
    	klawa = InlineKeyboardMarkup(row_width=1).add(InlineKeyboardButton(text=&#x27;Узнать статус&#x27;, callback_data=f&#x27;new_status_{id_number}&#x27;))
    	if int_status == 0:
    		klawa.add(InlineKeyboardButton(text=&#x27;Отменить активацию&#x27;, callback_data=f&#x27;cancel_akt_{id_number}&#x27;))
    	elif int_status == 1:
    		klawa.add(InlineKeyboardButton(text=&#x27;Получить новый номер&#x27;, callback_data=&#x27;new_number&#x27;))
    	else:
    		klawa.add(InlineKeyboardButton(text=&#x27;Подтвердить SMS-код и завершить активацию&#x27;, callback_data=f&#x27;true_aktiv_{id_number}&#x27;),
    			InlineKeyboardButton(text=&#x27;Запросить еще одну смс&#x27;, callback_data=f&#x27;dop_sms_{id_number}&#x27;))
    	try: #Если смогли отредактировать сообщение
    		await bot.edit_message_text(chat_id=id_user, message_id=call.message.message_id, text=call.message.html_text, reply_markup=klawa)
    	except: #Если произошла любая ошибка
    		pass</pre>
  <p id="HO9U">Давайте проверим что мы с вами написали:</p>
  <figure id="4AS1" class="m_custom">
    <img src="https://img4.teletype.in/files/f7/da/f7daced0-9818-4c56-baa5-12bcedb6460e.png" width="707" />
  </figure>
  <p id="IhJ6">Всё работает, а что на счёт кнопки?<br />Давайте проверять:</p>
  <figure id="ydBz" class="m_custom">
    <img src="https://img1.teletype.in/files/05/7e/057eb163-f8c2-4015-aefe-f3d280af62c4.png" width="682" />
  </figure>
  <p id="DSgb">Работает и даже кнопки поменялись)</p>
  <p id="CpKP">Дальше проверим получение статуса путём нажатия на кнопку:</p>
  <figure id="kLdQ" class="m_original">
    <img src="https://img3.teletype.in/files/28/49/28498069-7f93-4b26-9493-92ded992caeb.png" width="401" />
  </figure>
  <p id="9WrE">И она работает, давайте начнём регистрировать аккаунт в вк на этот номер</p>
  <p id="6yp9">И так я отправил смс на номер, давайте проверим статус</p>
  <figure id="AgOr" class="m_custom">
    <img src="https://img2.teletype.in/files/1d/0b/1d0b535d-57e6-4f4f-a303-5bc985a8275c.png" width="691" />
  </figure>
  <p id="9nDw">Зарегать вк не получилось, смс на номер индонезии не приходит (отменил номер на сайте), решил поменять на рф озон, меняем код:</p>
  <pre id="XMnQ" data-lang="python">elif message.text == &#x27;Получить номер&#x27;:
    	#Будем получать номер для вк без оператора и регистрироваться через бота (Страну возьмём индонезию потому что дёшево ID: 6)
    	number = work_sms.new_number(servis=&#x27;sg&#x27;, strana=0)</pre>
  <p id="lSxn">У рф код страны 0<br />У озона код sg</p>
  <p id="LPND">Получаем новый номер через бота:</p>
  <figure id="157m" class="m_custom">
    <img src="https://img3.teletype.in/files/65/87/65876724-c3f8-4e24-8128-6e0f896b5bde.png" width="712" />
  </figure>
  <p id="SDsX">Нажимаем на кнопку изменить статус</p>
  <p id="n3o4">Далее отправляем смс с озона:</p>
  <figure id="vaws" class="m_original">
    <img src="https://img3.teletype.in/files/e4/86/e486b6b6-ced6-4b0f-86f4-fc60b441c52c.png" width="520" />
  </figure>
  <p id="ZRVT">Ждём, нажимаем на кнопку получить смс код</p>
  <p id="y4k9">Смс опять не приходит...</p>
  <p id="LLdO">Решил попробовать Qiwi, и наконец то получилось, ну ладно не суть</p>
  <pre id="IiOy" data-lang="python">number = work_sms.new_number(servis=&#x27;qw&#x27;, strana=0)</pre>
  <p id="Catl">На сайте есть код из смс:</p>
  <figure id="FS7n" class="m_custom">
    <img src="https://img4.teletype.in/files/b1/fb/b1fbec26-bb41-4ba8-b4b6-1bfde85b95f0.png" width="1020" />
  </figure>
  <p id="MvNv">Проверим статус через бота:</p>
  <figure id="aI7t" class="m_original">
    <img src="https://img3.teletype.in/files/61/9e/619ed30a-9217-4b05-9372-951deda18743.png" width="362" />
  </figure>
  <p id="21Vz">Работает, и опять же кнопки поменялись</p>
  <p id="0b8L">Давайте напишем обработчик кнопки &quot;Запросить ещё одну смс&quot;</p>
  <pre id="HGEs" data-lang="python">elif &#x27;dop_sms_&#x27; in call.data:
    	id_number = call.data.replace(&#x27;dop_sms_&#x27;, &#x27;&#x27;)
    	await call.answer(&#x27;Новый статус установлен&#x27;, show_alert=True)
    	work_sms.new_status(idi=id_number, status=3) #Устанавливаем статус 3 - нужна повторная смс
    	klawa = InlineKeyboardMarkup(row_width=1).add(InlineKeyboardButton(text=&#x27;Узнать статус&#x27;, callback_data=f&#x27;new_status_{id_number}&#x27;),
    		InlineKeyboardButton(text=&#x27;Подтвердить SMS-код и завершить активацию&#x27;, callback_data=f&#x27;true_aktiv_{id_number}&#x27;))
    	await bot.edit_message_text(chat_id=id_user, message_id=call.message.message_id, text=call.message.html_text, reply_markup=klawa)</pre>
  <p id="YmHR">Теперь проверим как она работает</p>
  <figure id="4pRk" class="m_custom">
    <img src="https://img2.teletype.in/files/99/e5/99e56484-d8d1-4558-8695-2e52d553643c.png" width="988" />
  </figure>
  <p id="BYL8">Запросил код для отключения смс оповещений:</p>
  <figure id="squZ" class="m_original">
    <img src="https://img3.teletype.in/files/2d/29/2d295c0e-c967-4101-800c-88445a7c710e.png" width="347" />
  </figure>
  <p id="jtyU">Ждём...<br />Пришёл</p>
  <figure id="XvQm" class="m_custom">
    <img src="https://img3.teletype.in/files/ac/79/ac791d2d-8183-458f-b6c9-1ef00bbf766e.png" width="970" />
  </figure>
  <p id="njUO">Проверяем в боте</p>
  <figure id="6LiD" class="m_original">
    <img src="https://img2.teletype.in/files/51/04/51040966-7321-4993-9ecb-ca28a2f39e31.png" width="349" />
  </figure>
  <p id="1rRb">Хорошо, работает)</p>
  <p id="Y9nc">Напишем обработчик кнопки &quot;Подтвердить SMS-код и завершить активацию&quot;:</p>
  <pre id="L6bD" data-lang="python">elif &#x27;true_aktiv_&#x27; in call.data:
    	id_number = call.data.replace(&#x27;true_aktiv_&#x27;, &#x27;&#x27;)
    	await call.answer(&#x27;Новый статус установлен&#x27;, show_alert=True)
    	work_sms.new_status(idi=id_number, status=6) #Устанавливаем статус 6 - Подтвердить SMS-код и завершить активацию
    	klawa = InlineKeyboardMarkup(row_width=1).add(InlineKeyboardButton(text=&#x27;Получить новый номер&#x27;, callback_data=&#x27;new_number&#x27;))
    	await bot.edit_message_text(chat_id=id_user, message_id=call.message.message_id, text=f&#x27;{call.message.html_text}\nАктивация завершена&#x27;, reply_markup=klawa)</pre>
  <p id="MZHa">Проверяем в боте</p>
  <figure id="rwDZ" class="m_original">
    <img src="https://img3.teletype.in/files/ee/6a/ee6a3cb6-9b52-4c8d-b61a-d9502dc0e0e1.png" width="350" />
  </figure>
  <p id="w5Xp">Теперь напишем обработчик кнопки &quot;Отменить активацию&quot;:</p>
  <pre id="8dba" data-lang="python">elif &#x27;cancel_akt_&#x27; in call.data:
    	id_number = call.data.replace(&#x27;cancel_akt_&#x27;, &#x27;&#x27;)
    	status_number = work_sms.new_status(idi=id_number, status=8) #Устанавливаем статус 8 - Отменить активацию
    	await call.answer(&#x27;Активация отменена&#x27;, show_alert=True)
    	await bot.send_message(id_user, &#x27;Хай, вы попали в смс бота для работы с сайтом 365sms.ru&#x27;, reply_markup=bb.mark_menu)</pre>
  <p id="V0UE">Проверить не могу, поэтому в дз будет проверить на сколько это работает, в <a href="https://t.me/Xacker_Name_new" target="_blank">лс</a> пришлёте отчёт)</p>
  <p id="fOMc">Давайте напишем ещё обработчик кнопки &quot;Получить новый номер&quot;:</p>
  <p id="fYyr">Кароч решил просто скопировать код из текстовой кнопки &quot;Получить номер&quot;, а собственно почему нет?</p>
  <pre id="EHZJ" data-lang="python">elif call.data == &#x27;new_number&#x27;:
    	await bot.delete_message(id_user, call.message.message_id) #Удаляем сообщение
    	#Будем получать номер для вк без оператора и регистрироваться через бота (Страну возьмём индонезию потому что дёшево ID: 6)
    	number = work_sms.new_number(servis=&#x27;qw&#x27;, strana=0)
    	#Обработаем ошибки:
    	if number == &#x27;NO_NUMBERS&#x27;: #Если пришёл ответ что нет номеров
    		await bot.send_message(id_user, &#x27;Нет номеров с заданными параметрами, попробуйте позже, или поменяйте оператора, страну&#x27;, reply_markup=bb.mark_menu)
    	elif number == &#x27;NO_BALANCE&#x27;: #Если на балансе не хватает денег на номер телефона
    		await bot.send_message(id_user, &#x27;Закончились деньги на аккаунте&#x27;, reply_markup=bb.mark_menu)
    	elif number == &#x27;WRONG_SERVICE&#x27;: #Если не правильно указали &quot;servis&quot;
    		await bot.send_message(id_user, &#x27;Неверный идентификатор сервиса&#x27;, reply_markup=bb.mark_menu)
    	else: #Если номер упешно получен
    		#В ответе будет такой формат: ACCESS_NUMBER:ID:NUMBER - Пример: ACCESS_NUMBER:234242:79123456789
    		#Делим ответ на список:
    		info_number = number.split(&#x27;:&#x27;)
    		#Итоговый список будет выглядеть так: [&#x27;ACCESS_NUMBER&#x27;, &#x27;ID&#x27;, &#x27;NUMBER&#x27;] - Пример: [&#x27;ACCESS_NUMBER&#x27;, &#x27;234242&#x27;, &#x27;79123456789&#x27;]
    		#Индексы списка начинаються с 0
    		#т.е с индексом 0 - &#x27;ACCESS_NUMBER&#x27;, c индексом 1 - &#x27;ID&#x27;, c индексом 2 - &#x27;NUMBER&#x27;
    		#Отправляем данные пользователю:
    		await bot.send_message(id_user, f&#x27;ID номера: {info_number[1]}\nНомер: &lt;code&gt;{info_number[2]}&lt;/code&gt;&#x27;, reply_markup=InlineKeyboardMarkup(row_width=1).add(
    			InlineKeyboardButton(text=&#x27;Изменить статус&#x27;, callback_data=f&#x27;new_status_{info_number[1]}&#x27;))) #Передаём id номера в callback_data</pre>
  <p id="Y0eI">Основные методы я с вами разобрал, сможете ли вы написать текстовую кнопку которая будет красиво выводить данные из метода <a href="https://365sms.ru/api365#:~:text=%D0%97%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D0%B8%D1%82%D1%8C%20%D0%B2%D1%81%D0%B5%20%D1%86%D0%B5%D0%BD%D1%8B-,getPrices,-%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA%20%D1%81%D1%82%D1%80%D0%B0%D0%BD" target="_blank">getPrices</a>?</p>
  <p id="p26i"></p>
  <p id="nfLT">Итоговый код:</p>
  <pre id="b5mo" data-lang="python">from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton, KeyboardButton, ReplyKeyboardMarkup, BotCommand, WebAppInfo
from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.contrib.fsm_storage.memory import MemoryStorage
from aiogram import Bot, Dispatcher, executor, types
from aiogram.dispatcher import FSMContext
import config as c
import test as bb
import asyncio
import pymysql
from class_db import work_db
from module_sms import main_sms
from datetime import datetime
import pytz


bot = Bot(token=c.token_bot, parse_mode=types.ParseMode.HTML) #Берём токен бота из файла config.py который импортировали ранее в переменную c
dp = Dispatcher(bot, storage=MemoryStorage())
db_work = work_db(c.host, c.port, c.user, c.password, c.database) #Создаём экземпляр класса для работы с базой данных, передав все нужные параметры из конфига
work_sms = main_sms(c.token_sms) #Создаём экземпляр класса для работы с сервисом смс


def time_Moscow():
	# Устанавливаем часовой пояс Москвы
	moscow_tz = pytz.timezone(&#x27;Europe/Moscow&#x27;)

	# Получаем текущее время в часовом поясе Москвы
	moscow_time = datetime.now(moscow_tz)

	# Форматируем время в часы:минуты:секунды
	formatted_time = moscow_time.strftime(&#x27;%H:%M:%S&#x27;)
	return str(formatted_time) #Возвращаем строку с временем


@dp.message_handler(content_types=[&#x27;text&#x27;])
async def text(message: types.Message):
    id_user = message.from_user.id #Записываем id пользователя (Ранее писали message.chat.id)
    if message.text == &#x27;/start&#x27;:
    	await bot.send_message(id_user, &#x27;Хай, вы попали в смс бота для работы с сайтом 365sms.ru&#x27;, reply_markup=bb.mark_menu) #При команде старт отправляем приветственное сообщение и рассказываем о себе, и выводим клавиатуру
    elif message.text == &#x27;Получить баланс&#x27;:
    	balanse_sms = work_sms.get_balanse() #Запрашиваем баланс с сайта по api
    	time_msk = time_Moscow() #Получаем время мск
    	try:
    		await bot.send_message(id_user, f&#x27;&lt;b&gt;[{time_msk}]&lt;/b&gt; Текущий баланс: {float(balanse_sms):.2f}₽&#x27;, reply_markup=InlineKeyboardMarkup(row_width=1).add(
    		InlineKeyboardButton(text=&#x27;Обновить&#x27;, callback_data=&#x27;new_balance&#x27;))) #Пока выводим то что получили от сайта
    	except:
    		if &#x27;BAD_KEY&#x27; in balanse_sms:
    			await bot.send_message(id_user, &#x27;Не правильный токен для запроса, проверьте и обновите его!&#x27;) #Если указали не верный токен
    		elif &#x27;ERROR_SQL&#x27; in balanse_sms:
    			await bot.send_message(id_user, &#x27;Ошибка на стороне сайта поопробуйте позже!&#x27;) #Если на сайте произошла ошибка
    		else:
    			await bot.send_message(id_user, &#x27;Ваш запрос был составлен не правильно!&#x27;) #Если мы не правильно составили запрос (в уроке такого не будет)
    elif message.text == &#x27;Получить номер&#x27;:
    	#Будем получать номер для вк без оператора и регистрироваться через бота (Страну возьмём индонезию потому что дёшево ID: 6)
    	number = work_sms.new_number(servis=&#x27;qw&#x27;, strana=0)
    	#Обработаем ошибки:
    	if number == &#x27;NO_NUMBERS&#x27;: #Если пришёл ответ что нет номеров
    		await bot.send_message(id_user, &#x27;Нет номеров с заданными параметрами, попробуйте позже, или поменяйте оператора, страну&#x27;, reply_markup=bb.mark_menu)
    	elif number == &#x27;NO_BALANCE&#x27;: #Если на балансе не хватает денег на номер телефона
    		await bot.send_message(id_user, &#x27;Закончились деньги на аккаунте&#x27;, reply_markup=bb.mark_menu)
    	elif number == &#x27;WRONG_SERVICE&#x27;: #Если не правильно указали &quot;servis&quot;
    		await bot.send_message(id_user, &#x27;Неверный идентификатор сервиса&#x27;, reply_markup=bb.mark_menu)
    	else: #Если номер упешно получен
    		#В ответе будет такой формат: ACCESS_NUMBER:ID:NUMBER - Пример: ACCESS_NUMBER:234242:79123456789
    		#Делим ответ на список:
    		info_number = number.split(&#x27;:&#x27;)
    		#Итоговый список будет выглядеть так: [&#x27;ACCESS_NUMBER&#x27;, &#x27;ID&#x27;, &#x27;NUMBER&#x27;] - Пример: [&#x27;ACCESS_NUMBER&#x27;, &#x27;234242&#x27;, &#x27;79123456789&#x27;]
    		#Индексы списка начинаються с 0
    		#т.е с индексом 0 - &#x27;ACCESS_NUMBER&#x27;, c индексом 1 - &#x27;ID&#x27;, c индексом 2 - &#x27;NUMBER&#x27;
    		#Отправляем данные пользователю:
    		await bot.send_message(id_user, f&#x27;ID номера: {info_number[1]}\nНомер: &lt;code&gt;{info_number[2]}&lt;/code&gt;&#x27;, reply_markup=InlineKeyboardMarkup(row_width=1).add(
    			InlineKeyboardButton(text=&#x27;Изменить статус&#x27;, callback_data=f&#x27;new_status_{info_number[1]}&#x27;))) #Передаём id номера в callback_data


@dp.callback_query_handler(lambda call: True, state=&#x27;*&#x27;)
async def callback_inline(call, state: FSMContext):
    id_user = call.from_user.id
    if call.data == &#x27;new_balance&#x27;:
    	time_msk = time_Moscow() #Получаем время мск
    	balanse_sms = work_sms.get_balanse() #Запрашиваем баланс с сайта по api
    	await bot.edit_message_text(chat_id=id_user, message_id=call.message.message_id, text=f&#x27;{call.message.html_text}\n&lt;b&gt;[{time_msk}]&lt;/b&gt; Текущий баланс: {float(balanse_sms):.2f}₽&#x27;, reply_markup=InlineKeyboardMarkup(row_width=1).add(
    		InlineKeyboardButton(text=&#x27;Обновить&#x27;, callback_data=&#x27;new_balance&#x27;)))
    elif &#x27;new_status_&#x27; in call.data: #В call.data содержиться callback_data
    	id_number = int(call.data.replace(&#x27;new_status_&#x27;, &#x27;&#x27;)) #С момощью этого кода мы получим число типа int, удалив из call.data не нужное нам
    	#Грубыми словами с помощью replace мы заменяем new_status_ на ничего
    	#Отправим клавиатуру с дальнейшими статусами, перед этим проверив текущий статус номера
    	status_number = work_sms.get_status(idi=id_number)
    	#Давайте в зависимости от статуса выведем клавиатуру:
    	if status_number == &#x27;STATUS_WAIT_CODE&#x27;: #Данный статус будет после получения номера он означает &quot;Ожидание смс&quot;
    		int_status = 0 #Поставим 0 будет означать что номер только что получен
    		await call.answer(&#x27;Текущий статус: Ожидает смс&#x27;, show_alert=True) #Выводим табличку с текущим статусом (show_alert позваляет вывести табличку с кнопко &quot;ОК&quot;)
    	elif status_number == &#x27;STATUS_CANCEL&#x27;: #Данный статус будет после отмены номера он означает &quot;Активация отменена&quot;
    		int_status = 1 #Поставим 1 будет означать что номер больше не активен (отменён)
    		await call.answer(&#x27;Текущий статус: Активация отменена&#x27;, show_alert=True) #Выводим табличку с текущим статусом (show_alert позваляет вывести табличку с кнопко &quot;ОК&quot;)
    	else: #Т.к. больше статусов которые может вернуть сайт нет, будем обабатывать успешное получение смс
    		#Делим полученное сообение на список с помощью split
    		kode_aktivate = status_number.split(&#x27;:&#x27;) #Получили список [&quot;STATUS_OK&quot;, &quot;CODE&quot;]
    		int_status = 2 #Поставим 2 будет означать что смс получен
    		await call.answer(f&#x27;Текущий статус: Смс получено\nКод: {kode_aktivate[1]}&#x27;, show_alert=True)
    	#Сделаем стандартную клавиатуру с дефолтной нопкой:
    	klawa = InlineKeyboardMarkup(row_width=1).add(InlineKeyboardButton(text=&#x27;Узнать статус&#x27;, callback_data=f&#x27;new_status_{id_number}&#x27;))
    	if int_status == 0:
    		klawa.add(InlineKeyboardButton(text=&#x27;Отменить активацию&#x27;, callback_data=f&#x27;cancel_akt_{id_number}&#x27;))
    	elif int_status == 1:
    		klawa.add(InlineKeyboardButton(text=&#x27;Получить новый номер&#x27;, callback_data=&#x27;new_number&#x27;))
    	else:
    		klawa.add(InlineKeyboardButton(text=&#x27;Подтвердить SMS-код и завершить активацию&#x27;, callback_data=f&#x27;true_aktiv_{id_number}&#x27;),
    			InlineKeyboardButton(text=&#x27;Запросить еще одну смс&#x27;, callback_data=f&#x27;dop_sms_{id_number}&#x27;))
    	try: #Если смогли отредактировать сообщение
    		await bot.edit_message_text(chat_id=id_user, message_id=call.message.message_id, text=call.message.html_text, reply_markup=klawa)
    	except: #Если произошла любая ошибка
    		pass
    elif &#x27;dop_sms_&#x27; in call.data:
    	id_number = call.data.replace(&#x27;dop_sms_&#x27;, &#x27;&#x27;)
    	await call.answer(&#x27;Новый статус установлен&#x27;, show_alert=True)
    	work_sms.new_status(idi=id_number, status=3) #Устанавливаем статус 3 - нужна повторная смс
    	klawa = InlineKeyboardMarkup(row_width=1).add(InlineKeyboardButton(text=&#x27;Узнать статус&#x27;, callback_data=f&#x27;new_status_{id_number}&#x27;),
    		InlineKeyboardButton(text=&#x27;Подтвердить SMS-код и завершить активацию&#x27;, callback_data=f&#x27;true_aktiv_{id_number}&#x27;))
    	await bot.edit_message_text(chat_id=id_user, message_id=call.message.message_id, text=call.message.html_text, reply_markup=klawa)
    elif &#x27;true_aktiv_&#x27; in call.data:
    	id_number = call.data.replace(&#x27;true_aktiv_&#x27;, &#x27;&#x27;)
    	await call.answer(&#x27;Новый статус установлен&#x27;, show_alert=True)
    	work_sms.new_status(idi=id_number, status=6) #Устанавливаем статус 6 - Подтвердить SMS-код и завершить активацию
    	klawa = InlineKeyboardMarkup(row_width=1).add(InlineKeyboardButton(text=&#x27;Получить новый номер&#x27;, callback_data=&#x27;new_number&#x27;))
    	await bot.edit_message_text(chat_id=id_user, message_id=call.message.message_id, text=f&#x27;{call.message.html_text}\nАктивация завершена&#x27;, reply_markup=klawa)
    elif &#x27;cancel_akt_&#x27; in call.data:
    	id_number = call.data.replace(&#x27;cancel_akt_&#x27;, &#x27;&#x27;)
    	status_number = work_sms.new_status(idi=id_number, status=8) #Устанавливаем статус 8 - Отменить активацию
    	await call.answer(&#x27;Активация отменена&#x27;, show_alert=True)
    	await bot.send_message(id_user, &#x27;Хай, вы попали в смс бота для работы с сайтом 365sms.ru&#x27;, reply_markup=bb.mark_menu)
    elif call.data == &#x27;new_number&#x27;:
    	await bot.delete_message(id_user, call.message.message_id) #Удаляем сообщение
    	#Будем получать номер для вк без оператора и регистрироваться через бота (Страну возьмём индонезию потому что дёшево ID: 6)
    	number = work_sms.new_number(servis=&#x27;qw&#x27;, strana=0)
    	#Обработаем ошибки:
    	if number == &#x27;NO_NUMBERS&#x27;: #Если пришёл ответ что нет номеров
    		await bot.send_message(id_user, &#x27;Нет номеров с заданными параметрами, попробуйте позже, или поменяйте оператора, страну&#x27;, reply_markup=bb.mark_menu)
    	elif number == &#x27;NO_BALANCE&#x27;: #Если на балансе не хватает денег на номер телефона
    		await bot.send_message(id_user, &#x27;Закончились деньги на аккаунте&#x27;, reply_markup=bb.mark_menu)
    	elif number == &#x27;WRONG_SERVICE&#x27;: #Если не правильно указали &quot;servis&quot;
    		await bot.send_message(id_user, &#x27;Неверный идентификатор сервиса&#x27;, reply_markup=bb.mark_menu)
    	else: #Если номер упешно получен
    		#В ответе будет такой формат: ACCESS_NUMBER:ID:NUMBER - Пример: ACCESS_NUMBER:234242:79123456789
    		#Делим ответ на список:
    		info_number = number.split(&#x27;:&#x27;)
    		#Итоговый список будет выглядеть так: [&#x27;ACCESS_NUMBER&#x27;, &#x27;ID&#x27;, &#x27;NUMBER&#x27;] - Пример: [&#x27;ACCESS_NUMBER&#x27;, &#x27;234242&#x27;, &#x27;79123456789&#x27;]
    		#Индексы списка начинаються с 0
    		#т.е с индексом 0 - &#x27;ACCESS_NUMBER&#x27;, c индексом 1 - &#x27;ID&#x27;, c индексом 2 - &#x27;NUMBER&#x27;
    		#Отправляем данные пользователю:
    		await bot.send_message(id_user, f&#x27;ID номера: {info_number[1]}\nНомер: &lt;code&gt;{info_number[2]}&lt;/code&gt;&#x27;, reply_markup=InlineKeyboardMarkup(row_width=1).add(
    			InlineKeyboardButton(text=&#x27;Изменить статус&#x27;, callback_data=f&#x27;new_status_{info_number[1]}&#x27;))) #Передаём id номера в callback_data

if __name__ == &quot;__main__&quot;:
    executor.start_polling(dp, skip_updates=True)</pre>
  <p id="ylIo"></p>
  <p id="D66M"></p>
  <p id="x51L"></p>
  <p id="hvl5"><strong>Вот и дз сформировалось:</strong></p>
  <ol id="TrQ1">
    <li id="dDx1"><strong>Проверить работу <a href="#w5Xp">кода</a> (если есть ошибки исправить)</strong></li>
    <li id="2Bog"><strong>Написать текстовую кнопку которая будет красиво выводить данные метода <a href="https://365sms.ru/api365#:~:text=%D0%97%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D0%B8%D1%82%D1%8C%20%D0%B2%D1%81%D0%B5%20%D1%86%D0%B5%D0%BD%D1%8B-,getPrices,-%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA%20%D1%81%D1%82%D1%80%D0%B0%D0%BD" target="_blank">getPrices</a></strong></li>
    <li id="VwIA"><strong>Подключить базу данных</strong></li>
  </ol>
  <ol id="ruiV">
    <ol id="ZUXL">
      <li id="cbVz"><strong>Регистрировать пользователей</strong></li>
      <li id="uexW"><strong>Считать номера которые они взяли в аренду</strong></li>
      <li id="WXes"><strong>Считать номера которые успешно завершили</strong></li>
      <li id="fiSC"><strong>Записывать номера в отдельную таблицу</strong></li>
      <ol id="xH2Q">
        <li id="S5Ob"><strong>ID номера</strong></li>
        <li id="bfsv"><strong>Сам номер</strong></li>
        <li id="xa57"><strong>Пользователь который взял этот номер</strong></li>
      </ol>
    </ol>
  </ol>
  <p id="KB13"><strong>ДЗ выполнить в течении 4х дней, так же в канале проходит голосование, что будем изучать дальше!</strong></p>
  <p id="9Fi1"></p>
  <p id="N8Mx"></p>
  <p id="Vqle"></p>
  <h2 id="XBgD">Спасибо за внимание</h2>
  <p id="nXCL">С вами был <a href="https://t.me/Xacker_Name_new" target="_blank">@Xacker_Name_new</a></p>
  <p id="eyUE">Поддержка: <a href="https://t.me/Bsc_Black_Secret_Club_bot" target="_blank">@Bsc_Black_Secret_Club_bot</a></p>
  <p id="1piM">Канал: <a href="https://t.me/education_python_aiogram" target="_blank">@education_python_aiogram</a></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@xacker_name_new/PqqQ-NNhOfB</guid><link>https://teletype.in/@xacker_name_new/PqqQ-NNhOfB?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=xacker_name_new</link><comments>https://teletype.in/@xacker_name_new/PqqQ-NNhOfB?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=xacker_name_new#comments</comments><dc:creator>xacker_name_new</dc:creator><title>Обучение #4</title><pubDate>Fri, 29 Sep 2023 06:38:05 GMT</pubDate><media:content medium="image" url="https://img2.teletype.in/files/50/e3/50e31141-824f-4f69-8473-ed3aa0599887.png"></media:content><category>Обучение Python+aiogram+MySQL</category><description><![CDATA[<img src="https://img4.teletype.in/files/3a/72/3a720c74-3487-46cc-ac94-4ec752d144cc.png"></img>Обучение #4]]></description><content:encoded><![CDATA[
  <p id="V4tv">Хай, как и говорил начнём с удаления данных с базы данных</p>
  <p id="kqtM">Давайте возьмём готовый код из <a href="https://teletype.in/@xacker_name_new/1ehent_u3EK" target="_blank">предыдущего урока</a></p>
  <pre id="QLcn" data-lang="python">from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.contrib.fsm_storage.memory import MemoryStorage
from aiogram import Bot, Dispatcher, executor, types
from aiogram.dispatcher import FSMContext
from aiogram.types import ReplyKeyboardRemove, InlineKeyboardMarkup, InlineKeyboardButton
from class_db import work_db #Импорируем класс для работы с базой данных из файла class_db.py
import test as bb #Импортируем файл test.py в переменную bb (мне так удобнее работать с ним)
import config as c #Импортируем файл config.py в переменную с (опять же мне так удобнее)



#Создаём класс бота и дистпетчера
bot = Bot(token=c.token, parse_mode=types.ParseMode.HTML) #Берём токен бота из файла config.py который импортировали ранее в переменную c
dp = Dispatcher(bot, storage=MemoryStorage())
db_work = work_db(c.host, c.port, c.user, c.password, c.database) #Создаём экземпляр класса для работы с базой данных, передав все нужные параметры из конфига


class anketa(StatesGroup):
	name = State()
	floor = State()
	age = State()


class new_values(StatesGroup):
	new_value = State()


def creat_table(): #Данную функцию будем запускать при каждом запуске кода, параметры функция не принимает
	#Для начала конектимся к базе данных:
	connection = db_work.connect_db()
	if connection: #Если класс вернул конект, а не False
		#Напишем сам запрос
		creat_table_request = &#x27;CREATE TABLE IF NOT EXISTS &#x60;ankets&#x60;(id int AUTO_INCREMENT, name varchar(32), floor varchar(10), age int, PRIMARY KEY (id));&#x27; #И так мы написали запрос, но для чего он нам?
		#Он нам для того что-бы создать таблицу для анкет где будут следующие данные: id - это будет id анкеты (число), оно будет прописываться само (из-за AUTO_INCREMENT)
		#name типа сроки длинной не более 32 символов, floor типа строки не более 10 символов и age типа числа без ограничения
		#Первичный ключ (PRIMARY KEY) — особенное поле в таблице, которое позволяет однозначно идентифицировать каждую запись в ней
		#Запрос написан, давайте его выполним:
		status = db_work.create_table(connection, creat_table_request) #Предаём необходимые данные (Конект и сам запрос)
		#Проверяем статус создания базы данных:
		if status: #Если вернуло True значит всё хорошо (выведем в консоль что запрос выполнен)
			print(&#x27;Таблица успешно создана&#x27;)
			#Закрываем конект
			if db_work.connect_close(connection):
				print(&#x27;Конект закрыт!&#x27;)
			else: #Если нам вернуло False, значит произошла ошибка, в вспомогательном классе мы прописали вывод ошибки
				print(&#x27;Ошибка указана выше&#x27;)
		else: #Если вернуло False, значит не удалось создать таблицу, ошибку мы так же вывели в классе
			print(&#x27;Ошибка указана выше&#x27;)
	else: #Если мы не смогли подключиться к базе данных, то опять же ошибка была выведена в классе
		print(&#x27;Ошибка указана выше&#x27;)


def insert_table(name_, floor_, age_): #Данная функция принимает имя таблицы в которую надо записать данные (Сразу скажу т.к. мы записывать будет в ankets ропишем получение данных)
	#Для начала конектимся к базе данных:
	connection = db_work.connect_db()
	if connection: #Если класс вернул конект, а не False
		#Напишем сам запрос
		insert_table_request = &#x27;INSERT INTO ankets (name, floor, age) VALUES (%s, %s, %s);&#x27; #И так в этом запросе мы создаём запись данных
		with connection.cursor() as cursor:
			cursor.execute(insert_table_request, (name_, floor_, age_)) #Записываем данные полученные в функцию
		connection.commit() #Сохраняем изменения
		print(&#x27;Данные записаны!&#x27;)
		if db_work.connect_close(connection):
			print(&#x27;Конект закрыт!&#x27;)
		else: #Если нам вернуло False, значит произошла ошибка, в вспомогательном классе мы прописали вывод ошибки
			print(&#x27;Ошибка указана выше&#x27;)
	else: #Если мы не смогли подключиться к базе данных, то опять же ошибка была выведена в классе
		print(&#x27;Ошибка указана выше&#x27;)


@dp.message_handler(content_types=[&#x27;text&#x27;]) #Обрабатываем каждое сообщение от пользователей, добавляем content_types для обработки текста, в будущих уроках будет фото и видео
async def text(message: types.Message): #Асинхронная функция с название &quot;text&quot; которая принимает в переменную message, текст пользователя отправевшего сообщение
	if message.text == &#x27;/start&#x27;:
		await bot.send_message(message.chat.id, &#x27;Привет, заполни анкету, или посмотри информацйию о мне&#x27;, reply_markup=bb.mark_menu) #Обрабатываем команду /start и выводим клавиатуру из файлы test.py
	elif message.text == &#x27;Информация&#x27;:
		await bot.send_message(message.chat.id, f&#x27;Сюда пишем какую либо информацию, например я хочу вывести ID пользователя\nТвой ID: {message.chat.id}&#x27;)
	elif message.text == &#x27;Заполнить анкету&#x27;:
		await bot.send_message(message.chat.id, &#x27;Введите своё имя:&#x27;)
		await anketa.name.set()
	elif message.text == &#x27;/info_table&#x27;:
		info_request = &#x27;SELECT * FROM ankets WHERE id = %s&#x27;
		values = (1,)
		connection = db_work.connect_db() #Конектимся к базе данных
		if connection: #Если конект успешный
			info = db_work.info_table(connection, info_request, values)
			if info: #Если получили данные по id = 1
				await bot.send_message(message.chat.id, f&#x27;Полученные данные:\nID: {info[&quot;id&quot;]}\nИмя: {info[&quot;name&quot;]}\nПол: {info[&quot;floor&quot;]}\nВозраст: {info[&quot;age&quot;]}&#x27;)
			else: #Если не смогли получить данные
				await bot.send_message(message.chat.id, &#x27;Не удалось получить данные&#x27;)
		else: #Если конект не удался
			await bot.send_message(message.chat.id, &#x27;Не удалось подключиться к базе данных&#x27;)
	elif message.text == &#x27;/new_value&#x27;:
		await bot.send_message(message.chat.id, &#x27;Введите ID для изменения возраста:&#x27;)
		await new_values.new_value.set()


@dp.message_handler(state=new_values.new_value)
async def anketa_name(message: types.Message, state: FSMContext): #Как видите у нас добавился FSMContext, он нам нужен как раз для обработки машины состояния
	#Записываем ID в кеш
	await state.update_data(id_value=message.text)
	#Выводим инлайн кнопки с числами
	#Пока напишу прямо тут, в следующих уроках будем создавать функции
	await bot.send_message(message.chat.id, &#x27;Выберите новое значение:&#x27;, reply_markup=InlineKeyboardMarkup(row_width=3).add(
		InlineKeyboardButton(text=&#x27;1&#x27;, callback_data=&#x27;new_value_1&#x27;),InlineKeyboardButton(text=&#x27;2&#x27;, callback_data=&#x27;new_value_2&#x27;), InlineKeyboardButton(text=&#x27;10&#x27;, callback_data=&#x27;new_value_10&#x27;),
		InlineKeyboardButton(text=&#x27;25&#x27;, callback_data=&#x27;new_value_25&#x27;)))
	#Этого достаточно



@dp.message_handler(state=anketa.name)
async def anketa_name(message: types.Message, state: FSMContext): #Как видите у нас добавился FSMContext, он нам нужен как раз для обработки машины состояния
	#Записываем имя в кеш
	await state.update_data(name=message.text)
	#Далее просим ввести пол, с выбором пола из кнопок
	await bot.send_message(message.chat.id, &#x27;Выберите свой пол:&#x27;, reply_markup=bb.menu_floor) #добавляем вывод кнопок с выбором пола
	await anketa.floor.set()


@dp.message_handler(state=anketa.floor)
async def anketa_name(message: types.Message, state: FSMContext):
	#Записываем пол в кеш
	await state.update_data(floor=message.text)
	#Далее просим ввести свой возраст
	await bot.send_message(message.chat.id, &#x27;Введите свой возраст:&#x27;, reply_markup=ReplyKeyboardRemove()) #убираем текстовую клавиатуру
	await anketa.age.set()


@dp.message_handler(state=anketa.age)
async def anketa_name(message: types.Message, state: FSMContext):
	#Получим все данные записанные в кеш
	data = await state.get_data()
	#Сортируем их по переменным
	name = data[&#x27;name&#x27;] #В ковычках пишем name, потому что сами записывали в такую переменную, там может быть любая другая
	floor = data[&#x27;floor&#x27;] #В ковычках пишем floor, потому что сами записывали в такую переменную, там может быть любая другая
	age = message.text #записываем ввод пользователя в переменную age
	await state.finish() #Завершаем работу с машиной состояний
	#Выведем анкету пользователю
	await bot.send_message(message.chat.id, f&#x27;Ваша анкета:\n\nИмя: {name}\nПол: {floor}\nВозраст: {age}\n\nСпасибо за уделение времени&#x27;, reply_markup=bb.mark_menu) #Отправляем анкету, благодарим, и выдаём ему текстовоем меню
	#Отправим анкету администратору по его ID из config.py
	#Так же выведем ID пользователя и его юзернейм
	await bot.send_message(c.admin, f&#x27;Пользователь: {message.chat.id}\n@{message.from_user.username} заполнил анкету\nЕго данные:\n\nИмя: {name}\nПол: {floor}\nВозраст: {age}&#x27;)
	insert_table(name, floor, age) #Передаём необходимые данные



@dp.callback_query_handler(lambda call: True, state=&#x27;*&#x27;) #Обрабатываем нажатия всех инлайн кнопок, даже когда активно ожидание ввода от пользователя
async def callback_inline(call, state: FSMContext): #В переменную call принимаем данные о нажатой кнопке
	try: #Обрабатываем ошибки, если всё успешно то мы получим переменную id_value на всю функцию
		data = await state.get_data()
		id_value = data[&#x27;id_value&#x27;]
		await state.finish()
	except Exception as eror: #Если будут ошибки мы их пришлём пользователю
		await bot.send_message(call.message.chat.id, f&#x27;Произошла ошибка: {eror}&#x27;)
		return #Останавливаем выполнение функции
	#Приступим к обработке нажатия кнопок, т.к. у нас записано новое чило в callback_data, но начало одно и тоже
	#Нам нужно проверять есть ли в нажатой кнопке начало:
	if &#x27;new_value_&#x27; in call.data: #В call.data содержиться callback_data
		new_value = int(call.data.replace(&#x27;new_value_&#x27;, &#x27;&#x27;)) #С момощью этого кода мы получим число типа int, удалив из call.data не нужное нам
		#Грубыми словами с помощью replace мы заменяем new_value_ на ничего
		#Теперь давайте заменим значение в таблице по ID которое вписали изначально
		#Конектимся к базе данных:
		connection = db_work.connect_db()
		if connection: #Если конект успешен
			#Возпользуемся функцией edit_table из вспомогательного класса:
			new_value_request = &#x27;UPDATE ankets SET age = %s WHERE id = %s&#x27;
			values = (new_value, int(id_value))
			status = db_work.edit_table(connection, new_value_request, values)
			if status: #Если успешно обновили данные
				await bot.send_message(call.message.chat.id, f&#x27;Данные для строки с ID: {id_value}\nУспешно обновлены на: {new_value}&#x27;)
			else: #Если произошла ошибка
				await bot.send_message(call.message.chat.id, &#x27;Произошла ошибка, она отобразилась в консоли!&#x27;)
		else: #Если не удалось подключиться к базе данных
			await bot.send_message(call.message.chat.id, &#x27;Не удалось подключиться к базе данных!&#x27;)


if __name__ == &quot;__main__&quot;: #Если скрипт запущен с этого файла, запускаем executor
	creat_table() #Запускаем функцию создания таблицы
	executor.start_polling(dp, skip_updates=True) #skip_updates=True - нужен для того чтобы не обрабатывать сообщения которые были присланы пользователем в тот момент когда бот был выключен</pre>
  <p id="MaVi">Добавим обработку команды &quot;/delete_strok_table&quot;:</p>
  <pre id="PZXn" data-lang="python">@dp.message_handler(content_types=[&#x27;text&#x27;]) #Обрабатываем каждое сообщение от пользователей, добавляем content_types для обработки текста, в будущих уроках будет фото и видео
async def text(message: types.Message): #Асинхронная функция с название &quot;text&quot; которая принимает в переменную message, текст пользователя отправевшего сообщение
	if message.text == &#x27;/start&#x27;:
		await bot.send_message(message.chat.id, &#x27;Привет, заполни анкету, или посмотри информацйию о мне&#x27;, reply_markup=bb.mark_menu) #Обрабатываем команду /start и выводим клавиатуру из файлы test.py
	elif message.text == &#x27;Информация&#x27;:
		await bot.send_message(message.chat.id, f&#x27;Сюда пишем какую либо информацию, например я хочу вывести ID пользователя\nТвой ID: {message.chat.id}&#x27;)
	elif message.text == &#x27;Заполнить анкету&#x27;:
		await bot.send_message(message.chat.id, &#x27;Введите своё имя:&#x27;)
		await anketa.name.set()
	elif message.text == &#x27;/info_table&#x27;:
		info_request = &#x27;SELECT * FROM ankets WHERE id = %s&#x27;
		values = (1,)
		connection = db_work.connect_db() #Конектимся к базе данных
		if connection: #Если конект успешный
			info = db_work.info_table(connection, info_request, values)
			if info: #Если получили данные по id = 1
				await bot.send_message(message.chat.id, f&#x27;Полученные данные:\nID: {info[&quot;id&quot;]}\nИмя: {info[&quot;name&quot;]}\nПол: {info[&quot;floor&quot;]}\nВозраст: {info[&quot;age&quot;]}&#x27;)
			else: #Если не смогли получить данные
				await bot.send_message(message.chat.id, &#x27;Не удалось получить данные&#x27;)
		else: #Если конект не удался
			await bot.send_message(message.chat.id, &#x27;Не удалось подключиться к базе данных&#x27;)
	elif message.text == &#x27;/new_value&#x27;:
		await bot.send_message(message.chat.id, &#x27;Введите ID для изменения возраста:&#x27;)
		await new_values.new_value.set()
	elif message.text == &#x27;/delete_strok_table&#x27;:
		await bot.send_message(message.chat.id, &#x27;Введите ID для удаления:&#x27;)</pre>
  <p id="XdNI">Создадим класс для ожидания ответа от пользователя:</p>
  <pre id="u7Ma" data-lang="python">class delete_strok_table(StatesGroup):
	id_strok = State()


@dp.message_handler(content_types=[&#x27;text&#x27;]) #Обрабатываем каждое сообщение от пользователей, добавляем content_types для обработки текста, в будущих уроках будет фото и видео
async def text(message: types.Message): #Асинхронная функция с название &quot;text&quot; которая принимает в переменную message, текст пользователя отправевшего сообщение
	if message.text == &#x27;/start&#x27;:
		await bot.send_message(message.chat.id, &#x27;Привет, заполни анкету, или посмотри информацйию о мне&#x27;, reply_markup=bb.mark_menu) #Обрабатываем команду /start и выводим клавиатуру из файлы test.py
	elif message.text == &#x27;Информация&#x27;:
		await bot.send_message(message.chat.id, f&#x27;Сюда пишем какую либо информацию, например я хочу вывести ID пользователя\nТвой ID: {message.chat.id}&#x27;)
	elif message.text == &#x27;Заполнить анкету&#x27;:
		await bot.send_message(message.chat.id, &#x27;Введите своё имя:&#x27;)
		await anketa.name.set()
	elif message.text == &#x27;/info_table&#x27;:
		info_request = &#x27;SELECT * FROM ankets WHERE id = %s&#x27;
		values = (1,)
		connection = db_work.connect_db() #Конектимся к базе данных
		if connection: #Если конект успешный
			info = db_work.info_table(connection, info_request, values)
			if info: #Если получили данные по id = 1
				await bot.send_message(message.chat.id, f&#x27;Полученные данные:\nID: {info[&quot;id&quot;]}\nИмя: {info[&quot;name&quot;]}\nПол: {info[&quot;floor&quot;]}\nВозраст: {info[&quot;age&quot;]}&#x27;)
			else: #Если не смогли получить данные
				await bot.send_message(message.chat.id, &#x27;Не удалось получить данные&#x27;)
		else: #Если конект не удался
			await bot.send_message(message.chat.id, &#x27;Не удалось подключиться к базе данных&#x27;)
	elif message.text == &#x27;/new_value&#x27;:
		await bot.send_message(message.chat.id, &#x27;Введите ID для изменения возраста:&#x27;)
		await new_values.new_value.set()
	elif message.text == &#x27;/delete_strok_table&#x27;:
		await bot.send_message(message.chat.id, &#x27;Введите ID для удаления:&#x27;)
		await delete_strok_table.id_strok.set()</pre>
  <p id="I1zS">Добавим обработчик ввода пользователя:</p>
  <pre id="eMxj" data-lang="python">@dp.message_handler(state=delete_strok_table.id_strok)
async def anketa_name(message: types.Message, state: FSMContext):
	await state.finish() #Завершаем работу с машиной состояний
	id_strok = message.text
	connection = db_work.connect_db()
	if connection: #Если класс вернул конект, а не False
		#Напишем сам запрос
		delete_table = &#x27;DELETE FROM ankets WHERE id = %s&#x27;
		values = (id_strok,)
		status = db_work.delete_from_table(connection, delete_table, values)
		if status: #Если успешно обновили данные
			await bot.send_message(message.chat.id, f&#x27;Данные строки с ID: {id_strok} - Удалены!&#x27;)
		else: #Если произошла ошибка
			await bot.send_message(message.chat.id, &#x27;Произошла ошибка, она отобразилась в консоли!&#x27;)
	else:
		await bot.send_message(message.chat.id, &#x27;Не удалось подключиться к базе данных!&#x27;)</pre>
  <p id="8qo1">Так же давайте перепишем функцию &quot;delete_from_table&quot;:</p>
  <pre id="KIhL" data-lang="python">	def delete_from_table(self, connection, delete_, values): #Функция для редактирования данных в таблице, в delete_ будем передавать текст запроса
		try:
			with connection.cursor() as cursor:
				cursor.execute(delete_, values)
			connection.commit()
			return True
		except Exception as eror:
			print(eror) #Если произошла ошибка, выводим её в консоль
			return False #Если произошла ошибка, возвращаем False</pre>
  <p id="v8GS">У нас в базе есть запись с ID: 1</p>
  <figure id="8LXZ" class="m_original">
    <img src="https://img1.teletype.in/files/02/06/0206f519-d0f9-4b78-9c42-fc71822811b9.png" width="292" />
  </figure>
  <p id="aGjr">Давайте запустим бота, и удалим её:</p>
  <figure id="j3G5" class="m_original">
    <img src="https://img2.teletype.in/files/d8/55/d855de0b-e863-4560-be3d-11b286b9961e.png" width="698" />
  </figure>
  <figure id="gGuX" class="m_original">
    <img src="https://img4.teletype.in/files/30/fa/30fa48bd-0b9a-47ab-bf6a-e28b1ba15db6.png" width="365" />
  </figure>
  <p id="xUDs">У нас всё работает, мы молодцы, так держать!</p>
  <p id="mzlL"><s>———————————————————————————————</s></p>
  <p id="SwyH">По итогам опроса на <a href="https://t.me/education_python_aiogram" target="_blank">канале</a>, я понял что вам интересна работа с файлами .txt</p>
  <p id="ZOZI">Давайте немного изучим циклы:</p>
  <p id="MFd5">Цикл while True<br />Данный цикл позволяет выполнять код пока мы не завершим цикл, пример:</p>
  <pre id="8CDZ" data-lang="python">#обозначим переменную a = 0
a = 0
#Создадим цикл, и заставим его завешиться толькко после того как переменна a будет равна 5
while True:
   print(a)
   if a == 5:
      print(&#x27;Цикл завершён&#x27;)
      break
   a += 1 #После каждого круга добавляем к переменной a 1
   # &quot;a +=1 &quot; сокращение кода: a = a + 1
#Вывод в консоль будет:
#1
#2
#3
#4
#5
#Цикл завершён</pre>
  <p id="ldqJ">Следующий цикл for i in spisok<br />Данный цикл перебирает все данные из переменной spisok в переменную i, после чего завершается, пример:</p>
  <pre id="ncmH" data-lang="python">spisok = [1, 2, 3, 4, 5]
for i in spisok:
    print(i)
print(&#x27;Цикл завершён&#x27;)
#Вывод в консоль:
#1
#2
#3
#4
#5
#Цикл завершён</pre>
  <p id="bOjQ">И так мы изучили базовые циклы, на простых примерах, перейдём к файлам .txt:</p>
  <p id="PZX6">Давайте напишем код который создаст файл index.txt, затем запишем в него данные из списка:</p>
  <pre id="t8sx" data-lang="python">spisok = [1, 2, 3, 4, 5, 6]

my_file = open(&quot;index.txt&quot;, &quot;w+&quot;) #Создали файл
for i in spisok:
   my_file.write(str(i)) #Записываем данные, меняя тип данных на строку (str)
my_file.close() #После записи, закрываем его</pre>
  <p id="Qy3z">После чего у нас появился файл &quot;index.txt&quot;</p>
  <figure id="BAkW" class="m_original">
    <img src="https://img4.teletype.in/files/3e/74/3e74cf10-1ba4-45e7-b4ed-4f04b5a3557d.png" width="655" />
  </figure>
  <p id="ebgQ">Открываем его:</p>
  <figure id="S9B0" class="m_original">
    <img src="https://img4.teletype.in/files/36/1a/361ac064-81f0-4708-8c81-ac37e6416d17.png" width="281" />
  </figure>
  <p id="MieJ">Данные записались в 1 строку, давайте это исправим, и запишем каждую цифру из списка в новой строке:</p>
  <pre id="M25q" data-lang="python">spisok = [1, 2, 3, 4, 5, 6]

my_file = open(&quot;index.txt&quot;, &quot;w+&quot;) #Создали файл
for i in spisok:
   my_file.write(f&#x27;{i}\n&#x27;) #Записываем данные, меняя тип данных на строку (str)
my_file.close() #После записи, закрываем его</pre>
  <p id="r0ts">Удаляем файл index.txt, и снова запускаем файл с кодом:</p>
  <p id="xcvr">У нас всё так же появился файл index.txt, открываем его:</p>
  <figure id="SEOb" class="m_original">
    <img src="https://img4.teletype.in/files/76/96/7696bf40-3a45-47bf-a86b-75a7be56a3dd.png" width="350" />
  </figure>
  <p id="tceG">Успешно записали, теперь давайте прочитаем данные и выведем в консоль:</p>
  <pre id="iRDK" data-lang="python">my_file = open(&quot;index.txt&quot;, &quot;r&quot;) #Открываем файл на чтение
for line in my_file:
   print(line)
my_file.close()</pre>
  <p id="MY5B">Вывод в консоль:</p>
  <figure id="Z1JC" class="m_original">
    <img src="https://img2.teletype.in/files/58/d2/58d2f9c2-1808-4b65-b345-7ca31a36ff63.png" width="47" />
  </figure>
  <p id="HK0c">Он так же выводит нам пустые строки (\n), давайте удалим их:</p>
  <pre id="Mv1S" data-lang="python">my_file = open(&quot;index.txt&quot;, &quot;r&quot;) #Создали файл
for line in my_file:
   print(line.replace(&#x27;\n&#x27;, &#x27;&#x27;))
my_file.close()</pre>
  <p id="YFed">Вывод в консоль:</p>
  <figure id="vUvP" class="m_original">
    <img src="https://img4.teletype.in/files/bd/a5/bda5d26d-5eb4-4016-bb4b-beb0c1710609.png" width="39" />
  </figure>
  <p id="wMYz">Давайте разберём ещё 1 цикл, для удобства:</p>
  <pre id="59LE" data-lang="python">with open(&#x27;index.txt&#x27;, &#x27;r&#x27;) as file: #Открываем файл на чтение, в переменную file
   #После открытия файла через этот цикл нам не нужно будет его закрывать каждый раз</pre>
  <p id="10kh">Напишем код который прочитает первые 3 строки файла:</p>
  <pre id="jzr7" data-lang="python"># Открываем файл для чтения
with open(&#x27;index.txt&#x27;, &#x27;r&#x27;) as file:
    # Читаем все строки из файла
    all_lines = file.readlines()

# Выбираем первые три строки
first_three_lines = all_lines[:3]

# Выводим прочитанные строки
for line in first_three_lines:
    print(line.replace(&#x27;\n&#x27;, &#x27;&#x27;)) #Удаляя \n</pre>
  <p id="3U13">Вывод в консоль:</p>
  <figure id="cHTi" class="m_original">
    <img src="https://img1.teletype.in/files/00/8a/008a3730-4f37-4402-9dd2-c82d03cd6e04.png" width="32" />
  </figure>
  <p id="kP1S">А теперь давайте выведем последние 3 строки:</p>
  <p id="1HdL">Пишем тот же код но меняем 1 участок:</p>
  <pre id="LL8e" data-lang="python"># Открываем файл для чтения
with open(&#x27;index.txt&#x27;, &#x27;r&#x27;) as file:
    # Читаем все строки из файла
    all_lines = file.readlines()

# Выбираем последние три строки
first_three_lines = all_lines[-3:]

# Выводим прочитанные строки
for line in first_three_lines:
    print(line.replace(&#x27;\n&#x27;, &#x27;&#x27;)) #Удаляя \n</pre>
  <p id="ZQvC">Вывод в консоль:</p>
  <figure id="NucX" class="m_original">
    <img src="https://img4.teletype.in/files/b0/14/b0149d99-7fd6-431d-8b38-bb6c54283658.png" width="22" />
  </figure>
  <p id="6JLp">Подробнее с работой с файлами .txt вы можете ознакомиться на сайте: <a href="https://pythonworld.ru/tipy-dannyx-v-python/fajly-rabota-s-fajlami.html" target="_blank">*КЛИКАБЕЛЬНО*</a></p>
  <p id="nVIM"></p>
  <p id="peuk">В канале в комментариях напишите что вам было бы ещё интересно...</p>
  <p id="xD3e"></p>
  <h2 id="XBgD">Спасибо за внимание</h2>
  <p id="nXCL">С вами был <a href="https://t.me/Xacker_Name_new" target="_blank">@Xacker_Name_new</a></p>
  <p id="eyUE">Поддержка: <a href="https://t.me/Bsc_Black_Secret_Club_bot" target="_blank">@Bsc_Black_Secret_Club_bot</a></p>
  <p id="1piM">Канал: <a href="https://t.me/education_python_aiogram" target="_blank">@education_python_aiogram</a></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@xacker_name_new/1ehent_u3EK</guid><link>https://teletype.in/@xacker_name_new/1ehent_u3EK?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=xacker_name_new</link><comments>https://teletype.in/@xacker_name_new/1ehent_u3EK?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=xacker_name_new#comments</comments><dc:creator>xacker_name_new</dc:creator><title>Обучение #3</title><pubDate>Tue, 26 Sep 2023 12:21:19 GMT</pubDate><media:content medium="image" url="https://img2.teletype.in/files/50/e3/50e31141-824f-4f69-8473-ed3aa0599887.png"></media:content><category>Обучение Python+aiogram+MySQL</category><description><![CDATA[<img src="https://img4.teletype.in/files/3a/72/3a720c74-3487-46cc-ac94-4ec752d144cc.png"></img>Обучение #3]]></description><content:encoded><![CDATA[
  <p id="zTlV">Хай, я получил от людей проблему с установкой программы для базы данных, из 1 урока, так вот, если у вас после установки нет программы как на скриншоте:</p>
  <figure id="Gaj7" class="m_original">
    <img src="https://img1.teletype.in/files/49/8a/498a686e-3e46-4222-b7f1-801116283edc.png" width="290" />
  </figure>
  <p id="Mgqp">Её можно скачать по ссылке - <a href="https://dev.mysql.com/get/Downloads/MySQLGUITools/mysql-workbench-community-8.0.34-winx64.msi" target="_blank">*КЛИКАБЕЛЬНО*</a></p>
  <blockquote id="eKq3">При установке, выбираем Modify</blockquote>
  <figure id="5NUk" class="m_custom">
    <img src="https://img2.teletype.in/files/5e/7a/5e7a05c8-3632-412e-bcde-072aa8d6e8b2.png" width="401" />
  </figure>
  <p id="9Hnd">Далее нажимаем везде &quot;Next&quot;</p>
  <p id="cOih"></p>
  <p id="X41L">Вроде разобрались (если не помогло прошу написать мне в личные сообщения: <a href="https://t.me/Xacker_Name_new" target="_blank">@Xacker_Name_new</a></p>
  <h3 id="7A0h"><strong><s>-------------------------------------------------------------------------</s></strong></h3>
  <p id="Mqb6">Давайте начнём работать с базой данных, с помощью вспомогательного класса work_db из файла <a href="/@xacker_name_new/SK-nC-byGW-#nPwS">class_db.py</a> мы будем записывать все анкеты в базу данных.</p>
  <p id="ToXf">Возьмём код бота из <a href="https://teletype.in/@xacker_name_new/SK-nC-byGW-" target="_blank">Урока #2</a></p>
  <pre id="Yt2G" data-lang="python">from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram import Bot, Dispatcher, executor, types
from aiogram.dispatcher import FSMContext
from aiogram.types import ReplyKeyboardRemove
from class_db import work_db #Импорируем класс для работы с базой данных из файла class_db.py
import test as bb #Импортируем файл test.py в переменную bb (мне так удобнее работать с ним)
import config as c #Импортируем файл config.py в переменную с (опять же мне так удобнее)



#Создаём класс бота и дистпетчера
bot = Bot(token=c.token) #Берём токен бота из файла config.py который импортировали ранее в переменную c
dp = Dispatcher(bot)
db_work = work_db(c.host, c.port, c.user, c.password, c.database) #Создаём экземпляр класса для работы с базой данных, передав все нужные параметры из конфига


class anketa(StatesGroup):
	name = State()
	floor = State()
	age = State()




@dp.message_handler(content_types=[&#x27;text&#x27;]) #Обрабатываем каждое сообщение от пользователей, добавляем content_types для обработки текста, в будущих уроках будет фото и видео
async def text(message: types.Message): #Асинхронная функция с название &quot;text&quot; которая принимает в переменную message, текст пользователя отправевшего сообщение
	if message.text == &#x27;/start&#x27;:
		await bot.send_message(message.chat.id, &#x27;Привет, заполни анкету, или посмотри информацйию о мне&#x27;, reply_markup=bb.mark_menu) #Обрабатываем команду /start и выводим клавиатуру из файлы test.py
	elif message.text == &#x27;Информация&#x27;:
		await bot.send_message(message.chat.id, f&#x27;Сюда пишем какую либо информацию, например я хочу вывести ID пользователя\nТвой ID: {message.chat.id}&#x27;)
	elif message.text == &#x27;Заполнить анкету&#x27;:
		await bot.send_message(message.chat.id, &#x27;Введите своё имя:&#x27;)
		await anketa.name.set()


@dp.message_handler(state=anketa.name)
async def anketa_name(message: types.Message, state: FSMContext): #Как видите у нас добавился FSMContext, он нам нужен как раз для обработки машины состояния
	#Записываем имя в кеш
	await state.update_data(name=name)
	#Далее просим ввести пол, с выбором пола из кнопок
	await bot.send_message(message.chat.id, &#x27;Выберите свой пол:&#x27;, reply_markup=bb.main_floor) #добавляем вывод кнопок с выбором пола
	await anketa.floor.set()


@dp.message_handler(state=anketa.floor)
async def anketa_name(message: types.Message, state: FSMContext):
	#Записываем пол в кеш
	await state.update_data(floor=floor)
	#Далее просим ввести свой возраст
	await bot.send_message(message.chat.id, &#x27;Выберите свой пол:&#x27;, reply_markup=ReplyKeyboardRemove()) #убираем текстовую клавиатуру
	await anketa.age.set()


@dp.message_handler(state=anketa.age)
async def anketa_name(message: types.Message, state: FSMContext):
	#Получим все данные записанные в кеш
	data = await state.get_data()
	#Сортируем их по переменным
	name = data[&#x27;name&#x27;] #В ковычках пишем name, потому что сами записывали в такую переменную, там может быть любая другая
	floor = data[&#x27;floor&#x27;] #В ковычках пишем floor, потому что сами записывали в такую переменную, там может быть любая другая
	age = message.text #записываем ввод пользователя в переменную age
	await state.finish() #Завершаем работу с машиной состояний
	#Выведем анкету пользователю
	await bot.send_message(message.chat.id, f&#x27;Ваша анкета:\n\nИмя: {name}\nПол: {floor}\nВозраст: {age}\n\nСпасибо за уделение времени&#x27;, reply_markup=bb.mark_menu) #Отправляем анкету, благодарим, и выдаём ему текстовоем меню
	#Отправим анкету администратору по его ID из config.py
	#Так же выведем ID пользователя и его юзернейм
	await bot.send_message(c.admin, f&#x27;Пользователь: {message.chat.id}\n@{message.from_user.username} заполнил анкету\nЕго данные:\n\nИмя: {name}\nПол: {floor}\nВозраст: {age}&#x27;)




if __name__ == &quot;__main__&quot;: #Если скрипт запущен с этого файла, запускаем executor
    executor.start_polling(dp, skip_updates=True) #skip_updates=True - нужен для того чтобы не обрабатывать сообщения которые были присланы пользователем в тот момент когда бот был выключен</pre>
  <p id="Xngr">Для начала давайте создадим функцию которая будет создавать таблицы:</p>
  <pre id="JiLc" data-lang="python">def creat_table(): #Данную функцию будем запускать при каждом запуске кода, параметры функция не принимает
	#Для начала конектимся к базе данных:
	connection = db_work.connect_db()
	if connection: #Если класс вернул конект, а не False
		#Напишем сам запрос
		creat_table_request = &#x27;CREATE TABLE IF NOT EXISTS &#x60;ankets&#x60;(id int AUTO_INCREMENT, name varchar(32), floor varchar(10), age int, PRIMARY KEY (id));&#x27; #И так мы написали запрос, но для чего он нам?
		#Он нам для того что-бы создать таблицу для анкет где будут следующие данные: id - это будет id анкеты (число), оно будет прописываться само (из-за AUTO_INCREMENT)
		#name типа сроки длинной не более 32 символов, floor типа строки не более 10 символов и age типа числа без ограничения
		#Первичный ключ (PRIMARY KEY) — особенное поле в таблице, которое позволяет однозначно идентифицировать каждую запись в ней
		#Запрос написан, давайте его выполним:
		status = db_work.create_table(connection, creat_table_request) #Предаём необходимые данные (Конект и сам запрос)
		#Проверяем статус создания базы данных:
		if status: #Если вернуло True значит всё хорошо (выведем в консоль что запрос выполнен)
			print(&#x27;Таблица успешно создана&#x27;)
			#Закрываем конект
			if db_work.connect_close(connection):
				print(&#x27;Конект закрыт!&#x27;)
			else: #Если нам вернуло False, значит произошла ошибка, в вспомогательном классе мы прописали вывод ошибки
				print(&#x27;Ошибка указана выше&#x27;)
		else: #Если вернуло False, значит не удалось создать таблицу, ошибку мы так же вывели в классе
			print(&#x27;Ошибка указана выше&#x27;)
	else: #Если мы не смогли подключиться к базе данных, то опять же ошибка была выведена в классе
		print(&#x27;Ошибка указана выше&#x27;)</pre>
  <p id="z3rn">И так давайте допишем запуск этой функции:</p>
  <pre id="yL9T" data-lang="python">if __name__ == &quot;__main__&quot;: #Если скрипт запущен с этого файла, запускаем executor
	creat_table() #Запускаем функцию создания таблицы
	executor.start_polling(dp, skip_updates=True) #skip_updates=True - нужен для того чтобы не обрабатывать сообщения которые были присланы пользователем в тот момент когда бот был выключен</pre>
  <p id="WHQg">Запускаем:</p>
  <p id="qG2Z">У меня возникла ошибка с вспомогательным классом для работы с базой данных, текст ошибки:</p>
  <pre id="dLg7">Traceback (most recent call last):
  File &quot;C:\Users\ffff1\OneDrive\Рабочий стол\bot_ankets\main.py&quot;, line 14, in &lt;module&gt;
    db_work = work_db(c.host, c.port, c.user, c.password, c.database) #Создаём экземпляр класса для работы с базой данных, передав все нужные параметры из конфига
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: work_db.__init__() takes 1 positional argument but 6 were given</pre>
  <p id="ulEG">Это из-за того что я не написал в функции &quot;__init__&quot; принятие нескольких аргументов, а передаю аж 6, поэтому давайте перепишем функцию &quot;__init__&quot;:</p>
  <pre id="mRQG" data-lang="python">def __init__(self, host, port, user, password, database): #Функция для иницилизирования переменных в класс, запускать её не надо
		self.host = host
		self.port = port
		self.user = user
		self.password = password
		self.database = database</pre>
  <p id="y4Kc">Запускаем:</p>
  <p id="aXZU">...Пишет что базы нет, в таком случае в программе Workbench 8.0 CE заходим в базу которые создали в <a href="https://teletype.in/@xacker_name_new/UqnaI47nEzx#ZIiJ" target="_blank">первом уроке</a></p>
  <figure id="3GYI" class="m_custom">
    <img src="https://img1.teletype.in/files/03/8b/038b54f7-0c18-4eb2-9b41-56d574922e03.png" width="1086" />
  </figure>
  <p id="BYpk">В строке (указанной прямоугольником пишем следующие:</p>
  <p id="A1Xw"><code>CREATE DATABASE usersdb;</code></p>
  <p id="WWQj">Должно получиться так:</p>
  <figure id="WT7X" class="m_custom">
    <img src="https://img3.teletype.in/files/e4/bc/e4bc7f18-b5d5-4e02-a411-06f39cdad8a2.png" width="1028" />
  </figure>
  <p id="nuQc">Далее нажимаем на молнию (указана стрелочкой)</p>
  <figure id="Jmfn" class="m_custom">
    <img src="https://img2.teletype.in/files/12/e6/12e68865-5e72-4f8b-af5e-32c08651c389.png" width="1042.7767857142858" />
  </figure>
  <p id="gOAb">Красная стрелочка: нам пишет что база данных создана!<br />Черная стрелочка: На том месте нажимаем правой кнопкой и Refresh (У нас появляется база данных)</p>
  <p id="yHmh">Далее покажу как смотреть данные из неё...</p>
  <p id="1tH7">Запускаем бота:</p>
  <figure id="mSJk" class="m_original">
    <img src="https://img2.teletype.in/files/d5/7b/d57be762-b134-48a1-8b68-144b8818de77.png" width="467" />
  </figure>
  <p id="t8vi">Таблица успешно создана, и конект успешно закрыт, я считаю это успех)</p>
  <p id="U5Ol">Давайте напишем функцию которая будет записывать данные в таблицу:</p>
  <pre id="ZJKS" data-lang="python">def insert_table(name_, floor_, age_): #Данная функция принимает имя таблицы в которую надо записать данные (Сразу скажу т.к. мы записывать будет в ankets ропишем получение данных)
	#Для начала конектимся к базе данных:
	connection = db_work.connect_db()
	if connection: #Если класс вернул конект, а не False
		#Напишем сам запрос
		insert_table_request = &#x27;INSERT INTO ankets (name, floor, age) VALUES (%s, %s, %s);&#x27; #И так в этом запросе мы создаём запись данных
		with connection.cursor() as cursor:
			cursor.execute(insert_table_request, (name_, floor_, age_)) #Записываем данные полученные в функцию
		connection.commit() #Сохраняем изменения
		print(&#x27;Данные записаны!&#x27;)
		if db_work.connect_close(connection):
			print(&#x27;Конект закрыт!&#x27;)
		else: #Если нам вернуло False, значит произошла ошибка, в вспомогательном классе мы прописали вывод ошибки
			print(&#x27;Ошибка указана выше&#x27;)
	else: #Если мы не смогли подключиться к базе данных, то опять же ошибка была выведена в классе
		print(&#x27;Ошибка указана выше&#x27;)</pre>
  <p id="shkb">Функция записана, давайте её добавим вызов функции из обработчика возраста:</p>
  <pre id="EURO" data-lang="python">@dp.message_handler(state=anketa.age)
async def anketa_name(message: types.Message, state: FSMContext):
	#Получим все данные записанные в кеш
	data = await state.get_data()
	#Сортируем их по переменным
	name = data[&#x27;name&#x27;] #В ковычках пишем name, потому что сами записывали в такую переменную, там может быть любая другая
	floor = data[&#x27;floor&#x27;] #В ковычках пишем floor, потому что сами записывали в такую переменную, там может быть любая другая
	age = message.text #записываем ввод пользователя в переменную age
	await state.finish() #Завершаем работу с машиной состояний
	#Выведем анкету пользователю
	await bot.send_message(message.chat.id, f&#x27;Ваша анкета:\n\nИмя: {name}\nПол: {floor}\nВозраст: {age}\n\nСпасибо за уделение времени&#x27;, reply_markup=bb.mark_menu) #Отправляем анкету, благодарим, и выдаём ему текстовоем меню
	#Отправим анкету администратору по его ID из config.py
	#Так же выведем ID пользователя и его юзернейм
	await bot.send_message(c.admin, f&#x27;Пользователь: {message.chat.id}\n@{message.from_user.username} заполнил анкету\nЕго данные:\n\nИмя: {name}\nПол: {floor}\nВозраст: {age}&#x27;)
	insert_table(name, floor, age) #Передаём необходимые данные</pre>
  <p id="4l3i">Перезапускаем бота, и заполняем анкету:</p>
  <p id="rGfk">Выдало ошибку:</p>
  <pre id="YSRU">FSMStorageWarning: You haven’t set any storage yet so no states and no data will be saved.
You can connect MemoryStorage for debug purposes or non-essential data.</pre>
  <p id="cUMn">Нужно добавить ещё 1 импорт в файл <a href="https://teletype.in/@xacker_name_new/SK-nC-byGW-#nPwS" target="_blank">main.py</a>:</p>
  <pre id="Aufj" data-lang="python">from aiogram.contrib.fsm_storage.memory import MemoryStorage</pre>
  <p id="pMlj">Так же поменяем класс бота и диспетчера:</p>
  <pre id="Mj7s" data-lang="python">bot = Bot(token=c.token, parse_mode=types.ParseMode.HTML)
dp = Dispatcher(bot, storage=MemoryStorage())</pre>
  <p id="ZMhx">Ещё я допустил ошибку в 2х обработчиках:</p>
  <pre id="4hc7" data-lang="python">@dp.message_handler(state=anketa.name)
async def anketa_name(message: types.Message, state: FSMContext): #Как видите у нас добавился FSMContext, он нам нужен как раз для обработки машины состояния
	#Записываем имя в кеш
	await state.update_data(name=message.text)
	#Далее просим ввести пол, с выбором пола из кнопок
	await bot.send_message(message.chat.id, &#x27;Выберите свой пол:&#x27;, reply_markup=bb.main_floor) #добавляем вывод кнопок с выбором пола
	await anketa.floor.set()


@dp.message_handler(state=anketa.floor)
async def anketa_name(message: types.Message, state: FSMContext):
	#Записываем пол в кеш
	await state.update_data(floor=message.text)
	#Далее просим ввести свой возраст
	await bot.send_message(message.chat.id, &#x27;Выберите свой пол:&#x27;, reply_markup=ReplyKeyboardRemove()) #убираем текстовую клавиатуру
	await anketa.age.set()</pre>
  <p id="6t5u">Не думайте что я не мастер своего дела, по мимо уроков я ещё и работаю, учусь, и иногда бывают такие ошибки...</p>
  <p id="2erX">Давайте продолжим, запускаем бота и заполняем анкету:</p>
  <figure id="7Ekx" class="m_original">
    <img src="https://img4.teletype.in/files/3d/a5/3da507c4-83e8-4c09-a586-da5d44634679.png" width="701" />
  </figure>
  <figure id="FBZB" class="m_original">
    <img src="https://img1.teletype.in/files/41/3b/413b8596-521f-4f8e-a5d5-8631881fb11f.png" width="457" />
  </figure>
  <p id="NKC3">И так мы успешно записали данные, давайте посмотрим их</p>
  <p id="knlV">Открываем программу (скрин)</p>
  <figure id="2Pt1" class="m_original">
    <img src="https://img4.teletype.in/files/bd/7d/bd7df69c-1043-42b8-8d6d-d2d30c217bbe.png" width="215" />
  </figure>
  <p id="th3e">Заходим двойным щелчком ЛКМ по базе &quot;test_basa&quot;</p>
  <p id="xkKC">Раскрываем базу:</p>
  <figure id="Q2R8" class="m_custom">
    <img src="https://img2.teletype.in/files/df/b0/dfb08950-f611-46d1-8013-6b2900aa8d32.png" width="1055.652818991098" />
  </figure>
  <p id="APZ7">Разворачиваем таблицы</p>
  <figure id="eV5L" class="m_custom">
    <img src="https://img1.teletype.in/files/c5/05/c505f468-447a-4933-9e91-1d34b759a069.png" width="194" />
  </figure>
  <p id="63JA">При наведении на таблице ankets у нас появляются кнопочки, нам нужна эта:</p>
  <figure id="juzL" class="m_original">
    <img src="https://img3.teletype.in/files/6f/65/6f652464-05a1-4ac5-8b28-00cd17977768.png" width="221" />
  </figure>
  <p id="qAMJ">Нажимаем и снизу у нас есть все данные записанные в таблицу:</p>
  <figure id="sjVR" class="m_custom">
    <img src="https://img4.teletype.in/files/3a/da/3ada070c-d92e-4db7-955c-3d1270e539a2.png" width="1088.0623762376238" />
  </figure>
  <p id="1S1n">Молодцы, теперь давайте по команду в бота &quot;/info_table&quot;</p>
  <p id="1R6m">Давайте перепишем функцию в вспомогательном классе:</p>
  <pre id="QKVk" data-lang="python">	def info_table(self, connection, info, values): #Функция для получения данных из таблицы, в info будем передавать текст запроса
		try:
			with connection.cursor() as cursor:
				cursor.execute(info, values)
			return cursor.fetchall()[0] #Возвращаем всё что нашли
		except Exception as eror:
			print(eror) #Если произошла ошибка, выводим её в консоль
			return False #Если произошла ошибка, возвращаем False</pre>
  <p id="31Hk">Выведем все данные по ID 1<br />Напишем обработчик команды &quot;/info_table&quot;:</p>
  <pre id="qtTZ" data-lang="python">@dp.message_handler(content_types=[&#x27;text&#x27;]) #Обрабатываем каждое сообщение от пользователей, добавляем content_types для обработки текста, в будущих уроках будет фото и видео
async def text(message: types.Message): #Асинхронная функция с название &quot;text&quot; которая принимает в переменную message, текст пользователя отправевшего сообщение
	if message.text == &#x27;/start&#x27;:
		await bot.send_message(message.chat.id, &#x27;Привет, заполни анкету, или посмотри информацйию о мне&#x27;, reply_markup=bb.mark_menu) #Обрабатываем команду /start и выводим клавиатуру из файлы test.py
	elif message.text == &#x27;Информация&#x27;:
		await bot.send_message(message.chat.id, f&#x27;Сюда пишем какую либо информацию, например я хочу вывести ID пользователя\nТвой ID: {message.chat.id}&#x27;)
	elif message.text == &#x27;Заполнить анкету&#x27;:
		await bot.send_message(message.chat.id, &#x27;Введите своё имя:&#x27;)
		await anketa.name.set()
	elif message.text == &#x27;/info_table&#x27;:
		info_request = &#x27;SELECT * FROM ankets WHERE id = %s&#x27;
		values = (1,)
		connection = db_work.connect_db() #Конектимся к базе данных
		if connection: #Если конект успешный
			info = db_work.info_table(connection, info_request, values)
			if info: #Если получили данные по id = 1
				await bot.send_message(message.chat.id, f&#x27;Полученные данные: {info}&#x27;)
			else: #Если не смогли получить данные
				await bot.send_message(message.chat.id, &#x27;Не удалось получить данные&#x27;)
		else: #Если конект не удался
			await bot.send_message(message.chat.id, &#x27;Не удалось подключиться к базе данных&#x27;)</pre>
  <p id="9FDS">У нас получился такой код, перезапускаем бота, и проверяем работоспособность команды:</p>
  <figure id="huLJ" class="m_original">
    <img src="https://img4.teletype.in/files/f3/fd/f3fde4ef-58c0-4f57-8f29-46f0df60f97f.png" width="695" />
  </figure>
  <p id="BC9k">Работает отлично, но выводит данные не особо красиво, давайте исправим:</p>
  <pre id="OuCG" data-lang="python">@dp.message_handler(content_types=[&#x27;text&#x27;]) #Обрабатываем каждое сообщение от пользователей, добавляем content_types для обработки текста, в будущих уроках будет фото и видео
async def text(message: types.Message): #Асинхронная функция с название &quot;text&quot; которая принимает в переменную message, текст пользователя отправевшего сообщение
	if message.text == &#x27;/start&#x27;:
		await bot.send_message(message.chat.id, &#x27;Привет, заполни анкету, или посмотри информацйию о мне&#x27;, reply_markup=bb.mark_menu) #Обрабатываем команду /start и выводим клавиатуру из файлы test.py
	elif message.text == &#x27;Информация&#x27;:
		await bot.send_message(message.chat.id, f&#x27;Сюда пишем какую либо информацию, например я хочу вывести ID пользователя\nТвой ID: {message.chat.id}&#x27;)
	elif message.text == &#x27;Заполнить анкету&#x27;:
		await bot.send_message(message.chat.id, &#x27;Введите своё имя:&#x27;)
		await anketa.name.set()
	elif message.text == &#x27;/info_table&#x27;:
		info_request = &#x27;SELECT * FROM ankets WHERE id = %s&#x27;
		values = (1,)
		connection = db_work.connect_db() #Конектимся к базе данных
		if connection: #Если конект успешный
			info = db_work.info_table(connection, info_request, values)
			if info: #Если получили данные по id = 1
				await bot.send_message(message.chat.id, f&#x27;Полученные данные:\nID: {info[&quot;id&quot;]}\nИмя: {info[&quot;name&quot;]}\nПол: {info[&quot;floor&quot;]}\nВозраст: {info[&quot;age&quot;]}&#x27;)
			else: #Если не смогли получить данные
				await bot.send_message(message.chat.id, &#x27;Не удалось получить данные&#x27;)
		else: #Если конект не удался
			await bot.send_message(message.chat.id, &#x27;Не удалось подключиться к базе данных&#x27;)</pre>
  <p id="ee46">Проверяем вывод, и наслаждаемся красотой:</p>
  <figure id="go19" class="m_original">
    <img src="https://img3.teletype.in/files/6c/a4/6ca45101-296d-4a2b-afe8-3e3379c2def9.png" width="697" />
  </figure>
  <p id="BZ8N">Так то лучше не так ли?</p>
  <p id="mF5I">Давайте обновим возраст с помощью инлайн кнопок?</p>
  <p id="OWs6">Создаём обработчик команды &quot;/new_value&quot;</p>
  <p id="H4ND">Но перед этим напишем класс для ввода ID записи в базе данных:</p>
  <pre id="Fbr4" data-lang="python">class new_values(StatesGroup):
	new_value = State()</pre>
  <p id="Sz1Q">И так продолжим писать обработчик:</p>
  <pre id="Y9Q9" data-lang="python">@dp.message_handler(content_types=[&#x27;text&#x27;]) #Обрабатываем каждое сообщение от пользователей, добавляем content_types для обработки текста, в будущих уроках будет фото и видео
async def text(message: types.Message): #Асинхронная функция с название &quot;text&quot; которая принимает в переменную message, текст пользователя отправевшего сообщение
	if message.text == &#x27;/start&#x27;:
		await bot.send_message(message.chat.id, &#x27;Привет, заполни анкету, или посмотри информацйию о мне&#x27;, reply_markup=bb.mark_menu) #Обрабатываем команду /start и выводим клавиатуру из файлы test.py
	elif message.text == &#x27;Информация&#x27;:
		await bot.send_message(message.chat.id, f&#x27;Сюда пишем какую либо информацию, например я хочу вывести ID пользователя\nТвой ID: {message.chat.id}&#x27;)
	elif message.text == &#x27;Заполнить анкету&#x27;:
		await bot.send_message(message.chat.id, &#x27;Введите своё имя:&#x27;)
		await anketa.name.set()
	elif message.text == &#x27;/info_table&#x27;:
		info_request = &#x27;SELECT * FROM ankets WHERE id = %s&#x27;
		values = (1,)
		connection = db_work.connect_db() #Конектимся к базе данных
		if connection: #Если конект успешный
			info = db_work.info_table(connection, info_request, values)
			if info: #Если получили данные по id = 1
				await bot.send_message(message.chat.id, f&#x27;Полученные данные:\nID: {info[&quot;id&quot;]}\nИмя: {info[&quot;name&quot;]}\nПол: {info[&quot;floor&quot;]}\nВозраст: {info[&quot;age&quot;]}&#x27;)
			else: #Если не смогли получить данные
				await bot.send_message(message.chat.id, &#x27;Не удалось получить данные&#x27;)
		else: #Если конект не удался
			await bot.send_message(message.chat.id, &#x27;Не удалось подключиться к базе данных&#x27;)
	elif message.text == &#x27;/new_value&#x27;:
		await bot.send_message(message.chat.id, &#x27;Введите ID для изменения возраста:&#x27;)
		await new_values.new_value.set()</pre>
  <p id="d0Tf">Пишем обработчик ввода пользователя:</p>
  <pre id="nKEe" data-lang="python">@dp.message_handler(state=new_values.new_value)
async def anketa_name(message: types.Message, state: FSMContext): #Как видите у нас добавился FSMContext, он нам нужен как раз для обработки машины состояния
	#Записываем ID в кеш
	await state.update_data(id_value=message.text)
	#Выводим инлайн кнопки с числами
	#Пока напишу прямо тут, в следующих уроках будем создавать функции
	await bot.send_message(message.chat.id, &#x27;Выберите новое значение:&#x27;, reply_markup=InlineKeyboardMarkup(row_width=3).add(
		InlineKeyboardButton(text=&#x27;1&#x27;, callback_data=&#x27;new_value_1&#x27;),InlineKeyboardButton(text=&#x27;2&#x27;, callback_data=&#x27;new_value_2&#x27;), InlineKeyboardButton(text=&#x27;10&#x27;, callback_data=&#x27;new_value_10&#x27;),
		InlineKeyboardButton(text=&#x27;25&#x27;, callback_data=&#x27;new_value_25&#x27;)))
	#Этого достаточно</pre>
  <p id="E54J">Давайте допишем ипорт:</p>
  <pre id="EOcf" data-lang="python">from aiogram.types import ReplyKeyboardRemove, InlineKeyboardMarkup, InlineKeyboardButton</pre>
  <p id="3PJD">Давайте ещё перепишем функцию в вспомогательном классе:</p>
  <pre id="2zGO" data-lang="python">	def edit_table(self, connection, edit, values): #Функция для редактирования данных в таблице, в edit будем передавать текст запроса
		try:
			with connection.cursor() as cursor:
				cursor.execute(edit, values)
			connection.commit()
			return True
		except Exception as eror:
			print(eror) #Если произошла ошибка, выводим её в консоль
			return False #Если произошла ошибка, возвращаем False</pre>
  <p id="a4Yl">Теперь перейдём к обработчику нажатий на инлайн кнопки:</p>
  <pre id="rLKi" data-lang="python">@dp.callback_query_handler(lambda call: True, state=&#x27;*&#x27;) #Обрабатываем нажатия всех инлайн кнопок, даже когда активно ожидание ввода от пользователя
async def callback_inline(call, state: FSMContext): #В переменную call принимаем данные о нажатой кнопке
	try: #Обрабатываем ошибки, если всё успешно то мы получим переменную id_value на всю функцию
		data = await state.get_data()
		id_value = data[&#x27;id_value&#x27;]
		await state.finish()
	except Exception as eror: #Если будут ошибки мы их пришлём пользователю
		await bot.send_message(call.message.chat.id, f&#x27;Произошла ошибка: {eror}&#x27;)
		return #Останавливаем выполнение функции
	#Приступим к обработке нажатия кнопок, т.к. у нас записано новое чило в callback_data, но начало одно и тоже
	#Нам нужно проверять есть ли в нажатой кнопке начало:
	if &#x27;new_value_&#x27; in call.data: #В call.data содержиться callback_data
		new_value = int(call.data.replace(&#x27;new_value_&#x27;, &#x27;&#x27;)) #С момощью этого кода мы получим число типа int, удалив из call.data не нужное нам
		#Грубыми словами с помощью replace мы заменяем new_value_ на ничего
		#Теперь давайте заменим значение в таблице по ID которое вписали изначально
		#Конектимся к базе данных:
		connection = db_work.connect_db()
		if connection: #Если конект успешен
			#Возпользуемся функцией edit_table из вспомогательного класса:
			new_value_request = &#x27;UPDATE ankets SET age = %s WHERE id = %s&#x27;
			values = (new_value, int(id_value))
			status = db_work.edit_table(connection, new_value_request, values)
			if status: #Если успешно обновили данные
				await bot.send_message(call.message.chat.id, f&#x27;Данные для строки с ID: {id_value}\nУспешно обновлены на: {new_value}&#x27;)
			else: #Если произошла ошибка
				await bot.send_message(call.message.chat.id, &#x27;Произошла ошибка, она отобразилась в консоли!&#x27;)
		else: #Если не удалось подключиться к базе данных
			await bot.send_message(call.message.chat.id, &#x27;Не удалось подключиться к базе данных!&#x27;)</pre>
  <p id="1X40">Запустим бота и проверим работоспособность:</p>
  <figure id="K49R" class="m_original">
    <img src="https://img3.teletype.in/files/ea/dc/eadcd1da-3510-4f64-b57b-1fd8e4eb0d2a.png" width="702" />
  </figure>
  <p id="3Sni">Всё работает, кайф, давайте проверим данные через программу </p>
  <figure id="DZyg" class="m_original">
    <img src="https://img1.teletype.in/files/07/8b/078b2c8d-f946-4101-8e7b-8e295e9a1741.png" width="215" />
  </figure>
  <p id="wwp3">Для обновления, нажимаем на кнопку:</p>
  <figure id="51EK" class="m_custom">
    <img src="https://img3.teletype.in/files/ef/42/ef424232-8a6b-4c72-99fa-299ab4eb1dd0.png" width="1065.580198019802" />
  </figure>
  <p id="c8Wj">И так, данные успешно обновлены:</p>
  <figure id="PVtU" class="m_custom">
    <img src="https://img4.teletype.in/files/f2/de/f2dea586-d57c-469a-a8e1-8b4be2684357.png" width="1081" />
  </figure>
  <p id="QBLF">На этом я предлагаю закончить наш урок)</p>
  <p id="5LHC">Итоговый код который у нас полчиться:</p>
  <pre id="9H7V" data-lang="python">from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.contrib.fsm_storage.memory import MemoryStorage
from aiogram import Bot, Dispatcher, executor, types
from aiogram.dispatcher import FSMContext
from aiogram.types import ReplyKeyboardRemove, InlineKeyboardMarkup, InlineKeyboardButton
from class_db import work_db #Импорируем класс для работы с базой данных из файла class_db.py
import test as bb #Импортируем файл test.py в переменную bb (мне так удобнее работать с ним)
import config as c #Импортируем файл config.py в переменную с (опять же мне так удобнее)



#Создаём класс бота и дистпетчера
bot = Bot(token=c.token, parse_mode=types.ParseMode.HTML) #Берём токен бота из файла config.py который импортировали ранее в переменную c
dp = Dispatcher(bot, storage=MemoryStorage())
db_work = work_db(c.host, c.port, c.user, c.password, c.database) #Создаём экземпляр класса для работы с базой данных, передав все нужные параметры из конфига


class anketa(StatesGroup):
	name = State()
	floor = State()
	age = State()


class new_values(StatesGroup):
	new_value = State()


def creat_table(): #Данную функцию будем запускать при каждом запуске кода, параметры функция не принимает
	#Для начала конектимся к базе данных:
	connection = db_work.connect_db()
	if connection: #Если класс вернул конект, а не False
		#Напишем сам запрос
		creat_table_request = &#x27;CREATE TABLE IF NOT EXISTS &#x60;ankets&#x60;(id int AUTO_INCREMENT, name varchar(32), floor varchar(10), age int, PRIMARY KEY (id));&#x27; #И так мы написали запрос, но для чего он нам?
		#Он нам для того что-бы создать таблицу для анкет где будут следующие данные: id - это будет id анкеты (число), оно будет прописываться само (из-за AUTO_INCREMENT)
		#name типа сроки длинной не более 32 символов, floor типа строки не более 10 символов и age типа числа без ограничения
		#Первичный ключ (PRIMARY KEY) — особенное поле в таблице, которое позволяет однозначно идентифицировать каждую запись в ней
		#Запрос написан, давайте его выполним:
		status = db_work.create_table(connection, creat_table_request) #Предаём необходимые данные (Конект и сам запрос)
		#Проверяем статус создания базы данных:
		if status: #Если вернуло True значит всё хорошо (выведем в консоль что запрос выполнен)
			print(&#x27;Таблица успешно создана&#x27;)
			#Закрываем конект
			if db_work.connect_close(connection):
				print(&#x27;Конект закрыт!&#x27;)
			else: #Если нам вернуло False, значит произошла ошибка, в вспомогательном классе мы прописали вывод ошибки
				print(&#x27;Ошибка указана выше&#x27;)
		else: #Если вернуло False, значит не удалось создать таблицу, ошибку мы так же вывели в классе
			print(&#x27;Ошибка указана выше&#x27;)
	else: #Если мы не смогли подключиться к базе данных, то опять же ошибка была выведена в классе
		print(&#x27;Ошибка указана выше&#x27;)


def insert_table(name_, floor_, age_): #Данная функция принимает имя таблицы в которую надо записать данные (Сразу скажу т.к. мы записывать будет в ankets ропишем получение данных)
	#Для начала конектимся к базе данных:
	connection = db_work.connect_db()
	if connection: #Если класс вернул конект, а не False
		#Напишем сам запрос
		insert_table_request = &#x27;INSERT INTO ankets (name, floor, age) VALUES (%s, %s, %s);&#x27; #И так в этом запросе мы создаём запись данных
		with connection.cursor() as cursor:
			cursor.execute(insert_table_request, (name_, floor_, age_)) #Записываем данные полученные в функцию
		connection.commit() #Сохраняем изменения
		print(&#x27;Данные записаны!&#x27;)
		if db_work.connect_close(connection):
			print(&#x27;Конект закрыт!&#x27;)
		else: #Если нам вернуло False, значит произошла ошибка, в вспомогательном классе мы прописали вывод ошибки
			print(&#x27;Ошибка указана выше&#x27;)
	else: #Если мы не смогли подключиться к базе данных, то опять же ошибка была выведена в классе
		print(&#x27;Ошибка указана выше&#x27;)


@dp.message_handler(content_types=[&#x27;text&#x27;]) #Обрабатываем каждое сообщение от пользователей, добавляем content_types для обработки текста, в будущих уроках будет фото и видео
async def text(message: types.Message): #Асинхронная функция с название &quot;text&quot; которая принимает в переменную message, текст пользователя отправевшего сообщение
	if message.text == &#x27;/start&#x27;:
		await bot.send_message(message.chat.id, &#x27;Привет, заполни анкету, или посмотри информацйию о мне&#x27;, reply_markup=bb.mark_menu) #Обрабатываем команду /start и выводим клавиатуру из файлы test.py
	elif message.text == &#x27;Информация&#x27;:
		await bot.send_message(message.chat.id, f&#x27;Сюда пишем какую либо информацию, например я хочу вывести ID пользователя\nТвой ID: {message.chat.id}&#x27;)
	elif message.text == &#x27;Заполнить анкету&#x27;:
		await bot.send_message(message.chat.id, &#x27;Введите своё имя:&#x27;)
		await anketa.name.set()
	elif message.text == &#x27;/info_table&#x27;:
		info_request = &#x27;SELECT * FROM ankets WHERE id = %s&#x27;
		values = (1,)
		connection = db_work.connect_db() #Конектимся к базе данных
		if connection: #Если конект успешный
			info = db_work.info_table(connection, info_request, values)
			if info: #Если получили данные по id = 1
				await bot.send_message(message.chat.id, f&#x27;Полученные данные:\nID: {info[&quot;id&quot;]}\nИмя: {info[&quot;name&quot;]}\nПол: {info[&quot;floor&quot;]}\nВозраст: {info[&quot;age&quot;]}&#x27;)
			else: #Если не смогли получить данные
				await bot.send_message(message.chat.id, &#x27;Не удалось получить данные&#x27;)
		else: #Если конект не удался
			await bot.send_message(message.chat.id, &#x27;Не удалось подключиться к базе данных&#x27;)
	elif message.text == &#x27;/new_value&#x27;:
		await bot.send_message(message.chat.id, &#x27;Введите ID для изменения возраста:&#x27;)
		await new_values.new_value.set()


@dp.message_handler(state=new_values.new_value)
async def anketa_name(message: types.Message, state: FSMContext): #Как видите у нас добавился FSMContext, он нам нужен как раз для обработки машины состояния
	#Записываем ID в кеш
	await state.update_data(id_value=message.text)
	#Выводим инлайн кнопки с числами
	#Пока напишу прямо тут, в следующих уроках будем создавать функции
	await bot.send_message(message.chat.id, &#x27;Выберите новое значение:&#x27;, reply_markup=InlineKeyboardMarkup(row_width=3).add(
		InlineKeyboardButton(text=&#x27;1&#x27;, callback_data=&#x27;new_value_1&#x27;),InlineKeyboardButton(text=&#x27;2&#x27;, callback_data=&#x27;new_value_2&#x27;), InlineKeyboardButton(text=&#x27;10&#x27;, callback_data=&#x27;new_value_10&#x27;),
		InlineKeyboardButton(text=&#x27;25&#x27;, callback_data=&#x27;new_value_25&#x27;)))
	#Этого достаточно



@dp.message_handler(state=anketa.name)
async def anketa_name(message: types.Message, state: FSMContext): #Как видите у нас добавился FSMContext, он нам нужен как раз для обработки машины состояния
	#Записываем имя в кеш
	await state.update_data(name=message.text)
	#Далее просим ввести пол, с выбором пола из кнопок
	await bot.send_message(message.chat.id, &#x27;Выберите свой пол:&#x27;, reply_markup=bb.menu_floor) #добавляем вывод кнопок с выбором пола
	await anketa.floor.set()


@dp.message_handler(state=anketa.floor)
async def anketa_name(message: types.Message, state: FSMContext):
	#Записываем пол в кеш
	await state.update_data(floor=message.text)
	#Далее просим ввести свой возраст
	await bot.send_message(message.chat.id, &#x27;Введите свой возраст:&#x27;, reply_markup=ReplyKeyboardRemove()) #убираем текстовую клавиатуру
	await anketa.age.set()


@dp.message_handler(state=anketa.age)
async def anketa_name(message: types.Message, state: FSMContext):
	#Получим все данные записанные в кеш
	data = await state.get_data()
	#Сортируем их по переменным
	name = data[&#x27;name&#x27;] #В ковычках пишем name, потому что сами записывали в такую переменную, там может быть любая другая
	floor = data[&#x27;floor&#x27;] #В ковычках пишем floor, потому что сами записывали в такую переменную, там может быть любая другая
	age = message.text #записываем ввод пользователя в переменную age
	await state.finish() #Завершаем работу с машиной состояний
	#Выведем анкету пользователю
	await bot.send_message(message.chat.id, f&#x27;Ваша анкета:\n\nИмя: {name}\nПол: {floor}\nВозраст: {age}\n\nСпасибо за уделение времени&#x27;, reply_markup=bb.mark_menu) #Отправляем анкету, благодарим, и выдаём ему текстовоем меню
	#Отправим анкету администратору по его ID из config.py
	#Так же выведем ID пользователя и его юзернейм
	await bot.send_message(c.admin, f&#x27;Пользователь: {message.chat.id}\n@{message.from_user.username} заполнил анкету\nЕго данные:\n\nИмя: {name}\nПол: {floor}\nВозраст: {age}&#x27;)
	insert_table(name, floor, age) #Передаём необходимые данные



@dp.callback_query_handler(lambda call: True, state=&#x27;*&#x27;) #Обрабатываем нажатия всех инлайн кнопок, даже когда активно ожидание ввода от пользователя
async def callback_inline(call, state: FSMContext): #В переменную call принимаем данные о нажатой кнопке
	try: #Обрабатываем ошибки, если всё успешно то мы получим переменную id_value на всю функцию
		data = await state.get_data()
		id_value = data[&#x27;id_value&#x27;]
		await state.finish()
	except Exception as eror: #Если будут ошибки мы их пришлём пользователю
		await bot.send_message(call.message.chat.id, f&#x27;Произошла ошибка: {eror}&#x27;)
		return #Останавливаем выполнение функции
	#Приступим к обработке нажатия кнопок, т.к. у нас записано новое чило в callback_data, но начало одно и тоже
	#Нам нужно проверять есть ли в нажатой кнопке начало:
	if &#x27;new_value_&#x27; in call.data: #В call.data содержиться callback_data
		new_value = int(call.data.replace(&#x27;new_value_&#x27;, &#x27;&#x27;)) #С момощью этого кода мы получим число типа int, удалив из call.data не нужное нам
		#Грубыми словами с помощью replace мы заменяем new_value_ на ничего
		#Теперь давайте заменим значение в таблице по ID которое вписали изначально
		#Конектимся к базе данных:
		connection = db_work.connect_db()
		if connection: #Если конект успешен
			#Возпользуемся функцией edit_table из вспомогательного класса:
			new_value_request = &#x27;UPDATE ankets SET age = %s WHERE id = %s&#x27;
			values = (new_value, int(id_value))
			status = db_work.edit_table(connection, new_value_request, values)
			if status: #Если успешно обновили данные
				await bot.send_message(call.message.chat.id, f&#x27;Данные для строки с ID: {id_value}\nУспешно обновлены на: {new_value}&#x27;)
			else: #Если произошла ошибка
				await bot.send_message(call.message.chat.id, &#x27;Произошла ошибка, она отобразилась в консоли!&#x27;)
		else: #Если не удалось подключиться к базе данных
			await bot.send_message(call.message.chat.id, &#x27;Не удалось подключиться к базе данных!&#x27;)


if __name__ == &quot;__main__&quot;: #Если скрипт запущен с этого файла, запускаем executor
	creat_table() #Запускаем функцию создания таблицы
	executor.start_polling(dp, skip_updates=True) #skip_updates=True - нужен для того чтобы не обрабатывать сообщения которые были присланы пользователем в тот момент когда бот был выключен</pre>
  <p id="P2QT">Я помню что не научил удалять данные с базы данных, но давайте будем честны, вы уже устали делать всё что выше, в следующем задании начнём с удаления данных!</p>
  <p id="Q8Eo" data-align="center">Домашнее задание:<br />1. Добавить больше кнопок для изменения возраста<br />2. Создать функцию &quot;creat_table_2&quot; и создать в ней таблицу &quot;users&quot; в которую добавить столбцы: <br />1. id - как в функции &quot;creat_table&quot;<br />2. name - типа varchar длинной не более 32 символов<br />3. password - типа varchar длинной не более 20 символов<br />4. Возраст - типа int<br />Записывать в таблицу ничего не надо, просто создать её при запуске бота, как мы это сделали с &quot;creat_table&quot;<br /><br />В обратной связи жду:<br />1. Скриншот кода с больший кол-вом кнопок<br />2. Скриншот кода функции &quot;creat_table_2&quot;<br />3. Скриншот с программы где видна новая таблица &quot;users&quot; и все столбца в ней<br /><br /><strong>Выполнить ДЗ до 28.09.2023</strong></p>
  <p id="EeFE"></p>
  <p id="V6ma"></p>
  <p id="3VEi"></p>
  <h2 id="XBgD">Спасибо за внимание</h2>
  <p id="nXCL">С вами был <a href="https://t.me/Xacker_Name_new" target="_blank">@Xacker_Name_new</a></p>
  <p id="eyUE">Поддержка: <a href="https://t.me/Bsc_Black_Secret_Club_bot" target="_blank">@Bsc_Black_Secret_Club_bot</a></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@xacker_name_new/SK-nC-byGW-</guid><link>https://teletype.in/@xacker_name_new/SK-nC-byGW-?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=xacker_name_new</link><comments>https://teletype.in/@xacker_name_new/SK-nC-byGW-?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=xacker_name_new#comments</comments><dc:creator>xacker_name_new</dc:creator><title>Обучение #2</title><pubDate>Mon, 25 Sep 2023 03:22:49 GMT</pubDate><media:content medium="image" url="https://img2.teletype.in/files/50/e3/50e31141-824f-4f69-8473-ed3aa0599887.png"></media:content><category>Обучение Python+aiogram+MySQL</category><description><![CDATA[<img src="https://img4.teletype.in/files/3a/72/3a720c74-3487-46cc-ac94-4ec752d144cc.png"></img>Обучение #2]]></description><content:encoded><![CDATA[
  <section style="background-color:hsl(hsl(199, 50%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <h3 id="OSVb">Язык программирования - Далее ЯП</h3>
    <h3 id="ZWeD">Операционная система - Далее ОС</h3>
    <h3 id="nmNE">Редактор кода - Далее IDE</h3>
    <h3 id="FbKl">CMD - Далее консоль</h3>
  </section>
  <h3 id="OmB3">Первый урок - <a href="https://teletype.in/@xacker_name_new/UqnaI47nEzx" target="_blank">*Кликабельно*</a></h3>
  <h2 id="ldF8">В этом уроке мы научимся:</h2>
  <p id="WhUl"><a href="#YxLb">Начало</a></p>
  <p id="FOfV">Работой с базой данных</p>
  <ol id="KQH9">
    <li id="rxbk">Научимся записывать данные в базу</li>
    <li id="DjNQ">Научимся читать данные из базы</li>
    <li id="ihIt">Научимся удалять данные с базы</li>
  </ol>
  <p id="Smrh">Напишем telegram бота с логикой анкетирования</p>
  <ol id="VITV">
    <li id="8DDD">Сможем получить имя</li>
    <li id="6FiA">Сможем получить пол</li>
    <li id="3Tq0">Сможем получить возраст</li>
  </ol>
  <p id="jStA">Работой с кнопками</p>
  <ol id="ieoi">
    <li id="ksCt">Сделаем 2 кнопки (Заполнить анкету\Информация)</li>
    <li id="5AcW">Сделаем текстовое меню</li>
    <li id="j2zg">Сделаем выбор пола через текстовое меню</li>
  </ol>
  <h2 id="YxLb" data-align="center">Начало</h2>
  <p id="nPwS">Для начала давайте создадим новый проект, создаём папку &quot;bot_ankets&quot;<br />В папке создадим 4 файла:<br />    1. main.py - в него будем писать основной код бота<br />    2. config.py - в него запишем токен бота, id админа, данные для подключения к базе данных<br />    3. class_db.py - в него напишем вспомогательный класс для работы с базой данных<br />    4. test.py - в нём я записываю все клавиатуры, если такое название вам не нравиться, вы можете назвать файл &quot;keyboards.py&quot;, от названия ничего не зависит</p>
  <p id="4lQR">Давайте заполним файл <a href="#nPwS">config.py</a>:</p>
  <pre id="uYXs" data-lang="python">token = &#x27;Токен телеграм бота&#x27;
admin = 132 #ID админа (позже научу его получать)
host = &#x27;localhost&#x27; #IP для подключения к базе данных (Ничего не менять, это локальный хостинг)
port = 8080 #Порт для подключения к базе данных (Ничего не меняем, мы его меняли при создании из первого урока)
user = &#x27;root&#x27; #Пользователь для подключения к базе данных (Стандартный - root)
password = &#x27;Password&#x27; #Пароль для подключения к базе данных (Замените на свой который вписывали на первом уроке)
database = &#x27;test_basa&#x27; #Имя базы данных которую мы создали в первом уроке</pre>
  <p id="Ajus">И так мы заполнили конфиг, нажимаем сочетание клавиш ctrl+s для сохранения изменений</p>
  <p id="OhId">Далее давайте напишем вспомогательный класс для работы с базой данных в файл <a href="#nPwS">class_db.py</a>:</p>
  <pre id="LuFO" data-lang="python">import pymysql #Импортируем модуль pymysql который установили в первом уроке
from config import host, port, user, password, database #Импортируем из файла config.py данные для подключения к базе данных

class work_db:
	def __init__(self): #Функция для иницилизирования переменных в класс, запускать её не надо
		self.host = host
		self.port = port
		self.user = user
		self.password = password
		self.database = database

	def connect_db(self): #Функция для конекта к базе данных
		try:
			connection = pymysql.connect(
				host = self.host,
				port = self.port,
				user = self.user,
				password = self.password,
				database = self.database,
				cursorclass = pymysql.cursors.DictCursor
			)
			return connection #Если конект прошёл успешно, возвращаем переменную connection, для дальнейшей работы
		except Exception as eror:
			print(eror) #Если произошла ошибка, выводим её в консоль
			return False #Если произошла ошибка, возвращаем False

	def connect_close(self, connection): #Передаём переменную connection если в коде подключились, после каждого подключения к базе данных и выполнения какого-либо когда, нужно закрывать подключение
		try:
			connection.close() #Закрываем подключение к базе данных
			return True #Если успешно закрыли подключение к базе, возвращаем True
		except Exception as eror:
			print(eror) #Если произошла ошибка, выводим её в консоль
			return False #Если произошла ошибка, возвращаем False

	def create_table(self, connection, creat): #Функция для создания таблице в базе данных, в creat будем передавать текст запроса
		try:
			with connection.cursor() as cursor:
				cursor.execute(creat)
			connection.commit()
			return True
		except Exception as eror:
			print(eror) #Если произошла ошибка, выводим её в консоль
			return False #Если произошла ошибка, возвращаем False

	def edit_table(self, connection, edit): #Функция для редактирования данных в таблице, в edit будем передавать текст запроса
		try:
			with connection.cursor() as cursor:
				cursor.execute(edit)
			connection.commit()
			return True
		except Exception as eror:
			print(eror) #Если произошла ошибка, выводим её в консоль
			return False #Если произошла ошибка, возвращаем False

	def info_table(self, connection, info): #Функция для получения данных из таблицы, в info будем передавать текст запроса
		try:
			with connection.cursor() as cursor:
				cursor.execute(info)
			return cursor.fetchall()[0] #Возвращаем всё что нашли
		except Exception as eror:
			print(eror) #Если произошла ошибка, выводим её в консоль
			return False #Если произошла ошибка, возвращаем False

	def delete_from_table(self, connection, delete_): #Функция для редактирования данных в таблице, в delete_ будем передавать текст запроса
		try:
			with connection.cursor() as cursor:
				cursor.execute(delete_)
			connection.commit()
			return True
		except Exception as eror:
			print(eror) #Если произошла ошибка, выводим её в консоль
			return False #Если произошла ошибка, возвращаем False</pre>
  <p id="uVTZ">И так класс для работы с базой данных написан, опять же сохраняем данные (нажимаем сочетание клавиш ctrl+s)</p>
  <p id="ZHGH">Давайте заполним файл <a href="#nPwS">test.py</a> записав в него клавиатуру:</p>
  <pre id="F0SL" data-lang="python">from aiogram.types import KeyboardButton, ReplyKeyboardMarkup #Импортируем классы для работы с текстовым меню\текстовыми кнопками

mainy = [[&#x27;Заполнить анкету&#x27;], [&#x27;Информация&#x27;]] #Создайм список кнопок для текстового меню в данном примере кнопки расположены в 2 строки
#Можно использовать такой список: [[&#x27;Заполнить анкету&#x27;, &#x27;Информация&#x27;]] Кнопки будут расположены в 1 строку

mark_menu = ReplyKeyboardMarkup(mainy, resize_keyboard=True) #Создаём клавиатуру, передав список представленный выше
#resize_keyboard=True нужен для того что-бы кнопки были маленькие, вы можете его на вписывать и посмотреть как это будет выглядеть</pre>
  <p id="yQjT">И так клавиатура создана, приступим к основному коду telegram бота, писать будем в файле <a href="#nPwS">main.py</a>:</p>
  <p id="oE0Y">Запишем нужные нам импорты:</p>
  <pre id="WT7Y" data-lang="python">from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram import Bot, Dispatcher, executor, types
from aiogram.dispatcher import FSMContext
from aiogram.types import ReplyKeyboardRemove
from class_db import work_db #Импорируем класс для работы с базой данных из файла class_db.py
import test as bb #Импортируем файл test.py в переменную bb (мне так удобнее работать с ним)
import config as c #Импортируем файл config.py в переменную с (опять же мне так удобнее)</pre>
  <p id="CrWf">Создадим нужные нам экземпляры классов для работы:</p>
  <pre id="TQN9" data-lang="python">bot = Bot(token=c.token) #Берём токен бота из файла config.py который импортировали ранее в переменную c
dp = Dispatcher(bot)
db_work = work_db(c.host, c.port, c.user, c.password, c.database) #Создаём экземпляр класса для работы с базой данных, передав все нужные параметры из конфига</pre>
  <p id="L2bb">Пишем обработчик текстовых сообщений:</p>
  <pre id="8bJm" data-lang="python">@dp.message_handler(content_types=[&#x27;text&#x27;]) #Обрабатываем каждое сообщение от пользователей, добавляем content_types для обработки текста, в будущих уроках будет фото и видео
async def text(message: types.Message): #Асинхронная функция с название &quot;text&quot; которая принимает в переменную message, текст пользователя отправевшего сообщение
	pass</pre>
  <p id="PKTS">Давайте напишем логику обработки сообщений, начнём с кнопки &quot;информация&quot; и команду /start:</p>
  <pre id="NyNi" data-lang="python">@dp.message_handler(content_types=[&#x27;text&#x27;]) #Обрабатываем каждое сообщение от пользователей, добавляем content_types для обработки текста, в будущих уроках будет фото и видео
async def text(message: types.Message): #Асинхронная функция с название &quot;text&quot; которая принимает в переменную message, текст пользователя отправевшего сообщение
	if message.text == &#x27;/start&#x27;:
		await bot.send_message(message.chat.id, &#x27;Привет, заполни анкету, или посмотри информацйию о мне&#x27;, reply_markup=bb.mark_menu) #Обрабатываем команду /start и выводим клавиатуру из файлы test.py
	elif message.text == &#x27;Информация&#x27;:
		await bot.send_message(message.chat.id, f&#x27;Сюда пишем какую либо информацию, например я хочу вывести ID пользователя\nТвой ID: {message.chat.id}&#x27;)</pre>
  <p id="0ejW">А теперь давайте напишем логику самого анкетирования</p>
  <p id="gZBA">Перед началом объясню как работает if, elif, else</p>
  <blockquote id="OjgK">Допустим нам нужно проверить какое число пришло в функцию<br />И в зависимости от числа вернуть какой то текст</blockquote>
  <p id="A5if">Для этого мы пишем саму функцию и запуск её с каким либо числом:</p>
  <pre id="m0GJ" data-lang="python">def info_number(number): #Данная функция принимает число в переменную number
    if number == 1: #Если полученное число равно одному, то возращаем слово Один
       return &#x27;Один&#x27;
    elif number == 2: #Если же число равно двум, то возращаем слово Два
       return &#x27;Два&#x27;
    else: #В ином случае говорим что такие числа мы не принимаем
       return &#x27;Я не принимаю такие числа&#x27;</pre>
  <p id="NMrf">Ещё нам понадобиться такая вещь как машина состояний, мы её уже импортировали в <a href="#oE0Y">начале</a></p>
  <p id="88c7">Давайте расскажу для чего нам машина состояний...</p>
  <p id="CwA3">Она нам нужна для того что-бы работать с определённым пользователем, и определённой логикой<br />Это всё что нам требуется на этом этапе да и в принципе в программировании</p>
  <p id="zy8O">Продолжим писать логику<br />Создаём класс для работы с машиной состояний:</p>
  <pre id="vjPE" data-lang="python">class anketa(StatesGroup):
	name = State()
	floor = State()
	age = State()</pre>
  <p id="xMTm">Далее дописываем ожидание именно имени, у нас получился код:</p>
  <pre id="5OYI" data-lang="python">@dp.message_handler(content_types=[&#x27;text&#x27;]) #Обрабатываем каждое сообщение от пользователей, добавляем content_types для обработки текста, в будущих уроках будет фото и видео
async def text(message: types.Message): #Асинхронная функция с название &quot;text&quot; которая принимает в переменную message, текст пользователя отправевшего сообщение
	if message.text == &#x27;/start&#x27;:
		await bot.send_message(message.chat.id, &#x27;Привет, заполни анкету, или посмотри информацйию о мне&#x27;, reply_markup=bb.mark_menu) #Обрабатываем текст /start и выводим клавиатуру из файлы test.py
	elif message.text == &#x27;Информация&#x27;:
		await bot.send_message(message.chat.id, f&#x27;Сюда пишем какую либо информацию, например я хочу вывести ID пользователя\nТвой ID: {message.chat.id}&#x27;)
	elif message.text == &#x27;Заполнить анкету&#x27;:
		await bot.send_message(message.chat.id, &#x27;Введите своё имя:&#x27;)
		await anketa.name.set()</pre>
  <p id="CW5s">В файле <a href="#nPwS">test.py</a> добавляем клавиатуру с выбором пола:</p>
  <pre id="cboo" data-lang="python">main_floor = [[&#x27;Мужской&#x27;, &#x27;Женский&#x27;]]
menu_floor = ReplyKeyboardMarkup(main_floor, resize_keyboard=True)</pre>
  <p id="jKhu">Далее нам нужен сам обработчик ввода пользователя:</p>
  <pre id="fWqg" data-lang="python">@dp.message_handler(state=anketa.name)
async def anketa_name(message: types.Message, state: FSMContext): #Как видите у нас добавился FSMContext, он нам нужен как раз для обработки машины состояния
	#Записываем имя в кеш
	await state.update_data(name=name)
	#Далее просим ввести пол, с выбором пола из кнопок
	await bot.send_message(message.chat.id, &#x27;Выберите свой пол:&#x27;, reply_markup=bb.main_floor) #добавляем вывод кнопок с выбором пола</pre>
  <p id="bD4F">Пишем обработчик ввода пола:</p>
  <pre id="QFPv" data-lang="python">@dp.message_handler(state=anketa.floor)
async def anketa_name(message: types.Message, state: FSMContext):
	#Записываем пол в кеш
	await state.update_data(floor=floor)
	#Далее просим ввести свой возраст
	await bot.send_message(message.chat.id, &#x27;Выберите свой пол:&#x27;, reply_markup=ReplyKeyboardRemove()) #убираем текстовую клавиатуру
	await anketa.age.set()</pre>
  <p id="vFiD">И наконец давайте обработаем возраст, и выведем данные которые ввёл пользователь, сначала пользователю, а затем админу по его ID из <a href="#nPwS">config.py</a></p>
  <p id="Uhmg">У нас получился такой код:</p>
  <pre id="UkNq" data-lang="python">@dp.message_handler(state=anketa.age)
async def anketa_name(message: types.Message, state: FSMContext):
	#Получим все данные записанные в кеш
	data = await state.get_data()
	#Сортируем их по переменным
	name = data[&#x27;name&#x27;] #В ковычках пишем name, потому что сами записывали в такую переменную, там может быть любая другая
	floor = data[&#x27;floor&#x27;] #В ковычках пишем floor, потому что сами записывали в такую переменную, там может быть любая другая
	age = message.text #записываем ввод пользователя в переменную age
	await state.finish() #Завершаем работу с машиной состояний
	#Выведем анкету пользователю
	await bot.send_message(message.chat.id, f&#x27;Ваша анкета:\n\nИмя: {name}\nПол: {floor}\nВозраст: {age}\n\nСпасибо за уделение времени&#x27;, reply_markup=bb.mark_menu) #Отправляем анкету, благодарим, и выдаём ему текстовоем меню
	#Отправим анкету администратору по его ID из config.py
	#Так же выведем ID пользователя и его юзернейм
	await bot.send_message(c.admin, f&#x27;Пользователь: {message.chat.id}\n@{message.from_user.username} заполнил анкету\nЕго данные:\n\nИмя: {name}\nПол: {floor}\nВозраст: {age}&#x27;)


if __name__ == &quot;__main__&quot;: #Если скрипт запущен с этого файла, запускаем executor
    executor.start_polling(dp, skip_updates=True) #skip_updates=True - нужен для того чтобы не обрабатывать сообщения которые были присланы пользователем в тот момент когда бот был выключен</pre>
  <p id="0B6c">Возможно у вас возникнет вопрос зачем я использую &quot;\n&quot; это для того что-бы перенести текст на 1 или более строк.</p>
  <p id="GdpB"></p>
  <p id="37Je">В итоге у нас получился такой код:</p>
  <pre id="tSsc" data-lang="python">from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram import Bot, Dispatcher, executor, types
from aiogram.dispatcher import FSMContext
from aiogram.types import ReplyKeyboardRemove
from class_db import work_db #Импорируем класс для работы с базой данных из файла class_db.py
import test as bb #Импортируем файл test.py в переменную bb (мне так удобнее работать с ним)
import config as c #Импортируем файл config.py в переменную с (опять же мне так удобнее)



#Создаём класс бота и дистпетчера
bot = Bot(token=c.token) #Берём токен бота из файла config.py который импортировали ранее в переменную c
dp = Dispatcher(bot)
db_work = work_db(c.host, c.port, c.user, c.password, c.database) #Создаём экземпляр класса для работы с базой данных, передав все нужные параметры из конфига


class anketa(StatesGroup):
	name = State()
	floor = State()
	age = State()

	
@dp.message_handler(content_types=[&#x27;text&#x27;]) #Обрабатываем каждое сообщение от пользователей, добавляем content_types для обработки текста, в будущих уроках будет фото и видео
async def text(message: types.Message): #Асинхронная функция с название &quot;text&quot; которая принимает в переменную message, текст пользователя отправевшего сообщение
	if message.text == &#x27;/start&#x27;:
		await bot.send_message(message.chat.id, &#x27;Привет, заполни анкету, или посмотри информацйию о мне&#x27;, reply_markup=bb.mark_menu) #Обрабатываем команду /start и выводим клавиатуру из файлы test.py
	elif message.text == &#x27;Информация&#x27;:
		await bot.send_message(message.chat.id, f&#x27;Сюда пишем какую либо информацию, например я хочу вывести ID пользователя\nТвой ID: {message.chat.id}&#x27;)
	elif message.text == &#x27;Заполнить анкету&#x27;:
		await bot.send_message(message.chat.id, &#x27;Введите своё имя:&#x27;)
		await anketa.name.set()


@dp.message_handler(state=anketa.name)
async def anketa_name(message: types.Message, state: FSMContext): #Как видите у нас добавился FSMContext, он нам нужен как раз для обработки машины состояния
	#Записываем имя в кеш
	await state.update_data(name=message.text)
	#Далее просим ввести пол, с выбором пола из кнопок
	await bot.send_message(message.chat.id, &#x27;Выберите свой пол:&#x27;, reply_markup=bb.main_floor) #добавляем вывод кнопок с выбором пола
	await anketa.floor.set()


@dp.message_handler(state=anketa.floor)
async def anketa_name(message: types.Message, state: FSMContext):
	#Записываем пол в кеш
	await state.update_data(floor=message.text)
	#Далее просим ввести свой возраст
	await bot.send_message(message.chat.id, &#x27;Выберите свой пол:&#x27;, reply_markup=ReplyKeyboardRemove()) #убираем текстовую клавиатуру
	await anketa.age.set()


@dp.message_handler(state=anketa.age)
async def anketa_name(message: types.Message, state: FSMContext):
	#Получим все данные записанные в кеш
	data = await state.get_data()
	#Сортируем их по переменным
	name = data[&#x27;name&#x27;] #В ковычках пишем name, потому что сами записывали в такую переменную, там может быть любая другая
	floor = data[&#x27;floor&#x27;] #В ковычках пишем floor, потому что сами записывали в такую переменную, там может быть любая другая
	age = message.text #записываем ввод пользователя в переменную age
	await state.finish() #Завершаем работу с машиной состояний
	#Выведем анкету пользователю
	await bot.send_message(message.chat.id, f&#x27;Ваша анкета:\n\nИмя: {name}\nПол: {floor}\nВозраст: {age}\n\nСпасибо за уделение времени&#x27;, reply_markup=bb.mark_menu) #Отправляем анкету, благодарим, и выдаём ему текстовоем меню
	#Отправим анкету администратору по его ID из config.py
	#Так же выведем ID пользователя и его юзернейм
	await bot.send_message(c.admin, f&#x27;Пользователь: {message.chat.id}\n@{message.from_user.username} заполнил анкету\nЕго данные:\n\nИмя: {name}\nПол: {floor}\nВозраст: {age}&#x27;)


if __name__ == &quot;__main__&quot;: #Если скрипт запущен с этого файла, запускаем executor
    executor.start_polling(dp, skip_updates=True) #skip_updates=True - нужен для того чтобы не обрабатывать сообщения которые были присланы пользователем в тот момент когда бот был выключен</pre>
  <p id="u3sS"></p>
  <p id="YJ8x"></p>
  <p id="snBw">Работу с базой данных я перенёс на третий урок, потому что информация для некоторых новая, и её достаточно много для новичка, поэтому ожидайте третий урок</p>
  <p id="uG3C"></p>
  <h2 id="LcHW">В третьей  части мы научимся работать с:</h2>
  <ol id="8Ab2">
    <li id="oaDy">Работой с базой данных</li>
    <ol id="X4j3">
      <li id="rxbk">Научимся записывать данные в базу</li>
      <li id="DjNQ">Научимся читать данные из базы</li>
      <li id="ihIt">Научимся удалять данные с базы</li>
    </ol>
    <li id="fPFB">Работой с кнопками</li>
    <ol id="Bayu">
      <li id="t0pN">Сделаем инлайн кнопки (Расскажу и покажу что это и с чем это едят)</li>
      <li id="tDgE">Сделаем обработку таких кнопок, сделаем им не сложную логику</li>
    </ol>
  </ol>
  <p id="hWSC"></p>
  <p id="Jsdi"></p>
  <p id="5zkc">Так же советую посмотреть мою статью по форматированию сообщений - <a href="https://teletype.in/@xacker_name_new/HKkIZf4oyEC" target="_blank">*КЛИКАБЕЛЬНО*</a></p>
  <p id="scgu">Но для них нам придётся переписать строку </p>
  <pre id="y5fm" data-lang="python">bot = Bot(token=c.token)</pre>
  <p id="2K8U">На:</p>
  <pre id="STSe" data-lang="python">bot = Bot(token=c.token, parse_mode=types.ParseMode.HTML)</pre>
  <p id="SKwW">Как видим у нас добавился parse_mode, это как раз для обработки HTML тегов в сообщениях...</p>
  <p id="wypF"></p>
  <h3 id="GP4e" data-align="center">Домашнее задание:</h3>
  <p id="lko4" data-align="center">1. Выдели сообщения (запрос имени, пола, возраста) в жирный шрифт <br />(по желанию можешь добавить наклонный текст)<br />2. Так же выдели в итоговой анкете, ID пользователя (само число)<br />в Текст для лёгкого копирования (Моноширинный)<br />(и у пользователя и у админа)<br /><br />В обратной связи жду:<br />1. Скриншот кода где видно, как реализовано выделение текста<br />2. Скриншот с telegram бота, где видно заполнение анкеты + выделения текстов<br />3. Скриншот с telegram бота где видна конечная анкета (у пользователя и админа)<br />Прислать можно: <a href="https://t.me/Xacker_Name_new" target="_blank">@Xacker_Name_new</a><br /></p>
  <p id="BNWj"></p>
  <p id="sbmR"></p>
  <h2 id="XBgD">Спасибо за внимание</h2>
  <p id="nXCL">С вами был <a href="https://t.me/Xacker_Name_new" target="_blank">@Xacker_Name_new</a></p>
  <p id="FthM">Поддержка: <a href="https://t.me/Bsc_Black_Secret_Club_bot" target="_blank">@Bsc_Black_Secret_Club_bot</a></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@xacker_name_new/UqnaI47nEzx</guid><link>https://teletype.in/@xacker_name_new/UqnaI47nEzx?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=xacker_name_new</link><comments>https://teletype.in/@xacker_name_new/UqnaI47nEzx?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=xacker_name_new#comments</comments><dc:creator>xacker_name_new</dc:creator><title>Обучение #1</title><pubDate>Sun, 24 Sep 2023 08:53:12 GMT</pubDate><media:content medium="image" url="https://img2.teletype.in/files/50/e3/50e31141-824f-4f69-8473-ed3aa0599887.png"></media:content><category>Обучение Python+aiogram+MySQL</category><description><![CDATA[<img src="https://img4.teletype.in/files/3a/72/3a720c74-3487-46cc-ac94-4ec752d144cc.png"></img>Обучение #1]]></description><content:encoded><![CDATA[
  <section style="background-color:hsl(hsl(199, 50%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <h3 id="OSVb">Язык программирования - Далее ЯП</h3>
    <h3 id="ZWeD">Операционная система - Далее ОС</h3>
    <h3 id="nmNE">Редактор кода - Далее IDE</h3>
    <h3 id="FbKl">CMD - Далее консоль</h3>
  </section>
  <p id="tiJq"></p>
  <p id="E81j">Использовать будет такую ЯП как Python (советую версию 3.10) — <a href="https://www.python.org/downloads/release/python-3100/#:~:text=Full%20Changelog-,Files,-Version" target="_blank">*КЛИКАБЕЛЬНО*</a>: Выбирайте свою ОС</p>
  <p id="vSMh">После того как скачали установочный файл, при установке нужно поставить галочку со словом PATH:</p>
  <figure id="GNvS" class="m_custom">
    <img src="https://img2.teletype.in/files/99/c5/99c57e37-5008-409f-8ca7-0446a38c3a95.png" width="556" />
  </figure>
  <section style="background-color:hsl(hsl(323, 50%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="UJYK">Нажимаем Install Now</p>
  </section>
  <p id="ucOt">Открываем консоль комбинация клавиш на клавиатуре: Win+R</p>
  <p id="eN7a">В открывшемся окне пишем &quot;cmd&quot;</p>
  <p id="rTNz">Вводим команды по порядку:</p>
  <section style="background-color:hsl(hsl(236, 74%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <ul id="FW5X">
      <li id="NBB9" data-align="center"><code>pip install aiogram==2.25.1</code></li>
      <li id="Txhb" data-align="center"><code>pip install asyncio</code></li>
      <li id="bzFr" data-align="center"><code>pip install pymysql</code></li>
    </ul>
  </section>
  <p id="zn2u" data-align="center">Немножко расскажу про модули которые мы установили:</p>
  <p id="J4al" data-align="center"><code>aiogram - Он нам нужен для работы с api telegram ботов</code></p>
  <p id="EDn3" data-align="center"><code>asyncio - Он нам нужен для ожидания (подобие модуля time, только time останавливает выполнение остального кода, а asyncio нет)</code></p>
  <p id="q4dm" data-align="center"><code>pymysql - Он нам нужен для работы с базой данных которую мы создадим далее</code></p>
  <p id="IfG4">Скачиваем IDE которым пользуюсь я - <a href="https://www.sublimetext.com/3#:~:text=over%20this%20version.-,Version%253A%20Build%203211,-OS%20X%20(10.7" target="_blank">*КЛИКАБЕЛЬНО*</a></p>
  <p id="ZSL9">Скачиваем MySQLServer - <a href="https://dev.mysql.com/downloads/installer/#:~:text=MySQL%20Installer%208.0.34" target="_blank">*КЛИКАБЕЛЬНО*</a></p>
  <blockquote id="Ncrd"><strong>При установке нажимаем везде далее</strong></blockquote>
  <blockquote id="Bujx">Добавлено: Если у вас не появилась программа показанная ниже, установить ей: <a href="https://dev.mysql.com/get/Downloads/MySQLGUITools/mysql-workbench-community-8.0.34-winx64.msi" target="_blank">*КЛИКАБЕЛЬНО*</a></blockquote>
  <section style="background-color:hsl(hsl(199, 50%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="j9st">После установки у нас должна быть такая программа:</p>
    <figure id="1NTa" class="m_custom">
      <img src="https://img4.teletype.in/files/fc/e0/fce0ad2e-6bfb-43d7-97a0-014452dee9bf.png" width="201" />
    </figure>
    <p id="JxiY">После запуска, должно быть что то такое:</p>
    <figure id="A4KJ" class="m_custom">
      <img src="https://img4.teletype.in/files/ff/0a/ff0ae251-846f-4d62-9f21-7191b2685a2d.png" width="875.6824925816023" />
    </figure>
    <h3 id="HAf5">Нажимаем на плюсик (указан стрелочкой)</h3>
    <figure id="qYFV" class="m_custom">
      <img src="https://img2.teletype.in/files/d0/b9/d0b9d3cd-5588-4809-a7aa-c87a8c8b5c2a.png" width="672" />
    </figure>
    <p id="pdal">Connection Name - Имя базы данных, по которому будем в будущем подключаться к базе данных <em>(Напишу test_basa)</em></p>
    <p id="JYo2">Connection Method - Метод подключения (Не трогаем)</p>
    <p id="iTMP">Hostname - Имя хоста для подключения (Не трогаем потому что нам нужна база данных на локальном хосте) 127.0.0.1 - это и есть локальный хост</p>
    <p id="iDmI">Port - Порт для подключения к базе данных (Меняем на 8080)</p>
    <p id="viCa">Username - Имя пользователя по которому будем подключаться к базе данных</p>
    <p id="TGBV">Password - Пароль для подключения, если вы его не знаете сначала нажимаете на кнопку &quot;Clear&quot; -&gt; &quot;Store in Vault&quot;</p>
    <figure id="dhZ9" class="m_custom">
      <img src="https://img3.teletype.in/files/27/60/27607c7b-b7c6-4892-a577-107208ba79b4.png" width="334" />
    </figure>
    <p id="yMCF">Вводим пароль в этом поле и нажимаем &quot;OK&quot;</p>
    <p id="wEsl">После ввода пароля нажимаем на &quot;Test Connection&quot;</p>
    <p id="ImTj">Должно появиться такое окошко:</p>
    <figure id="6uMA" class="m_custom">
      <img src="https://img4.teletype.in/files/ff/31/ff311a0d-9ac8-4957-85d7-5e99477c7167.png" width="299" />
    </figure>
    <p id="n4RS">Если вы не поменяли порт на 8080 то будет такое окошко:</p>
    <figure id="zJ8g" class="m_original">
      <img src="https://img1.teletype.in/files/ca/25/ca25ddf5-c975-46f0-b671-a0ab6c02270f.png" width="350" />
    </figure>
    <blockquote id="rUJq">Если же поменяв порт на 8080, у вас осталось такое окно, то поменяйте на порт 3306, и попробуйте снова</blockquote>
    <p id="lTZO">и так мы настроили базу, осталось её создать (Нажимаем на OK)</p>
    <p id="FIBZ">У нас появилась база данных:</p>
    <figure id="G3Iq" class="m_original">
      <img src="https://img2.teletype.in/files/1f/f6/1ff6461f-2ba9-493c-9eaf-056dd15431f4.png" width="254" />
    </figure>
    <p id="zg3m">В будущем через код мы сможем к ней подключиться...</p>
  </section>
  <p id="5Z6a">Давайте мы с вами посмотрим несколько уроков по aiogram:</p>
  <ol id="zrpn">
    <li id="nGJ8"><a href="https://youtu.be/ayUBlf9pvn0?list=PLe-iIMbo5JOJm6DRTjhleHojroS-Bbocr" target="_blank">Создание бота через BotFather</a></li>
    <li id="KhyL"><a href="https://youtu.be/WFIuSzaowlg?t=126" target="_blank">Пишем код простого Эхо бота</a> (Эхо бот - бот которому ты пишешь сообщение, он тебе отправляет твой текст)</li>
  </ol>
  <p id="e3uy">После просмотра 2 ролика у нас получился код:</p>
  <pre id="c00J" data-lang="python">from aiogram import Bot, types
from aiogram.dispatcher import Dispatcher
from aiogram.utils import executor

bot = Bot(token=&#x27;Токен вашего бота&#x27;)
dp = Dispatcher(bot)

@dp.message_handler()
async def echo(message: types.Message):
    await message.answer(message.text)


executor.start_polling(dp, skip_updates=True)</pre>
  <p id="pf0m">Давайте я подправлю код и напишу комментарии к некоторым участкам кода:</p>
  <pre id="VXO3" data-lang="python">from aiogram import Bot, types, Dispatcher
from aiogram.utils import executor


bot = Bot(token=&#x27;Токен вашего бота&#x27;)
dp = Dispatcher(bot)


@dp.message_handler() #Обрабатываем каждое сообщение от пользователей 
async def echo(message: types.Message): #Асинхронная функция с название &quot;echo&quot; которая принимает в переменную message, текст пользователя отправевшего сообщение
    await message.answer(message.text) #Отправляет сообщение пользователя обратно ему
    #Так же можно использовать: await bot.send_message(message.chat.id, messgae.text)
    #Отправляет сообщение пользователя обрано, но с помощью этой конструкции мы можем отправлять сообщение любому пользователю по его id


if __name__ == &quot;__main__&quot;: #Если скрипт запущен с этого файла, запускаем executor
    executor.start_polling(dp, skip_updates=True) #skip_updates=True - нужен для того чтобы не обрабатывать сообщения которые были присланы пользователем в тот момент когда бот был выключен</pre>
  <p id="B3AO">И так у нас получился переработанный код</p>
  <p id="umQJ">Для запуска подобных скриптов, нам нужна будет консоль (WIN+R -&gt; cmd)</p>
  <p id="eaou">В консоль пишем команду: </p>
  <pre id="7K8i">cd C:\путь\до\папки\с\ботом\</pre>
  <blockquote id="22Mq">Скопировать его можно тут:</blockquote>
  <figure id="6ba9" class="m_custom">
    <img src="https://img2.teletype.in/files/1f/79/1f797fd9-c330-49bc-9867-c09d58912a4e.png" width="675" />
  </figure>
  <p id="iaO9">Далее мы перешли в директорию с ботом</p>
  <p id="Pois">Пишем в консоль: </p>
  <pre id="aumO">python main.py</pre>
  <p id="VOxh">После чего ждём запуска, после запуска мы видим в консоли текст: </p>
  <pre id="kudE">Updates were skipped successfully.</pre>
  <p id="X2Pk">Это означает что бот успешно запущен!</p>
  <p id="ozyX"></p>
  <h2 id="FFuP">Во второй части мы научимся работать с:</h2>
  <ol id="P44s">
    <li id="Wm2T">Работой с базой данных</li>
    <ol id="KQH9">
      <li id="rxbk">Научимся записывать данные в базу</li>
      <li id="DjNQ">Научимся читать данные из базы</li>
      <li id="ihIt">Научимся удалять данные с базы</li>
    </ol>
    <li id="Bi8C">Напишем telegram бота с логикой анкетирования</li>
    <ol id="VITV">
      <li id="8DDD">Сможем получить имя</li>
      <li id="6FiA">Сможем получить пол</li>
      <li id="3Tq0">Сможем получить возраст</li>
    </ol>
    <li id="rM3w">Работой с кнопками</li>
    <ol id="ieoi">
      <li id="ksCt">Сделаем 2 кнопки (Заполнить анкету\Информация)</li>
      <li id="5AcW">Сделаем текстовое меню</li>
      <li id="j2zg">Сделаем выбор пола через текстовое меню</li>
    </ol>
  </ol>
  <p id="ita4"></p>
  <p id="JiPj"></p>
  <p id="BRe3"></p>
  <h2 id="XBgD">Спасибо за внимание</h2>
  <p id="nXCL">С вами был <a href="https://t.me/Xacker_Name_new" target="_blank">@Xacker_Name_new</a></p>
  <p id="FthM">Поддержка: <a href="https://t.me/Bsc_Black_Secret_Club_bot" target="_blank">@Bsc_Black_Secret_Club_bot</a></p>

]]></content:encoded></item></channel></rss>