diff options
| author | Charles Cabergs <me@cacharle.xyz> | 2021-06-18 20:17:07 +0200 |
|---|---|---|
| committer | Charles Cabergs <me@cacharle.xyz> | 2021-06-18 20:17:07 +0200 |
| commit | c0aeed4578bdaea39ddbed1b55896948f56b23f3 (patch) | |
| tree | e3959fe7472c63eab19bab0c81c72e60ae5f6c55 /generate | |
| parent | 815fbb2a697a060411f19f70ecdaa5c775b430cb (diff) | |
| download | project_euler-c0aeed4578bdaea39ddbed1b55896948f56b23f3.tar.gz project_euler-c0aeed4578bdaea39ddbed1b55896948f56b23f3.tar.bz2 project_euler-c0aeed4578bdaea39ddbed1b55896948f56b23f3.zip | |
Refactored generate script
Diffstat (limited to 'generate')
| -rwxr-xr-x | generate | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/generate b/generate new file mode 100755 index 0000000..fef0aed --- /dev/null +++ b/generate @@ -0,0 +1,94 @@ +#!/usr/bin/env python3 + +import json +import itertools +import textwrap +from pathlib import Path +from argparse import ArgumentParser + +import requests +from bs4 import BeautifulSoup + + +LANGUAGES_FILENAME = '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 = Path(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( + '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(index, language).fetch().write() + + +if __name__ == '__main__': + main() |
