Конечно, самая большая радость этих дней — python 3.9. Но кроме этой радости кто-то должен ворошить github в поисках мелких приятностей, которые несут добро и свет тем, кто пишет на python.


Transitions


Тем, кому приходилось писать реализацию какого-нибудь сложного информационного процесса, знает эту проблему.


У вас есть некий объект, который может находиться всегда только в одном состоянии.
Переходы между состояниями описываются диаграммой состояний — из какого в какое состояние объект может перейти, а из какого в какое — не может.



Например, пользователь у вас в системе может быть незарегистрированным, зарегистрированным, зарегистрированным и зааппрувленным, зарегистрированным, зааппрувленным и неактивным, зарегистрированным, зааппрувленным и заархивированным, заблокированным — ну и так далее. Понятно, что из незарегистрированного можно стать зарегистрированным, но из незарегистрированного нельзя стать заблокированным.


Программист посмотрит на все эти переходы, почешет репу — и нагородит кучу if-else условий для того, чтобы описать все возможные переходы между состояниями и запретить все невозможные. А хороший программист вспомнит (или нагуглит) абстракцию под названием “конечный автомат” и возьмет эту штуку для реализации своей задачи. И будет прав.


В python есть своя готовая реализация конечных автоматов, она называется transitions.


from transitions import Machine

# На этт объект будем вешать состояния
class Matter(object):
    pass

lump = Matter()

# Полный список состояний
states=['solid', 'liquid', 'gas', 'plasma']

# Добавляем таблицу переходов — из какое в какое состояние мы можем попасть
transitions = [
    { 'trigger': 'melt', 'source': 'solid', 'dest': 'liquid' },
    { 'trigger': 'evaporate', 'source': 'liquid', 'dest': 'gas' },
    { 'trigger': 'sublimate', 'source': 'solid', 'dest': 'gas' },
    { 'trigger': 'ionize', 'source': 'gas', 'dest': 'plasma' }
]

# Инициализация машины
machine = Machine(lump, states=states, transitions=transitions, initial='liquid')

# Проверяем начальное состояние
lump.state
>>> 'liquid'

# И пробуем изменить состояние триггерами перехода
lump.evaporate()
lump.state
>>> 'gas'
lump.trigger('ionize')
lump.state
>>> 'plasma'

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


Money


Вещь, которой некоторым из нас иногда приходится заниматься — правильно форматировать вывод различных валют. Да-да, для каждой валюты есть правила форматирования — где-то разряды нужно отделять точкой, а где-то — запятой. Иногда код валюты пишется перед суммой, а иногда — после. Помнить, гуглить или городить форматирование через locale каждый раз лень, поэтому мы будем пользоваться специализированной библиотекой для форматирования денежных сумм — money.


>>> from money import Money
>>> m = Money(amount='2.22', currency='EUR')
>>> m
EUR 2.22

Конечно же, объекты Money можно между собой еще и складывать/вычитать/умножать и делить.


Fastai


Библиотек для глубокого обучения уже и так хватает — tensorflow, pytorch, keras и другие штуки поменьше успешно решат любую задачу по построению и обучению любой нейронной сети. Но тут появляется fastai и становится понятно, еще одна библиотека, в общем, не помешает и что с этой штукой жизнь стала приятней и веселей.



Fastai — высокоуровневая абстрактная нашлепка сверху на PyTorch, которая автоматизирует кучу всякой рутины, сокращает количество кода в ваших проектах и ускоряет процесс создания моделей машинного обучения.


  • Встроенные удобные функции по очистке, нарезке, подготовке табличных, текстовых и графических данных.
  • Готовые решения для стандартных задач. Например, в одну строчку можно нарезать, почистить, трансформировать, оптимизировать и нарезать на выборки картинки перед тем, как будете кормить их вашим нейронным сетям.
  • Готовые высокоуровневые компоненты для работы с графикой, текстом, таблицами и медицинскими файлами Dicom.

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


Наличие высокоуровневых абстракций сильно ускоряет написание кода.


# В одну строчку можно превратить папку с картинками в  данные для обучения сети.
# Сразу же осуществляются все преобразования и присваиваются метки классов.
data = ImageDataBunch.from_name_re('./data', fnames, r'/([^/]+)_\d+.jpg$', ds_tfms=get_transforms(), size=224, bs=64).normalize(imagenet_stats)

# Еще одна строка грузит предобученную модель resnet34 и на ее основе создает нашу сеть,
# которую мы будем обучать на основе картинок из строчки выше.
learn = cnn_learner(data, models.resnet34, metrics=error_rate)

# Все, готово, обучили
learn.fit_one_cycle(4)

Конечно же, вы всегда можете опуститься на уровень ниже и обратиться непосредственно к PyTorch коду — например, для более тонкой настройки модели.


Если же вы понятия не имеете о том, как работать с нейронными сетями и глубоким обучением — авторы fastai сделали крутой и понятный курс, который позволит вам за пару недель научиться создавать модели машинного обучения под ваши задачи. На первом же занятии вы напишите детектор порд собак и кошек по фотографиям.



На сегодня все, прошлые питонячие радости смотрите по ссылке.