Code formatters

Лев Коваленко — Senior DS Engineer

AutoFormatters

Black

Очень длинные строки

Например мы задаем какой-то сложный пайплайн из множества шагов, прописываем его в одну строку и получаем что-то не читаемое:

res = chain(resample_data.s(tuple(series), c=c.model_dump()),compute_masks.s(c=c.model_dump()),slice_pathline.s(c=c.model_dump(), slice_num=200),done.s(c=c.model_dump()),)()

Примените black и у вас читаемый код:

res = chain(
    resample_data.s(tuple(series), c=c.model_dump()),
    compute_masks.s(c=c.model_dump()),
    slice_pathline.s(c=c.model_dump(), slice_num=200),
    done.s(c=c.model_dump()),
)()

Отсутствие пробелов

Например где-то вы пропустили пробелы и код слипся в сложноразделимые строки:

threshold = np.percentile(res, 0.5)
recall, precision,f1,cf = (
    m.recall_score(test_y,res>=threshold,pos_label=1),
    m.precision_score(test_y,res>=threshold,pos_label=1),
    m.f1_score(test_y,res>=threshold,pos_label=1),
    m.confusion_matrix(test_y,res>=threshold,labels=(1,0)).T,
)

Примените black и у вас читаемый код:

recall, precision, f1, cf = (
    m.recall_score(test_y, res >= threshold, pos_label=1),
    m.precision_score(test_y, res >= threshold, pos_label=1),
    m.f1_score(test_y, res >= threshold, pos_label=1),
    m.confusion_matrix(test_y, res >= threshold, labels=(1, 0)).T,
)

Неправильно перенесенные строки

Например где-то вы не знаете как лучше самому перенести строки:

conditional_probabilities = (
    joint_distribution.filter(
        pl.col(target.name) == target_value
    ).select(pl.col(feature.name)).to_series().value_counts()["counts"]
    / feature.shape[0]
)

Примените black и у вас читаемый код:

conditional_probabilities = (
    joint_distribution.filter(pl.col(target.name) == target_value)
    .select(pl.col(feature.name))
    .to_series()
    .value_counts()["counts"]
    / feature.shape[0]
)

Конфигурация

Конфигурацию black можно провести в файле pyproject.toml

[tool.black]
line-length = 88
skip-string-normalization = true

Добавление в vscode

Существует специальное расширение: black-formatter

Так же в settings.json можно добавить следующие настройки:

{
  "[python]": {
    "editor.defaultFormatter": "ms-python.black-formatter"
  }
}

Autopep8

Очень длинные строки

Например мы задаем какой-то сложный пайплайн из множества шагов, прописываем его в одну строку и получаем что-то не читаемое:

res = chain(resample_data.s(tuple(series), c=c.model_dump()),compute_masks.s(c=c.model_dump()),slice_pathline.s(c=c.model_dump(), slice_num=200),done.s(c=c.model_dump()),)()

Примените autopep8 и у вас нет ошибок pep8:

res = chain(resample_data.s(tuple(series), c=c.model_dump()), compute_masks.s(
    c=c.model_dump()), slice_pathline.s(c=c.model_dump(), slice_num=200), done.s(c=c.model_dump()),)()

Отсутствие пробелов

Например где-то вы пропустили пробелы и код слипся в сложноразделимые строки:

threshold = np.percentile(res, 0.5)
recall, precision,f1,cf = (
    m.recall_score(test_y,res>=threshold,pos_label=1),
    m.precision_score(test_y,res>=threshold,pos_label=1),
    m.f1_score(test_y,res>=threshold,pos_label=1),
    m.confusion_matrix(test_y,res>=threshold,labels=(1,0)).T,
)

Примените autopep8 и у вас нет ошибок pep8:

threshold = np.percentile(res, 0.5)
recall, precision, f1, cf = (
    m.recall_score(test_y, res >= threshold, pos_label=1),
    m.precision_score(test_y, res >= threshold, pos_label=1),
    m.f1_score(test_y, res >= threshold, pos_label=1),
    m.confusion_matrix(test_y, res >= threshold, labels=(1, 0)).T,
)

Неправильно перенесенные строки

Например где-то вы не знаете как лучше самому перенести строки:

conditional_probabilities = (
    joint_distribution.filter(
        pl.col(target.name) == target_value
    ).select(pl.col(feature.name)).to_series().value_counts()["counts"]
    / feature.shape[0]
)

Примените autopep8 и у вас нет ошибок pep8(иногда этот код может и не изменится):

conditional_probabilities = (
    joint_distribution.filter(
        pl.col(target.name) == target_value
    ).select(pl.col(feature.name)).to_series().value_counts()["counts"]
    / feature.shape[0]
)

Конфигурация

Конфигурацию autopep8 можно провести в файле pyproject.toml

[tool.autopep8]
max_line_length = 120
in-place = true
recursive = true
aggressive = 3

Добавление в vscode

Существует специальное расширение: autopep8

Так же в settings.json можно добавить следующие настройки:

{
  "[python]": {
    "editor.defaultFormatter": "ms-python.autopep8"
  }
}

YAPF

Очень длинные строки

Например мы задаем какой-то сложный пайплайн из множества шагов, прописываем его в одну строку и получаем что-то не читаемое:

res = chain(resample_data.s(tuple(series), c=c.model_dump()),compute_masks.s(c=c.model_dump()),slice_pathline.s(c=c.model_dump(), slice_num=200),done.s(c=c.model_dump()),)()

Примените yapf и код согласно codestyle google:

res = chain(
    resample_data.s(tuple(series), c=c.model_dump()),
    compute_masks.s(c=c.model_dump()),
    slice_pathline.s(c=c.model_dump(), slice_num=200),
    done.s(c=c.model_dump()),
)()

Отсутствие пробелов

Например где-то вы пропустили пробелы и код слипся в сложноразделимые строки:

threshold = np.percentile(res, 0.5)
recall, precision,f1,cf = (
    m.recall_score(test_y,res>=threshold,pos_label=1),
    m.precision_score(test_y,res>=threshold,pos_label=1),
    m.f1_score(test_y,res>=threshold,pos_label=1),
    m.confusion_matrix(test_y,res>=threshold,labels=(1,0)).T,
)

Примените yapf и код согласно codestyle google:

threshold = np.percentile(res, 0.5)
recall, precision, f1, cf = (
    m.recall_score(test_y, res >= threshold, pos_label=1),
    m.precision_score(test_y, res >= threshold, pos_label=1),
    m.f1_score(test_y, res >= threshold, pos_label=1),
    m.confusion_matrix(test_y, res >= threshold, labels=(1, 0)).T,
)

Неправильно перенесенные строки

Например где-то вы не знаете как лучше самому перенести строки:

conditional_probabilities = (
    joint_distribution.filter(
        pl.col(target.name) == target_value
    ).select(pl.col(feature.name)).to_series().value_counts()["counts"]
    / feature.shape[0]
)

Примените yapf и код согласно codestyle google:

conditional_probabilities = (
    joint_distribution.filter(pl.col(target.name) == target_value).select(
        pl.col(feature.name)).to_series().value_counts()["counts"]/
    feature.shape[0])

Конфигурация

Конфигурацию yapf можно провести в файле pyproject.toml. главное не запутаться в регуляторах.

[tool.yapf]
based_on_style = "google"
NO_SPACES_AROUND_SELECTED_BINARY_OPERATORS = "*,/"

Добавление в vscode

Существует специальное расширение: yapf

Так же в settings.json можно добавить следующие настройки:

{
    "[python]": {
        "editor.defaultFormatter": "eeyore.yapf"
    },
    "notebook.formatOnCellExecution": true,
    "notebook.formatOnSave.enabled": true
}

Isort

Пример работы

В процессе работы вы добавляли новые библиотеки в ваш ноутбук в случайном порядке и выстроилась громадная гора импортов:

import plotly.graph_objects as go
import numpy as np
import sklearn.metrics as m
import polars as pl
from pathlib import Path
from functools import partial
from src.config import compose_config
import src.clients
import src.metrics
from catboost import CatBoostClassifier
from src import model

isort позволит отсортировать вам все в нужном порядке:

from functools import partial
from pathlib import Path

import numpy as np
import plotly.graph_objects as go
import polars as pl
import sklearn.metrics as m
from catboost import CatBoostClassifier

import src.clients
import src.metrics
from src import model
from src.config import compose_config

Конфигурация

Важным параметром isort является профиль автоформаттера, что бы сортировка импортов совпадала с требованиями форматера. Isort поддерживает стили: black, pycharm, google и т.д.

[tool.isort]
profile = "black"

Добавление в vscode

Существует специальное расширение: isort

Так же в settings.json можно добавить следующие настройки:

{
    "[python]": {
        "editor.defaultFormatter": "ms-python.black-formatter",
        "editor.formatOnSave": true,
        "editor.codeActionsOnSave": {
            "source.organizeImports": "explicit"
        },
  },
}