DON'T STOP AND CODE
100 subscribers
62 photos
2 videos
1 file
123 links
Мой путь в программировании
#python

Для связи: @avagners
Download Telegram
This media is not supported in your browser
VIEW IN TELEGRAM
1) Когда-нибудь электронные вычислительные машины (ЭВМ) будут сами составлять для себя программы или же мы будем писать их на естественном языке.
-- Денни Ван Тассел, 1978 год
❤5👍2
2) Цель программирования - не создание
программы, а получение результатов
вычисления.
Кодирование, увы, само по себе ничего
не стоит - существенны результаты!
-- Денни Ван Тассел, 1978 год
💯4
[KiloCode + Mistral Large 3. Подвожу итоги]

Работать можно.

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

Исправил все ошибки, написал README, попросил вывести статистику по выполненным работам.

Получил довольно подробную статистику:
- кол-во задач
- стоимость затрат
- время работ (часов, дней)
- структуру проекта
- кол-во строк кода
- даже перфоманс сборки
- и еще кучу информации в различном разрезе

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

Я точечно проверил некоторые метрики. В целом информация похожа на правду.
Но по некоторым есть вопросы.

Попросил указать источники информации - любезно получил ответ.
Было интересно и познавательно. Есть над чем подумать.

Идем дальше.

P.s. на работе уже окончательно перешел на KiloCode.
Continue, спасибо! Было интересно!
🔥5
[Kilo Code изучает Kilo Code]

Почему бы и нет?
Решил изучить плагин.

Что сделал:
- пообщался с chatGPT, DeepSeek указав ссылку на оф. сайт и предоставив им возможность поиска источников в интернете - в итоге получил общее представление;
- создал подробный промпт для изучения проекта с помощью DeepSeek;
- склонировал репозиторий и запустил Kilo Code с промптом;

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

Также, получил подробные комментарии что и зачем выполняется с ссылками на код (я проверил - все ссылки точные)

P.s.
Дополнительно собрал различную статистику по кодовой базе и получил краткие интересные комментарии к ней.

Раньше на такое погружение потребовалось бы несопоставимо больше времени. Я под сильным впечатлением. Получил неплохое понимание объемного проекта буквально за пару часов.
👍2🔥1
This media is not supported in your browser
VIEW IN TELEGRAM
[Kilo Code. Изучаем работу агента с помощью Export Task]

Совершенно случайно нашел так скажем протокол сессии агента.

Это не просто диалог, который виден в окне плагина. Там гораздо больше интересной информации, изучив которую, можно больше понять процесс работы агента.
👍2
[Как устроен протокол задачи в Kilo Code?]

Изучил протокол и вот что выяснил.

При работе с Kilo Code каждая задача сохраняется в виде детализированного протокола kilo_code_task_*.md. Этот файл содержит полную историю взаимодействия с агентом, включая:

- Исходный запрос пользователя (тег <task>).
- Ход рассуждений ассистента (секция <thinking>).
- План действий с чек-листами (инструмент update_todo_list).
- Результаты выполнения команд (например, вывод read_file, search_files).
- Метаданные окружения <environment_details> (открытые файлы, текущий режим, стоимость сессии).

Что интересного?

Больше данных, чем в интерфейсе плагина:
В экспортированном файле сохраняются даже те детали, которые не всегда видны в окне VS Code (например, полный контекст окружения, промежуточные результаты).

Структурированный формат:
Протокол оформлен в Markdown с четкими разделителями (---), что упрощает анализ и повторное использование.

История принятия решений:
Видно, как агент пришел к финальному результату - от анализа задачи до применения инструментов.

Напоминания:
Явно указаны напоминания для LLM относительно плана работы. Именно поэтому агент не теряет фокус во время выполнения и продолжает придерживаться плана (хотя иногда теряет).
REMINDERS

Below is your current list of reminders for this task. Keep them updated as you progress.


Зачем это нужно?

1) Можно восстановить логику решений при отладке или ревью.

2) Протокол можно передать другому агенту или использовать как основу для новой задачи.

3) Удобно изучать паттерны работы LLM в сложных сценариях.
🔥5
[Итоги канала за 2025 год]

Посмотрите какой прикольный сервис сделала @neural_prosecco.

С помощью него можно посмотреть:
- статистику канала
- небольшой анализ от LLM (прикольно)

Итого:
75 постов · ❤️ 342 реакций · 👁 7.7K просмотров · 🔄 16 репостов

(до сих пор удивляюсь репостам😄)

P.s. ниже прикладываю что LLM думала о канале во время анализа:

1. Проанализировал основные темы канала за 2025 год — в фокусе AI, DDD, разработка, продуктивность и тренировки.
2. Тон коммуникации живой, разговорный, иногда с мемным или легким самоироничным вайбом.
3. Канал разбирает сложные темы простым языком, добавляя личный опыт и лайфхаки.
4. Автор честно делится как техническими деталями, так и айтишным жизненным опытом.
5. Встречаются глубокие объяснения архитектуры, LLM, AI, плюс заметки из жизни и спорта.
6. Часто решения, примеры кода и обзоры инструментов — всё без заоблачного пафоса.
7. Образ автора — прагматик, исследователь и коллега, который делится инсайтами без пафоса.
8. Канал сочетает обучение с реальным опытом, разбирает ошибки и даёт конкретику.

P.s.s.
ссылка на сам сервис: https://tgwrapped.com/
👍3🔥2🏆1
[Новый опыт - frontend, ci/cd, k8s]

Хочу поделиться следующими новостями с работы:

1) Я завершил разработку основного функционала UI одного внутреннего пользовательского сервиса.

Предложили такой проект - я не отказался (правда интересно).
Для меня это новый опыт. До этого максимум вносил небольшие изменения в работающие сервисы.
А тут все с нуля. Для меня практически все было в новинку: TypeScript, React, Redux.
Из-за того, что сервис внутренний, то жестких требований к дизайну не было и можно было собрать страницы из компонентов корпоративной дизайн-системы (очень удобно). Дизайна как такового не было, но это не значит что можно было сделать тяп-ляп на глаз. Требовалось соблюдать требования дизайн-системы. Благодаря этому на выходе получился красивый UI, который не отличается от других корпоративных сервисов в плане внешнего вида.

Делал все с использованием LLM. Сначала Continue, потом Kilo Code.

Рабочая схема:
ии-агент + тестировщик + опытный наставник

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

(при этом некоторая база как работает frontend у меня была)

2) Настроил CI/CD в кубер (впервые)

У нас в команде есть devops-ы, которые все сами настраивают. Но все ушли в отпуск до конца года.
Так как мне тоже это интересно и хотелось применить полученные ранее знания с обучения, решил сделать самостоятельно (тем более была цель выкатить сервис до НГ).

В качестве примера были соседние репозитории. Все делал по аналогии.
Сначала были некоторые проблемы со сборкой образа. Потом долго провозился с сетевыми настройками в кубере, чтобы все микросервисы могли взаимодействовать друг с другом. Очень помогли знания, которые получил пару месяцев назад на обучении.
Также, пришлось погрузиться в настройки keycloak. Была проблема что бэкенд не принимал токен из фронта.

На то, чтобы настроить работу сервиса на тесте я потратил 1 рабочий день.

В итоге получил работающий сервис и ценнейший опыт.
С таким интересом я давно не проводил время)
не шучу)

P.s. сегодня выполнил деплой на прод. Были также трудности с keycloak. Решили.
Есть небольшая проблема с одним из микросервисов бэкенда.
Вроде нашли причину и решение - нужно внести небольшие изменения в код на java.
Но это уже завтра.
🔥5👍2❤1
This media is not supported in your browser
VIEW IN TELEGRAM
DON'T STOP AND CODE pinned «[Про жизнь] Жизнь - интересная, непредсказуемая, удивительная штука, которая с завидной регулярностью заставляет пересмотреть некоторые свои взгляды на 180 градусов. Спустя годы выясняется, что многие принципы, которые ты считал единственно верными, оказываются…»
[Итоги года 2025]🪞

1) Работа
С июня этого года я поменял роль с DE на разработчика внутренних сервисов платформы. Этого я хотел несколько лет. Много работал с кодом. К концу года удалось добить до релиза с нуля один проект. Самостоятельно настроил деплой в кубер. Получил за этот неполный год хороший опыт, которому я очень рад.

2) Обучение
Завершил 2 внешних обучения:
- DDD
- Kubernetes для разработчиков
Полученные знания применяю в работе.

Также, в рамках вечерних активностей после работы активно осваивал LLM.
Изучал как и из чего строятся ИИ-приложения. Прогресс очень хороший. Это особенно чувствуется как в работе, так и просто в общении с коллегами. Полученные знания и навыки успешно применяю.

3) Тренажерный зал
Этой весной я достиг пика своей физической формы. В жиме лежа удалось дойти до КМС в своей весовой категории. Этому я очень рад. Получал регулярно комплименты в зале. Это приятно.
Летом были очередные изменения из-за которых был нарушен режим тренировок.
Смог вернуть режим только в ноябре (с 20 числа). За это время удалось восстановить форму (было 20 тренировок), но до весенних результатов мне еще далеко.
Как я писал ранее, для меня занятия в тренажерном зале стали обычной привычкой. Занимаюсь без фанатизма, без употребления каких-либо препаратов, просто в свое удовольствие для поддержания формы. При этом есть спортивный интерес вернуть весеннюю форму).

4) Канал
Этой осенью возобновил публикацию в канал. Кол-во подписчиков перевалило за 100. Хоть канал небольшой, но я очень рад общению, которое иногда случается с кем-то из вас. Всем огромное спасибо.

Итого:
Этот год я бы обозначил как "взросление". Многое удалось принять, успокоиться, осмотреться. Осенью вернулись энтузиазм, проактивность, интерес. Это проявляется в работе, обучении и даже в этом канале. Я получаю огромное удовольствие от работы. Это реально очень интересно).

P.s. что по целям?
Целей как таковых не было. Точнее были, но я не был сфокусирован на их достижение. Об этом писал. Да, вот так. Как есть)

Идем дальше.

С наступающим)
🎄🎄🎄🎄🎄🎄🎄🎄
Please open Telegram to view this post
VIEW IN TELEGRAM
🏆13🔥5👍4
This media is not supported in your browser
VIEW IN TELEGRAM
[Вы знакомы с Expression Problem?]

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

"Expression Problem показывает фундаментальное ограничение как объектно-ориентированных, так и функциональных языков: ни один из них не поддерживает удобное расширение как по оси типов, так и по оси операций."
-- Philip Wadler, 12 November 1998

Обратите внимание на год.

Оказывается Expression Problem - это лакмусовая бумажка выразительности языка. Идеальный язык должен позволять:
- добавить новый тип данных, не трогая старые функции
- добавить новую операцию, не трогая старые классы

Если язык программирования имеет решение, то его называют expressive (выразительным).
В Python есть решение - структурная типизация через Protocol (добавили в 2017 году в версии 3.8).

Например, вот мой путь:
1️) ООП с наследованием (ABC) - легко добавлять новые типы, но операции сложно
2️) ФП с матчингом - легко добавлять новые функции, но типы сложно
3️) Protocols - золотая середина в Python

Если погрузиться в "PEP 544 – Protocols: Structural subtyping (static duck typing)", то можно сделать вывод что это по сути официальное решение Expression Problem в Python.

Лайфхак:
Когда проектируешь систему, нужно спросить себя: "Что вероятнее будет расширяться - типы данных или операции над ними?" Исходя из ответа, нужно выбирать один подход из перечисленных выше.

Кажется, в современном быстроменяющемся мире, при проектировании систем нужно предпочтение отдавать Protocols. Так система должна легко поддерживать "удобное расширение как по оси типов, так и по оси операций".
👀3👍2
[Parse, Don't Validate]

Оказывается, привычка везде вставлять if (isValid(...)) - это системная ошибка.

Сегодня открыл для себя философию «Parse, Don't Validate».
Вместо того чтобы постоянно спрашивать «корректны ли данные?», нужно один раз на границе системы преобразовать их в гарантированно корректный, «богатый» тип. После этого можно просто ему доверять.


Как это работает:
1) На границе (API, форма, БД) мы парсим «сырые» данные.
2) Создаём объекты специальных типов (например, Email, NonEmptyList, PaidOrder), которые невозможно создать в некорректном состоянии.
3) Вся бизнес-логика внутри системы работает только с этими доверенными типами. Никаких if-ов.

Лайфхак:
Когда проектируешь систему, спроси себя: "Где настоящая граница моей системы?".
Именно там нужно парсить данные. Всё, что внутри - должно быть уже валидным.

Идеальная система должна:
- Преобразовывать сырые данные в "богатые" типы на границе
- Работать внутри только с гарантированно валидными данными
- Иметь 0 проверок в бизнес-логике

P.s.
Рекомендую прочитать статью-первоисточник: Parse, don’t validate
👍5👀3🔥1
[А вы используете логику Хоара в разработке?]

Я с ней знаком уже пару лет.
Хочу сейчас поделиться размышлениями по данной теме.

Что скрывается за терминами "предусловия", "постусловия" и "инварианты"? Если я скажу, что это та самая штука, которая превращает программирование из гадания на кофейной гуще в инженерную дисциплину, то это не будет преувеличением.

Вот в чём прикол:

1) Ваш код может "работать" и при этом быть полным фарсом
Вы когда-нибудь писали функцию, которая вроде бы делает что надо, но при этом где-то в глубине души понимаете, что она может сломаться в любой момент? Вот это и есть отсутствие гарантий. Логика Хоара говорит: давайте чётко прописывать, при каких условиях функция работает ("предусловие") и что она гарантирует на выходе ("постусловие").

2) Функции - это не чёрные ящики, а контракты
Каждая функция должна чётко заявлять: "Я принимаю вот это, и обещаю вернуть вот это". Если она начинает делать что-то ещё (например, менять глобальное состояние или выбрасывать неожиданные исключения), это как если бы вы заказали пиццу, а получили бутерброд. У меня, кстати, недавно так было - заказывали нагетсы, а получили картошку).

3) Инварианты - это правила, которые нельзя нарушать
Ваш код - это игра с правилами. Инвариант - это такое правило, которое должно выполняться всегда, что бы ни происходило.

Почему это важно?
Потому что когда начинаете мыслить в терминах логики Хоара, вы перестаёте надеяться на удачу и начинаете строить систему, которая действительно надёжна. Это как перейти от "авось пронесёт" к "я знаю, что это сработает, потому что я продумал все условия".

Лайфхак:
В следующий раз, когда будете писать функцию, спросите себя:
- Какие условия должны выполняться на входе? ("предусловие")
- Что я гарантирую на выходе? ("постусловие")
- Какие правила нельзя нарушать? ("инварианты")

Тогда код перестанет быть лотереей и станет предсказуемым, как швейцарские часы.
Но это не точно))
🔥6👍3👀2
This media is not supported in your browser
VIEW IN TELEGRAM
[Какие пред- и пост-условия должны быть? И почему это вообще важно?]

Продолжаю рассматривать данную тему. Она правда крайне интересна в практическом применении.
Слышали рекомендации "ослабляй предусловия и усиливай постусловия"?

1) Предусловия (Preconditions): Будьте либеральны на входе
- Какими должны быть: Максимально слабыми (широкими).
- Пример: Вместо "принимаю только массив строк", скажите "принимаю массив, одиночную строку или даже null".
- Почему это важно: Это делает ваш код удобным. Другим разработчикам (и вам через месяц) не нужно обкладывать вызов вашей функции кучей проверок if (x !== null && Array.isArray(x)). Вы берете эту рутину на себя, делая систему устойчивой к "грязным" данным.

2) Постусловия (Postconditions): Будьте строги на выходе
- Какими должны быть: Максимально сильными (узкими и точными).
- Пример: Вместо "возвращаю объект и null", гарантируйте "возвращаю валидный объект".
- Почему это важно: Это дает уверенность. Вызывающий код точно знает, чего ожидать. Ему не нужно гадать "а что, если вернется undefined?". Это снижает когнитивную нагрузку и количество багов.

Оказывается есть золотое правило:
"Будь строг к тому, что производишь, и либерален к тому, что принимаешь."
(Закон Постела)

Советую почитать об этом законе подробнее.

Этот принцип работает не только в протоколах интернета, но и в архитектуре любой надежной программы.

Но есть один нюанс.
Всегда ли нужно быть "либеральным" и принимать любые данные? Где именно нужно ослаблять предусловия? Неужели во всех функциях проекта?

В следующем посте разберем, где нужно ослаблять предусловия, а где этого делать не следует.
👍8
This media is not supported in your browser
VIEW IN TELEGRAM
[Где и когда применять ослабление предусловий?]

Неужели нужно придерживаться ослабления предусловий в каждой функции?
Зачем мы продумываем систему типов, если мы должны ослаблять предусловия?

Есть ответы на вопросы.

Этот подход критически важен на границах системы или модулей. Там, где я не контролирую вызывающий код.

1. Публичные библиотеки и утилиты:
- Функции типа formatDate, parseJson, safeDivide.
- Почему: Ими пользуются разные части системы. Если утилита падает от null, это заставляет каждого потребителя писать проверки. Лучше один раз обработать null внутри утилиты.

2. Обработчики данных из внешних источников (API, User Input):
- Парсеры ответов бэкенда, валидаторы форм.
- Почему: Мы не доверяем внешнему миру. Соседний микросервис может прислать мусор. Пользователь может ввести что угодно. Код на границе должен быть готов принять "любой" вход и безопасно его обработать (или отвергнуть с понятной ошибкой).

(Вспоминаем подход Parse, don't validate, о котором писал выше)

А вот внутри ядра системы, где я полностью контролирую потоки данных, лучше использовать сильные предусловия (Design by Contract).

1. Бизнес-логика и ядро (Domain Model):
- Методы сущностей (Order.calculateTotal(), User.changePassword()).
- Почему: Если метод calculateTotal вызван для заказа без товаров - это баг в логике программы, а не "допустимый случай". Здесь лучше упасть (fail fast) или выбросить исключение, чтобы разработчик сразу нашел ошибку. Замалчивание проблемы (возврат 0) может привести к потерям.

2. Приватные методы и внутренние хелперы:
- Функции, которые вызываются только из одного-двух мест, которые вы контролируете.
- Почему: Лишние проверки замусоривают код и снижают производительность. Если вы гарантируете (через типы или логику), что null сюда не придет - не надо его обрабатывать.

Есть еще правило "Баррикады"
(погуглите или спросите у LLM)

1) Стены замка (Границы):
Здесь стоят стражники (ослабленные предусловия). Они проверяют всех входящих, отсеивают врагов, чистят грязные ботинки (нормализуют данные).
2) Внутри замка (Ядро):
Все доверяют друг другу. Не нужно носить оружие и проверять документы на каждом шагу (сильные предусловия). Они ожидают, что стража на входе уже сделала свою работу.

Итого:
- На границах (UI, API, Utils):
Нужно быть либеральным (принимать многое - "слабые предусловия").

- В ядре (Domain):
Нужно быть строгим (требовать валидных данных - "сильные предусловия").
Не зря же я тратил время и продумывал систему типов))
👍4💯1