Marshal's channel
853 subscribers
288 photos
46 videos
8 files
328 links
About me: @ilya_marshal
Download Telegram
И тут я понял, что не шарю вообще за ООП, особенно в питоне. Или спать уже хочу. Кооороооочеее


Хочу замутить несколько синглтон классов (3). Возьмем изи пример:

class Singleton:
__singleton = None

@classmethod
def get_instance(cls):
if cls.__singleton is not None:
return cls.__singleton
else:
raise RuntimeError(f'{cls.__name__} not initialized')

Вооопрооос, если я хочу несколько синглтон классов и не хочу дублировать get_instance в каждом из нём, то как обобщить?

Если вынести выше и унаследоваться, то каждый класс будет юзать один экземляр родителя и будет полная белеберда. У всех будет доступ к инстансу обобщённого класса-родителя, а не текущего класса

UPD. Офигенно объяснил. Короче поле __singleton будет иметь общее значение у всех классов, что унаследовались от Singleton

UPD2. Ну точнее как, get_instance будет возвращать общее поле родителя, а не текущего класса. А как сделать так, чтоб с текущего класса( не хооочууу в каждом классе get_instance иметь(
Marshal's channel
И тут я понял, что не шарю вообще за ООП, особенно в питоне. Или спать уже хочу. Кооороооочеее Хочу замутить несколько синглтон классов (3). Возьмем изи пример: class Singleton: __singleton = None @classmethod def get_instance(cls): …
Что-то я уснул по щелку пальцев без задней мысли об этом, утром начали приходить нотификейты, разбудившие меня. Увлекательно предисловие.

Это мне писали "нафига тебе аж 3 синглтона?".

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

class Services:
def __init__(track_watcher=TrackWatcher()):
self.track_watcher = track_watcher

services = Services()

А потом где надо

from services import services
services.track_watcher.subscribe(update, context, track)

Когда мне сказали, что это Dependency injection - я ушёл гуглить. То, что нагуглил, вроде подходит под моё. Можно не переписывать

Надо доразобраться с DI

UPD. Собсна видос покрывает чуть ли не всё, что надо знать.

Dependency Injection - Jakob Jenkov

Пока без понятия как более правильно такое делать в питоне и делают ли. Вон кто-то аж либу юзает: Inject - PyPi, которая в своём описании "тонко" намекает the python way, the good way
Навигация

Так как в тележке можно редачить древние сообщения, то можно завести сборник постов. Там где не просто круги рисовать, покекать, а почитать что-то можно.

- CORS в FF
- Узнаем откуда отбрэнчевались (не всегда правильно выводит)
- Какие-то вкусности с спринта на работе (Джанго)
- Моя статейка на Habr'e после конкурса "IT-Планета"
- Офигенно-годные подкасты с англ фразами на яндух музыке (больше 900 шт)
- Докер и его кэша всякие
- Моё знакомство с GitHub Actions
- Про Headless CMS
- Очепчятка в янух апи
- Офигел с алхимии
- Разобрался когда документ должен быть встроенным, а когда нет (MongoDB)
- Эмоции после перехода на MongoDB
- Счастливый я с 100+ звёздами на GitHub'e у моей либы
- Про бинарные данные, передачу их в JSON, размер utf-8
- О самозагруженных треках в яндух музыке
- Немного о проблеме бота, которую я потом пытался решить (причины проблемы)
- Юзаем последний PyPy на Heroku
- Мой кэш запросов для API Яндекс.Музыки в ТГ боте
- PyPy, тайп хинты, жирные запросы у яндуха, моя вторая статья на Habr'e
- Про новую версию pytest и как засаппортить python3.6
- Вся активность на гитхабе за 2019 с приватными репами
- Мои итоги 2019 года
- Репорт бага в Telegram Desktop в URI
- XSS, не эскейпнутые данные у яндуха
- Dependency Injection
- Статистика и аналитика для ботов на примере бота Яндекс.Музыки и сервиса Chatbase.
А вы попались?
Большое спасибо @olegkovalov за публикацию в подборке каналов в @oleg_log! Вас сейчас уже приличное количество, но, надеюсь, меня это никак не смутит. Поэтому я в очередной раз выкладываю ночную какулю, а утром смотрю на неё и чуть что исправляю

Я из принципа уже не хочу хранить callback дату инлайн кнопок в монго. Продолжаю страдать с бинарными данными.

Раньше было так: указывался формат, по нему шла распаковка. Всё жестко ограничено до безобразия. Из-за этого я не мог поддерживать самозагруженные треки (ибо они у яндуха UUID, а не просто ID). Т.е. формат был l, а для UUID'a надо s в определённое кол-во символов (36?). Более того, из-за жесткой прописи формата "пакета" я не мог передавать неопределённое кол-во тех же треков. Из-за этого на последних страницах плейлиста (при пагинации ведь округляем вверх), отсутствовала кнопка "скачать текущую страницу". Списал это на фичу, хотя был костыль. Ибо в кнопке хранились все 7 ID'ов треков (на одной странице столько) и никак не меньше!

Поэтому, было решено чутка улучшить encode&decode данных:
1. Добавить поддержку строк (для UUID'a).
2. Распаковывать динамически (если есть еще байты, то брать слайс по размеру последнего формата и анпакать).

Решения вродь классные, но то, что вышло, мне особо не нрав (код ниже).

Вышло так, что строки оказались заифаны. Столкнулся с проблемой указания их длины. Вариантов так-то не много.
1. Указать длину перед строкой. Так-то да, но какие-то манипуляции с тем, что мы распаковали число, а это оказалось не часть данных которую надо будет передать дальше, а часть формата. Лабуда. Хотя, если принять ls за пару и никак иначе, то вроде ничего так.
2. Паковать строку без указания длинны. Распаковка тогда от первой встреченной s до конца. Сразу к минусам этого способа: нельзя указать несколько строк, нельзя вообще что-либо передать после s. UPD. На самом деле можно, идя с конца, зная форматы и их размер, но тогда только одна s может быть.

С продолжением формата всё понятно вродь. Я заюзал итератор по формату, с дефолтным значением на последний элемент, чтобы продлить его. Храню текущую позицию и прибавляю к ней step, где step - это calcsize() формата, что продлил.

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

А еще я уже потерял весь смысл от этих байтов, нафига (вообще интересно :D)? Просто бы положил в кнопку да и не парился. Раньше было необходимо, чтобы влезть в огрань телеги (64 байта utf-8 в callback дату кнопки влазит) , а сейчас я всё у себя кэширую и мне не надо много хранить у клиента, так, пару чиселок, юидик один
Вот собсна decode, так, посмотреть, не отдохя далеко, побить меня. А если хочется далеко, то вот ссылка на весь мой класс с callback датой: https://codepaste.ml/3031bf43/

Такими темпами всего бота по кускам уже собрать можно будет 😂

И да, это всё про ботика @music_yandex_bot

UPD. Не спрашивайте откуда там какие-то рандомные f-строки)
Статистика и аналитика для ботов на примере бота Яндекс.Музыки и сервиса Chatbase.

Пару слов о сервисе. В далёком 2017 году компашка людей из гугла запилила сервис для ботов с ИИ. Гугл взяла их под крылышко и сервис считается гугловым.

Сам сервис заточен конкретно на ботов, которые на нейронках генерят ответы пользователю. Собсна название говорит само за себя, однако! Однако еще в 2017 году я начал использовать его как аналитику для обычных ботов. Тогда выбор был не очень большой. Был Botan.io (эдакий мост между яндекс аппметрикой и ботами, раньше я использовал его, сейчас проект мёртв). К сожалению и chatbase не развивается, застрял в 17 году. Пытается выглядеть законченным продуктом.

Перейдём к его использованию. Быстро пробегусь по тому, что у нас есть.

Платформа. Если ваш бот работает не только в TG, но и в других местах, можно легко отделять их друг от друга. Лично я живу только в TG, но использую эту возможность по максимуму. Я разделяю статистику пользователей из разных регионов. У некоторых пользователей бота доступно поле language. Поэтому платформы у меня Telegram, Telegram-ru и т.д.

Версионность. Как и с платформой. Легко отделяем одну статистику от другой.

Тип отправителя. Имеется агент и пользователь. При отправке сообщения юзеру шлём с типом агент, если юзер нам прислал - пользователь. Это построит нам целые переписки при анализе поведения пользователей.

Намерение (Intents). Изначально заточен для того, чтобы понять смысл сообщения пользователя. Например, что он с нами поздоровался. Я же использую как стейты того, что он сделал. Проще говоря, просто указываю имя хандлера, который обработал его сообщение. Указывать надо как при отправке сообщения юзера, так и бота, для связи этих двух сущностей.

Not Handled. Можно передать с сообщением только с типом user. Сообщаем о том, что не поняли, что от нас хотят. Я использую как лог левых сообщений, на которых нет обработчиков (просто интересно). И как логирование ошибок.

Помимо всего этого конечно же мы указываем время, ID юзера. Я использую ID с телеги, а не из моей БД.

Стату можно собирать в пачу и отправлять одним запросом, что удобно (я ещё и в отдельных потоках это делаю).

Прикрутили отправку статы и получили следующее:

Активность юзеров, посещения, уники, кол-во сессий, авг сессий на юзера, среднее время на сессию, лог ошибок. Все это с фильтрами по версиям, датам, платформам.

Фигня, да? Согласен.

Переходим к самому интересному: session flow. Мы видим как пользователи передвигаются по нашему боту! Мы видим всё дерево от начало общения до последнего действия! Видим узкие места в юзабилити, как именно пользователи осуществляют переход к тому, или иному меню. Мы видим как нашим ботом пользуются! Сколько и куда пошло, сколько отвалилось. При желании можем открыть диалог с конкретным пользователем и проанализировать действия.

Что-нибудь еще? Дааа!

FUNNELS

Это цепочки наших Intents, которые мы создаем сами. Например, дефолт цепочкой юзера может быть: Меню -> Умные плейлисты -> Плейлист дня -> Скачать текущую страницу
Я создаю такие цепочки из отправленных Intents и потом отслеживаю уровень их достижимости. Наблюдаю за тем, как люди поэтапно проходят по ней и сколько людей. Цепочкам можно задавать имена.

ИТОГО

Сервис пригоден для использования, всё красиво, современно, удобно. API простое и понятное, дока легка для понимания и полноценна. Правда, на сервисе как-то одиноко, складывается ощущение, что ты юзаешь что-то мёртвое... Я бы с удовольствием рассмотрел бы ещё другие варианты.

А что используете вы?

UPD. Из пикчи сразу видно, что проблема с авторизацией, о которой я уже подробно писал, всё ещё есть

UPD2. Забыл рассказать о том, что не использую. Сервис ещё имеет трек ссылок. Т.е. если вы рассылаете линки, то можно оборачивать их через chatbase и смотреть переходы и т.д.

Пикча с session flow
Marshal's channel
JetBrains ❤️ Подогнали мне лицензии на все свои продукты для разработки https://github.com/MarshalX/yandex-music-api
Давно не было шит-постов. Продлить в последний раз или переехать на проектную 🤔 для студентов на два года дают? Тогда продлить 🌚

И да-да, spark лучший почтовый клиент
Когда не пришел на новогодний корпоратив, но коллеги исправили ситуэйшен 😆
Капец СМИ жоские. Через несколько секунд выкладывают материал на одну тему. Конкуренция у них там дикая, видать. Надеюсь, что ТГ шлёт без уведомления, когда я выключаю его и потом делаю прикрепление фотки 🤔

Ну и да, читаем

https://kod.ru/ton-gram-notice-jan-2020/

https://rozetked.me/news/9137-telegram-raz-yasnil-princip-i-osobennosti-raboty-ton-blockchain

UPD. Ориг https://t.tlinks.run/blog/ton-gram-notice
Искусство командной строки

Продвинутому использованию командной строки зачастую не уделяют достаточного внимания. О терминале говорят как о чем-то мистическом. На самом же деле, это умение очевидно (и не очевидно) увеличивает Вашу продуктивность в работе. Данный документ является подборкой заметок и советов, которые я нашел для себя полезными, работая с командной строкой в Linux. Некоторые из них – простые и очевидные, но некоторые - довольно сложные. И предназначены для решения конкретных задач. Это небольшая публикация, но если Вы уже знаете обо всем, что тут написано, и можете вспомнить, как это все использовать – вы много знаете!

https://github.com/jlevy/the-art-of-command-line/blob/master/README-ru.md

UPD. Там за 67к звёзд, а я первый раз вижу. Всё плохо, или таких много?)
Привет люди с ChatWars'a! Привет МРК!

А помните VK Coin? Первоапрельская шутка от ВК в 2019 году.

Первые дни апреля, типичный день, иду на пары после обеда и тут приходит сообщение от Славы с примерно следующим содержанием: "Илья, ты там с платёжными агрегаторами работал, да и вродь WM аттестат у тебя есть. Ты нам нужен, есть идейка". После этого меня минусануло на весь месяц...

У нас была целая инфраструктура!

Пулл ВК аккаунтов для фарма ВК коинов, бот для фарма, бот и группа для продажи ВК коинов без нашего участия, игровой бот виселица, игровой бот орёл и решка! Всё это жило едино, пиарило друг-друга и работало, приносило доход!

Вообще про реализацию всего можно писать отдельные посты. Как я выживал на Python'e держа по несколько сотен сообщений в секунду и т.д.

Проще просто вкинуть каких-нибудь цифр, что сохранились, фактов.

Коины

- Мы всё время висели в топ-100 ВК, потом начали чутка разносить коины по аккам.
- Осуществлено 1100+ успешных транзакций на покупку коинов.
- Около 100 аккаунтов фармило коины.

Орёл и Решка

- 138 тысяч уникальных пользователей!
- Больше миллиона сыгранных игр!
- Средний винрейт держался у всех возле 50%
- В группу вступило 13 тысяч человек.

К сожалению, база была утеряна и куча интересной статы потерялась. Кто сколько выиграл, кто в итоге остался в профите (бот или игрока) и т.д. и т.п.

Просто прикольно:
- проходить мимо человека и случайно замечать как он играет в твоего бота;
- отвечать куче людей в личке, когда тебе пишут каждую секунду (висели в топ-100 очень высоко, нас видел весь ВК, писали кому не лень);
- справляться с нагрузкой, общаться с администрацией ивента и просить уменьшить процент показа бота у пользователей;
- наблюдать за тем, как игроки пишут ботов для игры, что ты разработал. Как они продают свои творения.

Исходный код игрового бота "Орёл и Решка: https://github.com/MarshalX/VCoinGame

Код игрового бота "Виселица": https://github.com/DarkKeks/VCoinGame

UPD. Дааа, мы были в первом вагоне хайп-трейна
Чего я вдруг вспомнил про это? Да я решил сделать массовую рассылку и там 🌚

Пока искали скрипт для рассылки, ибо лень было писать для этого новый, наткнулись случайно на код бота для виселицы (который чел продавал). Поорали

https://codepaste.ml/3871f424/

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

Да-да, начинается самое интересное - выживание!

Этот канал - смесь блога, полезных вещей и дегродства.

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

Для обсуждения постов, кста, есть чатик - @MarshalCh

Все полезности для почитать есть в закрепе - https://t.me/MarshalC/349

UPD. Есть у кого какое-нить овнерство над ботиком, паблосом связанным с БГУИРом, БГУ, БНТУ? 🌚
Ментор форкнул либу, я напрягся и жду продолжения 👀
This media is not supported in your browser
VIEW IN TELEGRAM
Произошёл кек. Одмины быстрого реагирования @libmustdie

Upd. (Скинул мемас в чатик и в бота, а через несколько секунд он попал в профунктор, дааа, пришлось объяснить рофл)
image_2020-01-07_12-43-41.png
119.9 KB
Обновил mongoengine c 0.18.2 до 0.19.0 - упало.

Ребята отказались от *args в конструкторе доков, теперь явно надо сообщать какие поля передаём.

GitHub Commit - Drop support for positional arguments when instantiating a document

UPD. Убеейте, кто придумал сохранение галочки "отправить как файл" в тг
Marshal's channel
Большое спасибо @olegkovalov за публикацию в подборке каналов в @oleg_log! Вас сейчас уже приличное количество, но, надеюсь, меня это никак не смутит. Поэтому я в очередной раз выкладываю ночную какулю, а утром смотрю на неё и чуть что исправляю Я из принципа…
В общем пока писал пост, уже понял, что надо переписывать строки на указание длины. 

Я думал выйдет побольше правок после ночных посиделок. Конечно я не тестил, но с одной строкой работает корректно. Прогоняя в голове должно работать с несколькими)

Там это, во-первых плейлист "Подкасты недели" не работает. Чем он такой особенный я не знаю. Надо глянуть. Вроде все плейлисты обобщены.

А еще треки, что загружены пользователями не хотят скачиваться как обычные( тоже разобраться надо

Да-да, ботик @music_yandex_bot
И шо это? application.octet-stream.

На десктопе работает, Telegram X багует.

Короче еженедельные подкасты подъехали в ботика, но не все.

Больше 50 мб пока что нельзя.

Думал не упрусь в лимит, не понимал других разрабов, которые обходят огрань. Зачем они это делают... И все ещё не понимаю, только если они не поддерживают подкасты.

Пойду в чатик для репорта багов скрин закину

UPD. Они короче вместо того, чтобы написать "неизвестный исполнитель" пишут MIME тип