Блуждающий форвард
22 subscribers
6 photos
1 video
7 links
Очередной "здравствуй, дорогой дневник" про IT. А чё ещё делать в эмиграции?
Download Telegram
Короче, впервые я прикоснулся к написанию кода ещё в школе, в далёком 2008. Каким-то невероятным стечением обстоятельств мне повезло учиться в лицее, который готовил школьников к олимпиадам и меня стали учить решать паскалем и питоном задачки по спортивному программированию. Звёзд с неба я не хватал, но, конечно, безумно много о себе мнил. Я начал фрилансить, закончил лицей, переехал в Киев учиться и бросил учёбу, провалившись в социальную жизнь. Всё это время я не стеснялся делиться своим скудным опытом, пробовал учить одногруппников, писал (прости, господи) статьи, пока однажды, в 2014-ом судьба не забросила меня с нечастого фрилансерского заработка на первую галерку джанго-джуном и там-то я понял насколько я нулёвый чел. Столкнувшись с миром реальной разработки, с планированием, процессами, командной работой и всем прочим, я так оробел что на долгие годы обозначил для себя свои знания как ламерские и недостаточные и взрастил огромный комплекс самозванца.
Время шло, я, как заправский блуждающий форвард, сменил с пяток галерок, набрался опыта и осел на уютной удалёнке, перебравшись жить в Испанию. Давно прошёл "туристический" период переезда, активную социальную жизнь сменило старое доброе эмигрантское одиночество и у меня наконец-то появилось время для того, чтобы отрефлексировать свои профессиональные знания, заработанные за последнее десятилетие.
Тут я планирую, преодолевая синдром самозванца и неловкость, вести заметки о своём опыте и просто писать всё околоайтишное что взбредёт в голову.
👍1
О мелочах, которые бесят.

Вам не кажется, что поведение питоновского itertools.groupby совсем неинтуитивно? Ожидается, что функция groupby() буквально groups <iterable> by <key> — сгруппирует данные по ключу, но мы все знаем, что группировкой эта функция не занимается. Для последовательности "AABBAAAB" она сгенерирует 4 группы: по две на каждый ключ. Это работает за O(n), это позволяет "группировать" данные из генераторов, хоть из бесконечных, на лету, но это не groupby! Это итератор по уже сгруппированным данным. Почему не iterate_groups() или что-нибудь в этом духе?

Ладно, не мне учить отцов неймингу, но, согласитесь, вариант с "честной" группировкой на практике встречается куда чаще — в документации авторы и сами это признают:
It generates a break or new group every time the value of the key function changes (which is why it is usually necessary to have sorted the data using the same key function).

И при этом не дают нам отдельной функции, которая сделает всю группировку, а не половину. Хотя бы ключик (вроде -u в юниксовом uniq, который они приводят в доке в качестве примера) — но нет, ключика нам тоже не положено, поэтому в коде регулярно встречаются ужасно читаемые конструкции типа:

groupby(sorted(sequence, key=some_key), key=some_key)


Кстати, очевидно, что сортировать за O(n log n) в определённых условиях хуже, чем завести dict для групп, пройтись за O(n) по последовательности, на каждом шаге за O(1) достать нужный элемент из dict'а (или за O(1) добавить туда list в котором будут элементы новой группы) и за O(1) вставить в этот list очередное значение.

Неэффективно по памяти? А какая разница, если на практике чаще всего мы просто сортируем в памяти?
Не подходит для бесконечных генераторов? А когда вы в последний раз группировали данные из бесконечных генераторов?
👍2
О светлой теме в IDE.

Моё отношение к цвету окошка для написания кода менялось кучу раз. Я помню, как здорово было перейти из тёмно-синего окна Free Pascal'а во "взрослую" беленькую Borland Delphi, я помню, как светлый notepad++ в моём стеке сменился на чёрный стильный sublime. Потом было много разного софта, но тёмные темы в какой-то момент стали стандартом де-факто как для меня, так и для сообщества. А потом я переехал в Испанию и столкнулся с тем, что подавляющую часть времени вокруг меня адово светло. Я пробовал решить эту проблему по-разному — подбирал высококонтрастные чёрные темы, игрался со шрифтами и цветами, но ничего кроме "зашторить окна в ноль и не понимать зачем я приехал в солнечную страну и сижу 8–10 часов в тёмной комнате" не помогало. В какой-то момент я всё-таки сдался и засетапил во всех редакторах белую цветовую схему Alabaster (https://github.com/tonsky/sublime-scheme-alabaster). А она не только решила проблему работы в светлой комнате или на улице, но и избавила от другой, неотрефлексированной боли — теперь ключевые слова языка не выделяются отдельным цветом, так что код выглядит не как ёлка, а как внятный текст.

И жить стало легче, и жить стало веселее.
👍1
О программировании и юриспруденции.

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

Спасибо лучшему другу, у меня была возможность одним глазком взглянуть на работу юриста изнутри и убедиться, насколько похожи в своей основе наши процессы. И, в связи с этим меня беспокоит одна мысль — где у них рефлексия над практиками написания текстов и какая-то абстрактная, мета- работа? Почему в 2к22 у ребят есть командная работа над текстом, но нет аналогов код-ревью, нет контроля версий, шаблонизация текстов только-только входит в моду, а по-честному дальше 50 открытых вкладок с текстами в хроме и стёртых клавиш «c» и «v» они не ушли. Раньше я возмущался ценой в 200 евро за типовой контракт у любого хестора на Коста дель Соль, но со временем я начал понимать откуда ноги растут.

Желаю им (нам) в 3к22 описывать свои позиции лаконичным декларативным DSL-чиком и компилировать их в текст, верифицируя и доказывая непротиворечивость и прочие мелочи.
👍1
О паттерн матчинге в python.

В 3.10, помимо всего прочего, завезли паттерн матчинг. И вы об этом, конечно, слышали. А вы слышали про functools'овый singledispatch который доступен аж со времён 3.4 и реализует матчинг типов аргументов в функции? Выглядит это так:


Recipient = Email | SmsNumber

@singledispatch
def send_message(recipient: Recipient, message: str):
raise NotImplementedError()

@send_message.register
def send_message_via_email(recipient: Email, message: str):
# Send message via email by somehow

@send_message.register
def send_message_via_sms(recipient: SmsNumber, message: str):
# Send message via sms by somehow

some_email = Email('some@email.com')
some_phone = SmsNumber('+123456789')

send_message(some_email, 'message')
send_message(some_phone, 'message')


Ну практически haskell, нет? Увы, нет, ведь в python значение — это не то же самое что и тип, поэтому и возможности заматчить по значению у нас в этом случае нет. Но, так или иначе, singledispatch, бывает, здорово помогает организовать код лаконично и читаемо.

А вот чего в python не завезли (по, в целом, понятным причинам) так это возможности запилить sync и async реализации функции под одним именем. И это печально.

Важная ремарка (спасибо, @yakimka, что напомнил об этом, это действительно критичный ньюанс): матчинг в singledispatch происходит только по типу первого аргумента.
👍2
О ТРИЗе.

Есть такая антинаучная, но забавная штука — ТРИЗ. ТРИЗ — это продукт советского сумрачного гения, методология для изобретательства, да не простая, а, как и полагалось тогда любой приличной методологии, устойчиво стоящая на диалектическом материализме.

Её автор при решении задачи об улучшении некоторой системы предлагает находить противоречия в этой системе и размышлять над этими противоречиями пользуясь систематизированным набором методов.

Методы в ТРИЗе могут быть направлены на генерацию вариантов для решения задачи (например, метод аналогий — когда мы размышляем над похожими противоречиями в других системах), а могут помогать в ранжировании вариантов (например, бритва Оккама на инженерный манер — применение принципа "Технический объект идеален, если его нет, а функция выполняется", то есть минимизация сущностей и изменений). И методов этих многие сотни (хотя 99% из них невероятно очевидны и не представляют интереса).

Но это все не важно. В первую очередь ТРИЗ мне интересен как пример рефлексии над самой абстрактной частью нашей работы — мышлением. Едва ли в работе вам сильно помогут методы ТРИЗа. Но что вам поможет точно, так это изобретение своей системы для мышления задач. Рекомендую.
👍1
О мелочах, которые бесят. [2]

В 3.10 стало удобно записывать кастрированные питоновские типы-суммы в аннотациях. Вместо Union[A, B] теперь можно на хаскельный манер писать A | B. И вместе с этой фичей появилась отвратительная, как на мой вкус, неоднозначность.

Достаточно просто попробовать переопределить __or__ в метаклассе класса A и значение выражения A | B, очевидно, изменится, в том числе и в аннотациях. Причем, интерпретатор на пару с линтером будут молчать, вам никто не запретит это сделать, вам никто не ругнётся, что то, что вы только что зааннотировали это не Union — выражение просто вычислится, а его результат интерпретатор воспримет как тип для аннотации. Вот так:


class A:
pass

class B:
pass

class MetaC(type):
def __or__(self, other):
return A

class C(metaclass=MetaC):
pass

some_type: C | B # annotated as A


Вы, наверное, думаете, что никому в голову не придёт наследовать __or__ в метаклассе? Ну, например, мне пришло. А зачем оно мне понадобилось я расскажу как-нибудь в другой раз.
👍4
О pydantic.

Pydantic — это прекрасный способ сериализации/десериализации данных в python. Однако, время от времени бывают ситуации, когда его функциональность хочется немножко расширить. Об одной из таких ситуаций поговорим сегодня.

https://rowingforward.medium.com/%D0%BE-pydantic-cd76d14337c
👍5👎1
Вынес предыдущий пост в medium. Как думаете, стало лучше или хуже?
Вас тут немного, но напомнить будет нелишним, сейчас нет никаких других тем.

https://how-to-help-ukraine-now.super.site/
Двое моих знакомых мертвы. Десятки коллег и друзей сейчас под бомбёжками. Некоторые коллеги отложили макбуки и взяли в руки автоматы, чтобы защищать свою родину и её суверенитет. Отец присоединился к территориальной обороне. Если среди тех, кто меня читает есть граждане РФ — видео ниже для вас.

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

https://www.youtube.com/watch?v=Pnkxnks7r0Y
👍2
Media is too big
VIEW IN TELEGRAM
Когда война закончится, у меня для вас будет куча интересных постов про IT, а пока что вот.
👍1
Это моя школа. Здание было построено ещё в конце 20-х и было первой школой в моём городе. Во время второй мировой и немножко после оно функционировало как госпиталь. Там родилась моя бабушка и там же потом училась и она, и мой дед, и моя мама, и мы с сестрой.

Нашествия российских оккупантов это здание не выдержало.
😢5