def _retrieve_benchmarks() -> Benchmarks: config.RUNNING_BENCHMARKS = True benchmarks: Benchmarks = {} for year_path in get_full_year_paths(): year_dir = year_dir_from_path(year_path) year = clean_year(year_dir) benchmarks[year] = {} for day_file in get_full_day_paths(year_path): day = clean_day(day_file) benchmarks[year][day] = {} module_name = get_full_module_from_day_file(day_file) module = __import__(module_name, fromlist=["object"]) try: _run_day(module, year, day, benchmarks) except FileNotFoundError: console.print( f"[blue]{year} day {day:02}: [red]input file not found") config.RUNNING_BENCHMARKS = False console.log("finished running benchmarks") return benchmarks
def run_all() -> None: """ Gathers all year_*.day_* files and executes the part_one and part_two functions in those files. If input file is not found, or a function is not found, it will be printed to console """ config.RUNNING_ALL = True for year_path in get_full_year_paths(): year_dir = year_dir_from_path(year_path) year = clean_year(year_dir) console.print(year) for day_file in get_full_day_paths(year_path): day = clean_day(day_file) module_name = get_full_module_from_day_file(day_file) module = __import__(module_name, fromlist=["object"]) try: _run_day(module, year, day) except FileNotFoundError: console.print( f"[blue]{year} day {day:02}: [red]input file not found") config.RUNNING_ALL = False
def _clean_solutions(dry_run: bool = True): for directory in sorted(os.listdir(ROOT_DIR)): if directory.startswith("year_"): dir_path = os.path.join(ROOT_DIR, directory) for file in sorted(os.listdir(dir_path)): file_path = os.path.join(dir_path, file) if file == "__pycache__": continue if not dry_run: console.print(f"[red]deleting[/red] file {file_path}") os.remove(file_path) else: console.print(f"deleting file {file_path} (dry run)")
def _clean_inputs(dry_run: bool = True): inputs_dir = os.path.join(ROOT_DIR, "inputs") for directory in sorted(os.listdir(inputs_dir)): dir_path = os.path.join(inputs_dir, directory) for file in sorted(os.listdir(dir_path)): file_path = os.path.join(dir_path, file) if file == "__pycache__": continue if not dry_run: console.print(f"[red]deleting[/red] input directory {file_path}") os.remove(file_path) else: console.print(f"deleting input directory {file_path} (dry run)")
def _retrieve_benchmarks_for_day_mp(day_file: str, year: int) -> Dict[int, Dict[str, float]]: config.RUNNING_BENCHMARKS = True day = clean_day(day_file) benchmarks: Dict[int, Dict[str, float]] = {day: {}} module_name = get_full_module_from_day_file(day_file) module = __import__(module_name, fromlist=["object"]) try: _run_day_mp(module, year, day, benchmarks) except FileNotFoundError: console.print(f"[blue]{year} day {day:02}: [red]input file not found") return benchmarks
def add_day(): year, day = _parse_args(sys.argv[1:]) console.print(f"Creating solution day file for year {year} day {day}") # Solution file module_path = os.path.join(ROOT_DIR, f"year_{year}") solution_file = os.path.join(module_path, f"day_{day:02}_{year}.py") create_module_dir(module_path) write_solution_template(solution_file, year, day) # Test file test_module_path = os.path.abspath(os.path.join(ROOT_DIR, "../../tests/adventofcode", f"year_{year}")) test_file = os.path.join(test_module_path, f"test_day_{day:02}_{year}.py") create_module_dir(test_module_path) write_test_template(test_file, year, day) verify_input_exists(year, day)
def wrapper(*args, **kwargs): with cProfile.Profile() as profiler: solution = func(*args, **kwargs) stats = pstats.Stats(profiler) if sort == "time": stats.sort_stats(pstats.SortKey.TIME) elif sort == "cumulative": stats.sort_stats(pstats.SortKey.CUMULATIVE) else: raise ValueError('only "time" and "cumulative" are supported') stats.sort_stats(pstats.SortKey.TIME) console.print(f"{prefix} profiling") stats.print_stats(stats_amount) return solution
def generate_rich_tables(benchmarks: Benchmarks) -> List[Tuple[int, Table]]: tables: List[Tuple[int, Table]] = [] for year, days in benchmarks.items(): console.print(f"[bold]{year}") table = Table() table.add_column("Day", justify="left") table.add_column("Part", justify="center") table.add_column("Solution", justify="right") for day, parts in days.items(): for part, duration in parts.items(): table.add_row(f"{day:02}", f"{part}", f"{duration:.2f} ms") tables.append((year, table)) return tables
def wrapper(*args, **kwargs): try: start = time.perf_counter() solution = func(*args, **kwargs) if solution is None: raise SolutionNotFoundException(year, day, part) diff = (time.perf_counter() - start) * 1000 if not RUNNING_BENCHMARKS: console.print(f"{prefix}{solution} in {diff:.2f} ms") except (ValueError, ArithmeticError, TypeError): console.print_exception() except SolutionNotFoundException: console.print(f"{prefix}[red]solution not found") else: if RUNNING_BENCHMARKS: return diff return solution
def verify_input_exists(year: int, day: int) -> None: try: _ = get_input_for_day(year, day) console.print(f"[yellow]Input data already exists for year {year} day {day}, skipping download") return except FileNotFoundError: try: get_input(year, day) console.print(f"Automatically downloaded input data for year {year} day {day}") return except HTTPError as e: console.print(f"[red]Could not retrieve input data for year {year} day {day} automatically: {e}") except FileNotFoundError: console.print(f"[red]Could not retrieve input data for year {year} day {day}: .session not set correctly") raise ValueError("unknown exception occurred in verify_input_exists")
def write_benchmarks_to_readme(benchmarks: Benchmarks): console.log("writing benchmarks to readme") console.print_json(data=benchmarks) benchmark_text = create_benchmark_text(benchmarks) path = os.path.join(ROOT_DIR, "../../README.md") readme_file = os.path.abspath(path) with open(readme_file, encoding="UTF-8") as f: current_readme = f.read() readme = _replace_between_tags(current_readme, benchmark_text, "<!-- start benchmark section -->", "<!-- end benchmark section -->") with open(readme_file, "w", encoding="UTF-8") as f: f.write(readme) console.log("generating benchmarks table") tables = generate_rich_tables(benchmarks) console.print("[bold]Benchmarks 🚀") for year, table in tables: console.print(year) console.print(table)
def write_test_template(path: str, year: int, day: int) -> None: if not os.path.exists(path): write_template(path, read_test_template(year, day)) console.print(f"[green]Wrote test template to {path}") else: console.print(f"[yellow]Did not write test template for year {year} day {day}, the file already exists.")