Skip to content

Commit

Permalink
Merge pull request #164 from Stegallo/restructure
Browse files Browse the repository at this point in the history
Restructure
  • Loading branch information
Stegallo authored Nov 3, 2023
2 parents 78286ff + 157069b commit e2cf5c9
Show file tree
Hide file tree
Showing 125 changed files with 265 additions and 5,957 deletions.
29 changes: 17 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,40 @@
<a href="https://codeclimate.com/github/Stegallo/adventofcode/maintainability"><img src="https://api.codeclimate.com/v1/badges/d3a26d2fed4f5d3b04c7/maintainability" /></a>
# adventofcode

to run the adventofcode environment:
| | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 |
| - | - | - | - | - | - | - | - | - |
| 01 | [][201501] | | | | | | | |

[201501]: https://github.com/Stegallo/adventofcode/blob/master/y_2015/day1.py

## to run the code

activate the adventofcode virtual environment:
```
sh docker/run.sh
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements/base.txt
```

copy the input of the day inside the file
```
y_20xy/input_day<day>.txt
```
you can create a test file with name
you can create a test input file with name
```
y_20xy/input_day<day>_test.txt
```

inside the container, run the command (for years after 2019)
run the command
```
python -m y_20xy --day <day>
python -m src --year <year> --day <day>
```
if you want to run against the test file
```
python -m y_20xy --day <day> --test 1
```

inside the container, run the command (for years before 2019)
```
python y_20xy/common.py <day>
python -m src --year <year> --day <day> --test 1
```

note: to avoid tracking in git your credentials:
```
git update-index --assume-unchanged y_2022/secret.py
git update-index --assume-unchanged secret.py
```
File renamed without changes.
119 changes: 119 additions & 0 deletions common/aoc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import argparse
import importlib
from abc import ABC, abstractmethod
from datetime import datetime
from typing import List

from .get_file import pull_file


class AoCDay(ABC):
"""
Abstract class Day
"""

@abstractmethod
def __init__(self, path: str, test: bool):
day_info = AoCDay.get_day_info(path)
self._year = day_info.year
self._day = day_info.day
self._test = test
self._input_data = self._load_input()
self._preprocess_input()
self.__stop_watch = StopWatch()

@abstractmethod
def _preprocess_input(self):
"""
preprocessing of the input
"""

@abstractmethod
def _calculate_1(self):
"""
_calculate_1
"""

@abstractmethod
def _calculate_2(self):
"""
_calculate_2
"""

@staticmethod
def get_day_info(path: str):
"""
TODO typehint
"""
return DayInfo.from_path(path)

def _load_input(self) -> List[List[str]]:
raw_string = self._get_file_content()

if raw_string and raw_string[-1] == "\n":
raw_string = raw_string[:-1]
chunks = raw_string.split("\n\n")

return [k.split("\n") for k in chunks]

def _get_file_content(self):
file_name = (
f"y_{self._year}/input_day{self._day}{'_test'if self._test else ''}.txt"
)
try:
with open(file_name) as f:
raw_string = f.read()
except FileNotFoundError:
pull_file(self._year, self._day)
with open(file_name) as f:
raw_string = f.read()
return raw_string

def solve(self):
self.__stop_watch.start()
print(f"sol 1: {self._calculate_1()} Time taken: {self.__stop_watch.lap()}")

print(f"sol 2: {self._calculate_2()} Time taken: {self.__stop_watch.stop()}")


class DayInfo:
year: int
day: int

@staticmethod
def from_path(path: str):
"""
TODO typehint
"""
day_info = DayInfo()
day_info.year = path.split(".")[0].replace("y_", "")
day_info.day = path.split(".")[1].replace("day", "")
return day_info


class StopWatch:
def __init__(self):
self.__start_time = None

def start(self):
self.__start_time = datetime.now()

def lap(self):
return datetime.now() - self.__start_time

def stop(self):
return datetime.now() - self.__start_time


def main():
""""""
parser = argparse.ArgumentParser()
parser.add_argument("--year", type=int, help="year as a number")
parser.add_argument("--day", type=int, help="day as a number")
parser.add_argument("--test", type=int, help="test flag")
args = parser.parse_args()

module = importlib.import_module(f"y_{args.year}.day{args.day}")

day = getattr(module, "Day")(test=args.test)
day.solve()
6 changes: 3 additions & 3 deletions y_2022/get_file.py → common/get_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

import requests

from .secret import SESSION
from secret import SESSION


def pull_file(day: str):
def pull_file(year: str, day: str):
S = requests.Session()
S.headers["User-Agent"] = "github.com/stegallo"
URL = "https://adventofcode.com/{:d}/day/{:d}/{:s}"
YEAR, DAY = 2022, int(day)
YEAR, DAY = int(year), int(day)
S.cookies.set("session", SESSION)
r = S.get(URL.format(YEAR, DAY, "input"))
with open(f"y_{YEAR}/input_day{DAY}.txt", "w") as f:
Expand Down
1 change: 1 addition & 0 deletions requirements/base.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
requests
4 changes: 4 additions & 0 deletions requirements/test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
pytest
isort
black
flake8
File renamed without changes.
2 changes: 1 addition & 1 deletion y_2019/__main__.py → src/__main__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from .common import main
from common.aoc import main

if __name__ == "__main__":
main()
55 changes: 55 additions & 0 deletions tests/common/test_aoc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import contextlib
from unittest.mock import patch

from common.aoc import AoCDay, main


def test_load_input_string():
with patch("common.aoc.open") as open_patch:
AoCDay.__abstractmethods__ = set()
aoc_day = AoCDay("y_1900.day1", False)

open_patch().__enter__().read = lambda: "hello"
assert aoc_day._load_input() == [["hello"]]
open_patch().__enter__().read = lambda: ""
assert aoc_day._load_input() == [[""]]


def test_load_input_multiline():
with patch("common.aoc.open") as open_patch:
AoCDay.__abstractmethods__ = set()
aoc_day = AoCDay("y_1900.day1", False)

open_patch().__enter__().read = lambda: "hello\nworld\n"
assert aoc_day._load_input() == [["hello", "world"]]


def test_load_input_multiline_multisection():
with patch("common.aoc.open") as open_patch:
AoCDay.__abstractmethods__ = set()
aoc_day = AoCDay("y_1900.day1", False)

open_patch().__enter__().read = (
lambda: "hello\nworld\n\ngoodbye\nworld\n\nbye\n"
)
assert aoc_day._load_input() == [
["hello", "world"],
["goodbye", "world"],
["bye"],
]


def test_main():
with contextlib.ExitStack() as patches:
patches.enter_context(patch("common.aoc.argparse"))
patches.enter_context(patch("common.aoc.open"))
patches.enter_context(patch("common.aoc.importlib"))
assert main() is None


def test_AoCDay():
with patch("common.aoc.open") as open_patch:
AoCDay.__abstractmethods__ = set()
aoc_day = AoCDay("y_1900.day1", False)
open_patch().__enter__().read = lambda: "hello\nworld\n"
assert aoc_day.solve() is None
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@

from unittest.mock import mock_open, patch

from y_2022.get_file import pull_file
from common.get_file import pull_file


def test_pull_file():

with patch("requests.Session") as mock_session:
mock_session().get().text = ""
with patch("builtins.open", mock_open()) as mock_open_file:
pull_file(0)
mock_open_file.assert_called_with("y_2022/input_day0.txt", "w")
pull_file(0, 0)
mock_open_file.assert_called_with("y_0/input_day0.txt", "w")
52 changes: 39 additions & 13 deletions tests/y_2015/test_2015_day1.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,45 @@
from y_2015.day1 import calculate_1, calculate_2
from __future__ import annotations

from unittest.mock import mock_open, patch

from y_2015.day1 import Day

with patch("builtins.open", mock_open(read_data="0")):
day = Day()


def test_calculate_1():
assert calculate_1("(())") == 0
assert calculate_1("()()") == 0
assert calculate_1("(((") == 3
assert calculate_1("(()(()(") == 3
assert calculate_1("))(((((") == 3
assert calculate_1("())") == -1
assert calculate_1("))(") == -1
assert calculate_1(")))") == -3
assert calculate_1(")())())") == -3
day._Day__input_data = "(())"
assert day._calculate_1() == 0

day._Day__input_data = "((("
assert day._calculate_1() == 3

day._Day__input_data = "(()(()("
assert day._calculate_1() == 3

day._Day__input_data = "))((((("
assert day._calculate_1() == 3

day._Day__input_data = "())"
assert day._calculate_1() == -1

day._Day__input_data = "))("
assert day._calculate_1() == -1

day._Day__input_data = ")))"
assert day._calculate_1() == -3

day._Day__input_data = ")())())"
assert day._calculate_1() == -3


def test_calculate_2():
assert calculate_2(")") == 1
assert calculate_2("()())") == 5
assert calculate_2("(") == -1
day._Day__input_data = ")"
assert day._calculate_2() == 1

day._Day__input_data = "()())"
assert day._calculate_2() == 5

day._Day__input_data = "("
assert day._calculate_2() == -1
11 changes: 0 additions & 11 deletions tests/y_2015/test_2015_day2.py

This file was deleted.

13 changes: 0 additions & 13 deletions tests/y_2015/test_2015_day3.py

This file was deleted.

13 changes: 0 additions & 13 deletions tests/y_2015/test_2015_day4.py

This file was deleted.

Loading

0 comments on commit e2cf5c9

Please sign in to comment.