Skip to content

Commit 5c38a19

Browse files
committed
Script to upload to pypi
1 parent 610accf commit 5c38a19

File tree

22 files changed

+212
-157
lines changed

22 files changed

+212
-157
lines changed

.env

221 Bytes
Binary file not shown.

scripts/build_aoc_commons.ps1

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Author: Darren
2+
#
3+
# Utility script to build dazbo-aoc-commons and upload it to PyPI.
4+
# Then, install the module:
5+
# py -m pip install dazbo-aoc-commons
6+
7+
Set-Location C:\Users\djl\localdev\Python\Advent-of-Code\scripts
8+
Set-Location ..\src\aoc_common\
9+
"`nDeleting dist folder..."
10+
if (Test-Path "dist") {
11+
Remove-Item -LiteralPath "dist" -Recurse -Force
12+
}
13+
14+
"`nRunning package build..."
15+
py -m setup sdist
16+
17+
"`nUploading to PyPi..."
18+
py ..\..\scripts\upload_to_pypi.py
19+
20+
"`nResetting folder."
21+
Set-Location ..\..

scripts/upload_to_pypi.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
""" Python to upload the dist folder to PyPi """
2+
import os
3+
import subprocess
4+
from dotenv import load_dotenv
5+
6+
def upload_to_pypi():
7+
"""
8+
So that we can skip having to run this command (and pass in username and pwd) separately:
9+
twine upload dist/*
10+
"""
11+
load_dotenv()
12+
13+
# expect vars to be stored in .env or environment vars
14+
username = os.getenv('PYPI_USERNAME')
15+
api_key = os.getenv('PYPI_API_KEY')
16+
17+
if username is None or api_key is None:
18+
raise ValueError("PYPI_USERNAME and/or PYPI_PASSWORD are not set in the .env file")
19+
20+
try:
21+
subprocess.run(['twine', 'upload', 'dist/*', '-u', username, '-p', api_key], check=True)
22+
except subprocess.CalledProcessError as e:
23+
print(f"An error occurred during the upload: {e}")
24+
25+
upload_to_pypi()

src/AoC_2015/d19_molecular_retrosynthesis_str_replacement/reindeer_chemistry.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@
4444
import re
4545
import logging
4646
from collections import defaultdict
47-
import aoc_common.aoc_commons as td
47+
import aoc_commons as ac
4848

49-
locations = td.get_locations(__file__)
50-
logger = td.retrieve_console_logger(locations.script_name)
49+
locations = ac.get_locations(__file__)
50+
logger = ac.retrieve_console_logger(locations.script_name)
5151
logger.setLevel(logging.INFO)
5252

5353
def main():

src/AoC_2015/d20_elf_visits_counting_generators_factors_and_set_algebra/elf_delivery.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@
3535
import time
3636
from collections import defaultdict
3737
import logging
38-
import aoc_common.aoc_commons as td
38+
import aoc_commons as ac
3939

40-
locations = td.get_locations(__file__)
41-
logger = td.retrieve_console_logger(locations.script_name)
40+
locations = ac.get_locations(__file__)
41+
logger = ac.retrieve_console_logger(locations.script_name)
4242
logger.setLevel(logging.INFO)
4343

4444
TARGET = 36000000
@@ -53,7 +53,7 @@ def main():
5353
presents_dropped, house_num = 0, 0
5454
while presents_dropped < TARGET:
5555
house_num += 1
56-
presents_dropped = sum(factor * 10 for factor in td.get_factors(house_num))
56+
presents_dropped = sum(factor * 10 for factor in ac.get_factors(house_num))
5757

5858
logger.info("Part 1: House=%d, presents dropped=%d", house_num, presents_dropped)
5959

@@ -77,7 +77,7 @@ def generate_presents_for_house(per_elf_multiplier: int, elf_visit_limit: int =
7777
while True: # iterate for each house, yielding each time
7878
house_num += 1
7979
presents_dropped = 0
80-
factors_for_house = td.get_factors(house_num)
80+
factors_for_house = ac.get_factors(house_num)
8181

8282
# iterate through all the factors for this house
8383
for factor in factors_for_house:

src/AoC_2015/d21_boss_fight_classes_namedtuples_combinations_comprehension_if/boss_fight.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@
3232
from os import path
3333
from itertools import combinations
3434
from player import Player
35-
import aoc_common.aoc_commons as td
35+
import aoc_commons as ac
3636

37-
locations = td.get_locations(__file__)
38-
logger = td.retrieve_console_logger(locations.script_name)
37+
locations = ac.get_locations(__file__)
38+
logger = ac.retrieve_console_logger(locations.script_name)
3939
logger.setLevel(logging.DEBUG)
4040

4141
BOSS_FILE = "boss_stats.txt"

src/AoC_2015/d22_wizards_factories_dataclass_generators/spell_casting.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,10 @@
4040
from os import path
4141
from typing import Iterable
4242

43-
import aoc_common.aoc_commons as td
43+
import aoc_commons as ac
4444

45-
locations = td.get_locations(__file__)
46-
logger = td.retrieve_console_logger(locations.script_name)
45+
locations = ac.get_locations(__file__)
46+
logger = ac.retrieve_console_logger(locations.script_name)
4747
logger.setLevel(logging.INFO)
4848
# td.setup_file_logging(logger, folder=locations.output_dir)
4949

@@ -372,7 +372,7 @@ def attack_combos_generator(count_different_attacks: int) -> Iterable[str]:
372372
i = 0
373373
while True:
374374
# convert i to base-n (where n is the number of attacks we can choose from)
375-
yield td.to_base_n(i, count_different_attacks)
375+
yield ac.to_base_n(i, count_different_attacks)
376376
i += 1
377377

378378
@cache # I think there are only about 3000 different sorted attacks

src/AoC_2015/d22_wizards_factories_dataclass_generators/spell_casting_old.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@
3030
import time
3131
from os import path
3232
from typing import Iterable
33-
import aoc_common.aoc_commons as td
33+
import aoc_commons as ac
3434

35-
locations = td.get_locations(__file__)
36-
logger = td.retrieve_console_logger(locations.script_name)
35+
locations = ac.get_locations(__file__)
36+
logger = ac.retrieve_console_logger(locations.script_name)
3737
logger.setLevel(logging.INFO)
3838
# td.setup_file_logging(logger, folder=locations.script_dir)
3939

src/AoC_2015/d23_computer/computer.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@
1717
"""
1818
import logging
1919
import time
20-
import aoc_common.aoc_commons as td
20+
import aoc_commons as ac
2121

22-
locations = td.get_locations(__file__)
23-
logger = td.retrieve_console_logger(locations.script_name)
22+
locations = ac.get_locations(__file__)
23+
logger = ac.retrieve_console_logger(locations.script_name)
2424
logger.setLevel(logging.INFO)
2525

2626
class Instructions():

src/AoC_2015/d24_sleigh_balance_subset_sum/sleigh_balance.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,15 @@
3030
import time
3131
from math import prod
3232
from itertools import combinations
33-
import aoc_common.aoc_commons as td
33+
import aoc_commons as ac
3434

3535
YEAR = 2015
3636
DAY = 24
3737

38-
locations = td.get_locations(__file__)
39-
logger = td.retrieve_console_logger(locations.script_name)
38+
locations = ac.get_locations(__file__)
39+
logger = ac.retrieve_console_logger(locations.script_name)
4040
logger.setLevel(logging.INFO)
41-
td.write_puzzle_input_file(YEAR, DAY, locations)
41+
ac.write_puzzle_input_file(YEAR, DAY, locations)
4242

4343
def main():
4444
# with open(locations.sample_input_file, mode="rt") as f:

src/AoC_2015/d25_instr_manual_2d_list_gen/instr_manual_codes.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@
2121
"""
2222
import logging
2323
import time
24-
import aoc_common.aoc_commons as td
24+
import aoc_commons as ac
2525

26-
locations = td.get_locations(__file__)
27-
logger = td.retrieve_console_logger(locations.script_name)
26+
locations = ac.get_locations(__file__)
27+
logger = ac.retrieve_console_logger(locations.script_name)
2828
logger.setLevel(logging.DEBUG)
2929

3030
TARGET_ROW = 2947

src/AoC_2015/d25_instr_manual_2d_list_gen/instr_manual_codes_numpy.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@
2222
import logging
2323
import time
2424
import numpy as np
25-
import aoc_common.aoc_commons as td
25+
import aoc_commons as ac
2626

27-
locations = td.get_locations(__file__)
28-
logger = td.retrieve_console_logger(locations.script_name)
27+
locations = ac.get_locations(__file__)
28+
logger = ac.retrieve_console_logger(locations.script_name)
2929
logger.setLevel(logging.DEBUG)
3030

3131
TARGET_ROW = 2947

src/AoC_2022/d01_calorie_counting/elf_calories.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
import logging
3030
from pathlib import Path
3131
import time
32-
import aoc_common.aoc_commons as td
32+
import aoc_commons as ac
3333

3434
SCRIPT_NAME = Path(__file__).stem
3535
SCRIPT_DIR = Path(__file__).parent
@@ -38,7 +38,7 @@
3838

3939
logger = logging.getLogger(SCRIPT_NAME)
4040
logger.setLevel(logging.DEBUG)
41-
logger.addHandler(td.stream_handler)
41+
logger.addHandler(ac.stream_handler)
4242

4343
def main():
4444
with open(INPUT_FILE, mode="rt") as f:

src/AoC_2022/d12_hill_climbing_algorithm/hill_climbing_E_to_a.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
from pathlib import Path
3232
import time
3333
from matplotlib import pyplot as plt
34-
import aoc_common.aoc_commons as td
34+
import aoc_commons as ac
3535
from aoc_common.aoc_commons import Point
3636

3737
SCRIPT_NAME = Path(__file__).stem
@@ -42,7 +42,7 @@
4242

4343
logger = logging.getLogger(SCRIPT_NAME)
4444
logger.setLevel(logging.DEBUG)
45-
logger.addHandler(td.stream_handler)
45+
logger.addHandler(ac.stream_handler)
4646
# td.setup_file_logging(logger, OUTPUT_DIR, SCRIPT_NAME)
4747

4848
class Grid():

src/aoc_commons_package/README.md renamed to src/aoc_common/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ pip install dazbo-aoc-commons
88

99
## Use
1010

11-
import aoc_common.aoc_commons as td
11+
import aoc_commons as ac

src/aoc_commons_package/aoc_common/aoc_commons.py renamed to src/aoc_common/aoc_commons.py

Lines changed: 46 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
A set of helper functions, reusable classes and attributes used by my AoC solutions
66
Test with tests/test_aoc_commons.py
77
8-
You could import as follows:
9-
import common.aoc_commons as td
8+
You can import as follows:
9+
import aoc_commons as ac
1010
"""
1111
# py -m pip install requests python-dotenv
1212
from __future__ import annotations
@@ -111,7 +111,8 @@ class Locations:
111111
sample_input_file: Path
112112
input_file: Path
113113

114-
def get_locations(script_file):
114+
def get_locations(script_file) -> Locations:
115+
""" Set various paths, based on the location of the calling script. """
115116
script_name = Path(script_file).stem # this script file, without .py
116117
script_dir = Path(script_file).parent # the folder where this script lives
117118
input_dir = Path(script_dir, "input")
@@ -128,51 +129,61 @@ def get_locations(script_file):
128129
# Retrieving input data
129130
##################################################################
130131

131-
def write_puzzle_input_file(year: int, day: int, locations: Locations) -> bool:
132-
""" Use session key to obtain user's unique data for this year and day.
133-
Only retrieve if the input file does not already exist.
134-
Return True if retrieved; False if file exists.
135-
"""
136-
if os.path.exists(locations.input_file):
137-
logger.debug("%s already exists", os.path.basename(locations.input_file))
138-
return False
139-
140-
potential_paths = [
132+
def get_envs_from_file() -> bool:
133+
""" Look for .env files, read variables from it, and store as environment variables """
134+
potential_paths = [ # look for .env
141135
'.env',
142136
os.path.join('..', '.env'),
143137
os.path.join('..', '..', '.env'),
144138
]
145139

146-
env_path = ""
147140
for a_path in potential_paths:
148141
if os.path.exists(a_path):
149142
logger.info("Using .env at %s", a_path)
150-
env_path = a_path
143+
load_dotenv(a_path, verbose=True)
144+
return True
145+
146+
logger.warning("No .env file found.")
147+
return False
148+
149+
get_envs_from_file() # read env variables from a .env file, if we can find one
150+
151+
def write_puzzle_input_file(year: int, day: int, locations: Locations) -> bool:
152+
""" Use session key to obtain user's unique data for this year and day.
153+
Only retrieve if the input file does not already exist.
154+
Return True if successful.
155+
Requires env: AOC_SESSION_COOKIE, which can be set from the .env.
156+
"""
157+
if os.path.exists(locations.input_file):
158+
logger.debug("%s already exists", os.path.basename(locations.input_file))
159+
return True
151160

152-
load_dotenv(env_path)
153-
SESSION_COOKIE = os.getenv('AOC_SESSION_COOKIE')
154-
if SESSION_COOKIE:
161+
session_cookie = os.getenv('AOC_SESSION_COOKIE')
162+
if session_cookie:
155163
logger.info('Session cookie retrieved.')
156-
else:
157-
logger.error('Failed to retrieve session cookie. Is it in your .env?')
158164

159-
url = f"https://adventofcode.com/{year}/day/{day}/input"
160-
cookies = {"session": SESSION_COOKIE}
161-
response = requests.get(url, cookies=cookies)
162-
data = ""
163-
164-
if response.status_code == 200:
165-
data = response.text
165+
# Create input folder, if it doesn't exist
166+
if not locations.input_dir.exists():
167+
locations.input_dir.mkdir(parents=True, exist_ok=True)
168+
169+
url = f"https://adventofcode.com/{year}/day/{day}/input"
170+
cookies = {"session": session_cookie}
171+
response = requests.get(url, cookies=cookies, timeout=5)
172+
173+
data = ""
174+
if response.status_code == 200:
175+
data = response.text
176+
else:
177+
data = f"Failed to retrieve puzzle input: {response.status_code}"
178+
179+
with open(locations.input_file, 'w') as file:
180+
logger.debug("Writing input file %s", os.path.basename(locations.input_file))
181+
file.write(data)
182+
return True
166183
else:
167-
data = f"Failed to retrieve puzzle input: {response.status_code}"
168-
169-
if not locations.input_dir.exists():
170-
locations.input_dir.mkdir(parents=True, exist_ok=True)
171-
logger.debug("Writing %s", os.path.basename(locations.input_file))
172-
with open(locations.input_file, 'w') as file:
173-
file.write(data)
184+
logger.error('Failed to retrieve session cookie. Is it in your .env?')
174185

175-
return True
186+
return False
176187

177188
#################################################################
178189
# POINTS, VECTORS AND GRIDS

src/aoc_common/setup.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
"""
2+
Used to setup the aoc_commons package.
3+
Make sure you have installed twine first.
4+
py -m pip install twine
5+
6+
1. Delete any existing dist folder from aoc_commons_package.
7+
2. Before updating, be sure to increment the version number.
8+
3. Create the package. From the aoc_commons_package folder, run:
9+
py -m setup sdist
10+
4. Upload to PyPi:
11+
twine upload dist/*
12+
5. Install the package from your venv at the project folder level:
13+
py -m pip install dazbo-aoc-commons
14+
"""
15+
from setuptools import setup
16+
17+
setup(
18+
name='dazbo-aoc-commons',
19+
version='0.1.10',
20+
url='https://github.com/derailed-dash/Advent-of-Code',
21+
author='derailed-dash',
22+
description='A set up of helper functions and classes to assist with Advent of Code problems',
23+
long_description=open('README.md').read(),
24+
long_description_content_type="text/markdown",
25+
py_modules=["aoc_commons"],
26+
package_dir={'': '.'}, # Current directory
27+
install_requires=[],
28+
)
Binary file not shown.

0 commit comments

Comments
 (0)