import __hello__


Kanal geosi va tili: Ukraina, Ukraincha


Канал про IT, здебільшого WEB та Python, але буває й у інші теми заносить

Связанные каналы  |  Похожие каналы

Kanal geosi va tili
Ukraina, Ukraincha
Statistika
Postlar filtri


Мабуть функції не по 3 рядка писав 😁


Ну що, розпочався черговий Advent of Code - гарний спосіб відволіктись від буденного життя і отримати трохи новорічного настрою.

Цей івент також може стати гарною нагодою вивчити\підтягнути нову мову програмування (чи навіть технологію, бачив пости де чуваки боролись із aoc у Excel). Я хотів aoc2024 вирішувати на Go, але розумію що цього року у мене набагато менше вільного часу ніж минулоріч, тому знову озброюсь пайтоном, бо це для мене найшвидший спосіб вирішувати задачки.

Сьогоднішній день досить легкий, навідміну від 2023 року, тому не має одразу відпугнути нових учасників 😁

Доречі не забувайте заходити на reddit, після того як вирішете задачки дня, за мемами ☺️


Мене завжди дивує що у розмовах про дивацтва JavaScript обовʼзково згадують про те що 0.1 + 0.2 != 0.3, хоча насправді ця "проблема" є не лише у JS, це наслідок того як компʼютер представляє числа із плаваючою точкою.

Така ж ситуація із "дивацтвом" Пайтона коли хтось вперше бачить що all([]) is True і, не розуміючи чому так, відносить це до категорії unexpected behaviour.

Але це буквально 2500-річна філософська дискусія. Античні філософи вважали, що твердження 'всі єдинороги блакитні' має бути хибним, бо єдинорогів не існує, але сучасна логіка стверджує, що це істина, оскільки не існує єдинорогів, які не є блакитними. Python просто слідує сучасній предикатній логіці, але інша точка зору (у нашому випадку що all([]) має бути False як і порожній список) також досить поширена і була загальноприйнятою позицією до останніх кількох сотень років.

Але ми не філософи, ми програмісти, тому краще подивитись на більш практичні приклади:


all([]) # True
any([]) # False
math.prod([]) # 1
sum([]) # 0
max([]) # ValueError!


Справа у тому що ці функції реалізують концепцію з теорії категорій - моноїд.

Коли ми працюємо зі списками, нам важливо щоб операції над ними працювали передбачувано. Наприклад, якщо у нас є два списки xs та ys, то:

>>> from math import prod
>>> prod(xs + ys) == prod(xs) * prod(ys)
True
>>> sum(xs + ys) == sum(xs) + sum(ys)
True


А тепер цікавий момент - що буде якщо ys буде порожнім списком? Тоді:

prod(xs) == prod(xs + []) == prod(xs) * prod([])


Це рівняння може бути правдивим тільки якщо math.prod([]) == 1! Тобто одиниця тут виступає як нейтральний елемент для множення. У цього навіть є своє імʼя - порожній добуток (empty product).

Те саме і з іншими функціями:
- sum([]) == 0, бо 0 - нейтральний елемент для додавання
- all([]) == True, бо True - нейтральний елемент для and
- any([]) == False, бо False - нейтральний елемент для or

А от max() такого елемента не має! Не існує такого числа n, для якого max(x, n) == x для будь-якого x. Саме тому max([]) викидає помилку.

Доречі у цього явища є своє імʼя - вакуумна істина (vacuous truth). Це коли вираз вважається істинним, оскільки його умова не має сенсу.

Лінки:
- https://uk.wikipedia.org/wiki/%D0%9C%D0%BE%D0%BD%D0%BE%D1%97%D0%B4
- https://en.wikipedia.org/wiki/Empty_product
- https://en.wikipedia.org/wiki/Vacuous_truth
- https://news.ycombinator.com/item?id=37264149
- https://buttondown.com/hillelwayne/archive/why-any-is-true-prod-is-1-etc


Стаття про фічі нового Python 3.13. Ні, не про noGIL, JIT та інше, а про зміни які ви скоріш за все оминули увагою

https://www.bitecode.dev/p/python-313-what-didnt-make-the-headlines


Якось випадково натрапив на відос "Why don't Americans use electric kettles?" (ютуб рекомендації іноді підкидають щось неочікуване) і залип.
Саме так виглядав би ютуб канал гіка з 60х 😁. Автор бере якусь стару технологію і розповідає про неї так нібито це щойно презентований айфон чи макбук "The Antique Toaster that's Better than Yours"

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

Лінки:
- https://www.youtube.com/@TechnologyConnections

653 0 10 8 18

Мені подобається у якому напрямку рухається розвиток Python зараз.
Як на мене, нагальної потреби у додаванні нових фічей у мову зараз немає - вона вже досить давно є зрілою і містить достатню кількість мовних фічей (деякі із котрих можливо треба б було задепрекейтити і видалити)
І те що вже декілька версій у пайтон не додається багато нових можливостей (маю на увазі різний синтаксичний цукор) а навпаки core-розробники сконцентрували свою уваги над поліруванням того що є (покращують REPL, роблять повідомлення про помилки більш інформативними, видалять застарілі частини стдлібу, тощо) та над прискоренням CPython (nogil, JIT, subinterpreters, та звичайні оптимізації) як на мене дуже гарний знак того що у мови буде ще багато років планомірного розвитку.

Ось і новий реліз йде у сторону поліпшення швикодії та покращення developer expirience:

https://www.youtube.com/watch?v=gqqgwyNx52Q


Сьогодні на leetcode.com problem of the day це просто написати якийсь алгоритм сортування, тому ось вам стаття про те як імплементувати найпопулярніші із них із бенчмарками та переліком їх плюсів та мінусів.

Доречі ви знали що саме для Python вигадали новий алгоритм сортування Timsort (отримав назву по імені того хто його вигадав - Тім Пітерс)?
І що на співбесідах його ніхто ніколи не пише, бо для його імплементації спочатку треба написати insertion та merge алгоритми 😁.
Потім цей алгоритм утягнули до себе Swift, V8 та Rust.

Лінки:
- https://realpython.com/sorting-algorithms-python/
- https://en.wikipedia.org/wiki/Timsort

840 0 12 6 16

Виявляється що у coverage.py є альтернатива - Slipcover. Це така сама тулза для виміру покриття проєкту тестами але усього із 5% оверхеда у швидкодії (Coveragepy робить виконання вашого коду у три рази повільнішим, для порівняння).
На великих проєктах втричі більш швидкі тести це дуже суттєво.

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




У соурскоді sqlite 😁

За замовчуванням префікс був "sqlite". Але потім Mcafee почала використовувати SQLite у своєму антивірусному продукті, і він почав створювати файли з назвою "sqlite" у папці c:/temp. Це дратувало багатьох користувачів Windows. Ці користувачі шукали в Google "sqlite", знаходили номери телефонів розробників і телефонували їм уночі, щоб поскаржитися. З цієї причини префікс назви за замовчуванням було змінено на "sqlite", написане навпаки. Таким чином, тимчасові файли все ще можна ідентифікувати, але будь-хто, достатньо розумний, щоб зрозуміти код, також, ймовірно, достатньо розумний, щоб знати, що дзвінок розробнику не допоможе позбутися файлу.


Мабуть не відкрию ні для кого Америку, але метадата про кожний пакет у pypi, кількість скачувань і інша інформація доступна у публічному BigQuery.
Тож можна отримати будь яку цікаву для вас інформацію. Ось мені було цікаво знайти нові плагіни для flake8.


SELECT
name,
CONCAT('https://pypi.org/project/', name) AS project_url,
MAX(upload_time) AS most_recent_upload_time
FROM
`bigquery-public-data.pypi.distribution_metadata`
WHERE
name LIKE 'flake8-%'
GROUP BY
name
ORDER BY
most_recent_upload_time DESC


Звісно ганьба що pypi сам не дає способу нормально шукати по назвам та не показує кількість скачувань пакетів, але маємо що маємо.

Лінки:
- https://packaging.python.org/en/latest/guides/analyzing-pypi-package-downloads/#public-dataset
- https://console.cloud.google.com/bigquery?p=bigquery-public-data&d=pypi&page=dataset


Натрапив на просторах реддіта на репозиторій із переліком штук про котрі треба пам'ятати коли пишеш веб-сервіс на FastAPI.
Їх там зараз небагато, але всі дуже важливі. Мене найбільше зацікавив 9 пункт "Your dependencies may be running on threads" -
це може бути неочевидним, але якщо ваша async def view використовує синхронну залежність (навіть якщо вона нічого не робить а просто повертає примітивне значення)
то резолвінг цієї залежності буде відбуватись у тредпулі.

Тобто ось у цьому прикладі буде використовуватись тредпул незважаючи на те що root view використовує async def:


from fastapi import FastAPI, Depends

app = FastAPI()

def get_42():
return 42

@app.get("/")
async def root(value: int = Depends(get_42)):
return {"value": value}


Чим це погано? Тим що треди не резинові і за замовченням одночасно може жити лише 40 тредів, і якшо на ваш ендпоінт буде наплив трафіку, то перші 40 реквестів забʼють
тредпул, а решта буде чекати поки звільниться місце. Звісно що значення по-дефолту можна підняти, але воно всеодно не буде нескінченним.
Виправити у прикладі вище цю проблему просто - замінити def get_42(): на async def get_42(): і тоді всі реквести
будуть запускатись без тредпула, просто у поточному event loop.

Підсумовуючи:
- Завжди у першу чергу використовуйте async def для вьюх (це вже й так всі запамʼятали) і залежностей що інжектяться через Depends.
- Синхронні вьюхи використовуйте лише якщо вони роблять блокуючі операції, наприклад використовують бібліотеку requests для http запитів.
- Перевірте свої додатки - у тому ж пункті є код за допомогою якого можна це зробити

Лінки:
- https://github.com/Kludex/fastapi-tips


Мамкін Архітектор dan repost
Подивився на ютубі інтервʼю з чуваком, який переписав кафку.

⁃ написали все на golang. Сказав, що це мова, до якої немає питань. Типа вони з напарником ніколи її не обговорюють, а просто деліверять фічі;

⁃ в якості стореджа використовується S3. Це дає доволі суттєву економію, порівняно з EBS (що є по суті клаудним NAS на SSD). По суті це реальний cloud native storage, який може скейлитись до нескінченності і має майже 100% SLA. Недоліком є трохи вища latency;

⁃ хочуть повністю повторити протокол kafka, зараз вже все є, крім транзакцій. По суті це drop in replacement для кафки, і існуючі клієнти можуть перемкнутись на їхній сервіс без змін (якщо там немає транзакцій);

⁃ ноги у проекта ростуть з DataDog -- на початку є пара цікавих інсайдів про внутрянку останніх;

⁃ під час написання намагаються не дивитись на код kafka (який на java), натомість використовують код альтернативних клієнтів. Бо протокол дуже складний, мало документований, а в сторонніх клієнтах часто можна знайти коменти про реалізацію підтримки нововведень і різних corner cases

В цілому дуже сподобалось і саме інтервʼю, і проект який вони замутили. Ось посилання, якщо хочете подивитись самі: https://www.youtube.com/watch?v=xgzmxe6cj6A. Крім того, шо я тут написав, там багато цікавого про реалізацію, виклики, що стоять перед подібними системами, мотивацію і тд.

А це власне їхній стартап: https://www.warpstream.com/


Доречі, коли хочеться почати свій пет-проєкт який щось для мене покращить, чи просто just for fun, то треба якнайшвидше приступити до реализації, поки не перегоріло.
Бо поки засетапиш проєкт: додаси лінтери, сконфігуруєш їх, наставиш улюблених плагинів для пайтеста, напишеш Makefile, напишеш workflow для github actions (клятий github actions) - вже пройде декілька днів і бажання щось робити пропаде 😁.
А просто робити щось без цієї автоматизації і собі ж дорожче і не в кайф.

Тому одного разу я зробив собі шаблон для python-проєктів і одразу відчув користь:

- Не треба переносити сетап із минулого проєкту попутньо вирізаючи неактуальні частини конфігів і роблячи перейменування
- При створенні проєкту з шаблону можна робити різні налаштування і включати\виключати потрібні компоненти в новий проєкт. Наприклад якщо планується використовувати pydantic - одразу додати відповідний плагін до mypy
- Так як шаблон це тепер також мій окремий проєкт - він так само як будь який інший проєкт еволюціонує
- Dependabot допомагає слідкувати за актуальністю залежностей у шаблоні

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

Лінки:
- Cookiecutter - менеджер для таких от шаблонів. Не обовʼязково шаблон має бути для пайтона - це може бути шаблон будь чого, навіть не обовʼязково звʼязаний із програмуванням

436 0 3 10 18

У Django зʼявляться background workers

Декілька днів тому прийняли DEP-14, наступним кроком буде власне імплементація. Як я зрозумів вони просто зроблять django-tasks частиною Django.
Не те щоб мене ця новина якось обходила, бо я вже давно з Джангою справ не маю (ну майже) але це гарна пропозиція, бо майже будь яка апка на Django трохи більша ніж hello world потребує можливості запускати таски у фоні, а не заставляти юзера чекати її виконання.
Усі для цього використовували Celery, але ця ліба досить велика та потужна і до того не завжи тривіальна у налаштуванні і коли тобі треба зробити лише одну-дві простих дії у бекграунді то тащити цю монструозну лібу не дуже хочеться.
Ну от тепер і не треба буде - у Джанзі і для цього тепер буде рішення "із коробки".


Добре, поки мене не було я не лише серіали дивився, я також встиг написати ще одну DI бібліотеку для Python 😎.

Навіщо то взагалі у Пайтоні? Ну сама концепція DI це дуже крута штука, яку можна використовувати будь де без усіляких фреймворків. Але у такому разі треба самому бутстрапити залежності при старті апки і думати як оверайдити залежності у тестах. До того ж скоріш за все це все скатиться у service locator та нескінченні if my_service is None: my_service = get_my_service().

Раніше я користувався dependency-injector. Це чудова ліба, але вона завжди здавалась мені дуже навороченою для моїх цілей. І якщо на робочих проєктах її використання ще якось було виправдано, то для маленьких pet-проєктів це точно оверкіл - я завжди починаю з перечитування документації перш ніж засетапити новий проєкт із цією лібою. До того ж вона вже 2 роки не розвивається, тому я почав шукати альтернативи.

Мені подобається концепція DI у FastAPI - залежності це звичайні функції, ніяких контейнерів чи цілої пачки різних типів провайдерів - якщо хочеш щоб твоя залежність була кешованою - просто оберни її у lru_cache.

Із того що я знайшов цікавого у pypi:
- FastDepends - типу як у FastAPI, але із якимись лівими функціями, інколи скаржиться на аргументи які не мають інжектитись через тайп анотації, не має ресурс менеджменту і не може ніяк засунути async залежність у sync функцію, навіть якщо ми вже у async контексті, а ще не дуже дружить із FastAPI 🤯
- picobox - дуже крута концепція, але функціонал в основному зусереджений на Scopes (щоб залежності кешувались як сінглтон, у треді, у асінк тасці, реквестах, тощо), не має ресурс менеджменту і не дуже дружить із тайп анотаціями
- injector - стара ліба, мабуть непогана, але мені ніколи не подобався її API
- di та rodi - це більше схоже на ресолвери залежностей, над якими ще треба побудувати свій зручний API, хоча я може і помиляюсь

Тобто нічого із того що я знайшов мені не підходить. А мені усього то потрібно:
1. Власне інжекція залежностей у аргументи функцій, було б гарно якби як у FastAPI
2. Менеджмент ресурсів - щоб можна було зробити залежність яка має teardown і кешує свій результат впродовж життя апки - зручно для конекшенів у БД
3. Можливість оверайдити залежності для тестів
4. Зручний API і без зайвих можливостей

Тож я написав picodi (спочатку це мало бути nanodi, але pypi сказав що імʼя дуже схоже на вже існуючу лібу і не дав створити із такою назвою)- по суті це декоратор котрий резолвить (просто викликає функцію) залежності і сує їх у декоровану функцію, усе. Із додаткових можливостей - ресурс менеджмент, оверайдинг залежностей, працює із FastAPI і бонус - можливість резолвити асинхронну залежність-ресурс у синхронну функцію і ніякого вайрінгу (і ніякого детекту циклічних залежностей також 😁). Можливо імплементація трохи наївна, але поки мені подобається - я вже замінив dependency-injector на декількох своїх pet-проєктах без якихось проблем.

Тож якщо у когось з вас є схожі вимоги до DI фреймворку - можете спробувати, та не соромтесь робити issues та PR's 😊.

https://github.com/yakimka/picodi

499 0 4 18 14

Додивився серіал по Fallout і ось що я можу сказати як фанат 1, 2 частини, New Vegas та хейтер частин від Bethesda.

Загалом непоганий серіал, на 3 з плюсом. Із бісячого:
- Антураж схоже що взяли за основу із 4 частини - замість похмурого і сірого цвітасте та веселе
- Постанову масових перестрілок та бійок взагалі з трейлерів 4 та 76: всі бʼються під веселу музичку у слоумо
- Головний герой знову шукає свого родича, знов батька - або сценаристи Bethesda мають якісь дитячи травми, або вони великі фанати останніх Форсажів (головне - сімʼя), інших пояснень у мене немає
- Немає супермутантів
- Взагалі дуже мало канонічних монстрів, мабуть бюджет не дозволив
- Кігтя смерті показали лише у якості черепа
- Персонажів гри, які могли дожити до часу у який відбуваються події серіалу немає, хоча тут я може неуважно дивився
- Якась дурня із штукою за котрою увесь сезон полюють усі кому не лінь

Із того що сподобалось:
- Братство Сталі - покидьки
- Показали молодого Містера Хауса
- Не було відсилок до Легіону
- Загалом є відсилки до New Vegas, а другий сезон можливо взагалі буде про Вегас

Можна дивитись, я мабуть й другий сезон гляну як вийде

Так, це все ще канал про IT)


Алекс про усе dan repost
Дядько Боб на твічі – залітайте)

https://www.twitch.tv/ThePrimeagen

P.S. Це автор багатьох книг по програмуванні і хорошому коду. Якщо не читали дуже рекомендую
ThePrimeagen - Twitch
ADVENT OF CODE - DAY 1 - Elixir and Emojilang


Вийшов новий Technology Radar. Із цікавого (мені):
- Text to SQL in Trial (новий)
- CloudEvents in Adopt (піднявся із Trial)
- Pulumi in Trial (минулого разу також був у Trial)
- Rancher Desktop (новий, витиснув Colima)
- Kaniko in Adopt (минулий раз згадували у 2022 році)
- Mojo in Assess (новий)

Знов багато AI та не дуже багато чогось кардинально нового. Але може хтось для себе щось цікаве відкриє (мені не вдалось цього разу, хіба що Kaniko)

https://www.thoughtworks.com/radar


Тут Dave Plummer твітнув дуже повчальну історію про те як він у 94 році накидав тимчасовий UI для діалогу форматування диску у WindowsNT. І ось вже минуло 30 років, а ви й досі у актуальній версії Windows можете відкрити цей "тимчасовий" діалог і подивитись на результат його роботи 😁

Мораль всім відома - немає нічого більш постійного аніж тимчасове, тому коли робите щось "тимчасове" у кодовій базі, потурбуйтесь про те щоб воно було достатньо оптимальне і вам не довелось надто червоніти за свої рішення, бо скоріш за все результати вашої роботи буде спостерігати ще не одне нове покоління програмістів 😁

Доречі у цього чувака є прикольний канал на ютубі про DIY, C++ та історію Windows.

Лінки:
- https://twitter.com/davepl1968/status/1772042158046146792
- https://www.youtube.com/@DavesGarage

20 ta oxirgi post ko‘rsatilgan.