from abc import ABC, abstractmethod from dataclasses import dataclass from .load import get_input import logging logging.basicConfig(level=logging.DEBUG) @dataclass class DayBase(ABC): day_number: int test_data: str excepted_part1: str excepted_part2: str def __post_init__(self): if self.__class__ == DayBase: raise TypeError("Cannot instantiate abstract class.") @abstractmethod def parse_data(self, input: str): pass def test_part1(self): data = self.parse_data(self.test_data) assert self.solve_part1(data) == self.excepted_part1 def test_part2(self): data = self.parse_data(self.test_data) assert self.solve_part2(data) == self.excepted_part2 @abstractmethod def solve_part1(self, data): pass @abstractmethod def solve_part2(self, data): pass def run_tests(self): classes = list(self.__class__.__bases__) + [self.__class__] for klass in classes: for element in klass.__dict__: if callable(getattr(self, element)) and element.startswith("test_"): logging.debug("Found test: %s", element) getattr(self, element)() def run(self): data = self.parse_data(get_input(self.day_number)) logging.info("Part 01 (day %s): %s", self.day_number, self.solve_part1(data)) logging.info("Part 02 (day %s): %s", self.day_number, self.solve_part2(data))