Код на салфетке
2.24K subscribers
752 photos
15 videos
2 files
794 links
Канал для тех, кому интересно программирование на Python и не только.

Сайт: https://pressanybutton.ru/
Чат: https://t.iss.one/+Li2vbxfWo0Q4ZDk6
Заметки автора: @writeanynotes

Реклама и взаимопиар: @Murzyev1995
Сотрудничество и др.: @proDreams
Download Telegram
🚀 Встречайте революцию в IT Бизнесе!

🔥 Присоединяйтесь к "IT Бизнес-Идея" — вашему источнику самых горячих и прибыльных стартапов в мире технологий!

💸 Узнавайте, какие IT-проекты сейчас рвут рынок:

Как VPTOWN зарабатывает тысячи долларов, используя lowcode?
Чем FLX Websites покорил владельцев бизнеса в США?

📈 Мы делимся:

Реальными доходами проектов
Инсайдерской информацией о технологиях и стратегиях
Ссылками на графики доходности — все прозрачно и открыто!

👨‍💻 Если ты разработчик, предприниматель или просто фанат IT:

Получи вдохновение от успешных кейсов
Изучи стратегии, которые действительно работают
Начни свой проект, который может изменить рынок

🔗 Заходи в канал "IT Бизнес-Идея" и будь в курсе самых свежих и прибыльных IT-тенденций!

🌟 Не упусти свой шанс стать частью IT революции!
🔥4👍2💯1
AIOgram3 19. Капча для вступающих в чат
Автор: Иван Ашихмин

Время от времени в чат вступают странные личности, которые выжидают удобного момента для своей сомнительной рекламы. Не всегда удается сразу отреагировать и забанить спамера. Для решения этой проблемы сделаем так, чтобы вступивший в чат пользователь проходил капчу и если он ответит неверно, исключать его из чата.


Читать пост в Telegram

Пост на сайте
Поддержать проект на Boosty
Поддержать проект в Telegram

#Гайды #код_на_салфетке #aiogram #telegram #капча #telegram_бот #чат #pillow #appscheduler #планировщик #состояния
🔥11👍21
Приветствуем.

В прошлую пятницу мы опубликовали пост, в котором попросили вас задавать нам вопросы.

Было два вопроса в комментариях к посту.

Давайте на них ответим!

Избранные гиты.
Ссылка на сообщение.
Вопрос:
Есть ли какие избранные гиты, в которые можно подсматривать, для реализации тех или иных фич в aiogram 3?


Если брать именно гиты по AIOgram 3, то самым важным гитом для любого ботодела будет официальный репозиторий библиотеки.
Там есть код проекта, где можно посмотреть как он написан и что использует. Также есть раздел с примерами, который время от времени пополняется новыми файлами.

Также в комментариях упомянули репозиторий Мистера Груши.
Безусловно, каждый кто начинал писать ботов сталкивался с его гайдами, мы не исключение 😉.

Если смотреть в общем плане гиты не только по AIOgram, то в основном в закладках десятки гитов на библиотеки, нежели на конкретных людей.
Хотя есть такие, как Тимур Машков из нашего чата.
Из его репозитория можно подчерпнуть много интересного по разработке на FastAPI.


Обработка множественной оплаты.
Ссылка на сообщение.

Вопрос касается предупреждению при обработке pre-checkout-события, т.е. разработчику следует убедиться, что несколько выполняемых в одно время платежей будут корректно проведены.

Звёзды применяются только к продаже цифровых товаров. Если продаваемый товар не имеет лимита, условно, продаётся файл с кодом, то проверка pre-checkout всегда будет выдавать ok=True. Однако, в случае с конечным товаром, например, осталось пять мест на закрытый вебинар, а купить хотят шесть, тут следует грамотно построить процесс оплаты, чтобы шестой не смог купить, т.к. лимит всего пять.

Конкретного примера для этого нет, т.к. не приходилось такое реализовывать, но логика схожа с любым магазином, в котором есть конечный товар:
Возьмём пример с продажей доступа на вебинар. Изначально имеется 200 мест и в итоге осталось всего пять.
Шесть человек изъявили желание приобрести доступ в одно и то же время.
Им выставляется счёт, они нажимают оплатить и тут начинается интересное — у нас есть всего 10 секунд на то, чтобы подтвердить платёж или отклонить его.
За 10 секунд, нужно получить из БД информацию о доступном количестве мест и в зависимости от доступности подтвердить или отклонить, при этом сделать так, чтобы шестой человек не смог приобрести лишнее место.

Реализуется это разными способами, в зависимости от устройства логики проекта и используемой БД.
Можно сделать фоновую задачу для проверки количества мест, а можно использовать SQL-транзакции.
3👍1👏1😱1
Привет, друзья!

Наступила пятница, а это значит, что пришла пора для нашего традиционного кинопоста. Сегодня у нас в центре внимания российский блокбастер. Этот фильм рассказывает о бесстрашном майоре полиции Игоре Громе, который вступает в неравную схватку с таинственным и безжалостным злодеем, известным как Чумной Доктор. Устраивайтесь поудобнее, включайте фильм и наслаждайтесь просмотром!

Фильм: Майор Гром: Чумной доктор

Год: 2021

Майор полиции Игорь Гром известен всему Санкт-Петербургу своим пробивным характером и непримиримой позицией к преступникам. Его сила, аналитический ум и неподкупность делают его идеальным полицейским. Но всё меняется с появлением Чумного Доктора, который, заявив о "чуме беззакония" в городе, начинает убивать тех, кто избежал наказания благодаря деньгам и влиянию. Общество взбудоражено, полиция бессильна, и Игорь впервые сталкивается с трудностями в расследовании, от исхода которого зависит судьба города.

https://www.kinopoisk.ru/film/1109271/

Приятного просмотра!
Что выведет этот код? №32
🔥1
Подготовили для вас разбор задачи "Что выведет этот код? №32".

Видео на YouTube.

Будем благодарны за ваши лайки и досмотр видео до конца, это важно для продвижения на YouTube. Спасибо!

Если у вас проблемы с YouTube, то посмотреть также можно:
- RuTube
- VK Видео
- Dzen

Текстовый разбор будет через 2 часа.
🔥21
Вчерашняя задача с виду простая, но рекурсия в ней может доставить неприятностей. Задачу решило 55% человек из 42-х проголосовавших.

Код задачи:
def recursive_sum(lst):  
if not lst:
return 0
return lst[0] + recursive_sum(lst[1:])


numbers = [1, 2, 3, 4, 5]
print(recursive_sum(numbers))



Разбор задачи
Создаём переменную numbers со списком чисел.
При помощи print() выводим вызов функции recursive_sum, передав в неё список чисел.

Объявляем функцию recursive_sum, принимающую аргумент lst.
Внутри функции, в блоке if проверяем, если переданный список пуст, то возвращаем 0.
В противном случае возвращаем сложение первого (нулевого) элемента списка и вызов этой же функции с новым списком в аргументах.


Правильный ответ: 15.

Процесс рекурсии.
Главная проблема рекурсии (не считая расходы на ресурсы) в том, что она не очевидна с первого взгляда и порой трудно поддаётся мысленной интерпретации.

Рассмотрим процесс выполнения recursive_sum:
1. Первый вызов функции: lst = [1, 2, 3 , 4, 5], возвращается lst[0] = 1.
2. Второй вызов функции: lst = [2, 3 , 4, 5], возвращается lst[0] = 2.
3. Третий вызов функции: lst = [3 , 4, 5], возвращается lst[0] = 3.
4. Четвёртый вызов функции: lst = [4, 5], возвращается lst[0] = 4.
5. Пятый вызов функции: lst = [5], возвращается lst[0] = 5.
6. Шестой вызов функции: lst = [], возвращается 0.

После того, как рекурсия дошла до конца, она начинает возвращать результаты сложения в обратном порядке:
1. 5 + 0 = 5, возвращается 5
2. 4 + 5 = 9, возвращается 9
3. 3 + 9 = 12, возвращается 12
4. 2 + 12 = 14, возвращается 14
5. 1 + 14 = 15, возвращается 15

Таким образом получаем ответ - 15
🔥21
Те, кто занимается парсингом сайтов ни раз сталкивались с проблемами "палящегося" Selenum'а или необходимости скачать новый вебдрайвер для браузера, также Selenum достаточно медленный. Решение всех этих проблем предлагает библиотека Nodriver.

Nodriver — это библиотека для высокопроизводительного веб-скрапинга и автоматизации, не использующая традиционные методы WebDriver или Selenium. Она обходит защитные меры, такие как Captcha и Cloudflare, напрямую взаимодействуя с браузером и поддерживая асинхронные операции для повышения скорости. Библиотека проста в использовании благодаря продуманным настройкам по умолчанию, но также позволяет продвинутым пользователям настраивать её под свои задачи.

Репозиторий библиотеки.

Установка библиотеки:

Для установки достаточно выполнить команду:
pip install nodriver


Пример получения изображений из Яндекс Картинок:
import asyncio
from pathlib import Path

import httpx
import nodriver as uc


async def main():
url = 'https://yandex.ru/images/search?from=tabbar&text=котики&isize=eq&iw=1920&ih=1080'

browser = await uc.start()
page = await browser.get(url)

elems = await page.select_all('.JustifierRowLayout-Item')

for i, elem in enumerate(elems):
a = await elem.query_selector('a')
image_page = await browser.get(f"https://yandex.ru{a.attrs.get('href')}", new_window=True)
image = await image_page.select('.MMImage-Origin')
file_resp = httpx.get("https:" + image.attrs.get('src'))
with open(Path('downloads') / f"{i}.png", 'wb') as file:
file.write(file_resp.content)
await image_page.close()


asyncio.run(main())


Создаём асинхронную функцию main.
В ней указываем url страницы, с которой начнём парсинг.
Затем создаём экземпляр браузера и открываем в нём страницу.
Ищем нужные элементы, в данном случае содержащие превьюшки изображений.
Далее, итерируясь по полученным элементам, находим в них ссылки на страницы изображений и открываем в новом окне.
Затем, находим само изображение и скачиваем его при помощи httpx.

Данный код всего лишь пример работы с библиотекой, которая упростит жизнь разработчику парсеров.

P.S. Напишите в комментарии, нужны ли гайды по парсингу?
🔥8👍2
Сегодня исполнилось 11 лет с запуска Telegram, платформы, которая не только изменила мир мессенджеров для пользователей, но и предоставила обширные возможности для разработчиков.

В честь одиннадцатилетия Telegram прдоставил крупное обновление BotAPI 7.9, направленное на поддержку авторов контента.

В этом посте разберём те части обновления, которые касаются разработчиков. Полностью прочитать о представленных нововведениях можно по ссылке.


Звёздные реакции
Появилась возможность отправлять "Звёздные реакции" к постам в каналах - это способ отблагодарить автора контента используя Telegram Stars. Также, в меню звёздной реакции отображается "Список лидеров", подписчиков отправивших больше всего звёзд к конкретному посту.

Включить звёздные реакции на сообщения в канале можно в меню Настройки канала > Реакции > Включить платные реакции.


В API бота добавлена поддержка платных реакций и новый класс ReactionTypePaid, определяющий "звёздную реакцию".


Подписка на канал за Telegram Stars
С сегодняшнего дня, можно создавать пригласительные ссылки на канал с указанием ежемесячной платы в звёздах. Это позволяет авторам контента создать закрытый канал и предоставлять к нему доступ по подписке.

Чтобы сгенерировать ссылку для платной подписки на канал, перейдите в Настройки канала > Тип канала > Управление приглашениями > Создать ссылку и включите опцию Ежемесячная плата.


Также, такие ссылки может создавать и бот. Для этого были добавлены следующие API-методы и поля:
- Метод createChatSubscriptionInviteLink - Позволяющий ботам создавать пригласительные ссылки с подпиской.
- Метод editChatSubscriptionInviteLink - Позволяет ботам редактировать название уже имеющейся пригласительной ссылки.
- Поле until_date в класс ChatMemberMember - Необязательное поле для объекта класса, указывающее на то, имеется ли у подписчика канала платная подписка.


Публикация платного медиаконтента ботами
Изначально, платный контент за "Звёзды", можно было публиковать только в каналах, однако, теперь их могут отправлять и боты. Это позволит многим авторам контента продавать эксклюзивные фото и видео, а также предлагает новый способ монетизации сервиса.

Также, помимо классических ботов, отправлять платные медиа может и бот, подключенный к бизнес аккаунту.

В API бота добавили:
- Возможность отправки платного медиа в любой чат
- В метод sendPaidMedia добавлено поле business_connection_id для отправки платного контента в чат, используя бизнес аккаунт.
- В класс TransactionPartnerUser добавлено поле paid_media для платежей связанных с платным контентом.


Суперканалы
Сообщения в канале публикуются от имени канала, максимум, что можно было сделать раньше - это добавить подпись с именем автора сообщения. Теперь можно включить отправку сообщений непосредственно от своего имени или имени другого своего канала.

Чтобы превратить канал в суперканал, перейдите в Настройки канала > Администраторы и включите «Подписывать сообщения» и «Показывать профили авторов».


В API бота добавили поддержку Суперканалов, позволяющую получать сообщения из канала отправленные от лица пользователя или другого канала.

Поддержать проект на Boosty
Поддержать проект в Telegram

#Новости #Telegram #Stars #BotAPI #Telegram_Stars #Код_на_салфетке #Обновление #Бот #Telegram_бот
116🔥2
Веб-сервер Caddy - Альтернатива NGINX и Apache
Автор: Иван Ашихмин

В этом посте познакомимся с веб-сервером Caddy, современной альтернативой NGINX и Apache с автоматическим получением сертификатов для сайта.


Читать пост в Telegram

Пост на сайте
Поддержать проект на Boosty
Поддержать проект в Telegram

#Lets_Encrypt #гайды #полезные_инструменты #docker #docker_compose #apache #хотлинкинг #nginx #caddy #TLS #веб_сервер #сертификаты
145👍2🔥1
Приветствуем!

Продолжаем рубрику "Вопросы и ответы"!

В течение недели вы в комментариях к этому посту можете задавать различные вопросы нашей команде. Вопросы могут быть о чём угодно (в рамках разумного): о постах, о Python, о разработке в целом.

Ровно через неделю мы подготовим пост с ответами на появившиеся вопросы.

Также у нас есть чат, в котором тоже можно задавать вопросы и просто общаться)
🔥2
Приветствую!

Сегодня мы погружаемся в увлекательный мир фантастики и истории. Эта картина рассказывает о группе современных молодых людей, которые, занимаясь поисками артефактов времён Великой Отечественной войны, неожиданно перемещаются в прошлое и оказываются в самом центре боевых действий. Фильм захватывает дух и заставляет задуматься о ценностях, которые мы часто принимаем как должное. Устраивайтесь поудобнее, включайте фильм и наслаждайтесь просмотром!

Фильм: Мы из будущего

Год: 2008

Компания молодых парней по прозвищу Череп, Чуха и Спирт во главе с бывшим студентом-историком Борманом нашли себе оригинальный способ заработка – откапывать и продавать военные реликвии. Им нет дела до прошлого своей страны, их интересуют только деньги, которые можно выручить на черном рынке. Отрыв очередной «клад», парни обнаруживают солдатские книжки со своими фамилиями и фотографиями. Но на этом невероятные сюрпризы только начинаются.

Приятного просмотра!

P.S. Пиратских ссылок на фильмы больше не будет
🔥2
Что выведет код с изображения? №33
Anonymous Quiz
11%
14
6%
7
39%
RecursionError
28%
10
17%
28
👍1🔥1
Что выведет этот код? №33
🔥1
Вчерашняя задача была не простой, на первый взгляд. Бинарные деревья сложно даются многим, а данную задачу решило 29% из всего 14ти ответивших.

Код задачи:
from dataclasses import dataclass


@dataclass
class Node:
value: int
left: "Node" = None
right: "Node" = None


def sod(root, depth=0):
if root is None:
return 0
return depth + sod(root.left, depth + 1) + sod(root.right, depth + 1)


root_node = Node(
value=1,
left=Node(value=2, left=Node(4), right=Node(5)),
right=Node(value=3, left=Node(6), right=Node(7))
)

print(sod(root_node))



Разбор задачи
Пойдём сверху вниз. Сперва создаём датакаласс Node, описывающий узел бинарного дерева. Применение датакласса описано в посте "[AIOgram3 5.1. Создание структуры](https://pressanybutton.ru/post/telegram-bot-na-aiogram3/aiogram3-51-sozdanie-struktury/)".
В классе прописываем три поля:
1. value - числовое значение хранящееся в узле.
2. left - указание на дочерний узел в левой части дерева.
3. right - указание на дочерний узел в правой части дерева.
Обратите внимание, поля left и right являются объектами этого же класса Node и для указания типа данных используются двойные кавычки, поскольку мы не можем явно указать внутри класса, что он используется "сам в себе".

Далее идёт функция sod, принимающая аргументы:
- root - корневой узел.
- depth - глубина относительно начала дерева, по умолчанию 0.
Поскольку функция рекурсивная, необходимо в самом начале прописать условие выхода из рекурсии. Прописываем блок if, проверяющий, что переданный корень существует, если же вместо него пришёл None, возвращаем 0.
Если выхода из функции не произошло, то возвращаем сумму текущей глубины с глубинами дочерних узлов в рекурсивном вызове.

После класса и функции, создаём переменную root_node, в которой определяем экземпляр класса Node с рядом дочерних узлов.

В самом конце выводим результат вызова функции sod в терминал.

Правильный ответ: 10.


Что это за дерево такое?
Теперь разберёмся, какое дерево у нас получилось. Мы построили классическое бинарное дерево. В нашем случае, корневой узел содержит значение 1, его левый потомок - узел с значением 2, правый - 3, и так далее. Каждый узел может иметь до двух потомков: left и right. Графически дерево можно изобразить следующим образом:

       1
/ \
2 3
/ \ / \
4 5 6 7


Это идеальный пример полного бинарного дерева, где каждый узел, кроме листовых, имеет ровно два потомка. Такие структуры часто используются в алгоритмах поиска, сортировки, а также для хранения данных, которые требуют быстрого доступа.


Процесс вычисления суммы глубин.
Теперь вернёмся к функции sod. В процессе её выполнения мы фактически проходим по всем узлам дерева, начиная с корня. На каждом уровне прибавляем текущее значение глубины к результату рекурсивного вызова для левого и правого потомков.


Пройдемся по дереву:
1. Стартуем с корня (1). Глубина 0.
2. Переходим на левую ветку: узел 2, глубина 1.
3. Снова идём влево: узел 4, глубина 2. Узел не имеет потомков, возвращаем 2.
4. Возвращаемся к узлу 2, идём вправо: узел 5, глубина 2. Узел не имеет потомков, возвращаем 2.
5. Возвращаемся к узлу 1, обрабатываем правую ветку: узел 3, глубина 1.
6. Идём влево: узел 6, глубина 2. Узел не имеет потомков, возвращаем 2.
7. Возвращаемся к узлу 3, идём вправо: узел 7, глубина 2. Узел не имеет потомков, возвращаем 2.

Суммируем результат:
- Глубина 0 (узел 1): 0
- Глубина 1 (узлы 2 и 3): 1 + 1 = 2
- Глубина 2 (узлы 4, 5, 6, 7): 2 + 2 + 2 + 2 = 8

Общая сумма глубин = 0 + 2 + 8 = 10.

Вот и весь процесс. В итоге мы получили ответ 10, который и является суммой всех глубин узлов в этом бинарном дереве.


Заключение
Таким образом, задача оказалась не такой сложной, как показалось на первый взгляд, особенно если разбить её на части. Основной вызов здесь – правильно понять, как работает рекурсия и как она взаимодействует с каждым узлом в дереве.
244🔥3
При работе с различными API-запросами, чаще всего на ум приходит библиотека requests. Она отлично выполняет свою функцию, однако, она не поддерживает асинхронное выполнение. На замену requests пришла новая библиотека httpx.

Пример выполнения GET-запроса:
response = httpx.get("https://reqres.in/api/users/2")
print(response.status_code)
print(response.json())


В этом примере выполнен базовый GET-запрос. Метод .get() возвращает объект Response, который содержит статус ответа, заголовки и данные ответа.


Пример выполнения асинхронного POST-запроса:
async def fetch_data():
async with httpx.AsyncClient() as client:
response = await client.post(
"https://reqres.in/api/users", data={"name": "Napkin", "job": "Author"}
)
print(response.status_code)
print(response.json())


asyncio.run(fetch_data())


В этом примере мы открыли асинхронный клиент в контекстном менеджере для выполнения запроса. В метод .post(), также передали аргумент data, содержащий словарь данных.


Пример выполнения stream-запроса:
async def fetch_data():
async with httpx.AsyncClient() as client:
async with client.stream(
"POST",
"https://api.openai.com/v1/chat/completions",
json={
"model": "gpt-4o-mini",
"messages": [
{"role": "system", "content": "You are a assistant."},
{"role": "user", "content": "Hello!"},
],
"stream": True,
},
headers={
"Authorization": "Bearer <token>"
},
) as response:
async for chunk in response.aiter_text():
yield chunk


async def main():
async for data in fetch_data():
print(data)


asyncio.run(main())


Этот пример показывает, как httpx может использоваться для выполнения запросов в режиме "стриминга".
5🔥5
108❤‍🔥3🔥3
Channel photo updated