Технологии
Цифровой мир, как он есть, и немного, каким должен быть
Рубрикатор
Последние записи
Автодокументирование моделей Sequel

Набросал предварительную версию YARD-плагина для автодокументирования Sequel-моделей — yard-is-sequel.
Существующий yard-sequel с современными версиями YARD/Ruby/Sequel не работает.
Мой вариант, конечно, не может пока похвастаться полнофункциональностью (версия 0.8.0 — это ранняя альфа), но кое-что самое важное умеет:
-
Генерирует список ассоциаций:
many_to_many,many_to_oneиone_to_manyс корректными ссылками на типы. -
Генерирует список полей. Также с типами, но тут есть нюансы…
-
Маппинг типов полей требует доработки. Кроме того, типы, не поддерживаемые SQLite, скорее всего, не будут нормально обрабатываться в принципе.
Поля берутся из
Database#schemaна созданной in-memory SQLite базе данных. Было бы хорошо, безусловно, брать их непосредственно из миграций, но пока непонятно, как это сделать. -
Путь к миграциям следует указать через переменную окружения.
-
Чего нужно доделать?
-
Отрефакторить и упростить обработку ассоциаций.
-
Расширить обработку типов в полях и сделать ее менее хрупкой. Сейчас есть подозрение, что минорная смена версии Sequel может всё поломать…
-
Добавить возможность брать схему из отдельно сохраненного файла (в формате JSON, скорее всего).
Но надо понимать, что я буду что-то править и дорабатывать только постольку, поскольку мне это самому нужно… Однако, если кто-то предложит свои пулл-реквесты, или хотя бы подробные баг-репорты, отнесусь со вниманием.
Об инвалидацию кэша

Как известно, в программировании есть только две реально сложные задачи: именование переменных и инвалидация кэша1. С первой мы сделать ничего не можем, со второй, конечно, тоже, но что-то делать приходится…
И вот в процессе большого рефакторинга inat-get я в очередной раз задумался. Суть тут вот в чем: данные, которые требуется получать из API iNaturalist — очень большие (зависит от целей, конечно, но они могут быть очень большими), и логично их закэшировать в локальной базе данных. Естественно, кэшированные данные нужно обновлять.
Есть прекрасный параметр updated_since в запросах к API, т.е. мы храним у себя информацию о сделанных запросах, и когда
нам нужно получить новые данные по тем же условиям, указываем дату/время предыдущего запроса в этом параметре. Но полностью
проблему это не решает: updated_since не отменяет (и не должен отменять) все остальные параметры запроса, т.е. те
наблюдения, которые выпали из запроса, в выборку не попадут. И останутся в локальной БД в старом состоянии.
Ну, то есть, выбрали мы, например, данные по проекту, который фильтрует наблюдения с quality_grade=research, а потом
пришел добрый человек и заметил, что в наблюдении культурное растение. Наблюдение выпадает из проекта, но мы об этом
не можем узнать через обновление…
Какие есть пути решения? Вижу несколько вариантов, ни один из которых меня не устраивает полностью…
-
Автор этой фразы, предположительно, Фил Карлтон (Phil Karlton), ведущий инженер компании Netscape. ↩
Паттерн «Фасад» и гем для DSL

При написании inat-channel я столкнулся вот с какой проблемой: с одной стороны, более-менее сложные
действия должны быть декомпозированы, то есть разбиты на модули и отдельные методы в них; с другой — глубокая декомпозиция заставляет
писать длинные обращения к методам типа INatChannel::Telegram::send_observation, что неудобно, да и не эстетично. По хорошему вообще
нужно верхний уровень методов инклюдить и писать send_observation в основной программе, но если писать все как включаемые методы модулей,
то во-первых, они все из всех модулей попадут в финале в одно пространство имен, а во-вторых, туда же попадут и приватные методы.
Для подобных случаев и предназначен паттерн «Фасад» — мы создаем отдельный программный модуль — в данном случае это модуль же в терминах Ruby — который содержит только нужные извне методы, делегируя их в основной нормально декомпозированный код. И затем его спокойно инклюдим в коде основного скрипта.
Собственно, именно так я и сделал, определив модуль IC и заполняя его методами в тех же файлах, где они определены. Туда же отправились
некоторые методы, не нужные вовне, а используемые слабо логически связанными модулями — здесь речь скорее не о логике и отделении фасада,
а о сокращении (текстовом) кроссмодульных вызовов. Впрочем, по мере разрастания структуры вопрос, что считать внутренним, а что внешним,
становится не очень однозначным.
Подумав немного на эту тему, я решил вынести абстракцию в код и написал is-dsl — гем, упрощающий, а главное — структурирующий делегирование методов и констант фасаду. Подробнее — в README репозитория (есть русская версия), а также в yard-документации. Здесь коротко обозначу основные особенности:
-
Помимо основного модуля фасада формируется теневой модуль — для использования внутри библиотеки. Все, что попадает в основной, попадает и в теневой, обратное неверно. См.
shadow-методы. -
Можно делегировать как статически синглтон-методы классов и модулей, так и лениво методы произвольных синглтон-объектов, где сам объект создается или получается через вызов блока. См.
lazy-методы. Предполагается применение с методом классаinstanceв первую очередь.
Планов менять или добавлять что-то в основную функциональность нет, думаю когда-нибудь сделать плагин для YARD, чтобы делегирование методов правильно автоматически документировалось.
Пара апдейтов
inat-channel v0.9.2
Что это такое — см. предыдущий пост.
Помимо исправления мелкого бага (имя lock-файла по умолчанию), изменил немного логику — при запросе свежих наблюдений отсечка происходит не по дате загрузки наблюдения, а по дате его последнего обновления. Это позволяет попадать в выборку наблюдениям, которые долго пролежали без исследовательского статуса. В целом это должно улучшить ситуацию с поступлением наблюдений в «несезон», по крайней мере, я на это надеюсь.
При этом удаление устаревших наблюдений из пула по прежнему контролируется по дате загрузки наблюдения.
jekyll-is-announcer v0.8.3
Опять же, о нем я уже писал. Впрочем, детали и концепция, чую, будут еще меняться и меняться…
А сейчас поменял кнопку перехода в канал на виджет от телеграма с комментариями. Что характерно, когда я делал кнопку, я ведь спрашивал у двух нейросетей, существует ли такой виджет… Но, видимо, как-то неправильно сформулировал и заузил область поиска1. А потом почти случайно сам наткнулся.
Что-то широкий и разнородный плагин получается… Пока не могу сообразить, как его окончательно заархитектурить — кнопки-то можно бы делать к разным сервисам легко, а вот встраиваемые виджеты — уже сложнее. Буду думать дальше. Раскидывать же его на несколько плагинов по отдельным сервисам не хочется, чтобы не плодить массу отдельных вспомогательных JSON-файликов.
Визуальную составляющую пока не дорабатывал — тут тоже надо сначала с общей картиной определиться, потом верстать конкретику.
-
См. раздел об использовании LLM в программировании в соответствующем посте. ↩
iNaturalist + Telegram

Анонс
Написал скрипт для автопостинга выборок из iNaturalist в tg-каналы. Скрипт делает выборку по произвольно сконфигурированным параметрам (которые, разумеется, должны поддерживаться iNaturalist API), затем берет случайное наблюдение, постит его, а остальные складывает в пул, который будет задействован, если свежие кончатся. Это если коротко.
Более подробно, как это все работает, а главное — как настраивается, я описал в README проекта inat-get/inat-channel. В том числе и на русском. Здесь пара моментов:
-
Наблюдения не дублируются.
-
Можно включить режим, когда и таксоны не будут дублироваться, с ограниченным, правда, сроком. Но его можно выставить произвольно большим.
-
Форматирование делается ERB-шаблоном, т.е. максимально гибко.
-
Скрипт прекрасно работает на GitHub Actions, запускаясь по расписанию. Для контроля неповторямости необходимо настроить обратный пуш, чтобы данные, которые хранятся в JSON-файлах, сохранялись в репозитории между сеансами.
-
Используется iNaturalist API v2, которое находится в ранней бете и может поломаться. Однако, на первой версии пришлось бы вытягивать в десятки, если не в сотни раз бо́льшие объемы данных, что малоприемлемо.
Примеры
На реальных примерах работу скрипта можно посмотреть на двух моих каналах:
-
Во-первых, я оживил канал «Природа Урала — наблюдения с iNaturalist». Там, напомню, наблюдения со всего Урала и прилегающих районов — от Оренбуржья до ЯНАО. Ни один регион не входит в выборку целиком, только отдельные районы, относящиеся непосредственно к Уральским горам, или прилегающие. В канале выходит до четырех постов в день по разным группам таксонов.
Все настройки и workflow для Actions доступны в репозитории inat-get/channel-ural.
-
Во-вторых, для проекта «Биоразнообразие районов Свердловской области» тоже завел канал, под немудреным названием «Биоразнообразие Свердловской области в TG». Там один пост в день (да и выборка поменьше).
Все его настройки и workflow также доступны на GitHub — inat-get/channel-sverdlobl.
Подписывайтесь, ставьте лайки, комментируйте… Отелеграмливайте свои проекты. В общем, велкам.
Анонсер — техническая сторона

В посте о подключении телеграм-канала я уже предполагал, что напишу подробнее о технической стороне этого подключения. Вообще-то, я планировал этим заняться попозже, а пока переключиться на «Практическое руководство по darktable»… Но внезапно обнаружил, что толком переключиться не могу, пока не доведу эту задачу с анонсером до какой-то логической точки.
Что ж, причесал Actions, отладил это хозяйство до более-менее стабильного состояния — хоть и далекого от завершения, но уже приемлемого для описания. Принципиальных изменений в ближайших версиях, скорее всего, не будет, а о плановых доделках я здесь еще скажу.
Задача
Собственно, основная задача стояла в следующем:
-
Отправлять анонсы (пока только в телеграм-канал) новых постов;
-
Сохранять ссылки на анонсы и показывать их на страницах, чтобы можно было перейти к обсуждению.
Уже по ходу дела решил добавить в Actions отправку уведомлений себе о выполненных операциях.
Телеграм-канал сайта

Завел себе (точнее, этому сайту) канал в телеге — https://t.me/shikhalev_blog.
-
Во-первых, для анонсов новых постов (даже заморочился и автоматизировал анонсирование на GitHub Actions).
-
Во-вторых, для комментариев, а то, похоже, аккаунт на GitHub мало у кого есть… Хотя, может, просто обсуждать нечего.
-
Ну, и в-третьих, там можно донатить «звездами». Впрочем, тут я иллюзий не питаю.
Кнопка для перехода в канал в постах выглядит корявенько, но я сейчас не хочу заморачиваться с частностями дизайна, поскольку планирую большой рефакторинг в относительно скором времени (весной).
В общем, приглашаю подписываться и обсуждать что-нибудь. Сейчас я закинул туда ссылки на посты этого года и несколько более старых, какие счел нужным. Новые посты буду анонсировать обязательно, может быть, докину и какие-то из старых.
Что касается технической стороны вопроса: плагин для Jekyll можно посмотреть на GitHub —
jekyll-is/jekyll-is-announcer, а его использование —
в каталоге .github/workflows
репозитория сайта. Думаю, еще написать об этом подробнее, но перед этим выделить основные действия из workflow в отдельные
action-репозитории — тогда можно будет поговорить на этом примере и об устройстве GitHub Actions в целом.
Заметки об LLM и нейросетях вообще

За последнее время (особенно последний год) мне довелось довольно активно поработать с большими языковыми моделями (LLM), которые сейчас модно называть искусственным интеллектом. Захотелось кое-что сформулировать и подытожить.
По этому поводу перечитал свои старые посты: «Отставить панику…» и «Паникуем иначе», с удовлетворением убедился, что основной посыл остался верным и на текущий момент, хотя, конечно, за это время многое стало яснее и накопился реальный опыт использования — как у меня лично, так и, не побоюсь этого слова, у человечества в целом.
Кстати, КДПВ сгененирована по тому же промпту, что и в тех старых постах — «deep learned girl in fantasy style». Пожалуй, это будет моя новая традиция для постов на подобные темы. В конце концов, не искусственный же интеллект рисовать — его никто не видел.
В общем, я, пожалуй, сначала пройдусь по своим основным тезисам из старых постов, а затем перейду к новому опыту и мыслям по его поводу. При этом я не собираюсь ограничиваться критическим взглядом, наоборот — основной упор будет на то, как извлечь реальную пользу из применения нейросетей.
Первая глава «Практического руководства...»

Выложил первую главу «Практического руководства по darktable» — «Базовая обработка».
Вместе с «Введением» первая глава должна дать полноценный быстрый старт — основные вещи, которые необходимы, чтобы начать уже делать что-то полезное.
Описаны действия и модули для:
-
Выставления баланса белого;
-
Исправления оптических искажений и шумоподавления;
-
Кадрирования и изменения геометрии;
-
Работы с общим контрастом и экспозицией, вытягивания теней;
-
Подчеркивания деталей посредством локального контраста.
Огроменный вышел справочный раздел, подумываю о том, чтобы вынести переводы справки отдельно от глав все-таки… Но пока не уверен.
По прежнему жду замечаний и вопросов.
Следующая глава будет про организацию изображений — снова представление светового стола, но уже в максимально развернутом виде.
Этим стулом...

Начал писать большое Практическое руководство по darktable. Выложил «Введение», где рассматриваю общий интерфейс и базовое управление снимками.
Это всё пока черновик, который будет правиться и дорабатываться, поэтому замечания и вопросы крайне приветствуются.
Общая идея — соединить изложение в практическом ключе, посредством сквозных примеров и теоретических отступлений, со справочными материалами, прямо соответствующими родной справке darktable.
На данный момент справочная часть — это ИИ-перевод, тогда как практическая — оригинальный текст (писать не-перевод посредством ИИ оказалось практически невозможно, т.е. писать промпт куда сложнее и дольше, чем сам текст… это отдельная интересная тема, надо будет пост написать). По ходу дела буду и справочную часть активно редактировать, чтобы привести язык в порядок и единообразие.
Вообще, конечно, задумка масштабная, писать буду долго, тем более, что не могу этому посвятить все свое время… Но надеюсь где-то за полгода-год закончить. И опять же, рассчитываю на фидбэк по ходу дела, чтобы ничего не забыть и не схалтурить.
Показаны 10 записей из 84