Простір для вивчення нової професії, зростання в кар’єрі або розвитку бізнесу👇🏻
Наша команда пише для вас найкращі та найцікавіші матеріали, які обов’язково допоможуть у вашому навчанні: https://genius.space/lab/
Last updated 1 month, 3 weeks ago
Мене завжди дивує що у розмовах про дивацтва 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"
Або ось він досліджував наскільки сильно зовнішні навіси на вікна охолоджують будинок у літню спеку і чому їх більше не використовують, чи про проблеми які зʼявились у інженерів котрі проєктують автомобільні стоп-сигнали із появою електрокарів.
Коротше якщо вам також подобаються гіковскі відоси із акцентом на старі технології - дуже рекомендую
Мабуть не відкрию ні для кого Америку, але метадата про кожний пакет у 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 запитів.
- Перевірте свої додатки - у тому ж пункті є код за допомогою якого можна це зробити
Подивився на ютубі інтервʼю з чуваком, який переписав кафку.
⁃ написали все на 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/
Простір для вивчення нової професії, зростання в кар’єрі або розвитку бізнесу👇🏻
Наша команда пише для вас найкращі та найцікавіші матеріали, які обов’язково допоможуть у вашому навчанні: https://genius.space/lab/
Last updated 1 month, 3 weeks ago