Учимся писать чистый код на Python: разбор задания к S1E1

Ну что, решений в комментах к прошлому посту скинули немало, пора их разобрать. Но сначала небольшое отступление.


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

Общие ошибки

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


Их можно разделить на 2 группы:

- нейминг (названия объектов);

- структура/компоновка кода внутри функции.


В этом посте разберу компоновку, а в следующей серии подробнее расскажу про нейминг. Погнали :)

if/else в одну строку

@Amplicon, @kashinec, достаточно неплохие решения.

Учимся писать чистый код на Python: разбор задания к S1E1 Python, Программирование, IT, Обучение, Чистый код, Длиннопост

Малину немного попортило стремление впихнуть невпихуемое, а именно - записать тело `if/else` в одну строку.

Учимся писать чистый код на Python: разбор задания к S1E1 Python, Программирование, IT, Обучение, Чистый код, Длиннопост

Делать так категорически не рекомендуется. Против этого выступает как PEP8, так и Google Style Guide. Просто переносите тело на новую строку, даже если оно небольшое. Это выглядит гораздо красивее и читабельнее.

Пробелы

Учимся писать чистый код на Python: разбор задания к S1E1 Python, Программирование, IT, Обучение, Чистый код, Длиннопост

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

Лишние слои

Следующая распространённая ошибка - это заворачивание куска кода в ненужный `if` или `else`. @DavidSarif, @Nikydzman, вы в телевизоре.

Учимся писать чистый код на Python: разбор задания к S1E1 Python, Программирование, IT, Обучение, Чистый код, Длиннопост

Ту же самую логику можно реализовать так:

Учимся писать чистый код на Python: разбор задания к S1E1 Python, Программирование, IT, Обучение, Чистый код, Длиннопост

Вместо того, чтобы использовать `if - pass` или `if - continue`, можно просто инвертировать условие, и код станет проще и линейнее.


Также стоит помнить о том, что `raise` и `return` прерывают выполнение, поэтому добавление `else` после `return` уже излишне.


P.S. Долго думал, разбирать ли код Nikydzman или нет, потому что он ЕДИНСТВЕННЫЙ НЕ ПОДПИСАЛСЯ 😈, но решил всё-таки разобрать, потому что он идеально иллюстрирует ситуацию с лишними слоями. Во второй раз такой халявы уже не будет)

Декомпозиция задачи

Отдельно отмечу решение @DarkPavlov. Дело в том, что он разбил большую задачу на отдельные функции. Это очень хороший подход, который значительно упрощает отладку и тестирование программы.

Учимся писать чистый код на Python: разбор задания к S1E1 Python, Программирование, IT, Обучение, Чистый код, Длиннопост

Сейчас выглядит довольно громоздко, но если убрать лишние слои `if/else`, то получается уже так:

Учимся писать чистый код на Python: разбор задания к S1E1 Python, Программирование, IT, Обучение, Чистый код, Длиннопост

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

UPD: Скорость выполнения кода

По совету @kashinec добавил результаты замеров скорости. Средние значения за 100 000 итераций, измеряются в микросекундах:


kashinec: 1.10

Nikydzman: 1.38

AnimalPy: 1.66

NuVasche: 1.79

Amplicon: 1.83

DavidSarif: 2.09

Mirakonda: 2.59

DarkPavlov: 3.24

budu.krokodit: 4.07

HaneLeiko: - (код не в виде функции)


Если кого-то забыл - прошу простить. Измерить можно самостоятельно с помощью модуля `timeit`. Абсолютная точность не гарантируется, на результаты могут повлиять разные факторы.

Что дальше?

Вчера много думал над тем, как правильно организовать выпуск постов, и пришёл к следующему варианту.


- раз в неделю буду публиковать очередную серию сериала "Чистый код" и задание. Тему буду выбирать исходя из ошибок, которые обнаружились в прошлой серии, но если вам интересен какой-то конкретный вопрос, то обозначьте его в комментарии. Если коммент заплюсуют, то можно будет рассмотреть этот вопрос в отдельном посте;

- спустя 1-2 дня после этого буду публиковать разбор задания. Пауза в 1-2 дня нужна для того, чтобы все успели почитать и написать код;

- спустя ещё пару дней буду выкладывать "прикладной" пост, в котором буду рассматривать какие-нибудь интересные фишки или давать полноценные идеи проектов для практики.


Таким образом, каждую неделю - новая итерация цикла. От таки дела :) Надеюсь, вам зайдёт.

Правила сообщества

Публиковать могут пользователи с любым рейтингом. Однако!


Приветствуется:

• уважение к читателям и авторам

• конструктивность комментариев

• простота и информативность повествования

• тег python2 или python3, если актуально

• код публиковать в виде цитаты, либо ссылкой на специализированный сайт


Не рекомендуется:

• допускать оскорбления и провокации

• распространять вредоносное ПО

• просить решить вашу полноценную задачу за вас

• нарушать правила Пикабу