Что нового

как правильно применить рекурсию?

JohnWind

Новичок
Сообщения
57
Репутация
0
Доброго времени суток,

существует программа (работающая) которая исполняет некоторые действия в браузере, окончание работы которой - выключение (гибернация) компа
в виду некоторых (пока всего 1 раз случалось за месяц работы) не объяснимых причин случается косяк с загрузкой приложения.

для защиты от этого, был написан код, проверки состояния (появился уникальный маркер загрузки или нет) - в результате которого после определённого кол-ва попыток, программа записывает в лог файл ошибку - и прекращает свою работу (через Exit)

вопрос: а если попытаться после того как выбило нужное кол-во ошибок - попробовать перезапустить программу - рекурсией?

потенциальные проблемы:
- все переменные которые были изменены к моменту проверки, при перезапуске вызовут обнуление и программа начнётся с самого начала - можно ли этого избежать?
- что произойдёт когда рекурсия закончит (допустим удачное) исполнение скрипта? учитывая что удачное завершение работы - это отключение компа, не окажется ли что после перезагрузки/включения компа, скрипт продолжил исполнение работы со след. строки 1го запуска - обнаружен фейл "проверки состояния" и если за ним оставить EXIT - то окажется что только что запущенный комп будет снова выключен.
- можно ли как-нибудь прекратить исполнение не только рекурсии (допустим по успешному окончанию), но и 1го (начального/оригинального) запуска программы? как например ExitLoop с указанием кол-ва уровней выхода из цикла


мысль:
- пока пришёл к мысли, что можно завести ещё 1 (например txt) файл, в который записывать маркер "запущена рекурсия" - 1.
в таком случае имея этот файл например в режиме апдейта - то добавление маркера ("1") внутри 1го запуска - и при новой инициализации ИЗ рекурсии - в таком лог файле УЖЕ будет храниться "1" что скажет - мы в рекурсии.

поделитесь опытом если кто сталкивался с подобными ситуациями...

заранее спасибо...
 

Oki

Продвинутый
Сообщения
452
Репутация
62
Проблема сформулирована неясно. И совершенно неочевидна потребность в каких-либо рекурсиях.
- все переменные которые были изменены к моменту проверки, при перезапуске вызовут обнуление и программа начнётся с самого начала - можно ли этого избежать?
Можно избежать: хранить значения нужных переменных в файле и считывать их из него при новых запусках. Если хранить также значения до последних обновлений, то есть появится возможность откатиться к предпоследнему набору значений в случае сбоя в период обновления значений, если важно синхронно использовать набор значений.
 
Автор
J

JohnWind

Новичок
Сообщения
57
Репутация
0
Проблема сформулирована неясно. И совершенно неочевидна потребность в каких-либо рекурсиях.
Оки :smile:

1. программа автоматизирует действия (координатные MouseMove/MouseClick) в браузерной-флеш игрушке
2. когда введён логин/пасс и нажата кнопка логин - появляется полоса загрузки
3. зная координаты и цвет в точке (недалеко от начала полосы загрузки) я могу определить если:

а) загрузка началась
б) загрузка идёт
с) загрузка закончилась

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

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

в том случае - случились н-цить попыток дождаться запуска игры.. когда этого не случилось - комп вырубился (гибернейтом).

идея:

что если при повторе ситуации - не вырубать комп, а попытаться перезапустить программу с начала - т.е. - рекурсия.

важность идеи "решения" этой ситуации в том, что для этой программы написан Windows Task, который ежедневно (ранним утром) запускает ком и выполняет эту программу... и достаточно критичный момент - это пропуск исполнения программы.
 

Oki

Продвинутый
Сообщения
452
Репутация
62
Код свой или чужой?

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

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

В обоих случаях не вижу никакой причины использовать рекурсии.
 
Автор
J

JohnWind

Новичок
Сообщения
57
Репутация
0
код свой... но!

в настоящий момент происходит проверка СОСТОЯНИЯ (наличия цвета в полосе загрузки)... и "до успеха" (в том ед. случае) - оказалось бесконечным повтором в виду того что загрузка просто тупо не пошла... даже несколько часов спустя... т.е. необходимо было не просто ждать, а рефрешнуть браузер и/или повторить его запуск

судя по тому, что рекурсию не советуют - кажется будет легче выделить в отдельную функцию - запуск браузера + линк + логин (учитывая что данный код УЖЕ написан и работает)

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

или что ЕЩЁ проще (учитывая что логин уже введён и кнопка логина нажата) - просто рефрешнуть браузер через F5

спасибо за ваши вопросы... отвечая на них, сам нашёл простой и очевидный вариант решения :smile:
из анекдота: "препод студентам: "я так долго вам всё это объяснял - что уже сам понял что рассказываю"" :D


p.s. хотя глобальный вопрос - стоит ли применять рекурсию, в каких условиях и какие есть нюансы - остаётся :smile:
 

AZJIO

Меценат
Меценат
Сообщения
2,879
Репутация
1,194
Рекурсия используется для рекурсивных данных, например дерево данных (файловая система, реестр). Например в папке имеется набор файлов и папок, которые можно перечислить, а во вложенных папках такие же папки и файлы. Функция вызывает саму себя для вложенного объекта, так как его структура повторяет родителя, то и функция по отношению к ней выполняется таким же образом. Функция делается рекурсивной, потому что так удобно её писать. А обработка данных в браузере линейная. Даже если из одно функции вызывается другая это не рекурсия, а просто логические условия, а рекурсия это когда функция вызывает саму себя, когда она в точности повторяет действие к вложенному объекту и вложенный объект по структуре такой же как родительский.
На счёт обнуления переменных, а зачем хранить в переменных, результаты можно записывать в файл при чём без необходимости вытаскивать данные из файла, нужны ли эти данные для дальнейшей работы? Это что, лог состояния или проверка в каком состоянии окно? Может тогда делать условия таким образом чтобы сбоя не было, не получение данных проверяется и из этого автор программы делает поведение, как дальше действовать, сбоя нет, есть правильная интерпретация состояния. Даже если браузер дал сбой то из любого места можно начать сначала или из какой то точки которую позволяет браузер. Если комп перезагружается в цикле, то это автор заложил неправильную интерпретацию данных, просто сделать правильную.
 
Автор
J

JohnWind

Новичок
Сообщения
57
Репутация
0
Рекурсия используется для рекурсивных данных, например дерево данных (файловая система, реестр). Например в папке имеется набор файлов и папок, которые можно перечислить, а во вложенных папках такие же папки и файлы. Функция вызывает саму себя для вложенного объекта, так как его структура повторяет родителя, то и функция по отношению к ней выполняется таким же образом. Функция делается рекурсивной, потому что так удобно её писать. А обработка данных в браузере линейная. Даже если из одно функции вызывается другая это не рекурсия, а просто логические условия, а рекурсия это когда функция вызывает саму себя, когда она в точности повторяет действие к вложенному объекту и вложенный объект по структуре такой же как родительский.
На счёт обнуления переменных, а зачем хранить в переменных, результаты можно записывать в файл при чём без необходимости вытаскивать данные из файла, нужны ли эти данные для дальнейшей работы? Это что, лог состояния или проверка в каком состоянии окно? Может тогда делать условия таким образом чтобы сбоя не было, не получение данных проверяется и из этого автор программы делает поведение, как дальше действовать, сбоя нет, есть правильная интерпретация состояния. Даже если браузер дал сбой то из любого места можно начать сначала или из какой то точки которую позволяет браузер. Если комп перезагружается в цикле, то это автор заложил неправильную интерпретацию данных, просто сделать правильную.
спасибо большое за пример... я давненько не задумывался (и не использовал) рекурсию...

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

не далее чем сегодня ночью - снова произошёл сбой... на первом же (из 62х) аккаунтов... не произошло загрузки и программа прекратила работу...

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

- сделать функцию которая будет делать и сохранять скриншот с экрана в случае если СЛУЧИЛОСЬ нечто (2 случая а я ни разу не знаю что именно случилось, и как следствие не могу придумать решение)
- попробовать обновить браузер, хотя если сам браузер не запустился - то обновление его не поможет
- написать проверку что сам браузер (Edge) запустился

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

IMStrelcov

CTPEJIbLLOB
Сообщения
258
Репутация
66
Не рекурсия, а цикл.
Т.е. в цикле запустить запуск браузера и проверку на запуск, если запуск успешен - выйти из цикла, если нет - запись в лог, повтор запуска (можно использовать счетчик на кол-во попыток).
Второй цикл: вход в аккаунт, проверка, если успешно - выйти из цикла, если не удалось повторить.
Третий цикл: загрузка, проверка, успешно - какие-то действия, нет - лог, повтор, и т.д.
 
Автор
J

JohnWind

Новичок
Сообщения
57
Репутация
0
Не рекурсия, а цикл.
Т.е. в цикле запустить запуск браузера и проверку на запуск, если запуск успешен - выйти из цикла, если нет - запись в лог, повтор запуска (можно использовать счетчик на кол-во попыток).
Второй цикл: вход в аккаунт, проверка, если успешно - выйти из цикла, если не удалось повторить.
Третий цикл: загрузка, проверка, успешно - какие-то действия, нет - лог, повтор, и т.д.
спасибо за идеи... уже пришёл к такой же мысли!
 

Oki

Продвинутый
Сообщения
452
Репутация
62
Ещё можно создать отдельный счётчик, который обнулять вне зависимости от того, завершён ли цикл, при достижении заданного количества попыток, после которых обновить браузер. Таким образом, не нарушая общий ход скрипта, можно с заданной регулярностью проделывать это действие. Подобных действий можно задать несколько (если потребуется), и для каждого действия можно даже иметь свой счётчик для поддержки различных частот.
 
Автор
J

JohnWind

Новичок
Сообщения
57
Репутация
0
Ещё можно создать отдельный счётчик, который обнулять вне зависимости от того, завершён ли цикл, при достижении заданного количества попыток, после которых обновить браузер. Таким образом, не нарушая общий ход скрипта, можно с заданной регулярностью проделывать это действие. Подобных действий можно задать несколько (если потребуется), и для каждого действия можно даже иметь свой счётчик для поддержки различных частот.
отличная мысль! спасибо
 
Верх