Package: aoctools
Automating your Advent of Code (AOC) Workflow: aoctoolsIntroductionaoctoolsis a command line interface (cli) that helps you automateAdvent of Code (AOC)boilerplate, e.g., downloading
the day's problem input and writing python boilerplate.WorkflowStep 0: Installpip3 install aoctoolsStep 1: Initialize a projectusage: aoctools init [-h] root_path year

positional arguments:
  root_path   the root project directory
  yearTheinitcommand will create anaoctoolsproject at the path that you
specify.Step 2: Bootstrap the boilerplate for a new dayMake sure that you set an environment variable namedAOC_SESSION_COOKIEto thesessioncookie of your AOC login; in Chrome, you can obtain this cookie by
opening Developer Tools (View > Developer > Developer Tools), opening theApplicationtab, and looking for the value that appears next tosession.As an alternative to setting this variable every time that you run the tool,aoctoolssupports.envfiles. You can create a.envfile under your
project directory and runaoctoolsfrom said directory for an even more
ergonomic workflow. NB:.envfiles are loaded relative to the working
directory (where you runaoctoolsfrom) -notthe project directory.usage: aoctools init_day [-h] [--root-path [ROOT_PATH]] [--year YEAR]
                         [--skip-bootstrap] [--skip-download]
                         [--session-cookie SESSION_COOKIE]
                         day

positional arguments:
  day                   aoc challenge day

optional arguments:
  -h, --help            show this help message and exit
  --root-path [ROOT_PATH]
                        the root project directory; defaults to the current
                        working directory
  --year YEAR           aoc challenge year; defaults to the project year
  --skip-bootstrap      don't generate python boilerplate
  --skip-download       don't download the challenge input data
  --session-cookie SESSION_COOKIE
                        an AOC login session cookie; defaults to the
                        environment variable AOC_SESSION_COOKIEIf you want to generate boilerplate for the challenge day without downloading
the day's input file, pass--skip-downloadto theaoctools init_daycommand; you can download the day's input file later by passing--skip-bootstrap; NB: theinit_daycommand will not clobber existing
python files, so running it twice without passing--skip-bootstrapwill fail.Step 3: HackBootstrapping will generate a new module under the rootaocmodule named after
the freshly bootstrapped day. For example, runningaoctools init_day 1will
create a file namedaoc/d01/main.pycontaining:fromtypingimportIOdefp_1(input_file:IO,debug=False):# pylint: disable=unused-argumentpassdefp_2(input_file:IO,debug=False):# pylint: disable=unused-argumentpassFilling inp_1andp_2is where you come in;aoctoolsrequires that
you return a (stringifiable) value if you want to use the built-in solution
printer and regression test framework, but there are no restrictions beyond
that.Running your solution withaoctoolswill result inp_1orp_2being
called with a reference to the input file; semantically, it's the same as if
you had written:importaoc.d01if__name__=='__main__':withopen('data/d01/input.txt','r',encoding='utf8')asinput_file:aoc.d01.p_1(input_file,False)# or Trueand run the file from the root of your project directory. Thedebugvariable
is set via thecliand makes it easy to control print output:defp_1(input_file:IO,debug=False):v_1=1v_2=2ifdebug:print(f"v_1 + v_2 ={v_1}+{v_2}={v_1+v_2}")returnv_1+v_2Step 4: Test the example inputsCreate a new example by running theinit_examplecommand:usage: aoctools init_example [-h] [--root-path [ROOT_PATH]]
                             day {1,2} expected [example_number]

positional arguments:
  day                   aoc challenge day
  {1,2}                 the challenge part for the example
  expected              the expected example value
  example_number        aoc challenge day; optional (autoincrement)

optional arguments:
  -h, --help            show this help message and exit
  --root-path [ROOT_PATH]
                        the root project directory; defaults to the current
                        working directoryExamples are created indata/day/example_n.txt. By default, your examples will
be numbered sequentially; you can specify a number explicitly by passing an
additional[example_number]argument.Example files take the form:part: 1
expected: 2

1-3 a: abcde
1-3 b: cdefg
2-9 c: cccccccccThe first line must bepart: (1|2)corresponding to the part of the AOC
problem that the example pertains to. The second line must be an expected
value:expected: (.+). The third line must be blank line. The rest of the file
should contain the example text.Run examples via therun_examplescommand:usage: aoctools run_examples [-h] [--root-path [ROOT_PATH]] [--debug]
                             day [example_number]

positional arguments:
  day                   aoc challenge day
  example_number        the example to run; defaults to all examples

optional arguments:
  -h, --help            show this help message and exit
  --root-path [ROOT_PATH]
                        the root project directory
  --debug               print debug infoYou must specify a day. You can optionally specify a specific example to run;
by default, all examples for the given day will run.Step 5: Run your solutionusage: aoctools run [-h] [--root-path [ROOT_PATH]] [--debug] day {1,2}

positional arguments:
  day                   aoc challenge day
  {1,2}                 the challenge part to run

optional arguments:
  -h, --help            show this help message and exit
  --root-path [ROOT_PATH]
                        the root project directory
  --debug               print debug infoAs an example, you can run Day 1, Pt 1 from your root project directory by
invoking:aoctools run 1 1

solution to day 1, part 1: xxxxStep 6 (Optional): Regression tests & Code QualityOnce you identify a solution you can populate the automatically generated
regression tests undertests/aoc/test_d*:importaoc.d01fromtests.aoc.test_baseimportBaseTestCaseclassTestAll(BaseTestCase):deftest_part_one(self):self.run_aoc_part(1,CHANGEME,aoc.d01.p_1)deftest_part_two(self):self.run_aoc_part(1,CHANGEME,aoc.d01.p_2)Runningmake testfrom the root project directory will run all regression
tests.Similarly, runningmake lintwill type lint and type check your code and
tests with bothpylintandmypy.