advent-of-code/src/holt59/aoc/base.py
Mikaël Capelle 8308940674
Some checks failed
continuous-integration/drone/push Build is failing
Allow creation of avi video.
2024-12-15 14:07:32 +01:00

97 lines
2.2 KiB
Python

from abc import abstractmethod
from logging import Logger
from pathlib import Path
from typing import (
Any,
Final,
Iterable,
Iterator,
Protocol,
Sequence,
TypeVar,
overload,
)
from numpy.typing import NDArray
_T = TypeVar("_T")
class ProgressHandler(Protocol):
@overload
def wrap(self, values: Sequence[_T]) -> Iterator[_T]: ...
@overload
def wrap(self, values: Iterable[_T], total: int) -> Iterator[_T]: ...
class FileHandler:
@abstractmethod
def make_path(self, filename: str) -> Path: ...
@abstractmethod
def notify_created(self, path: Path): ...
@abstractmethod
def _create(
self, path: Path, content: bytes, text: bool = False
) -> Path | None: ...
def create(self, filename: str, content: bytes, text: bool = False):
path = self._create(self.make_path(filename), content, text)
if path is not None:
self.notify_created(path)
def image(self, filename: str, image: NDArray[Any]):
import imageio.v3 as iio
from pygifsicle import optimize # type: ignore
path = self.make_path(filename)
iio.imwrite(path, image) # type: ignore
optimize(path, options=["--no-warnings"])
self.notify_created(path)
def video(self, filename: str, video: NDArray[Any]):
import cv2
path = self.make_path(filename)
fps = 5
out = cv2.VideoWriter(
path.as_posix(),
cv2.VideoWriter_fourcc(*"vp80"), # type: ignore
fps,
(video.shape[2], video.shape[1]),
True,
)
for picture in video:
out.write(picture)
out.release()
self.notify_created(path)
class BaseSolver:
def __init__(
self,
logger: Logger,
verbose: bool,
year: int,
day: int,
progress: ProgressHandler,
files: FileHandler | None = None,
):
self.logger: Final = logger
self.verbose: Final = verbose
self.year: Final = year
self.day: Final = day
self.progress: Final = progress
self.files: Final = files
@abstractmethod
def solve(self, input: str) -> Iterator[Any] | None: ...