Aspiring Data Science – Telegram
Aspiring Data Science
386 subscribers
465 photos
12 videos
12 files
2.15K links
Заметки экономиста о программировании, прогнозировании и принятии решений, научном методе познания.
Контакт: @fingoldo

I call myself a data scientist because I know just enough math, economics & programming to be dangerous.
Download Telegram
#python #codegems #typing #cleancode

Пример применения всратых средств типизации Питон.

Предположим, что требуется создать функцию top(it, n), которая возвращает n наибольших элементов из итерируемого объекта it:

>>> top([4, 1, 5, 2, 6, 7, 3], 3)
[7, 6, 5]
>>> l = 'mango pear apple kiwi banana'.split()
>>> top(l, 3)
['pear', 'mango', 'kiwi']
>>>
>>> l2 = [(len(s), s) for s in l]
>>> l2
[(5, 'mango'), (4, 'pear'), (5, 'apple'), (4, 'kiwi'), (6,
'banana')]
>>> top(l2, 3)
[(6, 'banana'), (5, 'mango'), (5, 'apple')]

как же такую функцию "правильно" аннотировать?

Казалось бы, можно сделать через TypeVar так:
from typing import TypeVar
T = TypeVar('T')

def top(series: Iterable[T], length: int) -> list[T]:
ordered = sorted(series, reverse=True)
return ordered[:length]

Вопрос в том, как ограничить T. Это не может быть Any или object, потому что series должен работать с функцией sorted.
Правильное, типа, решение - объявить протокол, поддерживающий операцию сравнения (для сортировки):

from typing import Protocol, Any
class SupportsLessThan(Protocol):
def __lt__(self, other: Any) -> bool: ...


и уже потом ограничить TypeVar этим протоколом:

LT = TypeVar('LT', bound=SupportsLessThan)
def top(series: Iterable[LT], length: int) -> list[LT]:
ordered = sorted(series, reverse=True)
return ordered[:length]

Ну и типа сидишь такой, думаешь: а стоит ли прохождение проверок типов mypy этих усилий, дополнительного кода, введённых несовместимостей? Я, честно, ХЗ.
#python #books #typing #cleancode

В книжке Fluent Python пишут:

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

Даже в тех контекстах, где статическая типизация наиболее полезна, на нее нельзя полагаться как на единственный критерий правильности. Вполне можно столкнуться с:
Ложноположительными результатами
Инструмент сообщает об ошибке, когда ее нет.

Ложноотрицательными результатами
Инструмент не сообщает об ошибке в заведомо неправильном коде.

Кроме того, требуя проверять типы всего на свете, мы утрачиваем часть выразительности Python:

некоторые удобные возможности нельзя проверить статически, например распаковку аргументов вида config(**settings);

программы проверки типов в общем случае плохо поддерживают или вообще не понимают таких продвинутых возможностей, как свойства, дескрипторы, метаклассы и метапрограммирование;

программы проверки типов не поспевают за выходом новых версий Python, отвергают код, содержащий новые возможности, или даже «падают» – и иногда это продолжается больше года.

Самые простые ограничения на данные невозможно выразить в системе типов. Например, аннотации типов не могут гарантировать, что «величина должна быть целым числом > 0» или что «метка должна быть строкой длиной от 6 до 12 символов ASCII». Вообще, аннотации слабо помогают отлавливать ошибки в прикладной логике.

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

Рассматривайте программы статической проверки типов как один из инструментов в современном конвейере непрерывной интеграции (CI) наряду с автоматизированными тестами, линтерами и т. д. Цель конвейера CI – уменьшить количество программных ошибок, а автоматизированные тесты находят многие ошибки, выходящие за рамки возможного для аннотаций типов. Любой код, который можно написать на Python, можно на Python и протестировать – с аннотациями типов или без них."

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

"Если кодинг – не ваша профессия, а лишь полезный инструмент, применяемый в профессиональных занятиях, или нечто такое, что вы изучаете ради удовольствия, то, пожалуй, аннотации типов нужны вам не больше, чем жесткие ботинки и металлические набойки большинству велосипедистов.
Просто кодируйте."

"Я согласен, что пользователи большинства API выигрывают от наличия аннотаций типов. Но Python привлекал меня – среди многих других причин – тем, что предоставляет чрезвычайно мощные функции, способные заменить целые API, и, более того, мы сами можем писать такие функции.

Рассмотрим встроенную функцию max(). Она мощная, но понять ее легко. Однако, как будет показано в разделе «Перегрузка max», чтобы ее правильно аннотировать, нужно 14 строчек аннотаций типов, и это не считая typing.Protocol и нескольких определений TypeVar, необходимых для поддержки этих аннотаций.

Я боюсь, что если библиотеки будут строго требовать аннотирования типов, то программисты раз и навсегда зарекутся писать такие функции."
#python #typing #cleancode

Ну и вдогонку.

"У аннотаций типов есть достоинства, но есть и цена. Во-первых, нужно потратить усилия, чтобы понять, как работает система типов. Но это одноразовые затраты.
А есть еще и постоянные, которые придется нести всегда.

Настаивая на вставке аннотаций везде и всюду, мы теряем часть выразительности Python. Такие замечательные средства, как распаковка аргументов - например, config(**settings), – выходят за пределы возможностей программ проверки типов.

Если вы хотите подвергнуть вызов вида config(**settings) проверке типов, то должны будете выписать каждый аргумент. Это наводит меня на воспоминания о Turbo Pascal, на котором я писал 35 лет назад.

Библиотеки, в которых используется метапрограммирование, трудно или даже невозможно анотировать. Конечно, метапрограммирование можно употребить во вред, но одновременно это вещь, благодаря которой со многими Python-пакетами так приятно работать.

Спасибо Гвидо за факультативную типизацию. Давайте будем использовать ее так, как она задумана, и не пытаться аннотировать все вокруг в строгом соответствии со стилем кодирования, напоминающим Java 1.5."

В общем, нужно найти баланс между всратостью и разумностью )
#music #rock #chyop

Год тому познакомился с парнишкой в поезде. пишет сегодня, мол, Анатолий, зацени, новую песню выпустил. Как вам?

https://www.youtube.com/shorts/XfY2vntaaTI

https://lnkfi.re/Clouds_
#astronomy #dangers

«DART дал нам представление о сложной гравитационной физике, которую невозможно изучить в лаборатории, и все эти исследования помогают нам узнать больше для защиты Земли в случае возникновения реальной угрозы. Существует ненулевая вероятность того, что астероид или комета приблизится и подвергнет планету опасности. Теперь у нас есть дополнительная линия защиты от такого рода внешних угроз», — считает Ричардсон.

https://3dnews.ru/1109977/missiya-nasa-dart-pomogla-uchyonim-uznat-bolshe-o-geofizike-legashchey-v-osnove-formirovaniya-i-evolyutsii-asteroidov
#python #vb #with #contextmanagers

"Не исключено, что контекстные менеджеры окажутся почти такими же важными, как сами подпрограммы. Мы затронули лишь самую верхушку айсберга […].

В языке Basic есть предложение with, как и во многих других языках. Но все они делают совсем не то – они лишь экономят время на повторяющемся поиске атрибутов с точкой, не производя ни инициализации, ни очистки. Не нужно думать, что раз названия одинаковы, то одинаковы и функции. Предложение with – очень мощная штука.

– Рэймонд Хэттингер"

Капец. Так вот откуда Рэй взял идею конструкций with. А какого хрена тогда было не сделать так же, как в Visual Basic, вложенные with с сокращённой нотацией?! Это ж очень удобно. Для доступа к полю A.B.C в VB можно написать
with A.B
.C=...

Кстати, до сих пор не пойму, почему в Python переменная, объявленная в контекстном менеджере, доступна ПОСЛЕ выхода из контекста. Это выглядит крайне нелогично:
import pymc as pm

# Define a model using a context manager
with pm.Model() as model:
# Define random variables within the model
mu = pm.Normal('mu', mu=0, sigma=1)
sigma = pm.HalfNormal('sigma', sigma=1)
observed_data = pm.Normal('observed_data', mu=mu, sigma=sigma, observed=[1.2, 1.8, 2.4])

# Outside the context, you can still access the 'model' and the variables
model.do_something()
1
#fun #jobs

- Человек, пой снова, мне понравилось!
- Позабыты хлопоты, остановлен бег, вкалывают роботы, счастлив человек...

- Громче!!!
#law #security

"Было установлено, что Uber нарушала Общий регламент ЕС по защите персональных данных (GDPR), передавая и храня информацию о европейских таксистах на серверах в США в течение более двух лет. Речь идёт о разнообразной конфиденциальной информации, включая учётные записи водителей Uber, лицензии на работу в такси, данные о местоположении, фотографии, платёжные реквизиты, удостоверяющие личность документы и др.

DPA уже дважды штрафовала Uber. Первый штраф в размере €600 тыс. был наложен в 2018 году после того, как компания не сообщила об утечке данных, произошедшей двумя годами ранее. В 2023 году Uber была оштрафована на €10 млн за неполную детализацию периодов хранения данных о европейских таксистах. Нынешний штраф стал самым крупным, но Uber собирается его обжаловать."

Закон о хранении данных на серверах определённой страны, если честно, тупейший, и нарушает права людей. На мой взгляд, он не связан с безопасностью клиентских данных НИКАК. От того, расположен сервер в Брюсселе или Атланте, его безопасность не зависит (при условии нахождений в дата-центре с нужным сертификатом защиты). Единственное желание, которое прослеживается - это желание правительств иметь доступ ко всем данным своих граждан. А я ХОЧУ хранить свои личные данные в любой стране, где мне надо, и подите все нахер со своими указаниями, где можно хранить мои данные.

https://3dnews.ru/1110020/uber-oshtrafovali-v-niderlandah-na-290-mln-za-nebezopasnuyu-peredachu-dannih
#hardware #storage

"На территории Таиланда у американской компании Western Digital функционирует предприятие, отвечающее за выпуск 80 % всех жёстких дисков в мире. Компания собирается увеличить его штат почти в полтора раза и вложить в расширение производства $693 млн, данная инициатива уже получила поддержку со стороны местных властей.

За десятилетие власти Таиланда в общей сложности одобрили инвестиции на развитие в стране производства жёстких дисков на сумму $2,43 млрд. В прошлом году разрешение вложить $470 млн на расширение своих производственных мощностей в стране получила американская компания Seagate Technology. Всего по итогам текущего года в различные сферы экономики Таиланда было вложено около $23,5 млрд."

А в России что? Климат не тот, видать.

https://3dnews.ru/1109993/vlasti-tailanda-odobrili-investitsii-western-digital-v-summe-693-mln-napravlyaemie-na-rasshirenie-proizvodstva-gyostkih-diskov
Forwarded from kyrillic
Новая программа для 🇪🇸 испанских номадов от Эстремадуры (региона на границе с Португалией): можно получить до 15к евро за переезд в маленький город региона.

Условия простые: испанский номад-внж и переезд в город региона. Если до 30 лет и в городе до 5 тыс населения, то дают 10к сразу и 5к через два года. Для остальных 8к сразу и 4к через два года (новость, источник).

Подавать можно будет после того, как программу опубликуют в официальном вестнике Эстремадуры через три недели.

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

Полагаю, что стоимость аренды дома/квартиры будет 400-600 евро/мес. На idealista есть и за 300 приличное.

Регион на границе с Португалией - всегда можно разнообразить жизнь поездкой к соседям. Жаль до моря неблизко!

Я бывал в регионе проездом, но никакого мнения не сложилось - вроде обычная приятная провинциальная Испания. Может кто-то из вас там живет или жил? Расскажите!

@kyrillic
Forwarded from kyrillic
⚡️ Быстрая диванная аналитика по обвинениям в отношении Телеграма:

1️⃣ Вменяют по всему сразу, о чем писал в посте - и все виды нелегальный контента, и отмывание денег. Но самое главное - по новой во французском кодексе статье про администрированию ресурсов, которые распространяют плохое. Кажется, что по ней доказать легче всего.

2️⃣ Телеграм теперь официально маргинальная площадка в ЕС. Если в медиа будет раскручиваться этот нарратив (не очень вероятно, но все же), то будут и ограничения всего телеграма в каком-то виде (думаю, что удаление из сторов).

3️⃣ Получение гражданства - это не только права, но и обязанности. Французы могут спокойно судить своего гражданина за преступления в других странах. Про такие риски получения паспорта не говорят, хотя эти строки прочитает множество репатриантов, которым формально запрещено въезжать например в Малайзию.

4️⃣ Ограничения телеграма, точечные по чернухе или глобальные, будут вводиться небыстро, отток из-за них будет медленный. Но начнется процесс и с другой стороны - те, кто рулит нелегальным, станут осторожнее использовать тг, а значит и желающих распространять нелегальное через тг будет меньше.

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

5️⃣ Если у вас есть средства в официальном кошельке wallet, то я бы их вывел на всякий случай. Там уже висит плашка, что транзакции обрабатываются с задержкой (как подсказывают в комментах - из-за листинга dogs). Ну и самым рисковым можно поиграть в ton, самое время!

@kyrillic
❤‍🔥111
#sklearn #mlgems

У Винсента всегда классные выступления. Кратко рассматривает кэширование конвейера (Pipeline(...,memory=...)), роутинг весов, дообучение для потоковых данных (partial_fit), модуль semi_supervised, Но вы этот раз всё очень кратко и галопом по Европам.

https://www.youtube.com/watch?v=es_8_iT-oQk
#python #books

С трудом дочитал "Л. Рамальо. Python – к вершинам мастерства: Лаконичное и эффективное программирование" (в оригинале - Fluent Python, 2nd Edition).

Книгу скорее не рекомендую. Под 900 страниц, но затронутые темы требуют кратно большего количества материала и примеров.

Мало ценных для бизнеса примеров, в основном какие-то дурацкие. Странная подача материала - при обсуждении продвинутых концепций вроде метаклассов автор в каждой такой главе умоляет не использовать их, обходясь более простыми (и ограниченными) средствами, вместо того чтобы привести конкретные примеры, где применение продвинутых техник наиболее полезно.

Странная смесь подачи базовых концепций и обсуждения сложного материала, уходящего к корням, в реализацию на С, порой в другие языки. Много откровенно дебильных сносок (не используйте сноски, шутки и благодарности при написании книги).

Русский перевод не рекомендую точно.

Мудила-переводчик перевел на русский абсолютно все термины, к примеру, framework у него не фреймфорк, а каркас. Ты, сука, где слышал, чтобы русскоязычные программисты говорили - я, мол, каркас новый написал давеча...

При этом для зачастую сложных терминов, переведённых им по наитию, он постеснялся указать общепринятые англоязычные эквиваленты. А нахера, ведь его читатель, наверное, никогда не полезет в документацию, не появится на международных форумах, зачем упрощать ему жизнь?

Причем переводил, похоже, Промптом из 2000-х (привет многократноядерным машинам), слово в слово, из-за чего сложилось впечатление, что автор оригинальной книги - косноязычный идиот (так всегда бывает, когда плохой переводчик и редактор). Ощущение, что ни переводчик, ни редактор не являются программистами. Вы зачем тогда взяли эту работу? Через текст приходиться буквально продираться.

Тем не менее, я повыписывал вещи, которые не знал/забыл/показались достойными повторения. Изложу их в нескольких постах ниже.
👍1
#python #codegems

По умолчанию любой экземпляр пользовательского класса считается истинным, но положение меняется, если реализован хотя бы один из методов bool или len. Функция bool(x), по существу, вызывает x.bool() и использует полученный результат. Если метод bool не реализован, то Python пытается вызвать x.len() и при получении нуля функция bool возвращает False. В противном случае bool возвращает True.

В программе на Python переход на другую строку внутри пар скобок [], {} и () игнорируется. Поэтому при построении многострочных списков, списковых включений, генераторных выражений, словарей и прочего можно обходиться без косой черты для экранирования символа новой строки, которая к тому же не работает, если после нее случайно поставлен пробел.

Переменные, которым присвоено значение в операторе :=, остаются доступными и после возврата из включения или выражения – в отличие от локальных переменных, определенных в функции. В документе PEP 572 область видимости оператора := определена как объемлющая функция, если только соответствующая переменная не является частью объявления global или nonlocal.
>>> x = 'ABC'
>>> codes = [last := ord(c) for c in x]
>>> last
67


Если мы хотим произвести сопоставление (match) произвольной последовательности-субъекта, начинающейся с str и заканчивающейся вложенной последовательностью из двух float, то можем написать:
case [str(name), *_, (float(lat), float(lon))]:

Здесь *_ сопоставляется с любым числом элементов без привязки их к переменной. Если вместо *_ использовать *extra, то с переменной extra будет связан список list, содержащий 0 или более элементов.

В NumPy … используется для сокращенного задания среза многомерного массива; например, если x – четырехмерный массив, то x[i, ...] – то же самое, что x[i, :, :, :,]. Имя класса ellipsis записывается строчными буквами, а его экземпляр – встроенный объект Ellipsis. Точно так же обстоит дело с классом bool и его экземплярами True и False.

Остерегайтесь выражений вида a * n, где a – последовательность, содержащая изменяемые элементы, потому что результат может оказаться неожиданным. Например, при попытке инициализировать список списков my_list = [[]] * 3 получится список, содержащий три ссылки на один и тот же внутренний список, хотя вы, скорее всего, хотели не этого.

Кратная конкатенация неизменяемых последовательностей выполняется неэффективно, потому что вместо добавления новых элементов интерпретатор вынужден копировать всю конечную последовательность, чтобы создать новую с добавленными элементами.

Строка my_dict.setdefault(key, []).append(new_value) дает такой же результат, как
if key not in my_dict:
my_dict[key] = []
my_dict[key].append(new_value)

… с тем отличием, что во втором фрагменте производится по меньшей мере два поиска ключа (три, если ключ не найден), тогда как setdefault довольствуется единственным поиском.


collections.ChainMap хранит список отображений, так что их можно просматривать как единое целое. Поиск производится в каждом отображении в порядке их перечисления в конструкторе и завершается успешно, если ключ найден хотя бы в одном. Например:
>>> d1 = dict(a=1, b=3)
>>> d2 = dict(a=2, b=4, c=6)
>>> from collections import ChainMap
>>> chain = ChainMap(d1, d2)
>>> chain['a']

1
>>> chain['c']

6

MappingProxyType можно использовать для защиты словаря от записи:

from types import MappingProxyType
>>> d = {1: 'A'}
>>> d_proxy = MappingProxyType(d)
>>> d_proxy
mappingproxy({1: 'A'})
>>> d_proxy[1]
'A'
>>> d_proxy[2] = 'x'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'mappingproxy' object does not support item assignment