Executando verificação de segurança...
1

Utilizando decorador e a fórmula de Bhaskara para modificar uma função e criar um laço de repetição com tempo de espera incremental no Python.

background

Motivação

Atualmente um dos problemas ao desenvolver é ter que esperar para que o código consiga executar normalmente, um exemplo clássico é a na utilização de Web Scraping, que nada mais é do que uma raspagem de dados na Web.
Às vezes precisamos esperar terminar um download para manipular aquele arquivo e não sabemos quanto tempo irá demorar, às vezes as páginas carregam um Loading para adicionar conteúdo, e se nesse meio tempo o nosso script tentar fazer alguma manipulação irá gerar erro e terminar a execução.
Pensando nisso eu resolvi criar uma função que trabalharia como decorador, no Python.
O decorador no Python é um elemento extremamente significante e também é conhecido como meta-programação, sua ideia principal é modificar uma outra função criando uma nova funcionalidade para a mesma. Com isso ela permite que o código seja menor, mais limpo e acaba se tornando Pythônico.

Ideia

A ideia é criar uma função que modifica outras funções, fazendo com que as funções sejam executadas repetidas vezes até que ela retorne sem erro ou estoure o tempo de sua execução, abaixo descrevo os requisitos da função:
Deve haver um laço de repetição para a função que será modificada
O tempo de espera será incremental de 1 em 1 segundo para cada laço de repetição, isto é a cada vez que repetir a tentativa o script irá esperar 1 segundo a mais que na tentativa anterior, assim caracterizando um soma de Gauss no tempo de espera.
O tempo total de espera padrão será de 60 segundos ou poderá ser informado pelo usuário no momento da chamada da função e o mesmo deve ser informado em segundos.
Retornar erro caso o tempo de espera total for maior que retorno sucesso.

Desenvolvimento

Para desenvolver o tempo incremental de 1 em 1 segundo e somente solicitar ao usuário o tempo total em segundos da execução preciso calcular o inverso da soma de Gauss (com ajuda do meu amigo João Francisco Vieira Rodrigues Filho conseguimos chegar ao cálculo), e o que é a soma de Gauss:
A soma de Gauss é um método para somar uma sequência de números entre eles. por exemplo, a soma de Gauss de 10 será a soma de 1+2+3+4+5+6+7+8+9+10, totalizando 55. Esse cálculo pode ser feito de cabeça graças a teoria da soma de Gauss.
Você deve somar o último número com o primeiro, no caso da soma de Gauss o primeiro sempre será 1, depois você irá multiplicar pela meta do número, com isso conseguimos a seguinte equação Soma de Gauss = (x+1)(x/2), simplificando e chamando a soma de Gauss de y teremos x²+x-2y=0
Com isso teremos que fazer um cálculo de equação do 2º grau, por exemplo y=55:
x² + x - 110= 0, Com isso temos a, b, e c onde a = 1, b = 1 e c = -110
A fórmula de ∆ = b² - 4 * a * c, evoluindo o cálculo ∆ = 1² - 4 * 1 * - 110 resultando ∆ = 441
A fórmula de Bhaskara = (-b+√∆)/2a, evoluindo o cálculo (-1+√441)/2
1, temos o resultado positivo 10 (Omiti o resultado negativo pois não iremos utilizar por se tratar de tempo e não existir tempo negativo).

Caso queiram dar uma força no artigo que publiquei no Linkedin será muito bem vindo.

Código

def retry(time:int=60):
    '''Decorador utilizado para fazer uma função retentar após
    segundos incrementais a cada nova tentativa.
    ---
    ### `time` [Opcional]: é o tempo total das tentativas.
    
    Construção obrigatória
    Obrigatoriamente posicionado antes da função que será chamado
    >>> @Retry()
    ou
    >>> @Retry(time=15)
    '''
    def decorator(function):
        # Calculate Delta
        delta = 1-4*-1*time*2
        # Rounds is the unknown that will be used in the sum of gauss
        rounds = (-1+math.sqrt(delta))/2
        def wrapper(*args,**kwargs):
            count=1
            while count<=rounds:
                try:
                    print(f'Tentativa {count}')
                    func_response = function(*args,**kwargs)
                    break
                except Exception as error:
                    sleep(count)
                    count+=1
                    func_response=None
                    print(str(error))
            return func_response
        return wrapper
    return decorator

Exemplo de uso

@retry(time=10)
def teste():
    #Está função apenas retorna um erro simples
    raise Exception("Erro genérico")

teste()
Carregando publicação patrocinada...
1

Bom post, apenas uma correção NÃO existe formula de bhaskara, o nome é formula quadratica ou equação do 2º grau. Bhaskara foi um historiador, ele NÂO INVENTOU essa formula, quem inventou essa formula foi outro indiano, Sidartha. Esse é um erro (dos milhares..) da educação brasileira, tanto que fora do país voce não encontra esse erro. Pelo que sei surgiu lá pelo idos de 1960.

2

Top, valeu pela informação. Só não vou corrigir aqui porque senão seu comentário ficaria sem sentido e acho ótimo ter esse apontamento. Irei corrigir no Linkedin e no Github.
Valeu...