СЛЕГ! <Z> ️
524 subscribers
678 photos
20 videos
12 files
307 links
Здесь создают авторских телеграм-ботов. Когда не справляются конструкторы и веб-студии - есть СЛЕГ.

Статистика ботов:
https://ssleg.tech/bots_view.html

Написать автору: @yesitsnew

TW: ещё тут политота, утечки баз и игры в товарища майора на минималках
加入频道
Тем временем, база тг-политоты доросла до 400 тысяч людей.

Ради интереса, сопоставил её с базой телефонов. Определилось 93 410 штук. 23%

То есть, по каждому четвёртому человеку в политчатиках, можно опеределить как минимум регион по номеру телефона, как максимум реальное имя и соцсети.

Напомню, проверить есть ли вы там, вы можете здесь, спросив Фому :)
Алгоритмы сравнения больших данных могут быть разными. Хорошо, когда все влезает в оперативную память, тогда можно загрузить все в один словарь и по нему пробежать. Это алгоритм раз (слева)

Второй (справа) немного сложнее, но в десятки раз экономнее. Юзерайди в телеграм это целое число в диапазоне от 0 до 1,4 млрд. Соответственно диапазон разбивается на 1400 кусочков по миллиону возможных айди в каждом и сравнивается частями. 1400 запросов к бд, загрузка словаря, сравнение, очистка.

В результате имеем.
Курсор 1 - 400к строк
Курсор 2 - 12М строк
Алгоритм 1 - 2Гб оперативки, 38 секунд.
Алгоритм 2 - 54Мб оперативки, 1 минута, 52 секунды.
Минутка плохих и очень плохих алгоритмов.

Спрашивает приятель:
- глянул твой канал, зачем тебе словари, если можно списки использовать или numpy? (речь идет о задаче сопоставления баз юзеров политоты и телефонов)

Ок, используем списки (сверху, алгоритм 1):
принадлежность проверяем через row[0] in list
1.6Гб памяти, обрабатывает 500 записей за 39 секунд, то есть работа будет сделана всего за 8.7 часа.

Списки (внизу слева, алгоритм 2):
те же списки, принадлежность проверяем через list.count(row[0]). Еще хуже, 500 записей за 56 секунд. Вся задача - 12.5 часов (потому что count всегда пробегает весь list, в отличии от in)

Numpy (внизу справа, алгоритм 3):
640Мб памяти, 10 000 записей за 53 сек. Общее время - 35 минут. Хахалити. 😂

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

Приятель сказал - множества! И написал программу в 4 строки. Она вычисляет пересечение двух множеств и печатает его размер.
1 минута 8 секунд. Это самое pythonic way решение. (верхний слайд)

Я написал класс, который изображает из себя btree. При 14к листьев - 1 минута 28 секунд. При 140к листьев - 47 секунд, 1,6-1.7Гб памяти.

В итоге словарь мы не догнали, но ещё два решения нашли.

Итак, перебор сверхбольших массивов в питоше от лучшего к худшему:
Словарями
Самопальным btree
Множествами.

Остальное лучше даже не пробовать 😄

P. S. Голосовать выше не забывайте, мне нужны ваши ориентиры.
Небольшой пример из жизни, для начинающих Питон.

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

Соответственно, сайт надо превратить в список кодов телефонов. Легко (все исходные тексты приложены в след. сообщении ↘️ )

Действие ноль
mobile_operator0.py — превращает список страниц сайта, скопированный с сайта в массив
(единственное ручное действие)

Делай раз
mobile_operator1.py — все страницы сайта загружены в файлики, чтобы их разобрать.
(reg_codes получен на этапе 0. внимание - создайте папку telcodes там, где вы положите эти скрипты или пропишите свой путь)

Делай два
mobile_operator2.py — все страницы очищены от html и превращены в csv

Делай три
mobile_operator3.py — csv прочитаны, проверены на ошибки и просчитаны диапазоны номеров. Сделан итоговый файл csv, которым можно легко пользоваться открыв его в excel.
(программа выловит одну ошибку в данных, это ошибка на сайте. Csv таблицу так же выкладываю ниже ↘️ )

Все готово. Повторив эти шаги вы получили удобную базу с диапазонами номеров, провайдерами и регионами. 7591 запись. А когда вы разберетесь в используемых командах (всего штук 15, в основном строковые и файловые операции) вы сможете гордо сказать, что вы теперь умеете в датамайнинг и почти датасайентист.

Бонусный файл, продвинутый уровень:
mobile_operator4.py — создание таблицы в базе PostgreSQL, с использованием типа данных int8range (да, постгрес умеет хранить и выбирать диапазоны значений). В принципе надо делать три таблицы и два внешних ключа (регион и оператор), но поскольку это статичная малая таблица, смысла усложнять запросы я не вижу.

P. S. Полученная база была протестирована на 12 млн номеров, опознание составило 99.93%. Осталось несколько диапазонов нагуглить и добавить ручками, чтобы довести до 100%.
А вот так уже выглядит запрос в постгрес и его результаты. Работа с диапазонами в слиянии таблиц - легко. Запрос выполняется 28мс.

Фома получит такой функционал в ближайшем обновлении, таблица уже на продакшене. :)
Просто познавательный слайд. План нумерации и сотовые операторы в Крыму сейчас. Выписка из таблицы россвязи от 26 июня 2020
https://rossvyaz.gov.ru/deyatelnost/resurs-numeracii/vypiska-iz-reestra-sistemy-i-plana-numeracii

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

Есть уже готовый csv, из официального источника, с актуальностью июнь 2020. Осталось только слегка перекодировать и загрузить файл в таблицу БД.

Так что первая заповедь питониста звучит так:
Сначала хорошо погугли, прежде чем писать. 😂
Государственная база полнее, свежее, но как всегда, пять разных наименований Москвы. 3 разных Питера, два Волгограда и так далее.

У нас в прессе строится цифровое ГУЛАГ государство, а в реале государевы базы данных выглядят так, как будто в них каждую ночь тролли ебались.

Когда там появятся программисты, дочитавшие учебник SQL до главы foreign key я не знаю.
Но на государеву базу легко, за 20 минут, написать патч. И в продакшен.

Фома обновился.

В принципе нужен ещё один патч, русского языка, от вырвиглазных сочетаний типа "Республика Удмуртская", но они действительно так пишут в минсвязи 😁
У asyncio есть очень удобные методы вызова функций, как обычных, так и асинхронных, через произвольное время в секундах, но есть ньюанс.

В потоке событий телеграм это эксплуатируется вот так (для обычных функций)

from telethon import TelegramClient
client: TelegramClient
client.loop.call_later(delta.seconds, basegen) - задержка в секундах, имя функции.

Соответственно мне нужно, чтобы функция бота basegen выполнялась каждый день в три часа ночи. В реальности она выполнилась несколько сотен раз в момент 2:59:59-3:00:00.

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

Из за неточностей таймера компа, asуncio гарантирует секунду, в которою все запустится, но не её доли. И функцию первый раз вызвало в 2:59:59.522.

Все бы хорошо, но timedelta вычитая разницу времени, даёт все что больше суток как дни и секунды. Получилось 1 день и ноль секунд.

Правильный вариант считать задержку через timedelta это 13 строка. :)
Тележенька взорвалась от выборов в Белоруссии. За сутки в чаты залетело 4905 человек.

Основная движуха здесь:

@minsk_new +772 человек. Чат Минска.
@majakrainablr +1899 чат выборов.

И наш "протестный" чат канала ateo
@Ateo_Chat +570

Приятного аппетита :)