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
98
99
100
101
102
|
#!/usr/bin/env python3
import json
import itertools
import textwrap
from pathlib import Path
from argparse import ArgumentParser
import requests
from bs4 import BeautifulSoup
ROOT_DIR = Path(__file__).resolve().parent
LANGUAGES_FILENAME = ROOT_DIR / 'languages.json'
URL_FORMAT = 'http://projecteuler.net/problem={index}'
LINE_WRAP = 89
PROBLEM_PADDING = 3
class Problem:
def __init__(self, index: int, language: dict):
self.index = index
self.language = language
def fetch(self):
url = URL_FORMAT.format(index=self.index)
print(f"Fetching problem {self.index} at {url}")
data = requests.get(url)
soup = BeautifulSoup(data.text, 'html.parser')
data = soup.find('div', {'id': 'content'})
self.title = data.h2.text
self.sub_title = data.h3.text
self.content = soup.find('div', {'class': 'problem_content'}).text
print(self)
return self
def write(self):
file_name = f'{self.index:03}-{self._slug}.{self.language["extension"]}'
file_path = ROOT_DIR / self.language['name'] / file_name
if file_path.exists():
raise FileExistsError(f'{file_path} already exists')
file_path.parent.mkdir(exist_ok=True)
with open(file_path, 'w') as file:
file.write(str(self))
return self
def __str__(self) -> str:
title = self.title.strip()
sub_title = self.sub_title.strip()
content = self.content.strip()
content_lines = []
for line in content.splitlines():
content_lines.extend(textwrap.wrap(line, width=LINE_WRAP))
lines = [title, sub_title, "", *content_lines]
lines = [self.language['comment']['prefix'] + line for line in lines]
lines.insert(0, self.language['comment']['top'])
lines.append(self.language['comment']['bottom'])
lines.extend(itertools.repeat("", PROBLEM_PADDING))
return '\n'.join(lines)
@property
def _slug(self) -> str:
title = self.title.lower().replace(' ', '_')
title = [c for c in title if c.isalnum() or c == '_']
return ''.join(title)
def main():
with open(LANGUAGES_FILENAME, 'r') as file:
languages = json.load(file)
parser = ArgumentParser(description='Project Euler problem file generator')
parser.add_argument(
'-p', '--preview',
action='store_true',
help='see a preview of the file without creating it',
)
parser.add_argument(
'language',
metavar='LANGUAGE',
choices=languages,
help='file programming language',
)
parser.add_argument(
'indices',
metavar='INDEX',
nargs='+',
type=int,
help='Project Euler problems index',
)
args = parser.parse_args()
for index in args.indices:
language = languages[args.language]
language['name'] = args.language
problem = Problem(index, language)
problem.fetch()
if not args.preview:
problem.write()
if __name__ == '__main__':
main()
|