Было ли у вас такое, что одним прекрасным утром, за чашечкой кофе и любимыми печеньками вы внезапно вспоминаете, что у вас сегодня дед лайн? Далее вы легким нажатием кнопки на корпусе включаете свой рабочий компьютер, вводите пароль и запускаете программу Discord, где вас уже около получаса ожидает заказчик.

На удивление, вы успели к дедлайну! Поздравляю вас, вы смогли уложиться в сроки впервые за долгое время. Вы спокойны, чувство невыполненного домашнего задания не преследует вас (по крайней мере при выполнении этого заказа), ваше сердце бьется с частой 90 колебаний в минуту, а ваш кот мило лежит у вас на коленках. В такие моменты легко можно словить нирвану, не так ли?

Но в какой-то момент, настанет время проверить вашу выполненную на пять работу, дабы получить свои честно заработанные деньги и пойти побаловать своего котика. Вы легкими двумя нажатиями открываете папку «Zakaz freelance(26)», попутно запуская «Visual Studio Code». Далее идет абсолютно привычное всем нам дело: проверка констант, запуск кода и самое главное, молитва, которую вы читаете в консоли, ведь ввод ее в консоль уже вошло к вам в привычку. И казалось бы, все идет хорошо, заказчик довольно смотрит на результат ваших усердий, как вдруг... Вы получаете банальную ошибку, которую вы можете исправить, но заказчику это не объяснить. Начинается паника, стресс, желание изобрести машину времени, чтобы переместиться на пару часов назад, дабы исправить ошибку раньше намеченного диалога. Но к сожалению, вам явно не до такого изобретения.

Заказчик, медленно покуривая, говорит самые суровые и страшные слова в вашей жизни: «Работай.». После этого, он кладет трубку, а вы в панике идете заново запускать код, дабы удостовериться в ошибке. Проворачивая все действия заново, программа выполняет все действия, что вы ей заготовили, все функции используется, программа выполняется за замеренное ранее время. Ошибки нет.

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

Почему словно фотон?

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


В нашем же случае, наблюдателем является заказчик, а программа - фотоном. Интересная аналогия, не правда ли?

ПАН

ПАН - это аббревиатура из трех слов (Повторение, Альтернатива, Наблюдение), которую когда-то я услышал от знакомого программиста. Этот термин не особо введен в общество программистов, но соблюдая три простых правила, вы сможете сильно уменьшить вероятность возникновения непредвиденных ошибок на кануне.

Повторение

Что же я имею ввиду? К примеру, вы работаете с языком python и библиотекой selenium.
Если вы хоть раз работали с данной библиотекой, то в курсе, что даже в самом идеальном коде обязательно выскочит какая-нибудь ошибка. И не важно, как много вы исправляли, ведь произойти может все, что угодно. Например нестабильное подключение, слишком быстрая загрузка, случайно появившееся окно на странице и прочие неожиданные действия, которые вызывают ошибку при работе с драйвером браузера. Большинство подобных ошибок решаются вполне просто, нужно просто перезагрузить драйвер. Вроде как банально.

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

def func():
  while True: # цикл нужен, чтобы в любом случае повторять действие вне зависимости от ошибки
    try:
      # код
      # 
      # /код
      break
    except:
      print("Error. I repeat the action")

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

Впрочем, опытных программистов подобным точно не удивишь :D

Альтернатива

Если приводить тот же пример с Selenium, то стоит понимать, что всегда стоит искать альтернативу больному решению. Повторение не сможет помочь в решении определенной задачи, если само решение не верное. с помощью той же конструкции try-except сделайте несколько альтернативных решений.

try:
  # код
  #
  # /код
  print("Решение 1")
except:
  try:
    # код
    #
    # /код
    print("Решение 2")
  except:
    # код
    #
    # /код
    print("Решение 3")

Также банально, но многие забывают о подобном решении некоторых проблем.

Наблюдение

А допустим, проблема не так уж и очевидна на первый взгляд? Запомните, что проведение наблюдений перед самым дед лайном очень важно. Нужно проанализировать абсолютно каждую деталь, от того, сколько оперативной памяти требуется для полноценной работы вашей программы вплоть до наблюдаемого изменения ресурса парсинга к примеру. Это тоже важная деталь. Стоит наблюдать все.

Итоги

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

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

Обучение программированию не может научить быть экспертом, также как и изучение кистей и красок не может превратить кого-либо в художника.— Eric S. Raymond

Комментарии (15)


  1. lair
    10.01.2024 18:50
    +10

    И так, первое решение заключается в повторе действия. Да, это банально, но действительно эффективно. [...] Да, этот простейший код уже решает множество ваших проблем. Лично я додумался поступить примерно также совсем недавно...

    ...не надо так. Далеко не все действия можно повторять.

    Если у вас что-то падает, нужно разбираться, что и почему падает, а не заниматься повтором одного и того же.


    1. MicroProger Автор
      10.01.2024 18:50

      Да, но я так и написал, мол, это может решить некоторые задачи


      1. lair
        10.01.2024 18:50

        Вы написали "множество проблем" и никак не указали условия применимости решения. Более того:

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

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

        Еще вы пишете:

        мы разберем, почему [...] любая программа неоднозначна.

        Но вы нигде этого не разбираете, хотя пишете про любую программу.


      1. MagnumMalum
        10.01.2024 18:50
        +1

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

        IMHO, все же надёжность и безопасность в ПО ещё важна. А try except без указания типа exception и логирования (да ещё внутри while True) - это зло как для разработчика так и для пользователя. Представьте что программа вместе того чтобы просто сообщить что сервер недоступен, будет бесконечно что-то пытаться грузить.


    1. Robastik
      10.01.2024 18:50
      +2

      нужно разбираться, что и почему падает, а не заниматься повтором

      Автор управляет браузером через драйвер с помощью скрипта. У него нет компетенций для исправления того и другого. Если он будет разбираться с Selenium и Chromium, то он будет уже не питоняшка, он не пойдет на панель торговать собой станет парсить на фрилансе.


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

      случайно появившееся окно на странице

      То есть к проблемам Selenium и Chromium добавляются проблемы сайта: от настроек сервера и до антифрода. Разбираться с этими проблемами часто просто нет смысла → не в твоей власти их исправить. Если это проблемы сайта, то у кого-то уже горит и он исправляет. Если это фича - это самое "появившееся" окно на странице для парсинга, изменившаяся структура данных, переименование класса кнопки и т.п. - это еще надо удостовериться → это точно фича или баг, который будет исправлен.

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


      1. lair
        10.01.2024 18:50
        +1

        Автор управляет браузером через драйвер с помощью скрипта.

        Так может не надо этот очень узко-специфичный опыт распространять на "любые программы"?


        1. Robastik
          10.01.2024 18:50
          +2

          Не надо конечно. Но он не знает, что бывают другие программы)

          Автор школьник, он еще только учится общаться)
          Стиль подкупает, да)


    1. 2medic
      10.01.2024 18:50

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

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

      Но, конечно, там был не try except, а опрос диспетчера управления службами на предмет состояния службы.


  1. ReadOnlySadUser
    10.01.2024 18:50
    +9

    Ну, если это действительно современные принципы разработки, многое в качестве современного ПО встаёт на свои места)


  1. kozlov_de
    10.01.2024 18:50
    -1

    не пишите больше

    не ваше это


    1. ovsds
      10.01.2024 18:50
      +1

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

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


  1. ivankudryavtsev
    10.01.2024 18:50

    Как говорится: «нормально делай - нормально будет». Пишите тесты, дамы и господа, контролируйте сложность кода. Например, вышепродемонстрированный код автора с вложенными try/except - это сам по себе источник проблем.


  1. Robastik
    10.01.2024 18:50
    +1

    сердце бьется с частой 90

    чувство невыполненного домашнего задания

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


  1. max-daniels
    10.01.2024 18:50

    Думал будет статья про информационную интерпретацию квантовой механики)


  1. ALexKud
    10.01.2024 18:50

    Если делать мало-мальски сложные программы, то не для web разработки это не будет работать. Программа это не фотон, это некоторая система, которая по мере усложнения сущностей и их взаимодействия начинает жить своей жизнью. И задача программиста валится в эту жизнь поддерживать и развивать. Или хотя бы изучить то что сотворил, чтобы не пользоваться костылями.