Math and Code
2.03K subscribers
1 photo
101 links
• По всем вопросам: @lesha_privet

• Поддержать канал голосом: https://t.me/boost?c=2187172722

• Ссылка для друга: https://t.me/+VZi8XKZsg7s3NmNi
Download Telegram
Как я загнал себя в переутомление и что из этого вышло.


Всем привет! В последнюю неделю словил сильное переутомление 🎮. Решил разобрать это по полочкам — может, кто-то узнает себя 🫡.


С чего всё началось?

После отпуска чувствовал, что у меня энергии на двоих. Каждый день состоял из спорта, работы, проектов до глубокой ночи. Первая неделя — огонь, силы будто бесконечные 😎. На самом деле я просто тратил их без меры 😡.


Первые звоночки, которые не были замечены мной.

• Сильная зависимость от кофеина;
Тяга к фастфуду в формате «вдруг захотелось»;
Игнорирование полноценного сна.


Итог этих резко развившихся и регулярных действий — простуда 😱.

На самом деле для меня это редкость, особенно летом. Обычно я болею глубокой осенью, и то очень редко 🤔.


Вторая ошибка, которую я допустил.

Простуда прошла, но я не сделал выводы, которые делаю сейчас. Из-за этого через пару дней спина и шея сказали «привет» 😎. Причина очевидна — слишком много времени в сидячем положении и не всегда с правильной осанкой 🙃.


Что пришлось менять, чтобы восстановиться?

Когда понял, что я просто физически себя измотал, пришлось отказаться от:

• Силовых тренировок;
• Бани;
• Читмилов;
• Кофеина.


Также пришлось сделать себе стоячее рабочее место, благо удаленная работа позволяет ⌨️. В будущем точно куплю себе подъёмный стол для компьютера 😎.

Взамен активностям, от которых на время отказался, добавил:

• Плотную растяжку для спины, шеи и всего организма;
• Турник;
• Активную ходьбу.


В ежедневном рационе оставил только домашнюю еду, а в качестве напитка воду 😐. Приложил максимальные усилия, чтобы спать стабильно по 8 часов в день — оказывается, это одно из самых сложных 🥵.


Результат, который не заставил себя ждать.

Два дня такого «детокса» — и организм реально сказал «спасибо». Чувствую, как возвращаюсь в привычный ритм 👍.


Вывод: рост и развитие требуют ресурса. Если расходуешь его без мерырасплачиваешься здоровьем 🫣.


А вы сталкивались с переутомлением? Как выбирались? Уверен, что можно подчеркнуть что-то полезное из ваших историй 😍.


#лайф 🤝🏻
Please open Telegram to view this post
VIEW IN TELEGRAM
1291613431
Всем привет 🌎! Ранее я уже писал, что занимаюсь разработкой своего приложения. Сегодня расскажу, как собрал простой прототип интерфейса с «in-memory» хранением данных, т.е. без серверов и БД 🪨.


Что означает «in-memory» применительно к данным?

Если говорить кратко, то это способ держать данные в оперативной памяти. Он очень быстрый и удобный для обработки данных прямо в прототипе приложения 🚶. Единственная проблема в том, что после перезапуска все данные исчезают, поэтому для серьёзных приложений добавляют сохранение информации в БД или на сервере 🧠.


Опишем «in-memory» простыми словами.

Для начала представьте три места, где можно хранить информацию:

Один листок бумаги на столе ✍️.
Он всегда под рукой, на него можно быстро что-то записать, но место ограничено. Если вы отойдёте от стола, листок уберут — восстановить его уже не получится.


Журналы в шкафу рядом со столом 📂.
Чтобы положить или взять листки, нужно дойти до шкафа и открыть определенный журнал, а это занимает время. Зато данные, которые лежат в шкафу, не исчезают.


Большой склад в соседнем здании 🔒.
Там поместится хоть несколько забитых журналами шкафов. За хранение отвечает управляющая складом компания, поэтому оно надёжное. Но идти до склада ещё дольше. Плюс за хранение на чужом складе придётся платить каждый месяц.


Соответствия такие:
• Один листок бумаги на столе — это «in-memory» хранение данных 👩‍💻.

Журналы в шкафу рядом со столом — хранение данных на сервере или в БД 😎.

Большой склад в соседнем здании — хранение данных в облаке 🤑.


В итоге «in-memory» — это тот самый одиночный лист бумаги на столе 🤬. Данные живут в памяти приложения, всё работает очень быстро, но при перезапуске или обновлении приложения данные сбрасываются 👊.


Теперь немного про мой прототип приложения, который работает с «элементами» и «событиями».

Я сделал интерфейсную часть и для быстрого тестирования выбрал «in-memory»-модель, т.е. все данные хранятся в памяти одной вкладки, в которой открыт интерфейс приложения ⌨️.


Что храню?

• Список элементов items.
У каждого элемента в списке есть: ID, наименование, флаг "True/False", счетчик, время создания, время обновления.


• Журнал событий events.
Каждая запись журнала событий фиксирует, что случилось с элементом и когда.



Почему это удобно для прототипа моего приложения?

1. Очень быстро: без сети и «сложных» настроек 🧐.

2. Быстрые итерации: изменил → проверил → переделал. Идеально, когда оттачиваешь интерфейс 😤.

3. Сейчас этап тестирования интерфейса: добавить тестовые записи прямо в код проще, чем разворачивать полноценную БД .


Что будет дальше?

Как только
закончу интерфейсную часть, так сразу разверну БД для хранения данных, потому что их потеря при обновлении приложения станет критичной 🥵. К тому же корректное хранение данных в БД необходимо, если приложением начинают пользоваться несколько пользователей 🤯.


P.S. Про структуру приложения написал обезличенно, так как до MVP-версии с БД и вариантом в формате Telegram Web App ещё далеко. Можете попробовать угадать в комментариях, что за приложение, или просто накидать реакций — они всегда приветствуются 😐.


#лайф 🤝🏻
Please open Telegram to view this post
VIEW IN TELEGRAM
12313105
Сегодня задумался над тем, как оформляю посты.

Потратил не мало времени на то, чтобы перечитать их с самого начала, а также на доработки оформления, списков и эмодзи.


Обращаюсь к вам, какой вариант оформления вам ближе всего и нужно ли оно вообще?

1. Структурированный текст.

2. Структурированный текст с выделением слов жирным шрифтом.

3. Структурированный текст, выделение жирным, эмодзи 👩‍💻.


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

🤔 — я за вариант №1.

⌨️ — я за вариант №2.

☺️ — я за вариант №3.


#лайф 🤝🏻
Please open Telegram to view this post
VIEW IN TELEGRAM
161491722
Сегодня решил вспомнить про свойство Парето или принцип 80/20, а также увязать его с перфекционизмом. Поехали 🤯!

Основной тезис:
При выполнении практически любой задачи ее ядро прорабатывается в первую очередь, и мы получаем основную часть пользы, которую приносит задача. Далее каждый следующий час, проведенный над задачей, — приносит меньше пользы, но стоит дороже 🤑.


Вытекающий вопрос:
Каким образом не уехать в бесполезный перфекционизм, который очень сильно увеличивает стоимость задачи, но не изменяет ее ценность 🤔?



Давайте посмотрим на прикладную суть принципа Парето.

Это скорее не конкретные цифры, а определенный паттерн, например: 90/10, 80/20, 70/30 и так далее 💀. Тут самое главное, что у любой задачи есть ядро, дающее основную ценность, и хвост, в рамках которого задача доводится до идеала или конца 🥸. Рассмотрим примеры:

• Пишем приложение 👩‍💻.
- Ядро: работающая MVP-версия.
- Хвост: темная тема, аналитика событий, офлайн-версия.


• Решаем 5 схожих задач по физике 😦.
- Ядро: освоить основные формулы и понять логику решения таких задач.
- Хвост: альтернативные методы решения, расчет погрешностей.


• Пишем пост ⌨️.
- Ядро: понятно написанный текст.
- Хвост: форматирование текста и эмодзи.



Где включается нездоровый перфекционизм и при чем тут хвост задачи?

Этот перфекционизм включается, когда вы находитесь в том самом хвосте задачи, а ваш фокус смещен со «сделать полезно и хорошо» на «сделать идеально настолько, насколько это возможно». С каждым часом правки всё мельче, аргументы всё эстетичнее, а итог почти не меняется 😕. Растут только затраты времени, энергии и нервов 😐.


Что с этим делать?

Давайте построим общую логику 👍. Если думать о задаче как об обмене пользы за час на цену этого часа, получается следующее:

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

• По мере продвижения польза за час падает, мы переходим в область хвоста задачи 👷‍♂️.

• Нам нужно выработать стоп-правило для работы над хвостом задачи. В общих словах оно следующее: если последующий час дает меньше пользы, чем стоит, — останавливаемся или меняем стратегию закрытия хвоста 🔍.


Какие нюансы нужно учитывать?

Все было бы классно, если бы не было нюансов, правда 😎? Но эти нюансы есть, и они существенные. Предлагаю рассмотреть их подробнее, так как иногда из-за них хвост задачи становится обязательным:

Работа с навыком 🥵.
Полировка задач, которые касаются какого-то навыка, который ты развиваешь — это важно. Тут экономить на хвосте задачи не нужно, так как выгода от проработки на 100% очевидна — навык прививается, и ты становишься более опытным и ценным.


Пороговые задачи 🥵.
Итог таких задач: «все или ничего», «работает или не работает». К таким задачам можно подходить оптимально, например: довели ее до порога, а уже потом включаем принцип 80/20.


Задачи, связанные с надежностью и риском 😐.
Когда задача касается безопасности системы или корректности данных: цена мелких ошибок, которые полируются в хвосте задачи, — может быть очень большой. Во всех таких случаях лучше потратить больше времени на решение.


Задачи, связанные с личным вкусом и эстетикой 🚶.
В таких задачах порогом является то, как итог этой задачи видит исполнитель. Главное не поднимать порог бесконечно, а после его преодоления включать принцип 80/20. На мой взгляд, это идеальный вариант для таких задач.


Задачи, связанные с написанием кода 🖥.
Когда вы пишете код, который потом будет использоваться кем-то другим, — сэкономленные вами 30 минут могут превратиться в несколько часов или дней работы для ваших коллег.



Итого — завожу небольшой чек-лист, который поможет определиться, что делать:

🤔 Ядро задачи закрыто?

🤔 Что заметно улучшится через час работы над задачей?

🤔 Какая метрика сейчас главная?

🤔 Есть ли более простой способ доработки?


Если ясных ответов нет — скорее всего, ты кормишь перфекционизм, а не увеличиваешь результат 🧠.


P.S. Как будто логику, которую описал, можно свести к обычной задаче оптимизации. Если хотите накидайте реакций, а я сделаю это в следующем посте 🥱!


#статья 📚
Please open Telegram to view this post
VIEW IN TELEGRAM
3216134
Всем привет! Последний день лета — самое время для лёгкого лайф-поста 👍.

Странно осознавать, что 1 сентября больше не про учёбу и трёхмесячных каникул уже нет, но чувство «конца лета» всё равно то самое, школьное 😦.

Эти выходные выдались неожиданно тёплыми — идеально, чтобы поностальгировать по июльской жаре, которая длилась совсем недолго.


Заодно словил «архитектурную яму» в своём приложении ⚙️.

Вчера вообще ничего не получалось: любые доработки — мимо. Помог вот такой набор действий:

1. Отдых от любой деятельности на несколько часов — всё-таки такой подход помогает мне разгрузить голову и все переосмыслить мощно и быстро 😎.

2. Смена обстановки — достаточно было просто выйти на улицу 🚶.

3. Встреча с друзьями и живое общение 🖥.

4. Почти написал пост с задачей оптимизации — да-да, он почти готов, я не забыл про него 🖨.


Ну и добил день качественным 8-часовым сном.


Сегодня проблему удалось закрыть. Впереди ещё большой тест — посмотрим, что покажет. В целом я доволен 😁.

Вечером снова сяду за приложение, а пока — уехал на водоём и символично закрываю купальный сезон. Хотя, может, в сентябре ещё получится сделать пару заплывов 🤔.

А вы как проводите эти выходные? Напишите в чат, с кайфом почитаю. Ну а если хотите остаться в тени — можно просто накидать реакций, их мало не бывает 💡.


P.S. Фотокарточку с водоема прилагаю.


#лайф 🤝🏻
Please open Telegram to view this post
VIEW IN TELEGRAM
2713104
Всем привет уже по-классике! Возвращаюсь к вам с задачей оптимизации, которую обещал рассмотреть в прошлых постах 🔍.


Кратко о том, что буду делать:

Моделирую задачу так, что польза B(x) — растёт, но с насыщением 🥸.

Цена часа C(x) будет линейной 👍.

Цель задачи в том, чтобы максимизировать чистую пользу N(x). К слову, N(x) = B(x) – C(x) 🥵.

Останавливаемся, когда прирост пользы за следующий час сравнялся с ценой следующего часа. Формально: B'(x) ⩽ C'(x), где B'(x) = C'(x) — это "порог" остановки 🤯.



Теперь углубимся в задачу посильнее и построим базовую математическую модель для нашего случая.

• x ⩾ 0 — это затраченные усилия. Будем измерять их в часах 🚶.

• B(x) = Bₘₐₓ · (1 – e⁻ᵅˣ), α > 0 — это то, как работает польза. На старте она быстро растёт, а затем из-за насыщения рост утихает 👩‍💻.

• С(x) = c · x, c > 0 — это стоимость часа 🤑.

• N(x) = B(x) – C(x) — это чистая польза, которую мы получаем 🥇.



Дальше найдем максимум чистой пользы N(x). Сделаю это по шагам, чтобы ничего не упустить:

• Так как B(x) и C(x) — гладкие (дифференцируемые) функции, справедливо следующее: N'(x) = B'(x) – C'(x) ☺️.

• Теперь проанализируем N'(x) = B'(x) – C'(x). По сути, B'(x) — это сколько пользы принесет следующий час, а С'(x) — это сколько следующий час будет стоить. Если B'(x) > C'(x) — выгодно делать задачу дальше, так как прибавка чистой пользы за следующий час положительная. Если B'(x) < C'(x) — прибавка чистой пользы за следующий час будет отрицательной, а это уже плохо и нас не устраивает. В итоге, приходим к тому, что в момент B'(x) = C'(x) накопления чистой пользы будут максимальными 🪨.

• Проверим "кандидата на максимум" с прошлого шага, чтобы удостовериться в том, что он глобальный, а не локальный. Видим, что B''(x) < 0, C''(x) = 0. Отсюда следует, что N''(x) < 0 ⇒ "кандидат на максимум" — глобальный, а это нам и нужно 😗.

• Теперь давайте рассмотрим уравнение остановки B'(x) = C'(x), ну и найдем точку остановки, которую я обозначу как x*. Делаем: B'(x) = C'(x) ⇔ α · Bₘₐₓ · e⁻ᵅˣ = c ⇔ x* = (1/α) · (ln(α · Bₘₐₓ) – ln(c)) 🥱.

• Не забудем отметить, что с учётом изначального ограничения x ⩾ 0 — оптимум усилий, затраченных на задачу, это {0, x*}, то есть: либо 0, либо x*. Тогда если на предыдущем шаге α · Bₘₐₓ ⩽ с, то x* ⩽ 0. В этом случае оптимум усилий на задачу равен 0. Отсюда следует, что углубляться в задачу невыгодно.



Сходу добавим числовой пример, чтобы стало яснее:

• Допустим Bₘₐₓ = 100, α = 0.6, с = 8.

• Тогда x* = (10/6) · (ln(60) – ln(8)) ≈ 3.36 часа.

• B(x*) = 100 · (1 – e^(-0.6 · 3.36)) ≈ 86.68.

• С(x*) = 8 · 3.36 = 26.88.

• N(x*) = 59.8.


Итог: исходя из расчетов, 3.36 часа работы над задачей дают 87% пользы 🥇. Дальше начинается хвост задачи, в котором каждый процент пользы даётся всё большим и большим количеством часов, а общая стоимость задачи всё сильнее и сильнее растёт, хотя из существенного уже мало что меняется 😕.


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

• Если вводим минимальный порог пользы (под этим порогом можно понимать MVP задачи), сначала доходим до этого порога, а уже после его пересечения используем логику с B'(x) ⩽ C'(x) 🤔.

• Если вводим штрафы за баги, которые могут возникнуть из-за игнорирования хвоста, то подключаем логику убывания вероятности бага с увеличением усилий над задачей. Работаем над задачей до тех пор, пока вероятность возникновения багов не снизится до приемлемого уровня, после — останавливаемся🤔.



P.S. Заморочился с оформлением и структурой поста, поэтому так поздно. Это прям наглядный пример траты времени на "хвост" задачи 😁.


☺️ — здраво!
— закинул пост другу.
⌨️ — распишу усложненные задачи оптимизации на бумажке.


#статья 📚
Please open Telegram to view this post
VIEW IN TELEGRAM
3114133
👨‍💻 Мои проекты: боты и приложения


Тут собраны посты про мои проекты: Telegram-боты, Telegram-приложения, инфраструктура и деплой, запуски, ошибки и решения по ходу разработки.

Proof of work + Build in public в одном лице.


📁 Готовые проекты (можно потестить):

📎 Таймтрекер — @TimeTrackerTGBot
📎 Бот для деловой переписки — @TextHelperTGBot


📁 Telegram Web App:

📎 Начал делать Telegram Web App
📎 Прототип интерфейса с in-memory хранением
📎 Мини-апп: темы, свайпы и рефакторинг
📎 Почему притормозил с базой данных
📎 Полировка приложения и мысли к 26 годам
📎 Прогон приложения по краевым кейсам
📎 Веб-разработка, ИИ-фон и чужая витрина


📁 Telegram-бот:

📎 Нюансы разработки бота, которые легко пропустить
📎 Запустил бота — отдаю на живой тест
📎 Честно: бот не взлетел


📁 Инфраструктура и деплой:

📎 Миграция таймтрекера на новый стек
📎 Почему выбрал инфраструктуру на одной VM
📎 Перенос проектов на новую инфраструктуру


#навигация 📝
Please open Telegram to view this post
VIEW IN TELEGRAM
16618144
Сегодня решил разобраться в том, что такое WIP, и как он влияет на выполнение рабочих или личных задач 🤔. Поехали 🚘!

Для начала: WIP (Work in Progress) — это количество задач, которые у исполнителя в работе 🔍.


Основной тезиc:

Чем выше WIP, тем ниже общий прогресс по задачам. Ты тратишь все больше сил на переключения и «въезжания» в контекст, а не на сами задачи 😦.



Посмотрим с точки зрения интуиции:

Когда задач много — тебе приходится постоянно менять контекст: то по одной задаче дернули, то по другой. Знакомая ситуация, правда 🥸?

Подводный камень кроется в том, что каждый прыжок между задачами — это своеобразный «разгон» мозга: вспомнить, где остановился, понять, что еще нужно сделать, подумать какие есть риски и так далее 😐.

Может так получиться, что весь день уйдет на такие «разгоны», и субъективное «я весь день занимался задачами» практически не конвертируется в реальный результат 🥵.


Теперь давайте построим простую модель, чтобы углубиться в проблему 🤯:

• Пусть мы работаем блоками по T минут.

• В каждом блоке у нас в работе k задач (это и есть наш WIP).

• Время входа в контекст i-й задачи — это τᵢ минут.

• Сложность i-й задачи — это cᵢ, cᵢ > 0.

• Усталость, настроение и прочие вещи, которые связаны с исполнителем, обернем в безразмерный коэффициент μ, который может быть разным между блоками, но в рамках одного блока μ = const и μ > 0.

• Также нам нужен перевод сложности задачи в минуты, чтобы не было конфликтов размерности, обозначим его γ.



Дальше опишем сколько времени теряем за блок из T минут, беря в работу k задач 🤑:

Loss(k) = ∑(τᵢ) + μ · γ · ∑(cᵢ).


Зная потери за блок из T минут — мы можем посчитать полезную долю времени за этот блок 🌚:

P(k) = 1 – Loss(k) / T.


Отсюда сразу можем заключить, что:

• P(k) убывает при росте количества задач k 🔍.

• P(k) убывает при росте сложностей задач ∑(cᵢ) 🔍.

• Видно критическую зону, когда Loss(k) ⩾ T. Если такое вдруг происходит, то полезная доля времени P(k) ⩽ 0. Переводя на русский язык — рабочий блок полностью «сгорел» на переключениях между задачами, а прогресса по этим задачам нет 🔍.



Наглядный числовой пример:

Пусть T = 60 минут, μ = 3, γ = 1, k = 4. Так как у нас четыре задачи:

• τ₁ = 2 мин., с₁ = 1 — это для задачи №1 📔.

• τ₂ = 4 мин., с₂ = 4 — это для задачи №2 📔.

• τ₃ = 5 мин., с₃ = 7 — это для задачи №3 📔.

• τ₄ = 7 мин., с₄ = 9 — это для задачи №4 📔.


Тогда:

• P(4) = 1 – (81 / 60) = 1 – 1.35 = –0.35 = –35%. По сути, это случай, когда весь рабочий блок ушел на переключения между задачами 🔥.

• P(3) = 1 – (47 / 60) ≈ 1 – 0.78 = 0.22 = 22%. Выкинули задачу №4, картина улучшилась .

• P(2) = 1 – (21 / 60) = 1 – 0.35 = 0.65 = 65%. Выкинули задачи №3 и №4, картина стала еще лучше 🥇.

• P(1) = 1 – (5 / 60) ≈ 1 – 0.08 = 0.92 = 92%. Оставили только задачу №1 — идеальный вариант 💎.



В итоге, можем свести рассуждения и аналитику к практическим советам:

Идеальный лимит WIP — это 1 или 2 задачи за рабочий блок, чаще всего это оптимально ⌨️.

• Если группировать задачи, которые идут в рабочий блок по контексту, то можно сильно снизить время входа в контекст ∑(τᵢ) по этим задачам. Такой подход поможет увеличить количество полезной работы 🖥.

• Если не успел доделать задачу, которую взял в рабочий блок — оставь небольшую заметку с контекстом «на чем остановился?». При добавлении такой задачи в новый блок — ее время входа в контекст τ будет меньше, а значит ты освобождаешь часть времени блока на полезную работу ✍️.

• Можно декомпозировать сложные задачи на более простые. Дробление уменьшит сложность задачи c, и ты сможешь набрать в рабочий блок несколько мелких и простых задач 🟦.

• Также можно влиять на коэффициент состояния исполнителя μ, уменьшая его, но если не получается — при больших μ нужно уменьшать WIP. В таком случае все будет ок 🔮.



В целом, можно усложнять данную модель, вводя в нее новые механики роста времени переключений между задачами, но глобальная суть от этого не меняется 👩‍💻.


⌨️ — так и есть.
🖥 — мой WIP > 2.
💎 — поделюсь примером WIP в комментариях.


#статья 📚
Please open Telegram to view this post
VIEW IN TELEGRAM
1271381
Привет 🥸! Сегодня начался мой долгожданный отпуск, и я наконец-то могу пару дней отдохнуть практически от всех своих дел и забот 😐.


Чтобы это сделать, мне пришлось уехать в другой город, а именно в Санкт-Петербург ☔️.


Ловлю себя на мысли, что уже просто не могу без ежедневной работы над личными проектами 🖥.


Кстати, вчера ночью произошла микропобеда над моим приложением:

Я полностью закончил работать над MVP-версией архитектуры и визуала .


Все-таки Flutter помогает практически сразу смотреть на то, что ты создаешь — это огромный плюс 🥇. Еще я явно осознал, зачем разбивать код своего проекта по различным папкам с сервисами, утилитами и так далее. Это мега-удобно, если проект уходит за 1000 строк, просто поверьте на слово 🔮.


Я думал, что следующий шаг — это прикручивание БД, но нет. Проще оставить это на потом, а первым делом обернуть приложение в Telegram Web App и отредактировать верстку прям в нем (это 100% надо будет делать) 🖥.

Да и к тому же, после обертки уже можно будет получать ID пользователя из init data, а следовательно не нужно будет заморачиваться с авторизацией, но работа с БД все равно будет строиться вокруг уникального пользователя 🤨.

Я ведь изначально выбирал такой формат приложения, чтобы не делать отдельную авторизацию в нем и все такое 😀.


Еще, буквально вчера, узнал, что JavaScript считается родным для встроенных приложений в Telegram. Да и слышу я об этом языке постоянно в последнее время. Посетила мысль поучить его с нуля. Думаю, что стоит развить эту мысль до чего-то реального. Остается только сделать изучение не душным и полезным, но это так — мелочи 🔍.


Я еще ни разу не рассказывал про суть своего приложения — попробуйте накидать идеи о нем в комментариях ✍️.

Ну и если тут есть те, кто разбирается или что-то пишет на JavaScript — буду благодарен, если подсветите подводные камни 🆘.


P.S. Фотокарточку как обычно прилагаю в конце поста.


⌨️ — держи в курсе.
🍾 — люблю СПб.
💡 — напишу в комментарии, а может и не напишу.


#лайф 🤝🏻
Please open Telegram to view this post
VIEW IN TELEGRAM
1372511221
Как же хорошо разгрузить голову и сфокусироваться на отдыхе и ходьбе — каждый раз в этом убеждаюсь ☺️.

Практически всегда такой отдых конвертируется в новые идеи и цели 🕺.


За три дня вот такие результаты, это прям классика уже:

• шаги: 85298.

• расстояние: 67,92 км.


Фотокарточка с пруфами внизу поста, как обычно 👈.


Хоть мой отпуск продолжается, но я планирую погрузиться в свое приложение и в этот канал 🎮.


Что касается канала — собрал несколько новых тем для постов:

• Хотели бы почитать про QR-коды, и про то, как они работают 👩‍💻?

• Или лучше взять тему, которая не так сильно связана с точными науками 😀?


Как же хорошо, когда бэк-лог тем для постов наполняется быстрее, чем темы вылетают из него.


⌨️ — лучше без точных наук.
🖥 — жду про QR коды.
💎 — почитаю и то, и то.


#лайф 🤝🏻
Please open Telegram to view this post
VIEW IN TELEGRAM
16431111
Всем привет ⌨️. По итогам прошлого поста давайте разберём основу структуры QR-кода. Также посмотрим, почему камера не путается, когда его считывает. Делаем 1-ую часть 🎮!


Кратко про QR-код.


QR-код — это квадратная матрица одинаковых клеток (модулей), в которых хранятся 0 или 1. У каждой такой клетки есть адрес в формате: [№ строки, № столбца]. Вся суть QR-кода заключается в том, где именно лежат служебные поля (группы клеток) и каким образом данные раскладываются по «свободным» клеткам 👩‍💻.


Что нужно, чтобы камера считала QR-код?

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


Теперь подробно про служебные поля:

Опорные угловые маркеры — это большие «мишени» в правом верхнем, левом верхнем и левом нижнем углах. Размер такого маркера 7×7 клеток и ещё белая рамка толщиной в 1 клетку вокруг него 🤔.

Синхронизирующие линии — это две дорожки из клеток, цвета которых чередуются: то чёрный, то белый. Расположены они всегда в одних местах: это 6-я строка и 6-й столбец матрицы, если нумеровать строки и столбцы с 0. Отметим, что эти линии тянутся между опорными угловыми маркерами и не заходят в их области 😐.

Выравнивающие метки — это маленькие «мишени» 5×5 внутри поля QR-кода. Такие метки не могут лежать на опорных угловых маркерах и на синхронизирующих линиях. В небольших QR-кодах они обычно видны в нижней правой части. Если QR-код большой, то таких меток несколько. Вообще они очень важны, так как помогают правильно считывать QR-код с кривых поверхностей, нивелируя искажения 👍.

Тихая зона — это пустая рамка вокруг QR-кода шириной в 4 клетки, отделяющая QR-код от фона 🫣.

Поле формата — в нем указан уровень защиты от ошибок и номер маски-узора QR-кода 🌚.

Поле версии — в нем указывается номер версии, но только если она ⩾ 7 ☺️.

Фиксированная чёрная клетка в известной позиции — это просто дополнительная отметка для распознавания ☺️.


Тут важно отметить, что в служебных полях ваши данные не передаются 🙌🙌.


А как данные оказываются в свободных клетках?

Опишем этот процесс по шагам:

• Берём две самые правые колонки ✍️.

• Идём снизу вверх: в каждой строке работаем с правой клеткой пары, потом с левой ✍️.

• Дошли до верха — сдвигаемся на две колонки влево ✍️.

• Идём сверху вниз, начиная с правой клетки пары, заканчивая левой клеткой ✍️.

• Далее, просто повторяем до тех пор, пока не дойдем до конца ✍️.


Если во время обхода встречаются служебные поля, то просто пропускаем их и идём дальше 🚶.


А сколько данных можно записать в QR-код?

Это зависит от размера и версии QR-кода: чем больше сторона матрицы, тем больше информации можно передать. Давайте опишем зависимость длины стороны матрицы от версии:

сторона = 21 + 4 · (версия – 1).


Отметим, что вне зависимости от роста версии — синхронизирующие линии все равно остаются в 6-й строке и 6-м столбце 🖥.


Зачем используется маска, если все и так может работать?

Перед выкладкой данных в матрицу к ним применяют маску, которая перекрашивает часть клеток, меняя их цвет на противоположный, по понятному правилу, например: «перекрасить, если сумма номера строки и столбца чётная» ⚙️.

Такой подход делает картинку QR-кода равномерной: без огромных однотонных пятен и длинных повторов, которые мешают распознаванию 🔍.

Важно то, что служебные поля маска не трогает. Поэтому номер маски успешно передаётся в служебном поле формата, о котором писал выше. Зная этот номер, камера выполняет обратное перекрашивание .


Кстати, часто слышу о том, что QR-код может считываться при ~30% повреждений, но это не совсем так. Тут важно отметить, что речь именно об ошибках в свободных клетках. Если повреждены служебные поля QR-кода, то считывание может сломаться и при меньших повреждениях 🤯. Вот такой итог !


P.S. Ниже приложил QR-код моего канала, теперь вижу на нем служебные поля, да и на других QR-кодах тоже 😀.


😎 — здраво.
💡 — жду 2-ую часть.
🍾 — теперь тоже вижу служебные поля.


#статья 📚
Please open Telegram to view this post
VIEW IN TELEGRAM
13721181
Сегодня настолько классная погода, что я не удержался и решил написать сюда — до 2-й части про структуру QR-кодов 🥱.


Сегодняшний и вчерашний дни позволили понять, почему многие так любят сентябрь и раннюю осень: ощущение, что она должна быть именно такой 👍.


Ещё один огромный плюс — не все тёплые дни выпали на будни. Чаще наоборот: они приходятся на середину недели, когда все на парах или на работе. Согласны 🤔?


Кстати, будет максимально здраво, если забустите мой канал, ссылка ниже:

https://t.me/boost?c=2187172722

Возникло очередное желание поискать кастомные эмодзи и поиграть с оформлением канала 🌊.


P.S. Фотокарточка внизу поста не сегодняшняя, но кайф этих дней точно передаёт 😺.


💎 — в тему про погоду.
⌨️ — держи в курсе.
☺️ — закинул(-а) бусты.


#лайф 🤝🏻
Please open Telegram to view this post
VIEW IN TELEGRAM
132218
Всем привет! Закончил 2-ю часть по QR-кодам. Тут про то, как текст превращается в биты, как всё защищено и причем тут математика. Как обычно, поехали 🌎!


Сначала давайте разберем маршрут данных от текста до матрицы QR-кода 😱:
Текст → Битовая строка → Байты (кодовые слова) → Защита от ошибок → Перемежение → Применение маски → Выкладка в матрицу.



Как конкретно текст превращается в байты ?

Тут отметим, что есть 4 режима, которыми можно кодировать вашу строку с текстом ⚙️:
Числовой (numeric) — когда кодируем только цифры.

Буквенно-цифровой (alphanumeric) — когда кодируем цифры и буквы.

Байтовый (byte) — когда кодируем любые байты, обычно в UTF-8.

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


Теперь соберем мини-алгоритм, по которому любой QR-код превращает вашу строку с текстом в битовую дорожку 🟦:
• Сначала выбираем режим кодирования: numeric / alphanumeric / byte / kanji.

• Дописываем индикатор режима: numeric — 0001, alphanumeric — 0010, byte — 0100, kanji — 1000.

• Затем сразу дописываем длину сообщения — это нужно, чтобы сканер знал, где заканчиваются данные. Эта длина сообщения также записывается битами, а их количество зависит от версии QR-кода и выбранного режима.

• Далее ваш текст кодируется в ту самую битовую дорожку. Тут не буду подробно останавливаться, так как это тема для отдельного поста 🚶.

• Теперь добиваем получившуюся битовую дорожку терминатором — это 4 нуля в ее конце. И, если нужно, дописываем еще нули, чтобы количество битов в дорожке было кратно 8 — это как раз для перевода битов в байты.

• На выходе получаем байты. Если их мало, то добиваем количество до нужного числа, используя байты: ЕС, 11. Тут важно учесть, что «добивочные» байты чередуются, то есть: EC, 11, EC, 11, ...



Что с этими байтами происходит дальше и причем тут коды Рида-Соломона (RS) 🥱?

В двух словах, QR-код защищается кодами RS в «байтовом поле» GF(256) 👩‍💻.

Что важно знать про GF(256) 🤔:
Элемент поля — это один байт.

Сложение в поле — поразрядное исключающее ИЛИ (XOR), переносов нет.

Умножение выполняется по фиксированному правилу, чтобы результат снова был байтом. Технически — это приведение по модулю заданного многочлена 8-й степени.

Прикладной смысл — байт в этом поле это полноценное число, с которым удобно строить и проверять «страховку».


Основа защиты строится на страховочных байтах. Что важно знать тут 🤔:
• Данные режутся на блоки. Для каждого блока к его k байтам добавляют r страховочных байтов.

Обозначается как RS(n, k), где n = k + r.

• «Починить» можем до r/2 байт-ошибок в каждом блоке. Измеряется именно в байтах-ошибках, а не пикселях или процентах.


Как страховочные байты получаются 🤔?
• Берем полином данных со степенью k – 1 над GF(256) — M(x).

Умножаем на x^r.

Делим на g(x) — генераторный полином степени r.

Остаток (полином степени < r) — это содержимое проверочных байтов.


Что именно они страхуют 🤔?
Ошибки из-за печати или плохой камеры, когда отдельные байты считываются неверно.

• Маленькие повреждения, например: царапины, логотипы в центре QR-кода.


Тут нужно помнить, что страховочные байты не страхуют поломку служебных полей: если камера не построит сетку, то до кодов RS сканер просто не дойдет 🫣.


Теперь про перемежение 🥵.

Перемежение — это когда байты из нескольких блоков выкладывают в матрицу не подряд, а «по кругу», чтобы любое локальное пятно повреждений превратилось в небольшое количество ошибок в каждом блоке 😐. В таком случае с помощью кодов RS можно будет спокойно исправить эти ошибки 👍.


В итоге: как именно сканер чинит поломки 🤔?

Краткий алгоритм:
Считали все байты блока → Посчитали синдромы по принятому кодовому слову → Синдромы нулевые? → Если да, ошибок нет.

• Если нет, то алгоритмом Берлекэмпа-Мэсси восстанавливаем полином локаторов ошибок.

• С помощью поиска Чиена находим позиции сломанных байтов.

• Используя формулу Форни, получаем величины ошибок, а затем, зная их, восстанавливаем сломанный блок.


Как-то так ☺️.


🌊 — здраво.
⌨️ — жду лайтовый пост.
🖥 — думал, что QR-коды устроены проще.


#статья 📚
Please open Telegram to view this post
VIEW IN TELEGRAM
1221512
Добрый вечер 🚶! Пропал почти на неделю, потому что столкнулся с сильной апатией. Долго думал, в чем причина — просто так она не появляется 🤔. После небольшого анализа понял, что жил несколько месяцев в очень жестком ритме:

• С работой.

• С каналом.

• С приложением.

• С регулярным спортом.

• С ежедневными записями целей и итогов дня.



В какой-то момент мне казалось, что я привык к такому ритму и не чувствую усталости от кучи дел и планов 😀. Сначала решил загружать будни по максимуму, а потом начал делать то же самое и с выходными 🎮. Результат не заставил себя ждать:

• Стало трудно вставать по утрам — хотелось спать как можно дольше.

• Каналу почти не уделял внимания, но постоянно думал о нем.

• Приложение застопорилось после большого и, к слову, успешного теста.

• Спорт отпал от слова совсем.



Как вы думаете, я эти моменты учел? В этот раз — да 🌚. Поэтому сделал следующее:

Перестал думать о канале и корить себя за то, что не пишу посты наперед.

Отпустил ситуацию с приложением и дал себе от него отдохнуть.

Оставил только тот спорт, который спонтанный и в удовольствие.

Постарался наладить режим сна.

Убрал ежедневное планирование и подведение итогов.

• Хорошо отдохнул от любых рабочих задач на выходных и провел время с друзьями.



Чтобы вы понимали, энергия начала возвращаться только спустя неделю вот такого «детокса», который в начале давался непросто из-за чувства вины перед собой за то, что я не занят чем-то полезным 🫣. Сейчас хочу пересмотреть то, как устраиваю свою недельную занятость, стараюсь потихоньку возвращать планы, цели и контроль над временем 👍.


Главный вывод из этого эпизода: перегрузки не проходят бесследно. У них есть накопительный эффект, и чем он сильнее, тем выше шанс, что он «выстрелит» в виде сильной апатии и усталости. Очень важно про это не забывать .


P.S. А как у вас обстоят дела с занятостью? Часто ли сталкиваетесь с такими же проблемами?


💡 — регулярно выгораю.
⌨️ — пока что не сталкивался с таким.
🍾 — идеально держу баланс между занятостью и отдыхом.


#лайф 🤝🏻
Please open Telegram to view this post
VIEW IN TELEGRAM
1471610733
Всем привет 💡! Недавно в голову пришла такая мысль: «прогресс либо растет, либо падает — третьего не дано» 😦. Давайте разберем и проанализируем 👩‍💻.


Кажется, что можно просто «держать уровень» прогресса, но на практике это почти невозможно . На любой навык или проект, которым вы занимаетесь, действуют три силы:

Улучшения — это то, что вы делаете осознано 🚶.

Естественный спад — это забывание, утомление, энтропия 🫣.

Случайности — форс-мажорные ситуации, ошибки или везение 🤔.



Для того, чтобы более глубоко понять мысль из заголовка поста — построим простую дискретную модель, в которой один шаг равен одному дню 🤯:

• Уровень прогресса — это xₜ.

• Намеренное улучшение прогресса — это gₜ.

• Естественный спад (энтропия) — это d. К слову, d > 0, потому что энтропию нельзя отключить.

• Ошибки или везения — это εₜ, которая может быть как положительной, так и отрицательной.

• «Шаг» модели — это t.



Отдельно стоит отметить, что наша модель мультипликативная 🤪. Если говорить по простому, то мультипликативность — это когда общий уровень навыка меняется в процентах относительного текущего уровня навыка 🌚. То есть новый уровень навыка получается не прибавлением, а умножением на коэффициент. Вот небольшой пример с мультипликативным ростом подписчиков в канале:

• 1 день — 1000 + 10% = 1100 участников 🖥.

• 2 день — 1100 + 10% = 1210 участников 🖥.



Что говорит в пользу мультипликативности нашей модели 😐:

• Интуитивно понятно, что качество навыка растет в процентах от его текущего уровня.

• Естественный спад также описывается процентом от текущего уровня навыка.

• В целом навык растет или падает всегда относительно текущей базы.



Исходя из этого итоговая модель будет такой 👍:

xₜ₊₁ = xₜ ∙ (1 + gₜ + εₜ – d) = xₜ ∙ (1 + rₜ), где rₜ = gₜ + εₜ – d.



Что делать с ней дальше 😀? Давайте пойдем по шагам:

1. Посмотрим, что будет с уровнем прогресса за k дней 🤔:

xₖ = x₀ ∙ ∏(1 + rₜ), где ∏ — это произведение элементов (1 + rₜ) c индексом t от 0 до k-1.


2. Возьмем логарифм от левой и правой части формулы, чтобы избавиться от умножения 🤔:

ln(xₖ) = ln(x₀) + ∑ln(1 + rₜ), где ∑ — это сумма элементов ln(1 + rₜ) c индексом t от 0 до k-1.


3. Теперь посчитаем средний темп роста уровня навыка за день 🤔:

(ln(xₖ) – ln(x₀)) / k = (∑ln(1 + rₜ)) / k.


4. Теперь возьмем правую часть уравнения, которая как раз является средним темпом роста уровня навыка за день, и посмотрим, что будет с ней, если k → ∞. Тут важно отметить, что мы будем считать, что дни похожи между собой по статистике, т.е. наш процесс стационарный. Тогда, по закону больших чисел верно следующее 🤔:

((∑ln(1 + rₜ)) / k) → 𝔼[ln(1 + rₜ)] ≡ γ.


5. Если перевести то, что мы получили в пункте №4 на слова, то получим следующее 🤔:

Если дни похожи, то средний рост навыка по небольшому количеству дней практически равен «истинному» среднему росту навыка за очень большое количество дней.


6. В итоге, после нашего анализа получаем 🤔:

• γ > 0 → наш навык геометрически растет.

• γ < 0 → наш навык геометрически падает.


7. А что будет если «истинный» средний рост навыка γ равен нулю 🤔?

• Если проценты прироста навыка небольшие, то верно следующее приближение: 𝔼[ln(1 + rₜ)] ≈ 𝔼[rₜ] – 0.5 ∙ Var(rₜ), где 𝔼[rₜ] — это средний дневной процент прироста навыка в долгую, а Var(rₜ) — это дисперсия дневных процентов прироста навыка.

В итоге, если 𝔼[rₜ] ≈ 0, Var(rₜ) будет понемногу уменьшать общий прогресс.

Простой пример: в первый день +10%, во второй день –10%. Кажется, что общий прогресс за эти два дня не изменится, но если посчитать: (1.1) ∙ (0.9) = 0.99. То есть общий прогресс за такие два дня упал на 1%.



Какие практические выводы можно вынести 👁?

Во-первых, ноль нестабилен — чтобы держать уровень, нужно перекрывать не только спад, но и «колебания» около этого нуля .

Во-вторых, дни поддержания — не пустые: они не дают общему результату катиться вниз 🥇.

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


😎 — согласен.
⌨️ — запишу себе выводы.
🖥 — жду пост про приложение.


#статья 📚
Please open Telegram to view this post
VIEW IN TELEGRAM
2232016
Всем привет ⌨️! Наконец-то нашел время на небольшой лайф-пост про свой Telegram мини-апп, на который сейчас уходит почти все свободное время 😱.


Сначала кратко 👩‍💻:

• Много времени ушло на темную и светлую тему, чтобы мини-апп корректно подхватывал их из Telegram .

• Долго разбирался, как отключить системный свайп, который сворачивает мини-апп 🕹.

• Когда все стало «нормально работать», занялся рефакторингом, чтобы стало плавно и стабильно 🌃.



Теперь подробнее, что получилось сделать:

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


Списки без дерганий 🧐.
Я использую вертикальные списки, и при смене порядка элементы подскакивали. Чтобы исправить, пришлось кэшировать текущее состояние списка и пересобирать логику рендера этого списка — теперь перетаскивание гладкое, без «подскоков».


• Пришел к тому, что использовать тикер нужно только там, где он нужен 🧐.
Звучит очевидно, но вначале об этом не думаешь и просто вешаешь тикер на всю страницу. По итогу изменение одного элемента влечет за собой перерисовку всей страницы. Долго правил и встраивал тикер в конкретные виджеты. В результате мини-апп перестал подлагивать. Если честно — получилось только с третьего раза. В будущем сразу буду продумывать логику обновления виджетов на страничке.


Живые графики без мельтешения 🧐.
Нашёл баланс: тултипы (подсказки на графиках) обновляются каждую секунду, отсюда ощущение «живости», а высота столбиков меняется раз в минуту, поэтому картинка спокойная и не дёргается. Смотреть приятно.


Анти-свайп — мастхэв 🧐.
Если у вас есть вертикальные списки, системный свайп Telegram будет сворачивать ваш мини-апп при прокрутке вверх. Это бесит. Решение: отключать свайп ещё на старте, прямо из index.html, и делать это с ретраями — Telegram API не всегда «просыпается» сразу. Звучит вроде просто, но боролся я с этой проблемой долго. Зато очень приятно, что анти-свайп работает стабильно.


Нормальный деплой 🧐.
Я ушёл от ручной заливки и сделал автодеплой со схемой версий: каждый релиз — в отдельную папку, стартовая страница index.html указывает на релизный index.html из последней релизной папки. Плюс смог настроить кэш-политику. Теперь Telegram не «липнет» к старым версиям, а первая загрузка быстрая. Когда этого не было — я переустанавливал Telegram, чтобы пробить кэш, это просто ад.



Что вообще удалось вынести из всего этого 🤔:

• Если у вас есть желание что-то закодить своими руками — лучше это сделать, чем просто думать об этом. К слову, со временем очень затягивает 📚.

Нейросети, особенно продвинутые — очень сильно помогают. Главное не просто делать ctrl+C и ctrl+V, а разбираться в том, что предлагает нейросеть и задавать вопросы. Со временем получится самостоятельно закрывать какие-то доработки и без сторонней помощи писать хелперы или описывать нужные классы. Очень хороший бустер, особенно когда хочется сразу видеть какой-нибудь результат 👁.

• Если, в итоге, мини-апп будет неиспользуемым, то я смогу забустить свое резюме описанием разработки от и до. Это приятный бонус 🔮!



В общем, вот почему слегка задержал выход лайф-поста: было много невидимой, но важной работы. Дальше — подключение БД к мини-аппу 😢.


💡 — лайк авансом.
🌊 — жду про подключение БД.
⌨️ — пойду поделаю свое приложение.


#лайф 🤝🏻
Please open Telegram to view this post
VIEW IN TELEGRAM
13118113
Внеплановый лайф-пост: почему притормозил с подключением БД?


Буквально в день, когда я сел подключать БД к мини-аппу, в голову пришли новые фичи и вообще новый отдельный раздел мини-аппа 🔥!

Принял решение отложить подключение БД и реализовать новый функционал ⌨️.


Сейчас этим уже занимаюсь и понимаю, что на 90% это правильное решение 👍. Объясню почему:

1. Во-первых, перед подключением БД нужно оптимизировать приложение, чтобы потом не гадать, из-за чего оно подвисает.

2. Во-вторых, подключать БД проще, когда локальные слои данных (по сути локальная БД, которая помогает пережить перезапуск приложения) уже реализованы и хорошо работают.



Вообще заметил, что в этот раз новый раздел вводить было намного проще. Жаль, что я не отслеживал, сколько времени это заняло в самый первый раз. По ощущениям, сейчас 100% быстрее 😀.

На самом деле очень жду момент, когда смогу сделать большое код-ревью, чтобы исходный код был максимально читаемым и масштабируемым. А там уже и до переезда на JS недалеко 🤨.

Но вообще переезд — не факт, что хорошая идея. Сяду с этим разбираться, когда закрою текущие задачки, а то, как всегда, бегу вперед 🌚.


💎 — нравится такой лайф-формат, его нужно больше.

💡 — жду какой-нибудь лонгрид на интересную тему.

😎 — интересно узнать, что с этим приложением будет в итоге.


#лайф 🤝🏻
Please open Telegram to view this post
VIEW IN TELEGRAM
130181521
Привет 😐! Недавно задумался о том, как именно работает доминанта. Если говорить кратко, то это утренняя установка на день, которая задает общее настроение 😎.


Простыми словами 🥱.

Доминанта — это призма: она не меняет факты, она меняет веса их интерпретации. Закрепишь в голове «сделаю минимум и продвинусь» — рутинные и сложные события читаются спокойнее 🤤. Закрепишь «я не вывезу» — те же события кажутся хуже и «подтверждают» провал 😨.


Раскроем суть ⌨️.

На мой взгляд, доминанта двигает два ключевых рычага:

1. Порог реакции 🤔.
Что считать важным, а что — нет. Одно и то же событие с разным порогом проходит фильтр по-разному: либо «сделаю позже», либо «занимаюсь этим сейчас».


2. Луч внимания 🤔.
Куда реально уйдут время и энергия. Узкий луч — сильный фокус, но на одну тему. Широкий луч — видишь альтернативы, но легко потерять фокус и уйти в рассуждения вместо конкретных действий.


Плюс есть инерция. Как только одна тема вырывается вперед, она «подтягивает» соседние: в голове формируется сюжет, и дальше все начинает подстраиваться под него 👩‍💻. Поэтому важны не только мысли, но и среда, в которой ты находишься в данный момент: настроение, люди рядом, физическое состояние — другими словами, это входы, которые усиливают доминирующий сюжет и ослабляют другие 🚶.



Давайте формализуем .


1. Разберем пороговый взгляд на ситуацию 🤯. Сырую оценку ситуации можно посчитать так: z = w · x + b, где:

• x — факты, связанные с ситуацией.

• w — веса этих фактов.

• b — смещение.


Решение по ситуации — это y = sign(z) 🤪. Функция sign() возвращает либо +1, либо -1 в зависимости от входной сырой оценки. Доминанта в этой формуле — это именно сдвиг b . Ее роль заметна при фиксированных w · x:

• Рост b повышает шанс, что z > 0 → нейтральная ситуация читается как «у меня получится / я разберусь».

• Падение b → нейтральная ситуация читается как «я не смогу / ничего не получится».



2. Рассмотрим конкурирующие мысли и распределение внимания . Обычно несколько оценок z₁, z₂, …, zⱼ соревнуются за внимание. Доли внимания можно посчитать так: aᵢ = (e^(βzᵢ)) / (∑ⱼe^(βzⱼ)), β = 1 / T, где:

• aᵢ — доля внимания к i-й мысли (сумма всех aᵢ = 1).

• β — «острота» распределения.

• Т — «температура» распределения.


Если β большое, а T низкая, то распределение острое и мысль, которая забирает большую часть внимания, в итоге получает все внимание, которое есть. Если β маленькое, а T высокаявзгляд шире и мысли получают больше «воздуха» 😁.


3. Перейдем к структуре связей 👻.

Мысли связаны как граф: одни активируют другие. Во времени внимание стремится выравниваться вдоль доминирующего собственного вектора матрицы связей графа, а именно туда, где связи сильнее всего. Роль доминанты — «подкрутить старт» и усилить нужные мысли так, чтобы система тянулась в правильную сторону ☺️.



4. Закончим динамикой 🥵.

Реальная система будет нелинейной: сильная конкуренция между мыслями (большая β), петли обратной связи, утомление. В такой системе возникают аттракторы — устойчивые режимы, например: «залипание» в страхе или стабильная продуктивность. В такой системе малые флуктуации держат внутри аттрактора, а редкие сильные импульсы могут выбить из устоявшегося аттрактора 🌚.




В итоге доминанта отвечает за изначальный вход в существующий режим. Но в реальности бывает так, что этой доминанты просто не хватает, если негативный режим очень сильно устоялся в твоей голове и ничего на него не влияет 😦. В таком случае помогают сильные импульсы, например: смена обстановки, смена деятельности и так далее. Важно только ловить момент перехода и подкручивать доминанту так, чтобы режим, который тебе нравится, стал устойчивым 🧠.


⌨️ — никогда об этом не задумывался.
💡 — просто закину эту реакцию.
😎 — пользуюсь доминантой ежедневно.


#статья 📚
Please open Telegram to view this post
VIEW IN TELEGRAM
1252081
Всем привет! Решил закинуть небольшой лайф-пост о разработке приложения, плюс пару мыслей, которые ясно осознал к 26 годам 🥸.


Начну с приложения🥵.

Я практически закончил с полировкой и оптимизацией новых фич, про которые писал в позапрошлом посте.

На самом деле заниматься своим продуктом и видеть, как он вырастает от простой идеи до чего-то, чем можно пользоваться ежедневно, — это очень воодушевляет 😺.


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

Сейчас, из-за того, что хочу быстрее сделать боевую версию, я этим пренебрег, но, поверьте, лучше так не делать, потому что мой main уже около 2к строк и похож на помойку. В нем неприятно ориентироваться 😁.


Хотя отмечу, что вначале я этим правилом не пренебрегал, поэтому уже есть достаточно хорошая структура, но из-за усложнения проекта она устарела. В общем и целом, буду дорабатывать ☠️.


Теперь о мыслях 👍.

Сейчас они засели в моей голове, как основа основ:

• Лучше фокусироваться на том, что в твоей зоне влияния, и действовать, чем просто ждать, что все само сложится так, как ты хочешь 😐.


• Жить проще, когда берёшь на себя свою долю ответственности за свои решения. Тогда вместо поиска виноватых мозг переключается на самоанализ, и почти каждое такое переключение становится точкой роста 🌚.


• В молодости важно как можно раньше начать осознанно искать дела, которые по-настоящему интересны. Чем раньше начинаешь такой поиск и задерживаешься вокруг того, что цепляет, тем меньше потом сожалений о годах в откровенно чужой деятельности 🤯.


Чем раньше учишься нормально чувствовать себя наедине с собой — без бегства в шум и чужие ожидания, — тем проще потом общаться с людьми и не терять себя в них ☺️.


Список мыслей выше — практически очевиден, но я точно могу сказать, что либо раньше об этом не задумывался, либо просто понимал их как-то по-другому 🤯.


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


P.P.S. Внизу поста прилагаю фотокарточку первого дня зимы.


🍾 — Согласен с выводами в посте.
💎 — Лайк за фотокарточку.
⌨️ — Напишу в комментариях, а может, и нет.


#лайф 🤝🏻
Please open Telegram to view this post
VIEW IN TELEGRAM
127241221
Всем привет! Закидываю в ленту очередной лайф-пост 😤.


Закончил две трудные недели:

Отработал 12 рабочих дней подряд 🥵.

Прогнал своё приложение по «краевым» кейсам, попробовал его сломать и поискать дыры в архитектуре — на удивление, ничего критичного не нашёл 😎.

Разнёс кучу кода из main по отдельным файлам, пересобрал структуру проекта и нормально связал части между собой 👾.

Не забывал про спорт и растяжку — наконец-то вижу прогресс, а не просто галочки 😺.



Без косяков, конечно, не обошлось:

• Рваный режим и недосып 🌚.

• Не самое правильное питание — классика, когда хочется закрыть просадку дофамина 🥸.



Сегодня наконец-то позволил себе нормально выдохнуть и просто отдохнуть.

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

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

Всем хороших выходных 😎!


⌨️ — читаю в режиме отдыха.
🍾 — заберу выводы себе.
💎 — тоже пора устроить себе выходной.


#лайф 🤝🏻
Please open Telegram to view this post
VIEW IN TELEGRAM
2622171
Всем привет 🥱! Давно ничего не писал сюда, пора исправляться. Сегодня пост про рабочее место в прямом смысле и немного про мой мини-апп. Если непонятно, как это связано — сейчас расскажу 🎮.

Я впервые по-настоящему почувствовал, насколько сильно эргономичное рабочее место влияет на продуктивность. Раньше вообще не думал ни про эргономику кресла, ни про высоту стола, хотя за ним провожу полдня 😨.

Осознал я это только тогда, когда сам всё выбрал, купил и собрал под себя 🤑. Вышло недёшево, но в этот раз сознательно не экономил. Кстати, клавиатура и мышь тоже важны: чем они приятнее в использовании, тем легче сидеть дольше и не разваливаться вниманием 👈.

С мышкой и клавиатурой всё понятно, а вот со столами и креслами сложнее. Кому-то стандартные варианты мелкие, кому-то, наоборот, огромные. Вот здесь в игру и включается математика, а именно: нормальное (гауссово) распределение 😐. Большинство людей — около «среднего» роста, под них и делают массовую мебель. Если вы ближе к краям распределения, т.е. выше или ниже среднего, — подобрать удобное рабочее место сложнее и чаще всего дороже 👊:

Я, например, долго думал, что придётся делать всё на заказ, но в итоге нашёл почти идеальный вариант, потратив реально много времени на поиски 🚪.


Через эту призму удобно смотреть на многое вокруг: сиденья в транспорте, высоту потолков в новостройках и т.д. Большая часть вещей делается под «среднего» человека, потому что такие вещи проще массово продать. Всё, что ориентировано на более узкую группу, почти всегда выходит дороже ⌨️.


А при чём тут приложение? Очень даже при чём: рабочее место для меня стало экспериментальным полигоном, сначала я его заапгрейдил, а потом замерил эффект своим же мини-аппом 😎.

Я замерял, сколько времени трачу на свои проекты и дела за пределами работы — сначала со старым рабочим местом, потом уже с новым. По цифрам и ощущениям вышло так:

• Примерно на 65% выросло время, которое я могу спокойно тратить на работу со своими задачами 🤔.

• Полностью ушли фоновые боли в спине и шее — сейчас что-то ноет только после хорошей тренировки с гирей 🤔.

• Тренироваться стал больше на 1 тренировку в неделю 🤔.


Параллельно я наконец-то пробил психологический блок по бэкенду мини-аппа и уже сделал несколько шагов:

Настроил виртуальное окружение на Python .

Описал БД и поднял кластер PostgreSQL в облаке — оказалось, что это не так страшно. Сейчас разработка стоит мне примерно 1 рубль в час (кластер останавливаю, когда не работаю, и выбрал минимальные настройки). Боевая конфигурация, конечно, будет дороже 🟦.

Полностью описал методы API и погонял их через Swagger — очень удобный способ тестировать эндпоинты ⚙️.

Подключил API к клиенту так, чтобы новые записи сразу улетали в БД 🖥.


Это, конечно, не финал. Дальше — забор данных из БД при старте приложения, аккуратный деплой и тесты с разных устройств 🙌🙌.


P.S. Как только закончу с бэком, сделаю отдельный пост про само приложение: что оно умеет и зачем оно вообще нужно. Если честно, мне самому уже надоело тянуть с этим 🥵.


💡 — давай подробнее про распределения и их применение.

💎 — интересно про порядок разработки бэка мини-аппа от и до.

⌨️ — жду анонс приложения и лайф-посты.


#лайф 🤝🏻
Please open Telegram to view this post
VIEW IN TELEGRAM
22921181