"""
Repeat a function for X times.
Return (True, ret_val) if function returns ret_val in any attempts.
Return (False, None) if function doesn't return ret_val in all attempts.
"""
def until_value(func : Callable,
args : tuple,
repeat_count : int,
repeat_delay_ms: Optional[int] = None,
ret_val : any = True) -> tuple:
if repeat_count < 1: raise ValueError("repeat_count < 1")
if repeat_delay_ms is not None \
and repeat_delay_ms <= 0: raise ValueError("delay <= 0")
i = 0
while i != repeat_count:
if repeat_delay_ms is not None \
and i > 0: sleep(repeat_delay_ms / 1000)
try:
res = func(*args)
if res == ret_val: return True, ret_val
else:
i += 1
continue
except:
i += 1
continue
return False, None
# Example usage:
# Repeat the "do_something(1)" function for maximum 5 times with 250ms delay until it returns True.
until_value(do_something, (1,), 5, 250, True)
# Repeat the "do_something2(1, 2, 3)" function for maximum 10 times with 0ms delay until it returns "hello".
until_value(do_something2, (1, 2, 3), 10, 0, "hello")