<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Лаборатория</title>
    <link>https://www.alexkorablev.ru/</link>
    <description>Recent content on Лаборатория</description>
    <generator>Hugo</generator>
    <language>ru-ru</language>
    <lastBuildDate>Tue, 09 Jun 2026 12:02:14 +0500</lastBuildDate>
    <atom:link href="https://www.alexkorablev.ru/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Возврат смысла хобби</title>
      <link>https://www.alexkorablev.ru/general/make-hobby-great-again/</link>
      <pubDate>Tue, 09 Jun 2026 12:02:14 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/general/make-hobby-great-again/</guid>
      <description>Эти 5 минут с гитарой приносят куда больше радости, чем любые занятия ради заработка — и именно это заставило меня пересмотреть и хобби, и работу.</description>
    </item>
    <item>
      <title>Макросы SugarCube 2 для диалогов</title>
      <link>https://www.alexkorablev.ru/gamedev/twine-dialogs/</link>
      <pubDate>Wed, 20 May 2026 18:11:31 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/gamedev/twine-dialogs/</guid>
      <description>&lt;p&gt;В своей игре «Заповедник» — текстовых sci‑fi приключениях Маши Ежевикиной в духе Булычёва — я активно использую диалоги. Маша и Ромка постоянно болтают — по делу и просто так.&lt;/p&gt;
&lt;p&gt;Для книги правила оформления диалогов понятны: каждая реплика — с новой строки, с чёрточки. Я попробовал делать так же в игре — и это быстро превратилось в… книгу. А мне нужна игра!&lt;/p&gt;
&lt;h2 id=&#34;эксперименты-с-диалогами&#34;&gt;Эксперименты с диалогами&lt;/h2&gt;
&lt;p&gt;Путём нескольких экспериментов я пришёл к такому варианту: диалоги выводятся блоками с небольшими иконками. Выглядит это вот так:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Новый формат блога</title>
      <link>https://www.alexkorablev.ru/general/new-format/</link>
      <pubDate>Tue, 12 May 2026 18:46:01 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/general/new-format/</guid>
      <description>&lt;p&gt;Этому блогу уже почти 11 лет. Я начал его в 2015 году, чтобы ускорить карьеру. Получилось более или менее — не совсем так, как я рассчитывал, но всё же помогло: я упорядочил знания и успешно строю карьеру. Теперь же такой блог мне не нужен. Вот почему:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Я выдохся писать про ИТ.&lt;/strong&gt; Мне по‑прежнему нравится изучать новое и разбираться в технологиях. Но писать подробные статьи уже не хочется: это долго и нудно, а на Хабре всё равно сделают лучше. А короткие заметки казались мне недостойными блога — хотя я их всё равно иногда писал.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;У меня поменялись приоритеты.&lt;/strong&gt; Работа, семья и хобби отнимают почти всё время. Писать для меня — хобби, но профессионально заниматься ИТ‑тематикой я не готов: как уже говорил, это слишком долго и утомительно.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Рекрутёрам блог не нужен.&lt;/strong&gt; Они на него не смотрят, и он не делает прохождение собеседования легче. От большинства статей польза только для меня: мысль выкристаллизовалась, знание закрепилось. Для этого достаточно короткой заметки, а не многостраничного разбора всех случаев — что, повторюсь, долго и нудно.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Я долго думал (и советовался с ИИ… чаще, чем хотелось) и решил: с этого момента мой ИТ‑блог становится «Лабораторией». Здесь будут заметки о том, что меня волнует прямо сейчас. Не обещаю регулярности — буду писать, когда есть что сказать. Ещё я соберу здесь всё, что писал для других своих блогов (в основном о хобби).&lt;/p&gt;</description>
    </item>
    <item>
      <title>Вторичные индексы в YDB</title>
      <link>https://www.alexkorablev.ru/dev/ydb-secondary-indexes/</link>
      <pubDate>Mon, 23 Mar 2026 21:40:27 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/ydb-secondary-indexes/</guid>
      <description>&lt;p&gt;Вторичные индексы в YDB живут в скрытых таблицах. Они так же чувствительны к возможности деления на партиции по ключам, как и обычные строковые таблицы.&lt;/p&gt;
&lt;p&gt;Способность делиться на партиции вторичные индесы наследуют от первичного ключа исходной таблицы.&lt;/p&gt;
&lt;p&gt;Согласно документации во вторичном индексе хранится:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;индексные колонки&lt;/li&gt;
&lt;li&gt;колонки первичного ключа таблицы&lt;/li&gt;
&lt;li&gt;копии дополнительных колонок для покрывающих индексов&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;NB!&lt;/strong&gt; первичный ключ таблицы вторичного ключа - это индексные колонки + колонки первичного ключа исходной таблицы.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Обман на собеседовании</title>
      <link>https://www.alexkorablev.ru/general/interview-cheating/</link>
      <pubDate>Thu, 19 Jun 2025 18:50:10 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/general/interview-cheating/</guid>
      <description>&lt;p&gt;На собеседовании хочется ответить на все вопросы, даже на те, на которые не знаешь ответа. Особенно если пришёл на собеседование в крутую компанию. Мотивация зашкаливает, и здесь можно допустить самую большую ошибку: попытаться схитрить и подсмотреть ответ. Во время онлайн‑интервью это ведь так просто сделать… Но есть более выгодная и безопасная стратегия: ответить «я не знаю» и записать вопрос для дальнейших поисков ответа.&lt;/p&gt;
&lt;p&gt;Есть три варианта действий при вопросе, ответа на который не знаешь. Вот они — в порядке пользы для кандидата:&lt;/p&gt;</description>
    </item>
    <item>
      <title>CLOG в базе знаний программиста</title>
      <link>https://www.alexkorablev.ru/general/clog/</link>
      <pubDate>Wed, 26 Mar 2025 18:47:52 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/general/clog/</guid>
      <description>&lt;p&gt;CLOG — удобный формат ведения лога проекта — для задачи, на которую требуется больше одного дня, — в базе знаний. Изначально идея &lt;a href=&#34;https://writing.bobdoto.computer/how-i-use-clogs-to-organize-my-writing-files/&#34;&gt;предложена&lt;/a&gt; Бобом Дото для работы над статьями. С минимальными изменениями CLOG подходит для рабочих проектов программиста.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Пока эта методика находится у меня на тестировании. Должно работать. Но может и взорваться…&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Суть CLOG (creative log) — создать запись в системе знаний, которая относится к конкретному проекту. В этой записи делается минимум два блока:&lt;/p&gt;</description>
    </item>
    <item>
      <title>За что платят программисту?</title>
      <link>https://www.alexkorablev.ru/general/programmer-capital/</link>
      <pubDate>Mon, 10 Mar 2025 18:42:16 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/general/programmer-capital/</guid>
      <description>&lt;p&gt;Программисту платят за код. Писать код — основной навык, который нужно показать в работе и на собеседовании. Знания технологий добавят очков, как и софт‑скилы. Но если программист не будет писать код, его уволят. Этот навык требует больше всего времени на освоение. Он же — лучший карьерный капитал программиста.&lt;/p&gt;
&lt;p&gt;Написание кода — сложный навык. Улучшить его — значит целенаправленно заниматься развитием этого навыка: писать много кода, который будет тестироваться, использоваться, модифицироваться.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Посмотреть процессы прибитые OOM</title>
      <link>https://www.alexkorablev.ru/dev/oom/</link>
      <pubDate>Sun, 08 Sep 2024 18:40:16 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/oom/</guid>
      <description>&lt;p&gt;PID убитого по out‑of‑memory‑процессу можно найти с помощью одной команды. Если есть логи с PID процесса, то найти пострадавшего можно, запустив ещё одну команду &lt;code&gt;grep&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;OOM‑киллер безжалостен. Кажется, что он выбирает процесс случайным образом — тот, который нужно «пристрелить» на машине. На самом деле под капотом он работает совсем по‑другому, и случайности в его действиях нет. Взглянув на таблицу процессов и пару файлов, можно предсказать, какой процесс будет убит, если сейчас случится OOM.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Heavy Rain</title>
      <link>https://www.alexkorablev.ru/music/alex-cargo/heavy-rain/</link>
      <pubDate>Thu, 08 Aug 2024 14:46:50 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/music/alex-cargo/heavy-rain/</guid>
      <description>&lt;p&gt;Я долго обходил тему сэмплов стороной. Для меня синтезаторы были главными действующими лицами. Конечно, я делал треки с использованием сэмплов перкуссии. И, конечно, я использую отдельные сэмплы для ударных. Но чтобы идея трека строилась от музыкальной фразы, взятой из набора сэмплов… Не могу сказать, что я не делал этого раньше. Но тогда это были скорее учебные проекты. &lt;em&gt;&lt;strong&gt;Heavy Rain&lt;/strong&gt;&lt;/em&gt; — первый серьёзный опыт в жанре мелодичного техно.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ссылки на трек собраны здесь: &lt;a href=&#34;https://band.link/heavyrain&#34;&gt;https://band.link/heavyrain&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Запасная сборка ссылок здесь: &lt;a href=&#34;https://onerpm.link/146039684268&#34;&gt;https://onerpm.link/146039684268&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Как я уже говорил, обычно я использую синтезаторы. При этом я коллекционирую сэмплы. В ней скопились сотни гигабайт сэмплов, большую часть из которых я даже не слышал ни разу. И вот моя коллекция пополнилась очередным набором сэмплов. Новый пак ждала такая же участь: хоть я его послушал, но трек делать не собирался. А ведь это был набор от моих любимых саунд‑дизайнеров из Riemann.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Chess</title>
      <link>https://www.alexkorablev.ru/music/alex-cargo/chess/</link>
      <pubDate>Fri, 21 Jun 2024 14:42:12 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/music/alex-cargo/chess/</guid>
      <description>&lt;p&gt;Вышел сингл &lt;em&gt;Chess&lt;/em&gt; — мелодичное техно с вкраплениями acid‑партии. Не аутентичного 303 от Roland, а имитации. Хотел проверить, как такой звук зайдёт в жанр. Проверил.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://band.link/alexcargochess&#34;&gt;Слушать &lt;em&gt;Chess&lt;/em&gt; на ваших любимых стриминговых платформах&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Часто название трека придумываю заранее, когда делаю первый набросок. Сохраняю проект и сразу даю название. И это название во многом определяет звук и идею трека. Так было с &lt;em&gt;Summer Holidays on Mars&lt;/em&gt;, с &lt;em&gt;Poker Face&lt;/em&gt;, с &lt;em&gt;Reunion&lt;/em&gt;. Обычно связь между названием и звуком понятна мне одному. В последнем случае название вызвало у меня ассоциации с «Бегущим по лезвию» и его саундтреком от Ван Гелиса.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Summer Holidays on Mars</title>
      <link>https://www.alexkorablev.ru/music/alex-cargo/summer-holidays-on-mars/</link>
      <pubDate>Fri, 10 May 2024 17:48:53 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/music/alex-cargo/summer-holidays-on-mars/</guid>
      <description>&lt;p&gt;&lt;strong&gt;Summer Holidays on Mars&lt;/strong&gt; — это мой новый трек в стиле Melodic Techno, который уже доступен на всех стриминговых платформах. Диджеи и создатели видео могут скачать его бесплатно.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://band.link/summerholidaysonmars&#34;&gt;Послушайте Summer Holidays on Mars на всех основных стриминговых сервисах&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Мелодия трека захватывает с первых нот, а ударные инструменты призывают танцевать. Мне очень нравится этот трек (кто бы мог подумать ;)). Я надеюсь, что &lt;em&gt;Summer Holidays on Mars&lt;/em&gt; можно будет наслаждаться как дома, так и в диджейском сете на шумной клубной вечеринке.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Практический пример использования Protocol</title>
      <link>https://www.alexkorablev.ru/dev/protocol/</link>
      <pubDate>Mon, 26 Feb 2024 18:36:23 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/protocol/</guid>
      <description>&lt;p&gt;Представьте себе ситуацию: у вас есть микросервисы, в каждом — своя конфигурация со своим набором параметров; есть библиотечный код, который получает и использует объекты конфигураций. Представили? А теперь в этот код надо завести подсказки типов. И тут представили? Давайте проведём мысленный эксперимент и попробуем это сделать. Вариантов в целом несколько.&lt;/p&gt;
&lt;p&gt;Варианты решения:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Базовый класс конфигурации с ещё одним ветвлением:*
&lt;ul&gt;
&lt;li&gt;затаскивать все возможные параметры;&lt;/li&gt;
&lt;li&gt;затаскивать только общие для микросервисов параметры.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Использовать протоколы для нотации типов.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Затаскивать все возможные варианты параметров в один базовый класс — гарантированный путь к «помойке». Затаскивать только общие параметры для микросервисов — получать кучу красного цвета от Pyright в общем коде.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Poker Face</title>
      <link>https://www.alexkorablev.ru/music/alex-cargo/poker-face/</link>
      <pubDate>Fri, 08 Dec 2023 17:44:10 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/music/alex-cargo/poker-face/</guid>
      <description>&lt;p&gt;В сердце электронного лабиринта лежит «Poker Face» — музыкальное путешествие сквозь пульсирующие тени тёмного, мелодичного техно.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://band.link/pokerface&#34;&gt;Слушать Poker Face на ваших любимых стриминговых платформах&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Это инструментальное произведение создаёт звуковую ткань, окутывая слушателей загадочной атмосферой. Благодаря осознанно низкой эмоциональной динамике трек создаёт таинственную атмосферу, управляемую гипнотическими битами и сложными аранжировками синтезаторов. Отсутствие вокала усиливает эффект погружения, позволяя музыке говорить напрямую с душой.&lt;/p&gt;
&lt;p&gt;«Poker Face» — это исследование неизведанных областей техно, путешествие по электронным звуковым ландшафтам, которое выходит за рамки традиционных границ жанра.&lt;/p&gt;</description>
    </item>
    <item>
      <title>У Kаждого Cвой SCRUM</title>
      <link>https://www.alexkorablev.ru/general/scrum/</link>
      <pubDate>Tue, 28 Nov 2023 18:31:44 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/general/scrum/</guid>
      <description>&lt;p&gt;У каждого свой Scrum. Он описан в книгах как стройный, понятный и простой процесс. Участники семинаров и тренингов утверждают, что применять его легко. Однако в реальной жизни Scrum каждого человека не похож ни на пример из книг или тренингов, ни на процессы коллег… за редкими исключениями. Почему? Не знаю. Куда интереснее выяснить, что с этим делать и нужно ли это.&lt;/p&gt;
&lt;h2 id=&#34;tldr&#34;&gt;TL;DR&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Scrum эффективен, когда желания бизнеса и разработки совпадают и они готовы играть по этим правилам.&lt;/li&gt;
&lt;li&gt;Scrum определяет чёткие зоны ответственности и правила для скрам‑команды. Если попытаться изменить их, это может привести к проблемам.&lt;/li&gt;
&lt;li&gt;Если вы устанавливаете сроки для разработчиков, определяете исполнителей задач и не ведёте бэклог, то у вас нет Scrum, даже при наличии спринтов и ежедневных митингов.&lt;/li&gt;
&lt;li&gt;В вашей команде есть скрам‑мастер, даже если он не выделен формально. Один из членов команды выполняет эту функцию. Это занимает у него время и, возможно, вызывает лишний стресс.&lt;/li&gt;
&lt;li&gt;Наём скрам‑мастера показывает разработке, что компания готова играть по правилам и ожидает долгосрочного применения Scrum.&lt;/li&gt;
&lt;li&gt;При работе с большой командой следует разделить её на несколько подгрупп и использовать LeSS или «Scrum of Scrums».&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Я не знаю, какой Scrum можно считать идеальным. Я не являюсь сертифицированным скрам‑мастером. Я всего лишь разработчик. Эта статья — моя попытка понять, каким должен быть Scrum, зачем вам нужен скрам‑мастер и в каких случаях Scrum не работает. Повторяю: это мнение разработчика, участника скрам‑команды, а не консультанта.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Использование typing.Generic в Python</title>
      <link>https://www.alexkorablev.ru/dev/generics-in-python/</link>
      <pubDate>Fri, 18 Feb 2022 18:28:28 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/generics-in-python/</guid>
      <description>&lt;p&gt;Я работаю над проектом с довольно большой кодовой базой. Проект с историей.&lt;/p&gt;
&lt;p&gt;Некоторые части наша команда написала задолго до аннотаций типов. Мы до сих пор добавляем их в наш легаси‑код и улучшаем существующие подсказки. Стоит ли эта игра свеч? Определённо — да.&lt;/p&gt;
&lt;p&gt;Наши пользователи — разработчики. Они открывают наш код в PyCharm ежедневно и надеются, что он поможет им решить их задачи максимально быстро и просто.&lt;/p&gt;
&lt;p&gt;Могу уверенно сказать, что существует корреляция между точностью автодополнения кода и тем, как быстро работают разработчики. Наша цель — не только добавить более точный статический анализ или автодополнение, но и не сломать их боевой код.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Для чего Python лучше не использовать?</title>
      <link>https://www.alexkorablev.ru/dev/what-is-python-not-good-for/</link>
      <pubDate>Fri, 22 Nov 2019 18:26:11 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/what-is-python-not-good-for/</guid>
      <description>&lt;p&gt;На Quora относительно недавно задали вопрос «What is Python not good for?». Я бы хотел сказать, что Python хорош для всего. Но это неправда. Python во многих областях — второй. Не так много областей, где Python — номер один.&lt;/p&gt;
&lt;p&gt;К примеру, Go сейчас гораздо больше подходит для веб‑разработки, чем Python. Его довольно легко выучить, его гораздо легче деплоить. В Go есть достаточное количество «батареек» для любого веб‑приложения. Тем не менее Python остаётся второй опцией.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Подсказки типов в Python</title>
      <link>https://www.alexkorablev.ru/dev/python-typing-hints-list/</link>
      <pubDate>Fri, 24 May 2019 18:22:15 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/python-typing-hints-list/</guid>
      <description>&lt;p&gt;Мой небольшой список источников по type hints в Python, которые я использую в повседневной практике.&lt;/p&gt;
&lt;p&gt;Относительно недавно я сменил проект. Теперь я работаю над DWH и ETL‑процессами. Проект большой: в нём сравнимое количество кода с предыдущим, но разработчиков гораздо больше. Я убеждён, что для этого проекта подсказки типов даже нужнее. Дело не только в количестве разработчиков.&lt;/p&gt;
&lt;p&gt;Особенность DWH/ETL‑проектов — наличие разнообразных источников, мест хранения и потребителей данных. Отсюда довольно сильная фрагментированность проекта. И если не добавить «клея», он развалится на отдельные скрипты.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Clash of Code</title>
      <link>https://www.alexkorablev.ru/dev/clash-of-code/</link>
      <pubDate>Fri, 26 Apr 2019 18:20:27 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/clash-of-code/</guid>
      <description>&lt;p&gt;В начале года я &lt;a href=&#34;%7Bfilename%7D/2019-01-02-2019-plans.md&#34;&gt;писал&lt;/a&gt;, что хочу сделать большой и интересный проект с &lt;a href=&#34;https://www.codingame.com&#34;&gt;Codingame&lt;/a&gt;: создать и обучить бота для &lt;em&gt;Legends of Code &amp;amp; Magic&lt;/em&gt;. В очередной раз, когда я прокрастинировал начало этого проекта, я наткнулся на &lt;a href=&#34;https://www.codingame.com/multiplayer/clashofcode&#34;&gt;Clash of Code!&lt;/a&gt; — быстрые мини‑соревнования по кодированию на этом же сайте. Попробовав поиграть, я могу сказать, что это отличный способ отвлечься от рабочей рутины, попутно потренировав свои навыки.&lt;/p&gt;
&lt;h2 id=&#34;формат-clash-of-code&#34;&gt;Формат Clash of Code&lt;/h2&gt;
&lt;p&gt;Эти мини‑соревнования строятся по такому принципу:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Переименование при импорте</title>
      <link>https://www.alexkorablev.ru/dev/import-aliases/</link>
      <pubDate>Mon, 18 Mar 2019 18:18:34 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/import-aliases/</guid>
      <description>&lt;p&gt;В Python есть замечательная возможность присваивать свои имена при импорте (&lt;code&gt;import foo.bar.baz as fbb&lt;/code&gt;). Так можно легко избежать конфликтов имён при импорте и повысить читаемость кода, если требуется. Но этой же возможностью можно легко превратить хороший код в абсолютно нечитаемый. В последнее время я несколько раз встречался с этим: попадались мне в основном странные сокращения и непонятные имена для алиасов.&lt;/p&gt;
&lt;p&gt;Продемонстрирую проблему на примере сокращений. Хороший пример придумать с ними проще:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Пожалуйста, не используйте else</title>
      <link>https://www.alexkorablev.ru/dev/if-else/</link>
      <pubDate>Tue, 29 Jan 2019 18:15:47 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/if-else/</guid>
      <description>&lt;p&gt;Я не люблю &lt;code&gt;else&lt;/code&gt;, когда обе ветки содержат &lt;code&gt;return&lt;/code&gt;. Всегда можно написать код без этого придатка для &lt;code&gt;if&lt;/code&gt;. Такой код будет компактнее, проще читаться и лучше выглядеть. Так зачем же многие пишут этот никчёмный &lt;code&gt;else&lt;/code&gt;?&lt;/p&gt;
&lt;p&gt;Делая ревью кода одного из коллег, я указал на то, что его код можно упростить, убрав &lt;code&gt;else&lt;/code&gt;. Ответом была ссылка на PEP8, где такое поведение определяется допустимым. Код был примерно таким:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;get_magic_number&lt;/span&gt;(use_magic):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; use_magic:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; calculate_with_magic()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; calculate_with_science()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;С точки зрения работоспособности этому коду нечего предъявить. Меня, как читателя, такой код заставляет остановиться и задуматься:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Мобильное приложение на Kivy и Python? Мм… Не сейчас</title>
      <link>https://www.alexkorablev.ru/dev/kivy-mobile/</link>
      <pubDate>Thu, 25 Oct 2018 16:47:52 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/kivy-mobile/</guid>
      <description>&lt;p&gt;Есть несколько GUI‑фреймворков на Python. Большинство из них предназначены только для десктопных приложений. Kivy — редкое исключение: с использованием этого фреймворка можно, в теории, строить мобильные приложения. К сожалению, он не готов к продакшену. Вы вынуждены жонглировать версиями библиотек, чтобы заставить это работать. Так что, даже сидя в футболке с надписью &lt;code&gt;print(&amp;quot;Python is my favorite language&amp;quot;)&lt;/code&gt;, я должен признать, что Kivy не подходит для мобильной разработки.&lt;/p&gt;
&lt;p&gt;Хорошо. Жонглировать версиями приходится и в случае веб‑приложения. Но всё‑таки тогда в 99 % случаев речь идёт о библиотеках Python либо есть контроль над окружением. В целом вы можете построить Docker‑образ с любыми версиями, какие необходимы. Kivy же вносит кучу бинарных зависимостей, которые должны быть установлены с помощью специфичных для платформ инструментов. И в целом вы не сможете контролировать окружение — а это меняет всё.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Использовать Optional в абстрактных классах или нет?</title>
      <link>https://www.alexkorablev.ru/dev/optional-or-not/</link>
      <pubDate>Thu, 06 Sep 2018 16:45:46 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/optional-or-not/</guid>
      <description>&lt;p&gt;Подсказки типов в Python необязательны: вы вольны выбирать, пользоваться ими или нет. Но, начав включать их в свой код, вы точно столкнётесь с определёнными трудностями аннотирования функций или переменных. Эта статья — моя точка зрения на один специфический случай.&lt;/p&gt;
&lt;p&gt;К примеру, имеется иерархия классов, которая выглядит похожей на ту, что представлена в коде ниже. Это может быть какой‑то маппинг в базу или иерархия команд. Самая важная часть в этом примере — то, что имеется один абстрактный класс и несколько реальных классов, его наследников. Не так важно, помечен ли этот абстрактный класс специальным образом или нет. Я просто предполагаю, что он используется в качестве такового.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Coders Strike Back Post-mortem</title>
      <link>https://www.alexkorablev.ru/dev/coders-strike-back/</link>
      <pubDate>Thu, 12 Jul 2018 16:42:09 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/coders-strike-back/</guid>
      <description>&lt;p&gt;За последние несколько месяцев я потратил порядка 40 часов в выходные и по вечерам на то, чтобы написать бота, способного пройти трассу &lt;a href=&#34;https://www.codingame.com/multiplayer/bot-programming/coders-strike-back&#34;&gt;Coders Strike Back&lt;/a&gt; быстрее соперников. За эти 40 часов я умудрился набить порядочное количество шишек, выбраться в легендарную лигу и даже занять там, на мой взгляд, пристойное место. Данный пост — post mortem этого проекта.&lt;/p&gt;
&lt;p&gt;Важная оговорка: бо́льшая часть пути была проделана с ботами на Python, но заключительные этапы были пройдены на C++. Не думаю, что дело в Python — скорее всего, я не заметил кучу ошибок в своём коде, которые было лень исправлять, но об этом ниже.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Computer Science Distilled</title>
      <link>https://www.alexkorablev.ru/dev/computer-science-distilled/</link>
      <pubDate>Wed, 28 Feb 2018 16:38:43 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/computer-science-distilled/</guid>
      <description>&lt;p&gt;Хотите найти небольшую простую книгу о компьютерных науках? Возможно, &lt;a href=&#34;https://sourcemaking.com/computer-science-distilled&#34;&gt;Computer Science Distilled&lt;/a&gt; подойдёт. К сожалению, только в том случае, если вы не планируете программировать профессионально. В этом случае эта книга — хороший вводный курс, хороший проводник в мир компьютерных наук. Но если вы профессиональный девелопер или студент, можно смело пропускать эту книгу.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It’s a short book, written in plain, basic English. It presents ideas in their simplest form. It focuses on practical aspects of computer science that matter most: everyday things that directly impact the quality of your code.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Tuple[Callable, Any, ...]</title>
      <link>https://www.alexkorablev.ru/dev/tuple-type/</link>
      <pubDate>Mon, 29 Jan 2018 16:35:53 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/tuple-type/</guid>
      <description>&lt;p&gt;Подсказки с типами могут сильно помочь в работе с большим проектом на Python. Тем не менее иногда они требуют рефакторинга кода. Я писал об этом в прошлом году &lt;a href=&#34;%7Bfilename%7D2017-11-10-typing-ci.md&#34;&gt;в этой статье&lt;/a&gt;, но тогда я не смог найти хорошего примера, иллюстрирующего то, что я хочу сказать.&lt;/p&gt;
&lt;p&gt;Взгляните на этот код:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;process&lt;/span&gt;(workflow_step):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    func &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; step[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    args &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; step[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;:]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; func(&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;args)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Что можно понять о типах из этого кусочка? То, что &lt;code&gt;workflow_step&lt;/code&gt; — это последовательность, первый элемент которой — &lt;code&gt;Callable&lt;/code&gt; object, а остальные элементы, если таковые имеются, — аргументы для этого вызываемого объекта. Предположим, что &lt;code&gt;workflow_step&lt;/code&gt; — &lt;code&gt;Tuple&lt;/code&gt;. Проблема в том, что тип &lt;code&gt;(Tuple) -&amp;gt; Any&lt;/code&gt; для этой функции слишком общий и неинформативный. Можем ли мы вызвать её с пустым кортежем? Пройдёт ли &lt;code&gt;(1, 2, 3)&lt;/code&gt;?&lt;/p&gt;</description>
    </item>
    <item>
      <title>Как внедрить mypy в проекте на Python 2.7</title>
      <link>https://www.alexkorablev.ru/dev/typing-ci/</link>
      <pubDate>Mon, 11 Dec 2017 17:34:15 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/typing-ci/</guid>
      <description>&lt;p&gt;Я многократно писал, что описание типов в Python помогает в работе с большими и средними проектами. При этом, если внедрять типы, то нужно регулярно делать статический анализ — причём в CI. А вот это уже не так‑то просто внедрить. Эта статья — мой рассказ о том, какие трудности придётся преодолеть в процессе внедрения.&lt;/p&gt;
&lt;p&gt;За то время, что я пытаюсь внедрить проверку типов в нашем проекте, я выработал несколько подходов к тому, как это можно сделать максимально быстро и безболезненно. На то, чтобы прийти к этому, я убил не один день. Пользуйтесь моим опытом.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Что почитать о asyncio. 9 полезных ссылок</title>
      <link>https://www.alexkorablev.ru/dev/asyncio-articles/</link>
      <pubDate>Fri, 20 Oct 2017 17:31:50 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/asyncio-articles/</guid>
      <description>&lt;p&gt;Asyncio — полезная библиотека. Но разобраться с ней не так‑то просто. Документации по большей части недостаточно. Хочется примеров. Хочется подробных объяснений. Последние несколько выходных я потратил на эксперименты с этой библиотекой. Во время чего в Pocket осели довольно интересные ссылки, которыми я хочу поделиться.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&#34;http://www.giantflyingsaucer.com/blog/?p=5557&#34;&gt;Exploring Python 3’s Asyncio by Example&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Короткое введение в &lt;code&gt;asyncio&lt;/code&gt; и &lt;code&gt;aiohttp&lt;/code&gt; на нескольких небольших примерах. Примеры сделаны максимально простыми. Используется синтаксис с декораторами — статья написана довольно давно. Как отмечает автор, эта статья показывает лишь верхушку айсберга.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Поддержка целостности проекта в Python требует усилий</title>
      <link>https://www.alexkorablev.ru/dev/python-project-integrity/</link>
      <pubDate>Fri, 06 Oct 2017 17:28:58 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/python-project-integrity/</guid>
      <description>&lt;p&gt;Python позволяет программисту довольно много. Это очень выразительный язык. Его динамическая природа даёт возможность делать элегантные решения, которые довольно сложно представить, к примеру, в Java.&lt;/p&gt;
&lt;p&gt;Тем не менее за всё надо платить. При росте кодовой базы проекты на Python начинают требовать всё больше и больше ресурсов на поддержание своей целостности. Без некоторых усилий проект начинает разваливаться на куски.&lt;/p&gt;
&lt;h2 id=&#34;первая-проблема--навигация-по-коду&#34;&gt;Первая проблема — навигация по коду&lt;/h2&gt;
&lt;p&gt;Основная проблемная часть — навигация по коду. На начальном этапе её зачастую приносят в жертву более компактному решению, что впоследствии обязательно приведёт к ряду проблем. Главная из которых — высокая сложность поиска причин ошибок.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Хэш-функция для функции в Python</title>
      <link>https://www.alexkorablev.ru/dev/function-hash/</link>
      <pubDate>Tue, 12 Sep 2017 17:26:17 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/function-hash/</guid>
      <description>&lt;p&gt;Пару недель назад один из моих коллег задал вопрос: можно ли использовать функцию в качестве ключа словаря? Да, можно. У каждой функции в Python есть хеш. Но как он считается? На основе имени функции? На основе байт‑кода? В действительности хэш считается как трансформация над указателем на объект функции. Тем не менее не так‑то легко отыскать эти расчёты в коде CPython.&lt;/p&gt;
&lt;p&gt;Навигация по C‑коду — довольно интересный опыт, хотя делать это совсем непросто: все эти макросы делают простой поиск нужных переходов довольно сложным. Конечно, я уверен, что вы сможете с этим справиться и найти все вызываемые функции при запросе хеша для объекта функции.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Success in Programming. Обзор Книги</title>
      <link>https://www.alexkorablev.ru/general/success-in-programming/</link>
      <pubDate>Thu, 17 Aug 2017 17:22:47 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/general/success-in-programming/</guid>
      <description>&lt;p&gt;Персональный бренд — тема, не так часто обсуждаемая среди программистов. В действительности я знаю всего несколько людей, обладающих сильным персональным брендом, и всего двоих, кто рассказывает о построении личного бренда программистам. Один из них — Фредерик Харпер (Frederic Harper) с его книгой «&lt;a href=&#34;https://www.amazon.com/Success-Programming-Recognition-Influence-Personal-ebook/dp/B00MUUI67C&#34;&gt;Success in Programming&lt;/a&gt;».&lt;/p&gt;
&lt;h2 id=&#34;почему-персональный-бренд-важен&#34;&gt;Почему персональный бренд важен?&lt;/h2&gt;
&lt;p&gt;OK. Вы знаете кого‑нибудь, кто бы получил работу в крупной технологической компании без прохождения ада интервью? Я знаю одного. Хедхантеры одной подобной компании умоляли его уделить им минуту — и не для того, чтобы начать долгий процесс из серии интервью. Нет. Только для того, чтобы обсудить с ним, над каким из их проектов он хотел бы работать.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Структуры данных и алгоритмы в Java (2-е издание)</title>
      <link>https://www.alexkorablev.ru/dev/lafore-java/</link>
      <pubDate>Tue, 15 Aug 2017 17:29:21 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/lafore-java/</guid>
      <description>&lt;p&gt;Для меня основное достоинство книги «&lt;a href=&#34;https://www.piter.com/product/struktury-dannyh-i-algoritmy-v-java-klassika-computers-science-2-e-izd&#34;&gt;Структуры данных и алгоритмы в Java&lt;/a&gt;» — язык, которым автор описывает алгоритмы. Он не использует сложный академический язык, приправленный тонной высшей математики. Роберт Лафоре использует простой язык и пытается дать максимально простое объяснение, какое только возможно, каждому алгоритму.&lt;/p&gt;
&lt;h2 id=&#34;почему-эта-книга&#34;&gt;Почему эта книга?&lt;/h2&gt;
&lt;p&gt;Эта книга — для занятых (или ленивых) студентов или программистов, которые решили повторить алгоритмы перед техническим интервью. Книгу можно просмотреть очень быстро: читаем список идей после каждой статьи, просматриваем примеры кода. Если что‑то показалось непонятным, возвращаемся к основному тексту главы.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Горячие клавиши Emacs в русской раскладке</title>
      <link>https://www.alexkorablev.ru/dev/emacs-got-keys/</link>
      <pubDate>Sat, 10 Jun 2017 17:27:10 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/emacs-got-keys/</guid>
      <description>&lt;p&gt;Думаю, вы, как и я, не можете позволить себе пользоваться только английской раскладкой клавиатуры. Так или иначе для работы приходится использовать обе: и русскую, и английскую. В целом это не доставляет никаких проблем, пока дело не касается Emacs.&lt;/p&gt;
&lt;p&gt;Не знаю почему, но в нём горячие клавиши в русской раскладке просто перестают работать. Видимо, сказывается страшное наследие «ASCII — единственно возможный набор символов для всех языков мира». Возможно, есть какие‑то другие причины.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Property в классе наследнике</title>
      <link>https://www.alexkorablev.ru/dev/property-and-inheritance/</link>
      <pubDate>Tue, 30 May 2017 17:25:13 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/property-and-inheritance/</guid>
      <description>&lt;p&gt;Кажется очевидным, что &lt;code&gt;property&lt;/code&gt; можно переопределить в классе‑наследнике и вызвать &lt;code&gt;super&lt;/code&gt; внутри этого переопределённого свойства. Вроде бы звучит нормально? Да, так и есть. Тем не менее, когда мой коллега задал мне такой вопрос, я «завис» на некоторое время. Возможно, я излишне подозрителен, но каждый раз, когда в коде есть какая‑то магия, я ожидаю подвоха. Поэтому я решил немного поэкспериментировать и доказать себе, что свойства (&lt;code&gt;property&lt;/code&gt;) работают так, как ожидается.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# -*- coding: utf-8 -*-&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;from&lt;/span&gt; __future__ &lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; print_function, unicode_literals, absolute_import
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Parent&lt;/span&gt;(object):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;@property&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;prop&lt;/span&gt;(self):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        print(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Parent property&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Child&lt;/span&gt;(Parent):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;@property&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;prop&lt;/span&gt;(self):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        super(Child, self)&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;prop
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        print(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Child property&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;child &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; Child()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;child&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;prop
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Работает, как и ожидалось:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Pyenv на маке</title>
      <link>https://www.alexkorablev.ru/dev/pyenv/</link>
      <pubDate>Fri, 19 May 2017 17:23:03 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/pyenv/</guid>
      <description>&lt;p&gt;Довольно сложно управляться с несколькими версиями Python на одном ноутбуке. Хотя это довольно распространённая ситуация. Обычно у разработчиков несколько проектов, требующих разных версий Python. В целом есть несколько вариантов для решения этой задачи, но моим любимым остаётся &lt;a href=&#34;https://github.com/pyenv/pyenv&#34;&gt;pyenv&lt;/a&gt; в компании с плагином &lt;a href=&#34;https://github.com/pyenv/pyenv-virtualenv&#34;&gt;pyenv‑virtualenv&lt;/a&gt;. Раньше я использовал «голый» Homebrew, но это далеко не так гибко и удобно.&lt;/p&gt;
&lt;h2 id=&#34;установка&#34;&gt;Установка&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ brew update
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ brew install pyenv
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ brew install pyenv-virtualenv
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;eval &amp;#34;$(pyenv init -)&amp;#34;&amp;#39;&lt;/span&gt; &amp;gt;&amp;gt; ~/.bash_profile
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;eval &amp;#34;$(pyenv virtualenv-init -)&amp;#34;&amp;#39;&lt;/span&gt; &amp;gt;&amp;gt; ~/.bash_profile
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;базовый-шаблон-использования&#34;&gt;Базовый шаблон использования&lt;/h2&gt;
&lt;p&gt;Настоятельно рекомендую делать отдельные виртуальные окружения для каждого проекта. Иногда бывает необходимо делать даже несколько окружений для одного проекта. К примеру, если хочется использовать mypy для проекта на Python 2.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Обзор Soft Skills</title>
      <link>https://www.alexkorablev.ru/general/soft-skills/</link>
      <pubDate>Sat, 15 Apr 2017 17:20:33 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/general/soft-skills/</guid>
      <description>&lt;p&gt;Когда я начал читать &lt;a href=&#34;https://www.amazon.com/Soft-Skills-software-developers-manual/dp/1617292397&#34;&gt;«Soft Skills» Джона Сонмеза&lt;/a&gt;, я не знал, чего от неё ожидать. С одной стороны, как программисты, мы считаем, что нет ничего важнее написания кода. И это правда. Тем не менее чрезвычайно сложно найти интересный проект без продвижения самого себя. Я сомневался, что кто‑нибудь способен объяснить это разработчикам. Не могу сказать, что Джон делает это идеально, но его попытка достаточно хороша, чтобы потратить время и прочитать его книгу.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Это MOOC-курс хорош для меня?</title>
      <link>https://www.alexkorablev.ru/general/mooc/</link>
      <pubDate>Wed, 05 Apr 2017 22:10:53 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/general/mooc/</guid>
      <description>&lt;p&gt;Сейчас в сети довольно много различных массовых открытых онлайн‑курсов (MOOC). Одни платные, другие бесплатные. Пару лет назад о подобных курсах говорили на каждом углу: утверждали, что они убьют все другие формы обучения. Этого, разумеется, не произошло. Тем не менее эта форма — полезный и удобный инструмент самообразования, её точно стоит использовать в собственном учебном плане. Правда, стоит для начала выбрать подходящий курс.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;«Все животные равны. Но некоторые животные равны более, чем другие».&lt;br&gt;
Джордж Оруэлл, «Скотный двор»&lt;/p&gt;</description>
    </item>
    <item>
      <title>Enums в Python</title>
      <link>https://www.alexkorablev.ru/dev/enums/</link>
      <pubDate>Fri, 17 Feb 2017 22:08:55 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/enums/</guid>
      <description>&lt;p&gt;&lt;code&gt;Enum&lt;/code&gt; — наименее используемая фича Python. Как программисты, мы предпочитаем использовать странные словари (дикты) или списки там, где могли бы использовать &lt;code&gt;enum&lt;/code&gt;. По большей части это происходит из‑за того, что это довольно новая фича, и требуется использовать внешнюю библиотеку обратной совместимости, если используется Python версии 2.7. Тем не менее довольно много случаев, когда использовать &lt;code&gt;enum&lt;/code&gt; гораздо удобнее.&lt;/p&gt;
&lt;p&gt;В любом проекте на Python легко найти код, который делает проверки против строковых литералов. Подобные конструкции используются для определения типов постов, ролей клиентов и тому подобного. Конечно, этот код меняется со временем — меняется набор используемых строковых литералов. Это делает такой код трудноподдерживаемым и труднотестируемым.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Почему я использую текстовые файлы</title>
      <link>https://www.alexkorablev.ru/general/plain-text/</link>
      <pubDate>Tue, 31 Jan 2017 22:06:35 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/general/plain-text/</guid>
      <description>&lt;p&gt;Примерно неделю назад я пытался мигрировать блог обратно на WordPress. Я решил дать ему ещё один шанс, поскольку у меня есть планы добавлять больше картинок к постам, что достаточно тяжело делать, используя &lt;a href=&#34;http://docs.getpelican.com/en/stable/&#34;&gt;Pelican&lt;/a&gt;: очень много ручной работы. В WordPress есть отличные инструменты для управления картинками. К тому же я думал, что WYSIWYG мне подойдёт. Я установил его и даже перенёс пару постов. Но всё же я решил остановиться: форматирование этих двух постов заняло у меня порядка 20 минут.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Effective Java второе издание</title>
      <link>https://www.alexkorablev.ru/dev/effective-java/</link>
      <pubDate>Fri, 30 Dec 2016 22:03:16 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/effective-java/</guid>
      <description>&lt;p&gt;Если задать вопрос о том, какую книгу стоит прочесть о Java, все скажут, что &lt;a href=&#34;https://www.amazon.com/Effective-Java-2nd-Joshua-Bloch/dp/0321356683&#34;&gt;«Effective Java»&lt;/a&gt;. Эта книга есть во всех списках рекомендованных книг по Java — за исключением, пожалуй, только тех, авторы которых пытаются продать вам свои книги. Есть несколько причин, почему эта довольно старая книга остаётся такой популярной.&lt;/p&gt;
&lt;p&gt;Во‑первых, эта книга учит, как писать хороший Java‑код. Это значит не только быстрый код, но и читаемый, и поддерживаемый. Она описывает общие Java‑паттерны, которые делают ваш код более понятным для других программистов. Книга не рассказывает о том, как «хачить» JVM, — только о том, как использовать её более эффективно.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Делаем Java-подобный Optional в Python</title>
      <link>https://www.alexkorablev.ru/dev/optional-in-python/</link>
      <pubDate>Fri, 25 Nov 2016 22:01:03 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/optional-in-python/</guid>
      <description>&lt;p&gt;В некоторых случаях использование &lt;code&gt;None&lt;/code&gt; может превратить код в нечитаемую и неподдерживаемую кашу. К примеру, если есть необходимость отличить «пустое» значение от отсутствия значения для целочисленного ввода, когда 0 не может использоваться в качестве этого «пустого» значения, обойтись, используя только &lt;code&gt;None&lt;/code&gt;, очень сложно. Одно из возможных решений — использовать что‑то подобное &lt;code&gt;Optional&lt;/code&gt; из Java.&lt;/p&gt;
&lt;p&gt;Конечно, &lt;code&gt;Optional&lt;/code&gt; — не совсем «питонячий» путь. В некоторых случаях можно использовать исключения, как предлагается в &lt;a href=&#34;http://stackoverflow.com/questions/22992433/is-there-a-python-equivalent-for-scalas-option-or-either&#34;&gt;этой дискуссии на Stack Overflow&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Бэктрекин без рекурсии на Python</title>
      <link>https://www.alexkorablev.ru/dev/python-backtracking/</link>
      <pubDate>Thu, 03 Nov 2016 22:02:16 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/python-backtracking/</guid>
      <description>&lt;p&gt;В Python нет оптимизации хвостовой рекурсии и достаточно жёсткий лимит на рекурсивные вызовы. Это может вызвать затруднения при решении задач с помощью алгоритма бэктрекинга: лимита хватает на поиск решения судоку, но он может оказаться слишком низким, если количество решений для проверки в задаче довольно высоко.&lt;/p&gt;
&lt;p&gt;Тем не менее реализация бэктрекинга с рекурсией на Python элегантна, легко читаема и понятна. Отказываться от неё имеет смысл только для «тяжёлых» задач.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;backtrack&lt;/span&gt;(self, solution):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; solution &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;seen_solutions:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;reject(solution):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;accept(solution):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;output(solution)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; child_solution &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;child_solutions(solution):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;backtrack(child_solution)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Когда сложность задачи достигнет лимита рекурсивных вызовов, можно переключиться на шаблон без рекурсии. Он уже не так элегантен, как рекурсивное решение, но не так страшен, как мог бы быть. К тому же он использует те же вспомогательные функции, что и его собрат с рекурсией.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Обзор курса Functional Programming Principles in Scala</title>
      <link>https://www.alexkorablev.ru/dev/progfun1/</link>
      <pubDate>Mon, 24 Oct 2016 22:00:40 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/progfun1/</guid>
      <description>&lt;p&gt;Этой осенью я закончил курс на Coursera &lt;a href=&#34;https://www.coursera.org/learn/progfun1&#34;&gt;«Functional Programming Principles in Scala»&lt;/a&gt;. Этот курс — часть специализации из 5 курсов «Functional Programming in Scala». Это шестинедельное введение в функциональное программирование и Scala.&lt;/p&gt;
&lt;p&gt;Автор курса — Мартин Одерски, создатель языка Scala. Он действительно великий учёный в области компьютерных наук. Тем не менее от его лекций клонит в сон. В общем‑то с его лекциями всё в порядке — просто я не сразу нашёл правильный способ прохождения курса: сначала надо пытаться решить практическую задачу, а потом с кучей готовых вопросов смотреть лекции. Так его лекции гораздо полезнее.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Хочется добавить тип локальной переменной? Пора делать рефакторинг!</title>
      <link>https://www.alexkorablev.ru/dev/local-variable-type/</link>
      <pubDate>Thu, 06 Oct 2016 21:58:54 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/local-variable-type/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://www.python.org/dev/peps/pep-0526/&#34;&gt;PEP 526&lt;/a&gt; добавляет, начиная с Python 3.6, опциональную возможность указать тип для локальной переменной. Это более стройная замена комментариям с указанием типа. Это хорошо, но есть одна ловушка: указание типа в Python может скрыть проблемы в коде.&lt;/p&gt;
&lt;p&gt;Эти аннотации придуманы и сделаны в основном для автоматических анализаторов кода. Python позволяет писать понятный людям код и без дополнительного указания типа переменной. Поэтому, если есть желание добавить к переменной такое определение, — вы в беде. Это последнее средство для увеличения читаемости кода, а не первое.&lt;/p&gt;</description>
    </item>
    <item>
      <title>MongoDB count могут сильно замедлить API</title>
      <link>https://www.alexkorablev.ru/dev/mongo-counters/</link>
      <pubDate>Fri, 23 Sep 2016 21:56:50 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/mongo-counters/</guid>
      <description>&lt;p&gt;Иногда команда фронтенда или другие потребители API просят выводить в эндпоинтах общее число объектов. Если в качестве хранилища используется MongoDB, постарайтесь избежать этого: такое поведение эндпоинтов может значительно их замедлить.&lt;/p&gt;
&lt;p&gt;Я говорю о тех случаях, когда ответ API похож на тот, что расположен ниже, — тогда ждите беды:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;total&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;XX&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;limit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;ZZ&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;offset&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;YY&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;objects&amp;#34;&lt;/span&gt;: [&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;...&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Если коллекция достаточно большая, а запрос достаточно тяжёлый, &lt;code&gt;count&lt;/code&gt; будет работать непозволительно долго. Запрос &lt;code&gt;find&lt;/code&gt; при этом может работать быстро: ему ведь надо вернуть всего‑то десяток объектов. &lt;code&gt;count&lt;/code&gt; будет перебирать весь набор объектов, подходящих под условия запроса.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Не используйте dict так часто</title>
      <link>https://www.alexkorablev.ru/dev/dict-vs-object/</link>
      <pubDate>Fri, 09 Sep 2016 21:53:40 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/dict-vs-object/</guid>
      <description>&lt;p&gt;У разработчиков на Python наблюдается тенденция использовать словари (дикты) там, где нужно, и там, где нет. В основном это касается передачи данных внутри приложения в виде словаря (дикта), вместо создания объекта. Это плохой дизайн, который приводит к целому вороху проблем, самая страшная из которых — такой код невозможно читать.&lt;/p&gt;
&lt;p&gt;К примеру, есть код, который вызывает внешнее API и получает в ответ JSON, который уже распарсили в &lt;code&gt;dict&lt;/code&gt;. Стоит мне отправлять этот словарь дальше или лучше трансформировать его в экземпляр более специфического класса? Оба варианта возможны. Обычно я предпочитаю использовать классы и объекты, хотя это требует определённых усилий и времени: соответствующий класс надо ещё написать.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Переезд с Python на Java. Первые впечатления</title>
      <link>https://www.alexkorablev.ru/dev/java-vs-python/</link>
      <pubDate>Fri, 26 Aug 2016 22:18:14 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/java-vs-python/</guid>
      <description>&lt;p&gt;Буквально неделю назад я добавил Java в свой рабочий стек технологий: мы начали делать новый проект с использованием Java Spring Framework. Для меня это интересный вызов. Я никогда раньше не использовал Java, кроме как для маленьких домашних проектов. Вот мои самые первые впечатления о «лютом энтерпрайзе».&lt;/p&gt;
&lt;p&gt;Я не хочу сравнивать Python и Java как языки программирования. Очевидно, что в Java есть статическая типизация, а в Python — нет. Очевидно, что Java более многословна, а Python — более компактен. Всё это не так интересно. Гораздо интереснее сравнить окружение языков, требуемый ими подход к программированию.&lt;/p&gt;</description>
    </item>
    <item>
      <title>mypy для проекта на Python 2.7</title>
      <link>https://www.alexkorablev.ru/dev/mypy-python-27/</link>
      <pubDate>Fri, 29 Jul 2016 22:16:02 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/mypy-python-27/</guid>
      <description>&lt;p&gt;Аннотация типов может сильно помочь при работе над большим проектом на Python: многие ошибки в дизайне и использовании функций выявляются практически сразу. Конечно, для этого требуется использование внешних инструментов для статического анализа, таких как MyPy. Это великолепный инструмент, но он поддерживает третью ветку Python. Поддержка Python 2.7 в нём требует некоторой подготовки.&lt;/p&gt;
&lt;h2 id=&#34;type-comments-vs-stub-files&#34;&gt;Type comments vs stub files&lt;/h2&gt;
&lt;p&gt;Для начала нужно определиться, как аннотировать типы в коде. Для второй ветки Python есть два варианта: аннотирование в комментариях или использование стаб‑файлов. Я предпочитаю первый путь: он информативнее (типы перед глазами) и его легче поддерживать.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Пишем код для Unity3d в Sublime Text 3</title>
      <link>https://www.alexkorablev.ru/gamedev/unity3d-in-sublime/</link>
      <pubDate>Fri, 22 Jul 2016 22:13:38 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/gamedev/unity3d-in-sublime/</guid>
      <description>&lt;p&gt;Необходимость использовать MonoDevelop — пожалуй, худшая часть разработки игр под Unity. Для пользователей Windows теперь есть альтернатива: они могут использовать Visual Studio. Что делать счастливым обладателям Mac? Переключаться на Sublime Text.&lt;/p&gt;
&lt;p&gt;Правда, в сети не так много информации о том, как это сделать. Я потратил достаточно много времени, чтобы разобраться, как настроить автодополнение для C# в Sublime Text. В итоге я нашёл достаточно простой путь, требующий всего трёх вещей, установленных на Mac:&lt;/p&gt;</description>
    </item>
    <item>
      <title>TrueType шрифты в LibGDX</title>
      <link>https://www.alexkorablev.ru/gamedev/libgdx-ttf/</link>
      <pubDate>Thu, 14 Jul 2016 22:04:49 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/gamedev/libgdx-ttf/</guid>
      <description>&lt;p&gt;LibGDX — прекрасная библиотека. Её очень легко использовать, хотя в ней есть некоторые аспекты, которые не так просты и понятны. Шрифты — один из примеров. Я провёл много часов, прежде чем нашёл решение, при котором шрифты и на десктопе, и в мобильных телефонах выглядят пристойно. Я уже писал, что у меня получилось добиться результатов с &lt;a href=&#34;https://www.alexkorablev.ru/gamedev/libgdx-fonts/&#34;&gt;Distance Field&lt;/a&gt;, но я ошибался. Заставить хорошо выглядеть удалось только TTF.&lt;/p&gt;
&lt;p&gt;Забудьте о bitmap‑шрифтах. На попытки заставить их выглядеть пристойно на всех девайсах уйдёт уйма времени. Результат при этом будет более чем посредственным — даже несмотря на то, что это более или менее &lt;a href=&#34;https://github.com/libgdx/libgdx/wiki/Distance-field-fonts&#34;&gt;рекомендованный путь&lt;/a&gt;. Но всё‑таки, если у вас не сотни шрифтов, лучше использовать TrueType Fonts.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Свой итератор поверх enumerate</title>
      <link>https://www.alexkorablev.ru/dev/logging-iterator/</link>
      <pubDate>Mon, 27 Jun 2016 22:08:24 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/logging-iterator/</guid>
      <description>&lt;p&gt;ППару дней назад коллега попросил сделать логирующий сам себя итератор поверх &lt;code&gt;enumerate&lt;/code&gt;. Я попробовал наследоваться напрямую и потерпел неудачу. Я абсолютно забыл, как работает магический метод &lt;code&gt;__new__&lt;/code&gt;. Поскольку я был занят, я пообещал себе разобраться с этой проблемой позже. А ларчик открывался очень просто: 18 строк кода — и у меня появилась нужная функциональность.&lt;/p&gt;
&lt;h2 id=&#34;изначальная-задача&#34;&gt;Изначальная задача&lt;/h2&gt;
&lt;p&gt;Сначала стоит объяснить, зачем нам вообще понадобился подобный итератор и почему нам не хватило обычного &lt;code&gt;enumerate&lt;/code&gt;. Всё дело в том, что у нас в проекте очень много задач, построенных по такому шаблону:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Онлайн курс по Clojure</title>
      <link>https://www.alexkorablev.ru/dev/clojure-mooc/</link>
      <pubDate>Tue, 07 Jun 2016 22:05:31 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/clojure-mooc/</guid>
      <description>&lt;p&gt;Clojure — интересный Lisp‑подобный функциональный язык. Если вы фанат круглых скобок, то программировать на этом языке интересно. К тому же Clojure компилируется в байт‑код JVM и транслируется в JavaScript. Вернее, в JS транслируется ClojureScript. Над ним работает та же команда, что и над Clojure, так что это всё‑таки один и тот же язык — за исключением некоторой разницы в типах и мелочах, зависящих от среды исполнения. При этом ресурсов для изучения этого языка не так много. Один из них — онлайн‑курс &lt;a href=&#34;http://iloveponies.github.io/120-hour-epic-sax-marathon/index.html&#34;&gt;Functional programming in Clojure&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Как управляться с большими проектами на Python</title>
      <link>https://www.alexkorablev.ru/dev/big-python-projects/</link>
      <pubDate>Wed, 01 Jun 2016 21:58:36 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/big-python-projects/</guid>
      <description>&lt;p&gt;На Hacker News появилась &lt;a href=&#34;https://news.ycombinator.com/item?id=11792474&#34;&gt;интересная дискуссия&lt;/a&gt; о том, как управляться с большими Python‑проектами. Поскольку я причастен к достаточно большому проекту, то не могу удержаться и не поделиться своим видением на этот вопрос. Я составил список из трёх моментов, на которые стоит обратить внимание.&lt;/p&gt;
&lt;h2 id=&#34;1-обеспечьте-себе-безболезненную-навигацию-по-коду&#34;&gt;1. Обеспечьте себе безболезненную навигацию по коду&lt;/h2&gt;
&lt;p&gt;В большом проекте навигация по коду и автокомплит сильно упрощают разработку и поддержку. Всё, что ломает навигацию, должно подвергаться сомнению. А это значит, что хитрые конструкции и метапрограммирование должны быть очень хорошо обоснованы: без них либо не обойтись, либо очень сложно обойтись. В остальных случаях лучше выбирать более очевидные (в том числе для тулзов) пути.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Проект на Kivy. Часть 1. Настройка окружения</title>
      <link>https://www.alexkorablev.ru/dev/setup-kivy-project/</link>
      <pubDate>Mon, 16 May 2016 21:52:27 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/setup-kivy-project/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://kivy.org/#home&#34;&gt;Kivy&lt;/a&gt; — интересный проект, который позволяет делать кроссплатформенные GUI‑приложения, включая мобильные. Я решил выяснить, можно ли использовать его для создания маленьких приложений на Python. В этой серии статей я попробую исследовать Kivy на примере клона «конструктора слов» — одного из упражнений для LingvoLeo.&lt;/p&gt;
&lt;p&gt;Эта серия — не учебник, а исследовательский лог моих попыток. В результате я планирую получить собранные приложения для трёх платформ минимум: Windows, Mac, Android. Будет здорово, если я соберу ещё и iOS‑версию. В качестве основной платформы для разработки я использую Mac, так что все инструкции по установке и настройке окружения будут для этой операционной системы.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Модификация параметров под args или kwargs</title>
      <link>https://www.alexkorablev.ru/dev/args-kwargs/</link>
      <pubDate>Wed, 04 May 2016 16:48:57 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/args-kwargs/</guid>
      <description>&lt;p&gt;В Python достаточно часто интерфейсы функций частично или полностью «сворачивают» с помощью &lt;code&gt;*args&lt;/code&gt; и &lt;code&gt;**kwargs&lt;/code&gt;. Это вполне естественно для питонистов, но вызывает вопросы при переходе с других языков. С самим «сворачиванием» никаких проблем нет. Сложности возникают при модификации аргументов: строятся проверки вокруг &lt;code&gt;args&lt;/code&gt; и &lt;code&gt;kwargs&lt;/code&gt;, вместо того чтобы «развернуть» интерфейс функции.&lt;/p&gt;
&lt;p&gt;Представьте себе такой кейс: есть две библиотеки, одна из которых имеет полностью прописанный интерфейс у функции &lt;code&gt;foo&lt;/code&gt;. Вторая определяет функцию &lt;code&gt;boo&lt;/code&gt;, которая вызывает &lt;code&gt;foo&lt;/code&gt;. Интерфейс &lt;code&gt;boo&lt;/code&gt; «свёрнут» с помощью &lt;code&gt;*args&lt;/code&gt; и &lt;code&gt;**kwargs&lt;/code&gt;:&lt;/p&gt;</description>
    </item>
    <item>
      <title>RoboVM закрылся. LibGDX мигрирует на Multi-OS Engine от Intel</title>
      <link>https://www.alexkorablev.ru/gamedev/robovm/</link>
      <pubDate>Mon, 25 Apr 2016 16:46:36 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/gamedev/robovm/</guid>
      <description>&lt;p&gt;RoboVM — проект, позволявший запускать Java‑код на iOS, — закрылся. Под ударом оказались все, кто использовал LibGDX для мобильных игр. Замену нашли быстро: LibGDX будет использовать Multi‑OS Engine от Intel. Тем не менее это хороший повод обсудить зависимости в библиотеках.&lt;/p&gt;
&lt;p&gt;15 апреля пользователи RoboVM получили «письмо счастья»: проект закрывается. Судя по объяснению в &lt;a href=&#34;https://robovm.com/robovm-winding-down/&#34;&gt;блоге проекта&lt;/a&gt;, основная причина закрытия — действия Microsoft с Xamarin. В том, что теперь кроссплатформенную мобильную разработку на Java ждут трудные времена, не поспоришь. Xamarin — действительно отличная альтернатива.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Почему я вернулся в PyCharm</title>
      <link>https://www.alexkorablev.ru/dev/comeback-to-pycharm/</link>
      <pubDate>Mon, 18 Apr 2016 16:43:57 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/comeback-to-pycharm/</guid>
      <description>&lt;p&gt;В конце января я переключался на Sublime как основную IDE для Python. Но уже через пару недель я был вынужден вернуться на PyCharm. Последние несколько недель я активно использовал Emacs. Он великолепен. И всё‑таки для рабочих проектов я снова возвращаюсь к PyCharm.&lt;/p&gt;
&lt;p&gt;Все три варианта хорошо подходят для работы с Python. Все три позволяют работать продуктивно. Так что выбирать приходится исходя из слабых сторон каждого из них.&lt;/p&gt;
&lt;h2 id=&#34;что-не-так-с-pycharm&#34;&gt;Что не так с PyCharm&lt;/h2&gt;
&lt;p&gt;Есть несколько причин, почему я периодически пытаюсь сбежать в какой‑нибудь другой редактор.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Изменяемы типы в качестве параметров по умолчанию в Python</title>
      <link>https://www.alexkorablev.ru/dev/default-params/</link>
      <pubDate>Mon, 11 Apr 2016 16:41:04 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/default-params/</guid>
      <description>&lt;p&gt;Почему изменяемые типы не рекомендуется использовать в качестве значений аргументов по умолчанию в Python? Если вы забрались по карьерной лестнице выше джуниора, то наверняка задумывались. И наверняка ответ был таким: «Это приводит к странным побочным эффектам». Но я почти наверняка уверен, что только малая часть разработчиков на Python сделала шаг дальше и разобралась, почему такое поведение у языка.&lt;/p&gt;
&lt;p&gt;Давайте разберёмся сначала с тем, с какими побочными эффектами имеем дело. Напишем вот такую функцию:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Обзор курса по Haskell на Stepic.org</title>
      <link>https://www.alexkorablev.ru/dev/stepic-haskell-mooc/</link>
      <pubDate>Mon, 04 Apr 2016 16:38:00 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/stepic-haskell-mooc/</guid>
      <description>&lt;p&gt;Как‑то я уже упоминал курс &lt;a href=&#34;https://stepic.org/course/%D0%A4%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B5-%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5-%D0%BD%D0%B0-%D1%8F%D0%B7%D1%8B%D0%BA%D0%B5-Haskell-75/syllabus&#34;&gt;«Функциональное программирование на языке Haskell»&lt;/a&gt;. Наконец могу поделиться собственными впечатлениями об этом курсе.&lt;/p&gt;
&lt;p&gt;Этот курс стоит того, чтобы его пройти и сделать (или хотя бы попытаться сделать) все предложенные задания. Лучшего вводного курса по Haskell я не встречал. Огромное спасибо Денису Москвину (основной преподаватель) и команде за курс!&lt;/p&gt;
&lt;p&gt;Курс состоит из 5 блоков, каждый из которых раскрывает некоторые аспекты языка: типы данных, списки, монады и т. п. Каждый блок — это набор видеоуроков с заданиями примерно на 5–6 часов работы.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Масштабируемые шрифты в LibGDX</title>
      <link>https://www.alexkorablev.ru/gamedev/libgdx-fonts/</link>
      <pubDate>Mon, 14 Mar 2016 22:04:49 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/gamedev/libgdx-fonts/</guid>
      <description>&lt;p&gt;&lt;strong&gt;Обновление 2016‑07‑14:&lt;/strong&gt; &lt;a href=&#34;https://www.alexkorablev.ru/gamedev/libgdx-ttf/&#34;&gt;Я всё‑таки нашёл способ работать с TTF‑шрифтами&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Работать со шрифтами в LibGDX оказалось неожиданно сложно. Создать растровый шрифт проблем нет, но вот заставить его масштабироваться под разные разрешения — реальная проблема. Более или менее рабочая практика — использовать Distance Field. После этого нужно ещё пробросить шрифт в описание скина.&lt;/p&gt;
&lt;p&gt;Попытка использовать TTF провалилась. Настроить её в LibGDX проще простого, но вот результат получается ужасным. Возможно, я не до конца разобрался с этим процессом. Если у кого‑либо из читателей есть опыт генерации красивых шрифтов из TTF, поделитесь в комментариях.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Полезняшка: responses</title>
      <link>https://www.alexkorablev.ru/dev/responses/</link>
      <pubDate>Wed, 09 Mar 2016 18:30:51 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/responses/</guid>
      <description>&lt;p&gt;Если вы используете в своём проекте &lt;code&gt;requests&lt;/code&gt;, то наверняка сталкиваетесь с проблемами тестирования. На помощь придёт библиотека &lt;a href=&#34;https://github.com/getsentry/responses&#34;&gt;&lt;code&gt;responses&lt;/code&gt;&lt;/a&gt;, которая позволяет делать моки ответов вызовов &lt;code&gt;requests&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Мы в своём проекте используем эту библиотеку не так давно. Хотя из‑за особенностей окружения проекта мы часто обращаемся к огромному количеству REST API смежных сервисов. И до того, как &lt;code&gt;requests&lt;/code&gt; попалась нам на глаза, код тестов представлял из себя нечто невообразимое, трудночитаемое.&lt;/p&gt;
&lt;p&gt;Пользоваться библиотекой невероятно просто. Для иллюстрации — пара примеров из документации.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Generator vs Iterator</title>
      <link>https://www.alexkorablev.ru/dev/generator-vs-iterator/</link>
      <pubDate>Mon, 29 Feb 2016 18:29:21 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/generator-vs-iterator/</guid>
      <description>&lt;p&gt;Как ни странно, вопрос о разнице между генераторами и итераторами в Python — довольно частый. В общем‑то эти сущности сильно связаны (любой генератор — это итератор), их довольно часто путают, что иногда приводит к недопониманиям.&lt;/p&gt;
&lt;p&gt;Итератор — более общая концепция. Это объект, у которого определены два метода: &lt;code&gt;__next__&lt;/code&gt; и &lt;code&gt;__iter__&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;С другой стороны, генератор — это итератор, но не наоборот. Генератор может получаться с использованием &lt;code&gt;yield&lt;/code&gt; в теле функции:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;squares&lt;/span&gt;(start, stop):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; i &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; range(start, stop):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;yield&lt;/span&gt; i &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; i
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;generator &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; squares(a, b)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Либо с использованием так называемых generator expression — например, такого:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Сохраняем JSON в LibGDX</title>
      <link>https://www.alexkorablev.ru/gamedev/json-libgdx/</link>
      <pubDate>Wed, 24 Feb 2016 18:27:11 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/gamedev/json-libgdx/</guid>
      <description>&lt;p&gt;Предыдущую неделю просидел дома. Из‑за высокой температуры особо на рабочих задачах сконцентрироваться шансов не было. Но вот сторонними проектами удалось позаниматься. В очередной раз порадовался связке LibGDX и Kotlin.&lt;/p&gt;
&lt;p&gt;Задачка такая: прочитать список объектов из JSON. Я уже приготовился писать много строк кода. Оказалось, что инструменты чтения JSON уже &lt;a href=&#34;https://github.com/libgdx/libgdx/wiki/Reading-&amp;amp;-writing-JSON#customizing-serialization&#34;&gt;встроены в LibGDX&lt;/a&gt;. Это немного странно. Я ожидал, что для этой задачи потребуется сторонняя библиотека. Хотя, с другой стороны, скин для UI описывается JSON, так что, по сути, разработчики LibGDX вытащили используемые хелперы в публичный API.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Как вы управляете своими pet-проектами?</title>
      <link>https://www.alexkorablev.ru/dev/pet-projects/</link>
      <pubDate>Tue, 16 Feb 2016 18:25:23 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/pet-projects/</guid>
      <description>&lt;p&gt;Сотни моих начинаний остаются недоделанными и даже близко не достигают целей, которые ставились перед проектом. И это при том, что зачастую основная цель — просто изучить ту или иную технологию.&lt;/p&gt;
&lt;p&gt;Самих идей проектов хоть отбавляй. Конечно, далеко не на всё есть время. Но самые «сочные» идеи хотелось бы реализовать — пусть не быстро, но хоть в какое‑нибудь разумное время.&lt;/p&gt;
&lt;p&gt;Из испробованных приёмов у меня более или менее нормально работает выделение времени по утрам. Причём работает где‑то половину года, когда светает достаточно рано. Заставить себя выбраться из‑под одеяла зимой — дохлый номер. Не помогает и какой‑нибудь ритуал, который хорошо работает летом. Обычно всё скатывается к просмотру какого‑нибудь сериала лёжа в кровати.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Страсть к смене технологий: с Python на Lua</title>
      <link>https://www.alexkorablev.ru/dev/from-python-to-lua/</link>
      <pubDate>Mon, 08 Feb 2016 18:23:14 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/from-python-to-lua/</guid>
      <description>&lt;p&gt;Брайан Майер из Distelli опубликовал любопытную статью &lt;a href=&#34;https://www.distelli.com/blog/using-lua-for-our-most-critical-production-code&#34;&gt;«Using Lua for Our Most Critical Production Code»&lt;/a&gt;. В статье расхваливается переход с одной технологии на другую и то, как это помогло решить кучу проблем. При этом совсем не упоминается, с какими проблемами при этом столкнулись, и совсем нет анализа, какие проблемы могут возникнуть в будущем.&lt;/p&gt;
&lt;p&gt;По большому счёту, смена технологии проекта в его середине — обычно очень плохая идея. Программистов надо вытащить из области, в которой они разбираются, в совершенно незнакомое окружение. Не могу сказать, что это всегда негативно сказывается на команде, но такие риски надо просчитывать. Если человека нанимали за его экспертные знания в Python, будет ли он счастлив писать на Lua?&lt;/p&gt;</description>
    </item>
    <item>
      <title>В чем главная слабость Python, как языка программирования?</title>
      <link>https://www.alexkorablev.ru/dev/python-weaknesses/</link>
      <pubDate>Mon, 25 Jan 2016 22:18:28 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/python-weaknesses/</guid>
      <description>&lt;p&gt;Я очень люблю Quora.com. В отличие от Stack Overflow, здесь можно найти интересные обсуждения, не связанные с конкретными вопросами, а с общими ощущениями от технологий. Недавно наткнулся, к примеру, на такое обсуждение: &lt;a href=&#34;https://www.quora.com/What-are-the-main-weaknesses-of-Python-as-a-programming-language&#34;&gt;«What are the main weaknesses of Python as a programming language?»&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;В основном Python ругают за тормознутость, сравнивая с компилируемыми языками. Я уже &lt;a href=&#34;https://www.alexkorablev.ru/dev/why-python-so-popular/&#34;&gt;писал&lt;/a&gt;, что считаю это обвинение надуманным. Для меня скорость разработки гораздо важнее. Для CPU‑bound задач я бы в первую очередь подумал об алгоритмах, а потом использовал Cython. Да и не так уж много таких задач. А если ваш проект весь такой, то какого лешего вы выбрали скриптовый язык для этого?&lt;/p&gt;</description>
    </item>
    <item>
      <title>Приватных полей в питоне нет</title>
      <link>https://www.alexkorablev.ru/dev/pivate-variable/</link>
      <pubDate>Mon, 18 Jan 2016 21:45:05 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/pivate-variable/</guid>
      <description>&lt;p&gt;Достаточно часто встречаю вопросы о приватных полях и методах в Python от людей, которые раньше программировали на Java (или C++). Вот только в Python класс — это не совсем то же, что и в Java. В Python класс — это просто контейнер, содержимое которого доступно всем.&lt;/p&gt;
&lt;p&gt;«Приватные» поля — это всего лишь договорённость по именам, которая никак не мешает работать с такими полями из любого места кода. Добавление имени класса к имени переменной — слабая защита.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Я влюбился в Django. Снова. А вы что сделали за новогодние каникулы?</title>
      <link>https://www.alexkorablev.ru/dev/fall-in-love-with-django/</link>
      <pubDate>Mon, 11 Jan 2016 21:43:06 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/fall-in-love-with-django/</guid>
      <description>&lt;p&gt;Ещё 31 декабря прошлого года у меня были гигантские планы на каникулы. Как минимум я должен был закончить один из своих сайт‑проектов. К сожалению, работе удалось уделить всего 4 часа. Но за это время я успел снова влюбиться в Django.&lt;/p&gt;
&lt;p&gt;Кажется, я где‑то уже об этом писал: Django — это мой проводник в мир Python. Именно благодаря этому фреймворку меня вырвало из хищных лап PHP. И первое время к Python я относился как к досадной необходимости, без которой Django не работает.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Постновогоднее. Целеполагательное</title>
      <link>https://www.alexkorablev.ru/general/agile-results/</link>
      <pubDate>Tue, 05 Jan 2016 18:34:24 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/general/agile-results/</guid>
      <description>&lt;p&gt;Наступил Новый год. Самое время разобраться с целями. Конечно, лучше бы это было сделать ещё в конце декабря, но лучше поздно, чем никогда. Сегодня я расскажу, как это делаю я.&lt;/p&gt;
&lt;p&gt;Почему‑то у меня не работает излюбленный народом метод: в новогоднюю ночь написать желание на бумажке, бумажку сжечь, пепел положить в бокал шампанского и выпить его. Наверное, всё из‑за того, что я не пью шампанское. И уже довольно давно. Так что за последние лет 7–8 я перепробовал кучу методик: от жёсткого тайм‑менеджмента до GTD.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Django или Flask?</title>
      <link>https://www.alexkorablev.ru/dev/django-vs-flask/</link>
      <pubDate>Mon, 28 Dec 2015 18:31:44 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/django-vs-flask/</guid>
      <description>&lt;p&gt;Решил восстановить свой сайт о настольных играх — VseNastolki.ru. Когда‑то там был интернет‑магазин, но, поскольку теперь на столь серьёзный проект меня не хватит, я буду делать всего лишь базу настольных игр. Оформив идею, я, как настоящий программист, взялся за выбор фреймворка: Flask или Django.&lt;/p&gt;
&lt;p&gt;Другие фреймворки я не рассматривал. Причина проста: у меня нет опыта работы с ними. Проект хочется закончить, так что использовать неизвестный фреймворк для этого не хочется. Так что в кандидатах остались только Flask — наш текущий фреймворк на работе — и Django — фреймворк, из‑за которого я попал в мир Python.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Деление данных по коллекциям в MongoDB</title>
      <link>https://www.alexkorablev.ru/dev/mongo/</link>
      <pubDate>Mon, 21 Dec 2015 18:28:04 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/mongo/</guid>
      <description>&lt;p&gt;Не надо лезть в MongoDB с реляционным подходом. Этот тезис вроде бы очевиден, но когда дело доходит до реализации, возникает множество вопросов. И стопроцентно одним из них будет: «Как делать join?». Правильный ответ: никак.&lt;/p&gt;
&lt;p&gt;Да, в версии 3.2 появился &lt;code&gt;$lookup&lt;/code&gt; в агрегациях. Отчасти это замена классическому &lt;code&gt;JOIN&lt;/code&gt; из реляционного мира. Но в целом агрегации — не самый быстрый в MongoDB инструмент. Лучше, когда запрос идёт к одной коллекции и это обычный &lt;code&gt;find&lt;/code&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Почему Python такой популярный, если он такой медленный?</title>
      <link>https://www.alexkorablev.ru/dev/why-python-so-popular/</link>
      <pubDate>Mon, 14 Dec 2015 18:25:43 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/why-python-so-popular/</guid>
      <description>&lt;p&gt;На Quora обсуждают &lt;a href=&#34;https://www.quora.com/Why-is-Python-so-popular-despite-being-so-slow&#34;&gt;«Почему Python такой популярный, хотя такой медленный»&lt;/a&gt;. Тема, конечно, холиварная. Но порассуждать на неё интересно. Ведь Python действительно медленный.&lt;/p&gt;
&lt;p&gt;Медленный, если сравнивать его с C/C++, Java или C#. Это факт. Python — достаточно медленный скриптовый динамический язык программирования. Любая метрика покажет, что программа на C++ будет работать быстрее. Но есть у языков и другая, не менее важная метрика — скорость разработки.&lt;/p&gt;
&lt;p&gt;Вот тут динамические языки начинают выигрывать. Разрабатывать на Python, Ruby, JS быстрее, чем на Java. А скорость разработки — это прямая экономия для компании. Сегодня разработка продукта заканчивается, только если проект закрывают. В остальных случаях купить ещё один инстанс у Amazon дешевле, чем увеличить срок разработки какой‑либо фичи на пару недель.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Sublime Text 3 как Python IDE</title>
      <link>https://www.alexkorablev.ru/dev/python-ide/</link>
      <pubDate>Mon, 07 Dec 2015 18:15:51 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/python-ide/</guid>
      <description>&lt;p&gt;Пока на RealPython разжигают войну IDE и объясняют, как настроить среду разработки на Python под:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://realpython.com/blog/python/setting-up-sublime-text-3-for-full-stack-python-development/&#34;&gt;Sublime&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://realpython.com/blog/python/vim-and-python-a-match-made-in-heaven/&#34;&gt;VIM&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://realpython.com/blog/python/emacs-the-best-python-editor/&#34;&gt;Emacs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Я расскажу, почему я (пока) переехал на Sublime Text 3 и как я его настроил. А также отмечу, чего в нём не хватает для счастливой разработки.&lt;/p&gt;
&lt;p&gt;PyCharm — замечательная IDE для Python. Это, несомненно, так, но если нужно разрабатывать full‑stack, то одним им не обойтись. На работе это не проблема. Но вот дома покупать лицензию на все продукты JetBrains ради экспериментов накладно.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Flask: что почитать</title>
      <link>https://www.alexkorablev.ru/dev/flask-reading-list/</link>
      <pubDate>Mon, 30 Nov 2015 13:58:48 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/flask-reading-list/</guid>
      <description>&lt;p&gt;&lt;strong&gt;НЕ! Обновляемый список полезных ссылок с материалами по Flask&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Версия: 1.0. Последнее обновление: 30.11.2015.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Начинающим&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-world&#34;&gt;«The Flask Mega‑Tutorial»&lt;/a&gt; — подробный пошаговый учебник по веб‑фреймворку Flask. Покрывает все основные темы: шаблоны, формы, базу данных, интернационализацию, деплоймент на сервере.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://youtu.be/DIcpEg77gdE&#34;&gt;«Flask Workshop»&lt;/a&gt; — трёхчасовое видео от того же автора. Демонстрация основных возможностей Flask на живом примере.&lt;/li&gt;
&lt;li&gt;Ещё один учебник — &lt;a href=&#34;http://simplectic.com/blog/2014/flask-todomvc-part1/&#34;&gt;«Flask TodoMVC»&lt;/a&gt;. На этот раз создают не блог, а список задач (To‑Do). Плюс этого учебника в том, что рассматривается не только Flask, но и его использование в связке с JS‑фреймворком &lt;a href=&#34;http://backbonejs.org/&#34;&gt;Backbone.js&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://realpython.com/blog/python/flask-by-example-part-1-project-setup/&#34;&gt;«Flask by Example»&lt;/a&gt; — учебный пример с Flask, Redis и Angular.&lt;/li&gt;
&lt;li&gt;Если ещё не устали от учебников и учебных проектов, посмотрите ещё один материал от Real Python — &lt;a href=&#34;https://realpython.com/blog/python/python-web-applications-with-flask-part-i/&#34;&gt;«Python Web Applications With Flask»&lt;/a&gt;. Помимо того, что это хороший, подробный и понятный учебник, в нём описывается переход от небольшого приложения к среднему — во Flask это нетривиальная задача. В &lt;a href=&#34;https://realpython.com/blog/python/python-web-applications-with-flask-part-iii/&#34;&gt;третьей части&lt;/a&gt; рассматриваются вопросы тестирования и отладки приложения.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Опытным пользователям&lt;/strong&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Libgdx Impressions</title>
      <link>https://www.alexkorablev.ru/gamedev/libgdx-impressions/</link>
      <pubDate>Mon, 23 Nov 2015 13:56:21 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/gamedev/libgdx-impressions/</guid>
      <description>&lt;p&gt;Мой первый проект на &lt;a href=&#34;https://libgdx.badlogicgames.com/&#34;&gt;LibGDX&lt;/a&gt; вышел на завершающую стадию. Ещё осталось сделать достаточно много для подготовки к запуску, но я уже могу сравнить эту библиотеку с Unity и Unreal Engine.&lt;/p&gt;
&lt;p&gt;Пару месяцев назад, когда я выбирал, на чём делать маленькую 2D‑игру, я очень долго колебался между Unity и Unreal Engine. С Unity у меня уже был опыт работы: пару проектов я на нём завершил. Основная проблема — отсутствие нормальной поддержки 2D. Она есть, но какая‑то несовершенная. Когда‑нибудь я обязательно про это напишу, но сегодня оставлю этот тезис без доказательств.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Конвертирование андроид приложения на Kotlin</title>
      <link>https://www.alexkorablev.ru/dev/converting-plaid-to-kotlin/</link>
      <pubDate>Mon, 16 Nov 2015 13:54:25 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/converting-plaid-to-kotlin/</guid>
      <description>&lt;p&gt;На прошлой неделе наткнулся на очень интересную статью от Антонио Лева: &lt;a href=&#34;http://antonioleiva.com/plaid-kotlin-1&#34;&gt;«Converting Plaid to Kotlin: Lessons Learned»&lt;/a&gt;. В ней автор на примере одного Android‑приложения сравнивает Kotlin и Java. Цель — выявить преимущества и недостатки разработки на Kotlin.&lt;/p&gt;
&lt;p&gt;Если посмотреть на числа, которые приводит автор, то по ним видно, что на Kotlin код получается значительно компактнее: на 22 % меньше строк, на 27 % меньше символов. Это значит, что программировать на Kotlin значительно быстрее, чем на Java. Да и приятнее (но это цифрами не измерить).&lt;/p&gt;</description>
    </item>
    <item>
      <title>Highload&#43;&#43; 2015</title>
      <link>https://www.alexkorablev.ru/dev/highload-2015/</link>
      <pubDate>Wed, 11 Nov 2015 13:48:28 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/highload-2015/</guid>
      <description>&lt;p&gt;На прошлой неделе прошла конференция Highload++ 2015. Конференция большая: доклады шли в 5 потоков. Казалось бы, выбор большой, но если отбросить секцию менеджмента и секцию фронтенд‑разработки, то в каждом втором докладе будет PostgreSQL. Один из моих коллег так высказался о конференции: «Highload++ 2015 — 40 % PostgreSQL, 40 % очереди, 20 % приправы».&lt;/p&gt;
&lt;p&gt;Не буду рассказывать о всех докладах, которые я посетил. Как и на всякой конференции, было много неудачных докладов. Я расскажу немного о трёх, на мой взгляд, самых достойных докладах конференции. Если будете покупать видео с этой конференции, то записи первых двух докладов стоят того, чтобы их посмотреть. Про третий доклад разговор отдельный.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Cpython Internals Walk Through</title>
      <link>https://www.alexkorablev.ru/dev/cpython-internals-walk-through/</link>
      <pubDate>Mon, 02 Nov 2015 13:45:31 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/cpython-internals-walk-through/</guid>
      <description>&lt;p&gt;Ресурсов о том, как работает стандартная реализация Python (CPython) внутри, мало. Пробиваться самому сквозь не самый очевидный код на C — задача для питониста очень сложная. Чтение кода на C требует определённой практики. &lt;a href=&#34;https://www.youtube.com/embed/videoseries?list=PLwyG5wA5gIzgTFj5KgJJ15lxq5Cv6lo_0&#34;&gt;Серия лекций&lt;/a&gt;, прочитанная Филипом Гио, — хорошая отправная точка.&lt;/p&gt;
&lt;p&gt;Филип подробно рассказывает о внутренних структурах Python, проводя студентов от байт‑кода к структурам, написанным на C.&lt;/p&gt;
&lt;p&gt;Темы, охваченные курсом:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Байт‑код и главный цикл интерпретатора.&lt;/li&gt;
&lt;li&gt;Фреймы, вызовы функций, области видимости.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PyObject&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Типы данных в Python.&lt;/li&gt;
&lt;li&gt;Объект с кодом, объект функции.&lt;/li&gt;
&lt;li&gt;Итераторы.&lt;/li&gt;
&lt;li&gt;Классы и объекты.&lt;/li&gt;
&lt;li&gt;Генераторы.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Рассказ ведётся с большим количеством примеров. Каждое погружение внутрь Python начинается с конкретного кусочка кода на Python. Потом разбирается получившийся байт‑код. Дальше — уже команда за командой — разбирается реализация команд байт‑кода на C.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Самые слабые стороны программистов-самоучек</title>
      <link>https://www.alexkorablev.ru/dev/self-taught-programmers-lack/</link>
      <pubDate>Mon, 26 Oct 2015 21:46:24 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/self-taught-programmers-lack/</guid>
      <description>&lt;p&gt;Меня огорчает реакция людей, когда на вопрос «Как мне стать хорошим программистом?» советуешь прочитать книгу по алгоритмам. Хорошо, если каждый десятый спрашивает, какую я посоветую. Остальные девять говорят, что им это не нужно. А ведь алгоритмы — это лишь одна из многих проблем у программистов‑самоучек.&lt;/p&gt;
&lt;p&gt;Я это очень хорошо знаю: я сам из самоучек. У меня план по закрытию пробелов в знаниях расписан года на два вперёд. Так что я провожу на Coursera по 3–4 часа в неделю, только чтобы добрать базу. А ведь надо ещё и новые технологии изучать, и работать с хорошей эффективностью. И я считаю, что мне ещё повезло: моих знаний в математике пока хватает.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Kotlin - мой следующий JVM-язык</title>
      <link>https://www.alexkorablev.ru/dev/kotlin/</link>
      <pubDate>Mon, 19 Oct 2015 21:42:27 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/kotlin/</guid>
      <description>&lt;p&gt;Утром, в дополнение к физическим упражнениям, я примерно час программирую. Для этого отлично подходят не очень сложные проекты, которые делаются в кайф. Для меня это маленькие игры и приложения для Android. Первый подобный проект я написал на Java. Второй стартовал так же — на Java. Но я решил его портировать на Kotlin.&lt;/p&gt;
&lt;p&gt;Основная проблема Java — её многословность. Проект очень быстро перестал «влазить» в голову, особенно по утрам. Обычно это означает, что пришло время рефакторинга и код придётся дробить, делать его похожим на «лютый энтерпрайз». Тоска. А так как проект делается для удовольствия, то я решил попробовать что‑нибудь новенькое и поменять язык разработки.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Паттерн Singleton</title>
      <link>https://www.alexkorablev.ru/dev/singleton/</link>
      <pubDate>Mon, 12 Oct 2015 10:00:00 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/singleton/</guid>
      <description>&lt;p&gt;&lt;code&gt;lambda&lt;/code&gt; не так часто встречается в коде на Python. Есть большая вероятность, что если потребовался синглтон, то в проекте есть проблемы с архитектурой. В первую очередь это касается небольших и средних проектов. Да и в больших проектах синглтон в чистом виде встретишь нечасто.&lt;/p&gt;
&lt;p&gt;Когда я готовился к этой статье, я планировал написать о вариантах реализации паттерна. Но когда я начал исследовать, первым делом я наткнулся на следующий код в Википедии:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Неплохой вводный видео-курс по Python</title>
      <link>https://www.alexkorablev.ru/dev/python-video-course/</link>
      <pubDate>Mon, 28 Sep 2015 10:00:40 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/python-video-course/</guid>
      <description>&lt;p&gt;Люблю смотреть разные видеокурсы по используемым языкам и технологиям. Причём не только по продвинутым темам, но и по базовым. Ещё не было такого курса, в котором не нашлось бы чего‑нибудь интересного и полезного для меня.&lt;/p&gt;
&lt;p&gt;О последнем просмотренном мной &lt;a href=&#34;https://www.youtube.com/embed/videoseries?list=PLPErILqzuTQr7QJ4rAFJVvzdTEFFPjaGz&#34;&gt;курсе&lt;/a&gt; от Георгия Курячего я хочу немного рассказать. Этот курс — отличное базовое введение в Python 2.&lt;/p&gt;
&lt;p&gt;Возможно, если вы изучали Python в университете, то этот курс покажется вам слабоватым. Но мне, как человеку, который изучал язык и его библиотеку разрозненно — по книгам, статьям и отдельным видео, — такой курс показался вполне достойным. Он полностью оправдал время, потраченное на него.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Итоги конференции PyConRu 2015</title>
      <link>https://www.alexkorablev.ru/dev/pyconru-2015/</link>
      <pubDate>Mon, 21 Sep 2015 10:00:12 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/pyconru-2015/</guid>
      <description>&lt;p&gt;В субботу закончилась конференция PyCon Ru 2015 в Екатеринбурге. Немного остыв, можно подвести некоторые итоги. Конференция получилась хорошей. Как говорит один мой коллега, если на двухдневной конференции было два интересных доклада, то конференция удалась. На PyCon интересных и полезных докладов было больше. Я выделил 4 таких доклада.&lt;/p&gt;
&lt;p&gt;Начало положил Гаель Вароко. Если про &lt;a href=&#34;http://scikit-learn.org/stable/&#34;&gt;&lt;code&gt;scikit&lt;/code&gt;&lt;/a&gt; было просто интересно послушать — в повседневной работе мы машинным обучением не занимаемся, — то рассказ о второй библиотеке &lt;a href=&#34;http://pythonhosted.org/joblib/&#34;&gt;&lt;code&gt;joblib&lt;/code&gt;&lt;/a&gt; заставил нас провести порядочное время на её сайте. Сама библиотека позволяет легко организовывать параллельные вычисления. И нам был очень интересен ответ на вопрос, сможем ли мы её использовать в своём проекте.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Почему не я люблю декораторы и метаклассы</title>
      <link>https://www.alexkorablev.ru/dev/why-i-hate-metaclasses/</link>
      <pubDate>Mon, 14 Sep 2015 10:00:10 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/why-i-hate-metaclasses/</guid>
      <description>&lt;p&gt;Я не люблю декораторы и метаклассы. Почти любое использование декоратора и любое использование метакласса ухудшает читаемость кода. Их трудно использовать без усложнения кода. Они приводят к трудновыявляемым багам. Так что их использование должно быть обосновано. И их не нужно использовать там, где можно легко и безболезненно обойтись без них.&lt;/p&gt;
&lt;p&gt;Если сравнить использование остальных конструкций языка с использованием рогатки, то использование декоратора — это стрельба из пушки, а метаклассы — из системы залпового огня «Град». Последствия их неправильного использования влияют на кодовую базу примерно так же. Декоратор «разламывает» несколько функций и методов, метакласс «разрывает в клочья» несколько классов.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Type Hinting в Python 3.5</title>
      <link>https://www.alexkorablev.ru/dev/type-hinting/</link>
      <pubDate>Mon, 31 Aug 2015 10:00:26 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/type-hinting/</guid>
      <description>&lt;p&gt;«Утиная» типизация, конечно, ускоряет написание программ, но только до определённых пределов. В больших проектах, когда количество кода достаточно велико, такая гибкость начинает давать сбои. С Python 3.0 можно делать типизацию для функций. Но только с 3.5 появится действительно мощный инструмент, встроенный в язык.&lt;/p&gt;
&lt;p&gt;Конечно, можно делать описание параметров и возвращаемых значений в докстрингах. Вот только кто их пишет? А если пишет, то кто следит за их актуальностью? Программисты ленивы: если можно что‑то не делать, они не будут этого делать.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Кастомные коллекции</title>
      <link>https://www.alexkorablev.ru/dev/magic-methods-getitem/</link>
      <pubDate>Mon, 24 Aug 2015 10:00:36 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/magic-methods-getitem/</guid>
      <description>&lt;p&gt;Хорошо написанный код на Python должен работать с последовательностями однообразно. При этом неважно, встроенные это последовательности или нет. Тем более что свою последовательность написать в Python очень просто. Нужно всего лишь переопределить &lt;code&gt;__len__&lt;/code&gt; и &lt;code&gt;__getitem__&lt;/code&gt;, чтобы работа с вашей последовательностью в большинстве случаев не отличалась от работы со встроенными последовательностями.&lt;/p&gt;
&lt;p&gt;В качестве иллюстрации возьмём такой пример. У нас есть класс &lt;code&gt;ShoppingBasket&lt;/code&gt;. В нём лежат какие‑то товары. Пусть нам нужно пройтись по всем товарам, научиться получать товары по ключу и добавлять товары.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Celery: Pickle от которого невозможно отказаться</title>
      <link>https://www.alexkorablev.ru/dev/celery-pickle-ot-kotorogo-nevozmozhno-otkazatsya/</link>
      <pubDate>Mon, 10 Aug 2015 11:00:00 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/celery-pickle-ot-kotorogo-nevozmozhno-otkazatsya/</guid>
      <description>&lt;p&gt;Если вы решили поменять сериализатор задач для Celery с Pickle на какой‑нибудь другой, ничего не выйдет. Вернее, задачи действительно будут сериализоваться и десериализоваться с помощью указанного сериализатора. Но внутри Celery всё равно используется Pickle, и это никак не изменить. Вернее, не в Celery, а в библиотеке &lt;code&gt;billiard&lt;/code&gt;, которая используется мастер‑процессом воркера для раздачи задач из очереди подпроцессам.&lt;/p&gt;
&lt;p&gt;В нашем проекте мы столкнулись с тем, что иногда передаём в качестве параметра задач Celery &lt;code&gt;NoneType&lt;/code&gt;. Причём не значение &lt;code&gt;None&lt;/code&gt;, а именно &lt;code&gt;NoneType&lt;/code&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Декораторы с параметрами по умолчанию</title>
      <link>https://www.alexkorablev.ru/dev/dekoratory-s-parametrami-po-umolchaniyu/</link>
      <pubDate>Mon, 03 Aug 2015 13:19:00 +0500</pubDate>
      <guid>https://www.alexkorablev.ru/dev/dekoratory-s-parametrami-po-umolchaniyu/</guid>
      <description>&lt;p&gt;Декораторы в Python — удобный инструмент. Если ими пользоваться с умом, они значительно повышают читаемость кода и его повторное использование.&lt;/p&gt;
&lt;p&gt;Но есть один момент, который меня немного напрягает: для декоратора с параметрами по умолчанию нужно ставить пустые круглые скобки после его вызова. Время от времени это приводит к ошибкам. Особенно это актуально, если декоратор является частью публичного API.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;@decorator_wo_params&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;f1&lt;/span&gt;():
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;pass&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;@decorator_w_defaults_params&lt;/span&gt;()  &lt;span style=&#34;color:#75715e&#34;&gt;# Ну зачем здесь пустые скобки?&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;f2&lt;/span&gt;():
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;pass&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;С этим можно смириться. В режиме жёстких сроков и большого потока задач времени на поиск решения, написание и тестирование дополнительного кода может просто не быть. Нормальное тестирование выявит проблему моментально. Но иногда невозможно удержаться и не сделать свой код немного красивее.&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
