Pull to refresh
19
0.6
Send message

Вопросом про реализацию правильнее отсеивать сеньоров, тот уж точно должен знать это из ОПЫТА

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

Вопрос который аппелирует к опыту, это требования к объекту, который складывают в эту мапу.

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

Ну если он линейный, то конечно да.

Но, на практике я вижу код, которые уже давно перестал быть линейным. Переменные объявяютя в одной части кода, а используются на 100 строк ниже, да и еще пару раз переопределяются.

Если не включать голову и так и так будет плохо. Но такой код можно быстро заинлайнить, а вот монолит на 300 строк разнести намного сложнее.

и разделенная на блоки комментариями

Вот тут и место для разделения, комментарий в название документацию метода, блок в тело.

А в выскоконагруженных задачах, где борешься за каждую ms так еще эти вызовы влияют на скорость.

Давайте говорить честно, такие задачи существуют, но они достаточно редки и их не поручают джунам. Джава машина кажется такие вещи может инлайнить сама.

Мне с сонаром как-то не пришлось плотно работать, его можно запустить на локальном коде?

Первый вариант который рекомендует pytest, мне привычнее, и кажется проще для разработки. Я локально гоняю только юниты, а всякие инсталляции можно сбросить на CI.

Вторая статья еще использует setup.py, но с тех пор появились новые инструменты например flit и poetry. Надо посмотреть, как они с такими структурами работают.


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

А что вы вкладываете в понятие интеграционные тесты? Почему они легче в отладке чем компонентные?

Имя src мне не нравится, это что-то техническое. Я предпочитаю использовать название проекта. То есть вместо src/gmaps_crawler/ просто gmaps_crawler/.

Есть еще и личная неприязнь к этому имени в контексте Питона, src ассоциируется с Джавой.
Я пишу и на Питоне и на Джаве, но попытки притащить парадигмы из одного языка в другой мне не нравятся.

Двойное подчёркивание в имени локальной переменной несколько перебор.
def __init__(self, db_image_name): __engine = EngineFactory() __engine.stand = 'localhost'

Синглтон тоже можно выкинуть, так как тесты это реализуют самостоятельно.

Комментарии дублируют код. Даже для обучающего кода это излишне.

# Тест метода processing.bookings.get_premium_psg_list()
# В текущих тестовых данных, для limit=10000, корректный результат == 4
def test_get_premium_psg_list(test_db):
    assert len(get_premium_psg_list(limit=10000)) == 4

После выполнения всех тестов, testcontainers завершит работу созданного контейнера и удалит созданные данные. Бывает полезно "придержать" тестовую БД на некоторое время, чтобы можно было залезть в БД из обычной IDE, чтобы выполнить пару-тройку SQL-запросов. Для этого нужно просто раскомментировать тест test_debug(test_db)

Я бы попробовал реализовать логику удаления как в фикстуре https://docs.pytest.org/en/6.2.x/reference.html#pytest.tmpdir.tmp_path

Ну ли просто не удалять по аргументу командной строки.

Вы вообще смысла моего кода не поняли.

Звучит двусмысленно :)

Пользователя никто циклы писать не заставляет - он может реализовывать свою логику как ему угодно, хоть создавая классы, хоть делая циклы.

Вложенное меню так часто используется, и всегда с циклами.

Мне паттерн `while true; rc = await chat.menu(...); if rc.data == ...` не нравится, слишком много кода. Это можно упрятать в библиотеку. Да, я ожидаю чтобы вложенные меню были внутри, библиотеки, а не собирались по кусочкам снаружи.

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

Радон более портируемая метрика чем размер экрана и шрифта.

Я разделяю по функциям по тому же признаку и еще когда хочу отделить разные уровни логики, какие-нибудь манипуляция с индексами или библиотеками и бизнес логику. Например вынести `message and message.text[0] == '/'` в is_chat_message(message)

Отличие в том, что у меня более жёсткие критерии.

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

Я не знаю, что вы понимаете под длинными путями в ветках логики. Вот самая глубокая вложенность. Человеческая кратковременная память может держать в себе 7 +- 2 элементов.
Здесь уже 7 уровней вложенности.

with ... if  ... with ... while ... try ... if ... if

В этих примерах функции с вложенными функциями

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

Хотя все претя писать объект класса - это раздражало. Я еще не использовал языков, в которых были бы объекты, но в их методах нужно было бы всегда явно его писать

Этот подход соответствует философии языка. Explicit is better than implicit.

Привыкните перестанет раздражать.

Претензию про main.py я тоже не понял. Этот файл - единый сборник примеров использования не особо связанных друг с другом.

Не сразу понял задумку с несвязанных объектах.

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

Зачем заставлять пользователя писать эти `while True` блоки, и давать ему возможность делать несогласованные части? Это всё от пользователя можно спрятать внутри библиотеки.

Весь main может состоять из создание экземпляров Menu и вызова строчки run_bot(menu).

class Item:
  def __init__(self, user_text, handler): ...

class Menu:
  def __init__(self, title, items: list[Item]): ...

---- main.py ---
from ... import Menu, Item
from ... import run_bot

menu = Menu(.....)

run_bot(menu)



Класc ISettings я использовал не как прокси (хотя он именно это), а в попытке хоть как-то разделить реализацию и описание т.к. я так и не понял какими методами это делается.

Не очень понимаю, что есть описание и зачем оно нужно.

Если хочется сделать, что то типа интерфейса, то листайте результаты поиска гугла на эту тему. Рано или поздно наткнетесь на абстрактные классы.

Хотя в данном случае можно и без интерфейсов обойтись. Одна из фишек Питона, это можно сделать потом, не меняя код в других файлах.

либо это не собиралось из-за циклических зависимостей

В файле три сущности. Вроде нет там циклических зависимостей.

И ситуация когда класс наследует интерфейс и его же экземпляр получает в конструктор мне кажется странной.

Чтобы говорить о сложности её нужно измерить. https://pypi.org/project/radon/
Уровень С и D уже считается избыточно сложным.

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

PS J:\projects\LinearBotLib> radon cc . -s -n C
bot.py
    M 468:4 BotChat.waitProcess - D (21)
    M 573:4 BotChat.logicStart - C (11)
bot_imessage.py
    M 135:4 BotIMessage._display - C (15)
main.py
    F 26:0 logic_MENU_Form - C (12)
    F 149:0 logic_MENU_Animation - C (12)

Откуда такой сарказм?

Да и сама статья написана в свободном стиле.

не соблюдение pep8(понимаю, автор пишет всего лишь 2 недели, но пусть хотя бы с snake_case можно же писать код)

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

> Все же этот код я писал как знакомство я языком и буду рад любым отзывам о его качестве.

В статье великий мастер божественного языка снизошёл для того, чтобы посмотреть языки простых смертных.

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

До Питона я не добрался, сломался на общих вещах.

Много лишней сложности. Класс (ISettings) принимает в конструктор экземпляр своего типа и проксирует его методы. Это можно решить с помощью наследования.

Класс Settings в котором почти в каждом методе стоит if по типу, это странное использование ООП.

main.py 500 строк кода, где логика размазана по разным местам.

Цикломатическая сложность зашкаливает.

Я иногда помогаю знакомым с Питоном, поэтому дочитал статью до конца. Не думаю, что она будет полезна новичкам.

Если использовать форматирование для С подобных языков, то оказывается, что пробелов там не сильно меньше и еще куча фигуруных скобок. Ваши претензии к пробелам мне не понятны. Привычка приходить в новый язык со своим самоваром мешает его изучению.

Мой комментарий про кнонтекст развития данного кода. Парсинг писем достаточно стабильная тема и я не ожидаю какоги-нибудь развития. В этом ключе этот код черезмерно усложнен.

Давайте представим, что это поле будте еще развиваться, и сложность имеет смысл для будущего.

Конструктор с суплаером, в виде интерфейса это отлично.

А вот первый конструктор это что-то интересное.
- Его сложно читать, там огромная вложенность.
- В нем есть вычисления (создаётся лямбда с логикой), что противоречит подходу элегантных объектов.
- Реализация интерфейса знает о других реализациях интерфейса. Иерархия наследования состоит из двух уровней (интерфейс и реализаций), а вот в иерархии зависимостей все реализации равны, но некоторые ровнее.

Этот код напрашивается в отдельный класс. Например отнаследоваться от Scalar и поместить код в value().

в финальном примере объект создаётся

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

Надо понимать стиль изложения и особенности написания кода Егором https://www.yegor256.com/.

Он излагает рекомендации для конкретных случаев, как аксиомы для любого кода.
Концепции заложенные в элегантных объектах решают много проблем, но и добалвяют некоторую толику сложности. Если у вас нет проблем которые они решают, то они не нужны.

Егор пишет много кода, в том числе библиотек. Элегантные объекты выигрывают на длинных дистанциях и при большом объеме кода.

Очень рекомендую посмотреть его видео они бодрые и провакационные.

https://www.yegor256.com/2015/05/07/ctors-must-be-code-free.html

No, it’s not. It’s a bad idea for one reason: It prevents composition of objects and makes them un-extensible.


Вместо простого решения мы используем сложное. За это мы получаем решение проблемы, которой у нас нет и вроде как не планируется в ближайшем будущем.

Information

Rating
1,790-th
Registered
Activity