-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutil.py
97 lines (66 loc) · 2.62 KB
/
util.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import re
from collections import Counter
separator = '─'*100
lines = str.splitlines
def paragraph(text):
return text.split('\n\n')
def helper_base(source: str, functions: callable = str, display: int = 10):
day_text = read_raw(source)
name, function, segmentation = functions()
parser_function = get_function(function)
if segmentation != 'lines':
custom_segmentation = get_function(segmentation)
segmentation = custom_segmentation(day_text.rstrip())
else:
segmentation = lines(day_text.rstrip())
print(name)
display_items('Raw input', day_text.splitlines(), display)
data = make_tuple(parser_function, segmentation)
if parser_function != str or parser_function != lines:
display_items('Parsed file', data, display)
return data
def get_function(function: str):
method_name = function
possibles = globals().copy()
possibles.update(locals())
method = possibles.get(method_name)
if not method:
raise NotImplementedError(f'Method {method_name} not implemented')
return method
def display_items(file_raw, items, display: int, separate=separator):
if display:
type_input = Counter(map(type, items))
def counter(types):
"""count lines and verbose if plural"""
for types, name in types.items():
return f'{name} {types.__name__}{"" if name == 1 else "s"}'
print(f'{separate}\n{file_raw}: {counter(type_input)}:\n{separate}')
for line in items[:display]:
print(truncate(line))
if display < len(items):
print('...')
def read_raw(source: str):
with open(source, 'r') as file:
data = file.read()
return data
def printer(part: str, result: str, func: callable = str, separate: str = separator):
_part = part
match part:
case 'part_1':
_part = 'Part 1'
case 'part_2':
_part = 'Part 2'
results = f'{_part}: {func(result)}'
return f'{separate}\n{results}\n{separate}'
def truncate(obj, width: int = 100, ellipsis: str = ' ...'):
string = str(obj)
if len(string) <= width:
return string
return string[:width - len(ellipsis)] + ellipsis
def make_tuple(function: callable, *sequences):
return tuple(map(function, *sequences))
def make_list(function: callable, *sequences):
return list(map(function, *sequences))
def find_digits(text: str):
return make_tuple(int, re.findall(r'[0-9]', text))
four_directions = ((1, 0), (0, 1), (-1, 0), (0, -1))