A Python utility belt containing simple tools, a stdlib like feel, and extra batteries
Progress iteration with ETA, timing utilities, and performance measurement tools for monitoring and profiling code execution.
Enhanced iteration with progress bars, timing information, and ETA calculation.
class ProgIter:
"""
Progress iterator with timing and ETA.
A faster, more feature-rich alternative to tqdm.
"""
def __init__(self, iterable, desc=None, total=None, freq=1, **kwargs):
"""
Args:
iterable: Items to iterate over
desc (str): Description shown in progress bar
total (int): Total number of items (auto-detected if possible)
freq (int): Update frequency (every N iterations)
verbose (int): Verbosity level
show_percent (bool): Show percentage complete
show_times (bool): Show timing information
show_rate (bool): Show iteration rate
clearline (bool): Clear line between updates
adjust (bool): Adjust total if iterable length changes
enabled (bool): Enable/disable progress display
**kwargs: Additional formatting options
"""
def __iter__(self): ...
def __next__(self): ...
def __enter__(self): ...
def __exit__(self, exc_type, exc_val, exc_tb): ...
def set_description(self, desc): ...
def set_postfix(self, **kwargs): ...
def format_infoline(self): ...Context managers and utilities for measuring execution time with high precision.
class Timer:
"""
Context manager and decorator for timing code execution.
"""
def __init__(self, label='Timer', verbose=None, newline=True):
"""
Args:
label (str): Label for timer output
verbose (int|bool): Verbosity level
newline (bool): Print newline after timing
"""
def __enter__(self): ...
def __exit__(self, exc_type, exc_val, exc_tb): ...
def __call__(self, func): ... # Decorator usage
def tic(self):
"""Start timing."""
def toc(self):
"""
Stop timing and return elapsed time.
Returns:
float: Elapsed time in seconds
"""
@property
def elapsed(self):
"""
Current elapsed time.
Returns:
float: Elapsed time in seconds
"""Functions for generating and parsing timestamp strings.
def timestamp(datetime=None, precision='milliseconds', timezone=True, **kwargs):
"""
Generate timestamp string.
Args:
datetime: Datetime object (current time if None)
precision (str): Time precision ('seconds', 'milliseconds', 'microseconds')
timezone (bool): Include timezone information
**kwargs: Additional formatting options
Returns:
str: Formatted timestamp string
"""
def timeparse(stamp):
"""
Parse timestamp string to datetime object.
Args:
stamp (str): Timestamp string to parse
Returns:
datetime.datetime: Parsed datetime object
Raises:
ValueError: Invalid timestamp format
"""import ubelt as ub
import time
# Basic progress iteration
items = range(100)
for item in ub.ProgIter(items, desc='Processing'):
time.sleep(0.01) # Simulate work
# Custom progress with total and description
data = [1, 2, 3, 4, 5] * 20
for item in ub.ProgIter(data, desc='Computing', total=len(data)):
result = item ** 2 # Some computation
time.sleep(0.005)
# Progress with custom frequency and formatting
large_dataset = range(10000)
for i, item in enumerate(ub.ProgIter(large_dataset, desc='Training', freq=100)):
# Update every 100 iterations for performance
if i % 1000 == 0:
# Do expensive operation occasionally
time.sleep(0.1)import ubelt as ub
# Progress with postfix information
items = range(50)
prog = ub.ProgIter(items, desc='Training Model')
for epoch, item in enumerate(prog):
# Simulate training metrics
loss = 1.0 / (epoch + 1)
accuracy = min(0.95, epoch * 0.02)
# Update progress bar with current metrics
prog.set_postfix(loss=f'{loss:.3f}', acc=f'{accuracy:.2%}')
time.sleep(0.1)
# Nested progress loops
outer_items = range(5)
inner_items = range(20)
for i in ub.ProgIter(outer_items, desc='Outer loop'):
for j in ub.ProgIter(inner_items, desc=f'Inner {i}', leave=False):
time.sleep(0.01)
# Progress with context manager
with ub.ProgIter(total=100, desc='Processing files') as prog:
for i in range(100):
# Manual progress updates
prog.update(1)
time.sleep(0.01)import ubelt as ub
import time
# Context manager timing
with ub.Timer('Database query'):
time.sleep(0.5) # Simulate database operation
# Prints: Database query time: 0.500s
# Decorator timing
@ub.Timer('Function execution')
def slow_function():
time.sleep(1.0)
return "result"
result = slow_function()
# Prints: Function execution time: 1.000s
# Manual timer control
timer = ub.Timer('Manual timing', verbose=False)
timer.tic()
time.sleep(0.3)
elapsed = timer.toc()
print(f"Elapsed: {elapsed:.3f} seconds")
# Multiple timing measurements
timer = ub.Timer()
times = []
for i in range(5):
timer.tic()
time.sleep(0.1)
times.append(timer.toc())
print(f"Average time: {sum(times)/len(times):.3f}s")import ubelt as ub
import time
# Compare function performance
def method_a():
return sum(range(1000))
def method_b():
return sum(x for x in range(1000))
# Time multiple runs
def benchmark_function(func, runs=100):
times = []
for _ in ub.ProgIter(range(runs), desc=f'Benchmarking {func.__name__}'):
with ub.Timer(verbose=False) as timer:
func()
times.append(timer.elapsed)
return {
'mean': sum(times) / len(times),
'min': min(times),
'max': max(times)
}
# Run benchmarks
results_a = benchmark_function(method_a)
results_b = benchmark_function(method_b)
print(f"Method A: {results_a['mean']:.6f}s avg")
print(f"Method B: {results_b['mean']:.6f}s avg")import ubelt as ub
from datetime import datetime
# Generate timestamps
now_stamp = ub.timestamp()
print(f"Current time: {now_stamp}")
# Custom precision
precise_stamp = ub.timestamp(precision='microseconds')
print(f"Precise time: {precise_stamp}")
# Custom datetime
custom_time = datetime(2023, 1, 1, 12, 0, 0)
custom_stamp = ub.timestamp(custom_time)
print(f"Custom time: {custom_stamp}")
# Parse timestamps back to datetime
parsed_time = ub.timeparse(now_stamp)
print(f"Parsed: {parsed_time}")
# Use timestamps for logging
with ub.Timer('Operation with timestamp', verbose=False) as timer:
start_time = ub.timestamp()
time.sleep(0.1)
end_time = ub.timestamp()
print(f"Started: {start_time}")
print(f"Ended: {end_time}")
print(f"Duration: {timer.elapsed:.3f}s")import ubelt as ub
import time
# Monitor long-running process
def process_data(data_items):
results = []
# Track overall progress
for item in ub.ProgIter(data_items, desc='Processing data'):
# Time individual operations
with ub.Timer(f'Item {item}', verbose=False) as timer:
# Simulate variable processing time
processing_time = 0.01 * (1 + item % 5)
time.sleep(processing_time)
result = item ** 2
results.append({
'item': item,
'result': result,
'time': timer.elapsed,
'timestamp': ub.timestamp()
})
return results
# Process with monitoring
data = range(20)
results = process_data(data)
# Analyze timing results
total_time = sum(r['time'] for r in results)
avg_time = total_time / len(results)
print(f"Total processing time: {total_time:.3f}s")
print(f"Average per item: {avg_time:.3f}s")Install with Tessl CLI
npx tessl i tessl/pypi-ubelt