Стендап Сьогодні

Що я зробив, що я хочу зробити, і що це все значить.
Повсякденні здобутки в форматі стендапу.
Детальніше в статті

Підписатись на RSS
📢 Канал в Telegram @stendap_sogodni
🦣 @stendap_sogodni@shevtsov.me в Федиверсі

16.06.2025

Проєкція GPX на світлину

⛰️ Дивився сьогодні на світлину схилу гори, на якій було видно стежку. Та це навіяло ідею: а що, якщо, маючи GPX-трек маршруту, показувати його на світлині? Тут є моменти, які очевидно майже нереально зробити автоматично (як-от не показувати те, що сховане за ландшафтом), але в цілому має бути здійсненно.

(Пошукові системи мене не розуміють, тож уточню: йдеться не про світлину згори вниз, тобто мапу, а про звичайну пейзажну світлину. На мапу накласти трек проблем не складає, та інструментів для цього вистачає.)

Переглянув, яку інформацію зберігає айфон у світлині. Виходить, що дуже багато! (Навіть є uptime телефону, але то нам не треба.) GPS-координати та висота — звісно, що є. Також є GPSImgDirection, тобто азимут фільмування. І нарешті, AccelerationVector - показники акселерометра, тобто кути нахилу телефону. Та навіть FOV - кут огляду камери (він різний у різних обʼєктивів). Одним словом, у нас є всі дані для реконструкції матриці камери!

Далі що. Завантажуємо трек (до речі, GPX - це XML.) Переводимо його у пласку систему координат XYZ. Тут головний нюанс — що градус довготи змінює довжину залежно від широти, а інші нюанси є в моїй статті про координати. Та, до речі, поки припустив, що викривлення земної поверхні не важливе, хоча й це можна врахувати.

Тепер наче залишається суто класична задача 3D-графіки: перспективна проєкція. Для того має сенс взяти готову бібліотеку, як-от Three.js. Там як раз можна збудувати камеру з кутів повороту, кута огляду, співвідношення сторін тощо. І далі однією операцією project() точки переходять в систему координат зображення.

А потім з тих координат малюємо поверх світлини ламану — наприклад, бібліотекою sharp або той же ж Three.js. То й все! Маршрут побудований.

От тільки поки я до кінця не налагодив всю цю математику, тому проміжний результат — ось, а далі буде.


15.06.2025

Метапрограмування та особливий стиль Clojure

В Clojure, абсолютно впевнено, код є даними. Насамперед для цього потрібно, щоб код не відрізнявся від даних на вигляд: саме для цього в ліспах такий дивакуватий синтаксис, де код не має особливих відзнак. Будь-яка конструкція з дужок може бути як “нормальним кодом”, так і вхідними даними для макроса, який інтерпретує цю конструкцію аж будь-яким чином.

Є макроси ситуативні: defroutes чи html5 тощо. Вони нагадують схожі конструкції в Ruby чи JavaScript, бо принаймні не ставлять задачі вигадати нові мовні конструкції. Але то тільки верхівка макросів на Clojure… Бо справжній айсберг то макроси, що спрощують деяку сталу мовну конструкцію. Таких повно в самій стандартній бібліотеці. Так званих спеціальних форм, тобто дійсно “аксіоматичного” коду, який напряму розуміється компілятором, лише з десяток. А всі інші — як cond, аналог switch-case, вже реалізовані як макроси.

Але звісно, стандартною бібліотекою все тільки починається. Бо все можна переробити під себе, або принаймні знайти вже перероблене.

Як приклад: бібліотека swiss-arrows. В Clojure вже є доволі проста протяжна форма (-> x f g), що еквівалентно (g (f x)). (Це лише один спосіб спростити вкладені виклики.) Але ця бібліотека додає макроси для набагато складніших ситуацій, як-от діамантова вудка (sic) -<><, що виконує одну форму та поширює результат до списку інших, можливо й в паралелі: (-<>< (+ 1 2) [<> 3] [4 <>]).

Не знаючи макроса, під час просто неможливо зрозуміти, що він робить. (Бо ота вудка нічим не видає своєї дії.) Такі можливості створюють екосистему, де від проєкту до проєкту код може відрізнятися радикально. Це й гарно і погано водночас.

Гарно, бо можна ліпити код під себе, та майже нічого не стоятиме поперек шляху. Та повір, знаходити (чи створювати) та використовувати зручні макроси — на Clojure частина повсякденної інженерії, та без неї виходитиме багатослівно та теж незрозуміло.

Погано, бо немає ніякого стандарту. Ідіоми Clojure містять більш загальні твердження, як-от “пиши функціональний код” та “використовуй функції вищого порядку.” Коли шукаєш приклади чи читаєш код бібліотек, часто здається, що вони написані різними мовами (та певною мірою, так і є!)

Чимсь все це нагадує бібліотеку Lodash, бо там теж можна писати фільтри та інші параметри різними спрощеними шляхами: _.map(xs, ["foo" bar]). Але я б радив спробувати Clojure, щоб на собі відчути цю силу вигадувати код таким, яким це зручно для твого проєкту.


14.06.2025

Як я робив проєкт аналізу автобусного руху

Років з 10 чи трохи більше тому в Дніпрі зʼявилася перша система відстеження руху автобусів - transit.in.ua (давно припинив існування, зараз там якийсь спам.) Вона показувала на карті координати автобусів… але більше не вміла нічого. Зокрема, не було там прогнозу прибуття автобуса.

Я якийсь час намагався цей прогноз запрограмувати. Виявилося, не так це легко! Втім, то був один з моїх експериментів на Clojure, та я хоч в цьому плані отримав користь.

Головна проблема ось в чому. Координати автобуса це є точка. Маршрут це є ламана. Точку потрібно перекласти в систему координат маршруту. Тобто отримати значення від 0 до 1, що показує пересування автобуса за маршрутом.

І тут далі… координати майже ніколи з ламаною не збігаються, бо такий реальний світ. Ба більше, за координатою не зрозуміло, в якому напрямку рухається автобус, бо через похибку її можна віднести як до прямого, так і до зворотного маршруту. (Зазвичай маршрути малюються як кільце, а не тільки лінія з кінця в кінець.)

Отже, доводилося також стежити за рухом точки ламаною та дивитися, чи буде він “у відʼємному напрямку”; тоді ми помилилися (“не вгадали”) з місцем — та треба брати місце на зворотному відрізку. Як можна уявити, коли в системі зʼявляється час, то вся архітектура ускладнюється.

А особливо допікав шум — автобуси, що стоять в тупику, ті, що поїхали в депо, або просто неправильно налаштували датчик. Я, напевно, тоді ще не зрозумів, що краще почати з часткового рішення, ніж намагатися покрити всі варіанти, та зрештою так і не розвʼязав цю задачу. А тепер, бачите, різні компанії вже розвʼязали.

Поставив питання — а де зараз взяти таку інформацію? Бо нині хто хочеш показує автобуси, включаючи Google Maps - але при тому самі трекери встановлює хтось один (влада?) Отже, повинне бути “джерело істини”. Та воно є! Відкрив для себе портал data.gov.ua, на якому, проміж іншим, є й API транспорту Дніпра, та й багатьох інших міст. Дуже цікаво!


13.06.2025

Чому ніхто не зробить нормальний застосунок для навігації?

Нещодавно приїхав за навігатором на турбазу в лісі… але був нюанс. Він обрав дорогу, хоч й максимально наближену до мого призначення, але з іншого боку річки. Через ці 20 метрів відстані довелося обʼїжджати 20 км лісу. Серйозно!

Я дуже люблю карти, але не можу любити поточний виводок навігаторів: Google, Waze, Apple… та всіляке дрібне, езотеричне та з різним рівнем доробки та підтримки. Наприклад, я люблю OpenStreetMaps всім серцем, але без врахування заторів в навігації великим містом нема сенсу.

Не люблю, що навігатори майже не беруть до відома особисті вподобання користувача. Є невеличкі покращення, але вони всі приховані за непрозорим інтерфейсом. Який все ж не йде далі ніж “з точки А в точку B”… можливо “через точку C”. Я все збираюся зробити свій навігатор для серйозних користувачів, але… ну ви знаєте, як воно буває з цими ідеями.

Для початку, просто хотілося б запланувати маршрут заздалегідь та знати, що він більше не зміниться. Ті застосунки, що я знаю, зберігають тільки точки маршруту, але сам маршрут може змінюватися. Інколи це гарно (коли затори), а в інших випадках ти ретельно перевірив маршрут (з міста у незнайоме місто), а навігатор несподівано веде зовсім іншою дорогою. (Та, звісно, хотілося б робити це в комфорті, з компʼютера, хоч це може й розкіш.)

Навздогін — хотілося б частину маршруту перемалювати вручну. Таке постійно доводиться робити, якщо десь на трасі відомі проблеми. Це така проста операція, але жодний навігатор такого не дозволяє.

Або взагалі, щоб деякі ділянки маршрутів можна було позначити, як улюблені. Як критичний випадок: заїзд у двори — завжди слабке місце в навігації. Але я чудово знаю, як саме я хочу заїжджати у свій двір. От можна було позначити це заздалегідь та уникати інших маршрутів. Зокрема в моєму дворі Waze відмовляється пропускати мене “під цеглину”, хоча це повний абсурд.

Чи вказати навпаки, ділянки, які я ніяк не хочу відвідувати. Може, бо там дорога погана, може там перекрито, чи просто не люблю. Така функція є в Garmin, але ж де зараз ті навігатори Garmin порівняно з застосунком на смартфон та CarPlay.

Можна сказати, що якщо ти знаєш дорогу, то навіщо тобі навігатор? Так, але не так. Часто ти знаєш тільки частину дороги. Або знаєш всю, але хочеш мати оцінку часу. Чи помітити та обʼїхати значні затори. Але, навігатори продовжують робити в найзагальнішому режимі (хоч і збирають з нас купу особистої інформації!)


12.06.2025

Capybara + Playwright: мрії здійснюються?

Не встиг я написати, що втомився від Capybara, як натрапив на незнайому мені досі бібліотеку capybara-playwright-driver. Так, це саме те, як що воно звучить: драйвер для Capybara через потужності Playwright - одного з передових інструментів інтеграційного тестування.

(До речі: знайшов я цю бібліотеку з іншого проєкту - capybara-lockstep - він стабілізує тести через неявне примусове очікування кожної операції. Але з нею досвіду не дуже маю.)

Отже, Capybara із Playwright, за досвідом, працює непогано — порівняно з Selenium, значно більше можливостей та менше місць, де доводиться робити криві обходи. Наприклад: є метод route для легкої підміни запитів з браузера. Дуже корисно для всяких сторонніх інтеграцій. Або Download - для перевірки завантажень. Це взагалі ексклюзив!

Також, оскільки цей драйвер керує звичайним сеансом Playwright, ми можемо трасувати тести, тобто зберігати повний хід виконання, включаючи всі запити до мережі, всю консоль, навіть стан DOM в кожний момент тесту! Це астрономічно більше інформації, ніж дає Capybara.

Втім, трасування виказує й недолік цього драйверу. Він використовує Playwright на простому, низькому рівні. Наприклад, в Playwright є власне очікування операцій — та дуже гарне. Але щоб зберегти поведінку Capybara, драйвер не користується ним, а тільки виконує команду перевірки багато разів.

Тут же ж є й альтернатива: пакет plsywright-ruby-client, на якому збудований драйвер. Він вже дає безпосередній доступ до дій та перевірок від Playwright. Тобто теоретично можна викинути капібару та писати тести прямо на Playwright, але з Ruby! Та зі збереженням повними можливостями підготовки стану та перевірки результатів на бекенді.

Поки я в захваті від цього нового підходу, та сподіваюся, він закриє частину недоліків Capybara. Одне тільки трасування чого варте.


11.06.2025

Відчуття від GTD

(Поки закінчую писати про GTD. Я наче пройшовся по основах, а також зрозумів, що краще писати, коли є натхнення з конкретної теми. Не кидаю надій зробити колись красивий посібник українською.)

Хотілося замість всього цього сухого поговорити про відчуття. Що я відчуваю без GTD та тоді, коли система працює.

Ось сцена, яка мені знайома як рідна. В ній герой хоче замінити лампочку, але натомість занурюється в яму послідовних задач: закріпити полку з лампами, змастити ящик з інструментом, купити мастило, і фінал — полагодити машину, на що в нього йде весь день. В серіалі це виглядає комічно — хіба не можна було закінчити першу справу, а потім братися за наступну? Але саме так я відчуваю себе без системи, в яку можна записати вхідні — я хапаюся за крайню справу, що здається важливою, бо без системи єдиний шанс зробити справу — це натрапити на неї та вхопитися негайно. Я називаю це “режим хомʼячка”.

Тобто звісно, якби всього в житті було пʼять задач, то нескладно розставити їх за порядком. А коли їх сто?

Напевно, все залежить від характеру (та від нейродивергенції.) Моя голова є нескінченним фонтаном ідей буквально для всього, тому в мене завжди більше незробленого, ніж часу. Частина цих ідей — чудові та розвʼязують справжні проблеми. Але інші — нереальні або тільки створюють додаткові проєкти та додаткове навантаження.

Без системи я заходжу на кухню та бачу мільйон задач — від законних “прибрати посуд” до наче важливих, але не зараз “повісити гачки для каструль” до зовсім казкових “зробити вертикальну грядку для зелені”. Виходжу з кухні та бачу ще мільйон задач… Річ не у тім, що всі їх треба зробити, та навіть не в тому, що треба виділити пріоритетні. Система GTD дозволяє мені зібрати всі задачі в єдину купу, та в спокійних обставинах приділити їм належну увагу.

З системою я оглядаю кухню та бачу — все як вчора, про все це я вже подумав. Можна спокійно прибрати посуд. О, і ще оце посилка нова лежить — запишу, щоб з нею розібратися. (Нарешті проєкт з гачками розблокований!)

Тобто, GTD існує (всупереч назві?) не заради того, щоб зробити всі справи, а щоб можна було спокійно взаємодіяти з життям та вже на ґрунті цього спокою будувати все інше. Та щоб я не захотів будувати - GTD допомагає рухатися до мети. Як кажуть, в GTD будь-що стає проєктом — значить, будь-що можна зробити - задачі, ідеї, мрії, турботи, тривоги. Ось заради цього спокою та впевненості я завжди повертаюся до GTD, скільки б не кидав.


10.06.2025

Звички GTD: огляд

Всю систему GTD можна розділити на дві частини:

“Активна” частина — це списки наступних дій та вхідні. Вона потребує щоденного перегляду. Дії ми просто робимо (сподіваюся), а вхідні обробляються за схемою. Це все, що потрібно робити постійно, щоб залишатися з робочою системою. (Ну й, звісно, користуватися календарем.)

Решту системи ми переглядаємо щотижня. Це називається, очікувано, тижневий огляд.

По-перше, під час тижневого огляду переглядаються всі проєкти; якщо є такі, що не мають наступної дії, чи застрягли без прогресу, то виправляються. Часто розумієш, що проєкт чи дія поставлені невірно та переформулюєш. Або — видаляєш / пересуваєш до “мабуть/колись”! Бо зайвих проєктів повинно не бути.

По-друге, ми додаємо нові проєкти. Вони можуть братися з календаря нагадувань, з “мабуть/колись”, або просто з навколишніх обставин. В офіційних посібниках для того є довжелезний перелік питань-тригерів, але можна зібрати й власний — з усіх сфер життя, де можуть виникнути проєкти.

Чому тижневий? Можна було б й рідше. Але краще стежити за обсягом системи та не брати більше справ, ніж можна переглянути за годину кожного тижня.

Що я не роблю щотижня, так це перегляд всіх “мабуть/колись” - їх просто надто багато. Натомість переглядаю тільки по одній категорії. Гадаю, це в моїй системі слабке місце, але з тим “мабуть/колись” - найменш термінова категорія, та зазвичай готова чекати.

Без регулярного огляду система розвалюється. Але, як бачите, саме завдяки систематизації нам вже не потрібно робити якийсь епічний огляд всього життя в абстракції, а достатньо переглянути кілька списків. Та, дуже приємно щотижня знати, що ти все переглянув та задачам більше немає де приховатися.


09.06.2025

GTD: систематизація

Нарешті я трохи підготований перелічити, з чого складається система GTD, а також де ці частини розташовані в мене. За моїм досвідом, немає ідеального застосунку для GTD просто через різноманіття потреб та функцій. І це нормально.

Серце системи — Списки наступних дій за контекстами та список проєктів — про ці я детально розповідав в останні дні. Я на те зробив собі застосунок CoreGTD, яким досі (вже майже рік!) користуюся.

Список очікування — сюди пишемо все, чого пасивно чекаємо, щоб 1) не забути та 2) відстежувати, що проєкт заблокований. В мене це просто ще один контекст, який я переглядаю щодня.

Календар — в ньому залишаються всі справи з конкретним часом. Календар — це святе. В мене календар в Apple Calendar.

Календар нагадувань Йдеться про нагадування на далекі дати. Наприклад, “купити подарунки на Різдво”, “фестиваль”, чи “перевірити систему опалення на зиму”. Англійською називається tickler file - я завжди думав що це вигадка GTD, але насправді така картотека існує ще з перших нотаріусів. В мене такі в Apple Reminders, де зручно налаштувати повторення.

Мабуть/колись — це величезне сховище ідей та планів на майбутнє. В мене воно все на канвах в Obsidian, за посиланням детально написано.

Плани проєктів — бо планування точно не закінчується на меті та наступній дії! План — це не тільки перелік дій, а ще й нотатки, довідки, ідеї, ілюстрації — все це обовʼязково варто збирати до купи. Це теж я тримаю в Obsidian, по канві на проєкт (якщо потрібно.)

База знань — без неї теж голову не спустошити, хоч до задач база знань не має відношення (майже за означенням). Тут можна залучити будь-яку систему, яка подобається (або ніякої.) І тут в мене теж Obsidian.

Вхідні — це теж частина GTD, бо повинно бути місце, куди легко записати на ходу. Для мене це передусім Drafts.


08.06.2025

Система GTD: контексти

Давайте головне: хоч GTD пропонує охопити всі сфери твого життя, але 100% немає мети охопити всі діяльності. Немає ніяких просвітлених монахів GTD, які з ранку до ночі роблять все життя по системі.

За моїм досвідом, у дні є трішечки часу, коли ти звернеш увагу на систему GTD. Спочатку — все рутинні справи, календарні події, відпочинок в решті решт. І от, між всім цим, є моменти, коли можна встигнути зробити щось неординарне. GTD нас готує до цих моментів, щоб ми не загубилися та влипли в телефон, а мали чіткий список дій, над яким більше не треба думати — час діяти!

Але з усіх дій ще треба обрати одну. Якщо їх мало, можна просто перебрати. (Або використати FVP чи інший алгоритм.) Втім, зазвичай дій багато — кілька десятків — та це обтяжує. Тому ми розбиваємо список дій на менші списки — за контекстами. Контекст задає обставини, в яких ми хочемо бачити ту чи іншу дію.

(Наприклад: в моїй системі для роботи контекстів немає, бо поточних дій не більше 20, та я дійсно можу взятися за будь-яку - “робота” це вже достатній контекст.)

В книжці про контексти написано якось абстрактно, та вони виходять надуманими: “вдома” чи “місто”, чи “комп”. На мою думку, тобі варто подивитися на своє життя, та на доступні в ньому ситуації та базувати контексти на них.

Коли контексти надумані: “Місто” велике, та ти не буваєш регулярно в усьому “місті”. Більшість поїздок треба планувати заздалегідь — то може краще мати контекст “планування справ”? А “комп” - поганий контекст, бо й так весь день за компом і це ні про що не каже. Може, краще “швидкі справи рано вранці” чи “поки чекаю дитину з тренування”. Або “дослідження”, теж зручно.

А от контекст “дзвінки”, чи в мене - “комунікація” - дуже мені подобається: я до нього звертаюся в понеділок зранку, та послідовно закриваю всі стресові дії. Та це інший підхід до контекстів: збирати схожі дії в пачку. Тільки все одно треба розуміти, коли ти ними займешся; контекст, в якому ти не буваєш — поганий контекст.


07.06.2025

Система GTD: проєкти

Вчора зачепив тему проєктів, але вона варта окремого поста, бо “проєктом” можна називати зовсім різні речі. Ось я вже писав про проєкти.

Зокрема, це зовсім не те що проєкт в керуванні проєктами. Наприклад, в мене проєктами в GTD стають задачі чи епіки з Jira. На мою думку, “проєкт” на цей день надто перевантажене слово, але маємо те що маємо.

Вчора ми розкручували задачі в наступні дії. З одного боку, тепер їх легше почати — та закінчити. З іншого, також мусимо памʼятати, до чого ми хочемо дійти. В GTD проєкт — це результат, до якого спрямовані наступні дії. Тож окрім списку наступних дій, ми ведемо список проєктів. Не просто “задач” незрозумілого рівня, а саме бажаних результатів.

Наприклад: “Зробити пошук в каналі”, “Приготувати карбонару на вечерю”, чи “Підготуватися до відпустки” - це все проєкти.

Список проєктів нам потрібний для контролю. Ми не звертаємося до нього для вибору задачі — на те є список дій. Але ми передивляємося список проєктів, щоб помітити застряглі справи та оцінити навантаження. Дивно, але за GTD цей список достатньо переглядати раз на тиждень. Це, певно, за тих умов, що після виконання дії ми додаємо наступну, бо інакше робитимемо по одній дії на проєкт щотижня (це якщо встигнеш!)

Проєкт — це великий чи малий результат? Я гадаю, в ідеалі від тижня до місяця роботи. Тиждень — бо це інтервал огляду; менші проєкти змушуватимуть звертатися до планування частіше. Місяць — бо надто великі проєкти втрачають чіткість та розтягуються. Такі краще розбити на кроки. Для мотивації важливо, щоб ми могли закрити проєкт та рухатися до наступного, а не жувати місяцями один й той самий.

Існує ціла школа правильної постановки цілей, як-от SMART тощо. Це, мабуть, гарно і для проєктів, але система працює і без того, завдяки оглядам.

Є ще питання надто маленьких проєктів, коли здається, що одна дія — це й все. Тут офіційних порад не бачив, але я схиляюся що проєкт краще знайти навіть “на одну дію”. Ніякі дії не існують в вакуумі. Тож варто визначити, звідки ця “одна” дія взялася, та для чого. Також краще мати віху для контролю, що справа зроблена, бо після виконання “однієї дії” часто зʼявляються продовження.