2024-10-30 20:22:09 -03:00
|
|
|
import random
|
2024-12-03 17:50:27 -03:00
|
|
|
from time import time, sleep
|
2025-01-19 10:32:27 -03:00
|
|
|
from typing import Iterator, Optional, Callable, IO
|
2024-11-25 19:03:54 -03:00
|
|
|
|
|
|
|
|
|
2024-12-14 06:34:11 -03:00
|
|
|
def await_predicate(
|
2024-12-20 19:49:07 -03:00
|
|
|
predicate: Callable[[], bool], timeout: float = 0, polling_interval: float = 0
|
2024-12-14 06:34:11 -03:00
|
|
|
) -> bool:
|
2025-01-20 15:00:02 -03:00
|
|
|
start_time = time()
|
|
|
|
|
while (timeout == 0) or ((time() - start_time) <= timeout):
|
2024-12-03 17:50:27 -03:00
|
|
|
if predicate():
|
|
|
|
|
return True
|
|
|
|
|
sleep(polling_interval)
|
|
|
|
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
2024-10-30 20:22:09 -03:00
|
|
|
def sample(n: int) -> Iterator[int]:
|
2024-11-01 18:07:08 -03:00
|
|
|
"""Samples without replacement using a basic Fisher-Yates shuffle."""
|
2024-10-30 20:22:09 -03:00
|
|
|
p = list(range(0, n))
|
|
|
|
|
for i in range(n - 1):
|
2024-11-27 11:36:17 -03:00
|
|
|
j = random.randint(i, n - 1)
|
2024-10-30 20:22:09 -03:00
|
|
|
tmp = p[j]
|
2024-11-27 11:22:07 -03:00
|
|
|
p[j] = p[i]
|
|
|
|
|
p[i] = tmp
|
2024-10-30 20:22:09 -03:00
|
|
|
yield p[i]
|
2024-11-01 18:07:08 -03:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def kilobytes(n: int) -> int:
|
|
|
|
|
return n * 1024
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def megabytes(n: int) -> int:
|
|
|
|
|
return kilobytes(n) * 1024
|
2024-12-20 13:57:28 -03:00
|
|
|
|
|
|
|
|
|
2025-01-19 10:32:27 -03:00
|
|
|
def random_data(
|
|
|
|
|
size: int, outfile: IO, batch_size: int = megabytes(50), seed: Optional[int] = None
|
2024-12-20 19:49:07 -03:00
|
|
|
):
|
2025-01-19 10:32:27 -03:00
|
|
|
rnd = random.Random(seed) if seed is not None else random
|
|
|
|
|
while size > 0:
|
|
|
|
|
batch = min(size, batch_size)
|
|
|
|
|
random_bytes = rnd.randbytes(batch)
|
|
|
|
|
outfile.write(random_bytes)
|
|
|
|
|
size -= batch
|