Skip to content

Instantly share code, notes, and snippets.

@nikpau
Created June 11, 2023 08:42
Show Gist options
  • Save nikpau/be60a92a7d246cf19b30510e9f5bf141 to your computer and use it in GitHub Desktop.
Save nikpau/be60a92a7d246cf19b30510e9f5bf141 to your computer and use it in GitHub Desktop.
A loader-like context manager using the moon emoji as a loading animation.
from itertools import cycle
from threading import Thread
import time
class Loader:
def __init__(
self,
desc="Buffering",
timeout=0.1,
):
"""
Args:
desc (str, optional): The loader's description. Defaults to "Buffering...".
timeout (float, optional): Sleep time between prints. Defaults to 0.1.
"""
self.desc = desc
self.timeout = timeout
self._thread = Thread(target=self._animate, daemon=True)
self.steps = ["πŸŒ‘","πŸŒ’","πŸŒ“","πŸŒ”","πŸŒ•","πŸŒ–","πŸŒ—","🌘"]
self.done = False
def start(self):
self.t_start = time.perf_counter()
self._thread.start()
return self
def _animate(self):
for c in cycle(self.steps):
if self.done:
break
print(f"{self.desc}... {c}", flush=True, end="\r")
time.sleep(self.timeout)
def __enter__(self):
self.start()
def stop(self):
self.done = True
self.t_end = time.perf_counter()
print(f"{self.desc} completed in [{(self.t_end-self.t_start):.1f} s]")
def __exit__(self, exc_type, exc_value, tb):
# handle exceptions with those variables ^
self.stop()
# Simple test
with Loader():
time.sleep(5)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment