Стендап Сьогодні
Що я зробив, що я хочу зробити, і що це все значить.
Повсякденні здобутки в форматі стендапу.
Детальніше в статті
Підписатись на RSS
📢
Канал в Telegram @stendap_sogodni
🦣
@stendap_sogodni@shevtsov.me в Федиверсі
15.03.2025
Коротко про каву вдома
Це якась містика, але останній раз про каву вдома я писав рівно 2 роки тому. От знову про неї нагадали, тому поділюся тим, що може помінялося.
Що не змінилося: якісний еспресо вдома — це як яхта: не хобі, а спосіб життя. Тобто, безперечно можна вдома робити еспресо ще й краще ніж в кавʼярні, бо в кавʼярні немає змоги стільки уваги приділяти кожній чашці. Але прилади, потрібні для приготування еспресо технологічно складні, а тому дорогі. Це треба памʼятати, коли капсульної чи автоматичної кавоварки не вистачає та хочеться чогось більшого.
Мій набір для еспресо це Commandante C40 та Picopresso. Пікопрессо з правильно підібраним помелом дуже непогані результати дає. Але, якщо поруч є кавʼярня третьої хвилі, то навіть такий набір ніщо інше як маленька “яхта”.
Про пуровер. Надбав Дотик. Це українська воронка V60 з унікальною комірчастою структурою. Річ у тім, що керамічні воронки значно відтягують на себе температуру, що помітно погіршує екстракцію. Через це якщо брати класичний Hario, я всяко раджу брати пластик. Або… Дотик! В нього такої проблеми немає. А ще він красивий.
Також збагнув, що головний фактор в пуровері — це рівномірність проливу. Причому звичайним чайником її важко досягнути, бо він надто інтенсивно ллє. Окрім спеціальних чайників з гусячою шиєю, є простіший, дешевший та компактніший варіант: сито Hario Drip Assist. Воно дійсно допомагає.
Нарешті, також отримав штучку під назвою Clever Dripper. Хоч він виглядає, як воронка, Клевер заварює занурювальним способом. Тобто в нього кладеш фільтр, каву, заливаєш водою, чекаєш 3 хвилини та зціджуєш. Звучить як наче надто просто, але кава така ж смачна як з пуровера. Трохи більш насичена.
Отже, Clever Dripper отримує від мене статус найпростішого способу заварити вдома хорошу каву. Настільки хорошим, що тепер я беру щось інше тільки через відчуття, що не виконую свою норму заморочок.
14.03.2025
Патерни програмування
Книжка Gang of Four є мало не обовʼязковим читанням для досвідчених програмістів. А з іншого боку — чув й такі думки, що це нудна академічна маячня, яку ніхто на практиці не використовує. Або що це щось зі світу Hello World Enterprise Edition.
Мені здається, що проблема цієї книжки в тому, як там ретельно розібраний кожний патерн. Це створює уяву, що патерни — це щось стале, як закони термодинаміки чи табличка похідних. Що десь хтось дуже досвідчений пише програми, де кожний клас відповідає патерну з книжки один в один.
Втім насправді ці патерни є формалізацією підходів, які й так існували. В них більше спільного з гуманітарними, а не точними науками. Наприклад, у психології є архетипи, а в літературі - 36 драматичних ситуацій. (Але не все у програмуванні таке “мʼяке”; от, алгоритми вимагають жорсткого дотримання.)
Відповідно, головну цінність патернів бачу в полегшенні комунікації. Фабрика сама собою напишеться, якщо буде потрібна, але спілкуватися з командою легше, коли можна сказати “тут шльопнемо фабрику” та всі зрозуміють, про який підхід йдеться. Або читаєш код, бачиш — адаптер — та відразу знаєш, що клас існує, щоб вставити квадратну деталь в круглий отвір.
13.03.2025
Про переписування
Всі, мабуть, вже чули про компілятор TypeScript переписують на Go. Хотів прокоментувати з позиції людини, яка багато чого переписувала, в тому числі й на Go.
Вони обрали найпростішу форму переписування - 1-до-1. Чудово, що була така можливість, бо не така вона вже й “найпростіша”. Переписати один модуль то вже важко, а тут величезний проєкт. Проте принаймні не доводиться адаптувати структури даних та ієрархію коду під іншу парадигму.
Власне, переписувати 1-до-1 гарно, якщо мови мають схожі парадигми. В разі TS це ще й залежить від стилю програмування; якби код був більш функціональним, навряд чи вдалося б його адаптувати через те, що Go змушує прописати типи кожної функції явно. Але, наскільки я знаю TS, там більш-менш імперативний код, не такий далекий від Go.
Але разом з тим їхній код на Go не такий вже ідіоматичний. Яскрава ознака для мене: бачу лише 125 місць, де з функції повертається error
. Також багато структур, що складаються із функцій — теж ідіома з JS, а не Go. Втім то все можна виправити, головне з чогось почати.
До речі, Microsoft не вперше цікавляться Go - в них є навіть власний форк заради якихось вимог криптографії, які мені важко зрозуміти. А сьогодні дізнався про такий проєкт як [Dapr]https://github.com/dapr/dapr) - теж від Microsoft.
А взагалі, я дуже радий тому, що відбувається: одна з моїх улюблених мов переписана на іншу. 🥳
12.03.2025
Здається, починаю не любити GitHub Actions
Є в AWS офіційна “дія” для GitHub Actions, щоб розгортувати сервіси. Це чудово. От тільки якщо розгортувати достатньо багато сервісів, вона почне відвалюватися з перебільшенням обмеження на кількість. Та ніякого шляху розвʼязку — ані через GA, ані через саму дію — немає.
При тому, розвʼязок дуже простий — збільшити кількість повторних спроб. AWS CLI та всілякі SDK вміють це робити. А дія — ні. Тікет про це висить вже майже два роки. Хтось зробив виправлення, але його дедалі ігнорують.
Можна було взяти форк з виправленням, або зробити свій. Натомість я обрав структурно простіший шлях: замінити виклик дії на виклики AWS CLI. Це трохи складніше, бо прямої заміни немає, треба робити два виклики - aws ecs register-task-definition
та aws deploy create-deployment
. Також треба передавати дані з одного в інший та будувати JSON - що можна зробити з jq.
Зате я отримав рішення, яке побудоване на більш надійних та прозорих компонентах. Очевидно, що AWS CLI використовується на багато порядків більше, ніж це дія GitHub Actions, тому й підтримка в нього краще.
А загальний тут висновок у тому, що треба добре подумати перед тим, як додавати до збірки спеціальні дії. Подумати, в першу чергу, про те, чи не можна замінити її звичайним скриптом. Хоч це і йде всупереч з усією пропозицією GitHub Actions - що весь процес можна зібрати з кубиків, без всякого бридкого коду.
Та й чесно, не дуже в них хороша система для створення тих спеціальних дій. Найгірше — їх потрібно писати на JavaScript, тобто видрати шматок шелскрипта не вийде. Плюс обовʼязково треба додавати до Git повністю зібраний код дії — це наче логічно, але ускладнює розробку.
Якби зараз з нуля переписував систему CI, то орієнтувався б якомога більше на шелскрипти та доступні їм засоби спрощення (як-от звичайнісінький виклик програм, без всякої спеціальної магії.)
11.03.2025
Пригоди з DietPi та HomeAssistant
Як колись писав, в мене розумний будинок крутиться на HomeAssistant, а той — на системі під назвою DietPi. До недавнього вважав, що можна забути про ручне налаштування, бо HA тут підтримується вбудованим інсталятором. Але не так все гарно.
Виявилося, що той інсталятор - dietpi-software
- взагалі не займається оновленнями. Та й взагалі це лише один величезний скрипт, де є інструкції до встановлення всього того переліченого софту. Звісно, якщо якийсь продукт встановлюється з репозиторію, то й оновлення на нього приходитимуть. Але в HomeAssistant немає репозиторію для Debian, а ставиться він з PyPi. Тому оновлення відбувається вручну.
(Тільки що помітив, що в посібнику від DietPI є інструкція, як це робити. Але, власне, нічого магічного там немає, суто pip3 install
.)
На цьому історія не закінчується, бо десь в залежностях до моїх інтеграцій є пакет av
, який в сучасній версії потребує FFmpeg 6. А в DietPi є тільки FFmpeg 5. Бо вона побудована на стабільному Debian Bookworm (з яким в мене останнім часом одні проблеми.)
Вдалося відшукати додатковий репозиторій deb-multimedia, в якому проміж іншого є й FFmpeg 6 для Bookworm. Так що наче обійшлося без якихось хаків. (А сайт цього репозиторію виглядає так, наче останній раз оновлювався десь в 90-х. Але ні — в цьому році, насправді.)
Попри все це, DietPi мені все одно подобається, бо робити ті ж саме налаштування вручну не хотілося б. До того ж я радий, що воно обрізане під мій SoC 10-річної давнини.
10.03.2025
"На гачку" - посібник свідомого розробника
На роботі спитали — яка книга зробила вплив на моє уявлення про свою професію? Мені відразу згадалася книга “На гачку” Ніра Еяля. Хоч вона й не про програмування, але знаєте… програмування не є самоціллю, воно завжди виконує якусь потребу.
Книжка вже не нова — вийшла у 2013, до Тіктоку та перетворення соціальних мереж на політичну зброю. Але тому уроки з неї стали тільки актуальнішими.
В чому суть: люди схильні до залежностей. Коли щось має на нас вплив та “натискає на вірні кнопки”, ми хочемо більше, попри ризики та недоліки. Це може бути алкоголь, азартні ігри, шоколад, любов… Але тепер зʼявилася нова залежність: програмні продукти.
Програми унікальні в тому, скільки контролю творець має над їхньою поведінкою. Бокал вина поводиться передбачувано; смак може бути різним, але ти знаєш свою межу. Однак програми можуть бути від невинних та незамінних до таких, що буквально зруйнують життя залежністю. Особливо погано, що немає ані маркування, ані регулювання програмних продуктів. Та оскільки власники зацікавлені в тому, щоб клієнти повертались, то програми, які свідомо будують звичку та залежність, є всюди навколо нас.
“На гачку” окреслює механізм формування звички: зачіпка, дія, нагорода, внесок. Вона досліджує реальні приклади: соціальні мережі, ігри та звичайні продукти.
Книга буде цікава, щоб помічати та розуміти ті темні підходи, а також щоб допомогти собі побудувати звички, корисні для себе. А також, якщо наважитесь, для ваших клієнтів.
“На гачку” навіть є в перекладі українською. Звісно, вже вийшла з друку, але на OLX можна знайти.
09.03.2025
Miniflux та його API
Я вже писав про Miniflux. Це чудовий агрегатор та читач RSS, та ще й написаний на Go, та ще й з перекладом українською!
Проте я ще не згадував про те, що в Miniflux є купа різних API - а значить, можливість автоматизувати рутинні задачі. Та оскільки це твій власний сервер. ніяких обмежень на використання цього APi немає.
Вчора довелося про це згадати, коли я імпортував OPML з оригінального скрипту та побачив оті стрічки з YouTube без назв. Одна справа — згенерувати кращий OPML, але інша — що робити з невдалими стрічками? Видаляти вручну сотні стрічок мені не хотілося, звісно. На це в нас є API.
Мені понад усе подобається офіційний клієнт на Go. Якось з ним все… по-домашньому. Хоча отут згадують й клієнта для Python, й навіть маніпулювання через консоль браузера. Одним словом, ось мій скрипт для видалення всіх стрічок в категорії.
А насправді можна піти й далі - стягувати зміст постів, спростити впорядкування стрічок, автоматизувати налаштування фільтрів. Приємно мати такий зручний інструмент для керування потоками інформації для себе, бо це важлива справа.
08.03.2025
Підписки з YouTube - до RSS
📺 Я якщо що великий прихильник не тільки RSS, а ще й читати їх раз на тиждень, щоб не витрачати час на вхідні потоки. От як раз нещодавно я повернувся на цей графік, бо він має схильність зʼїжджати: спочатку наздоганяєш щось що не встиг, а далі не встигнеш озирнутись, як заглядаєш в читач кожні 15 хвилин.
В цій схемі з RSS була одна діра: YouTube. Ніколи не міг знайти зручного способу передивлятися підписки. (Зручний — це коли я знаю, які нові відео зʼявилися, та можу їх відмітити як прочитані, щоб більше не бачити.)
В YouTube є RSS для кожного каналу, на щастя. Але немає RSS для всіх моїх підписок. Щоб не переносити вручну, знайшов оце скрипт, який генерує зі сторінки каналів файл OPML. Все б гарно, але в тому OPML є тільки адреси RSS, а назв не було.
Почав доробляти… та роздивився, що скрипт генерує з даних JSON, а потім парсить його регулярними виразами. Такого я ще не бачив! При тому, що дані для сторінки сидять в глобальній змінній (теж велика вдача.) Єдине, що там в змінній наче дані вже підготовані для компонент, тому знайти в структурі потрібні дані дійсно непросто, а скрипт з жорстко заданими шляхами буде надто крихким.
Отже, переробив скрипт. Мій варіант ходить по структурі даних та шукає обʼєкти, схожі на канали. Це працює, а головне — з обʼєкта каналу вже нескладно дістати його імʼя та адресу. А генерацію OPML залишив так саме як і було — через додавання рядків.
Ще мені в цьому скрипті сподобалося автоматичне направлення файлу на завантаження. В моїх попередніх рішеннях я просто виводив зміст в консоль для копіювання вручну, а тут значно зручніше.
Осьо мій скрипт. До речі, раніше я викладав схожі скрипти на GitHub Gist, але цього разу думаю — а чому не можу просто до себе на сайт? Тільки голий .js
на сайті не дуже зручно, а от як стаття разом зі стислою документацією — чудово.
07.03.2025
Ризики кореневих сертифікатів
Що найгірше може статися, якщо хтось підсуне вам власний кореневий сертифікат? Все залежить від того, хто саме.
Для споживача найважливіше, що власник кореневого сертифіката зможе уособити будь-який сервер для сеансу HTTPS. (Як я колись писав, без HTTPS взагалі немає проблем уособлювати чужі сервери.) Для того йому потрібно згенерувати сертифікат для домену та підписати приватним ключем від кореневого сертифіката. Цю операцію можна робити буквально в реальному часі — колись для одного проєкту я з цим стикався.
Але, власне, уособлювати цікаво тільки важливі сайти (наприклад, банк чи пошту). А для того мало сертифікату — потрібно ще й направити користувача на свій сервер. Цього можна досягнути двома шляхами: або якщо підмінити DNS, або за наявності проксі-сервера чи VPN. Ну, є ще й третій шлях: бути частиною інтернет-інфраструктури. Тому головне, щоб сертифікати не встановлював провайдер.
До речі, не всяким сертифікатом можна підписувати інші: для того є спеціальна відмітка. Тому, наприклад, якщо деякий ресурс має сертифікат, але він не підписаний жодним з ваших кореневих, то можна додати його на власну машину та це не надасть власникам ресурсу можливість уособлювати інші сайти.
Це поширена практика для внутрішніх ресурсів, не доступних для публіки, бо для них технічно неможливо отримати підписаний сертифікат, але мати TLS все ж хочеться.
06.03.2025
Як це мене вкусить в майбутньому?
Саме це питання я задаю собі найчастіше під час планування рішень, написання та перегляду коду. Красота, стиль, структура — це все гарно. Але… яким боком воно вилізе потім?
Чи вносимо ми зміни в дані, які потім буде важко відкотити чи доведеться підтримувати вічно? Чи додаємо побічний ефект там, де його не передбачували? Чи використовуємо сумнівні обходи? Або просто незрозуміле імʼя? Чи не вистачає коментарів?
99% написання коду — це його дописування. Тому що б не писав, доведеться мати з ним справу пізніше. В таких обставинах мушу ставитись до коду як до ризику.
Я завжди намагаюся уявити, як це рішення побачить незнайома людина. Без того, що я знаю зараз, а тільки по інформації з самого коду. Бо зовсім небагато часу мине та я сам позабуваю нюанси. Тримати знання про код в голові — страшне. Я вже мовчу, що це ніяк не допомагає решті команди.
Можна вирішити, що це надто песимістичний підхід. Втім зустрічаються й позитивні зміни — те, що запобігає майбутнім проблемам. Такого б більше!