Add actions (#4)

This commit is contained in:
yakimka
2022-01-18 20:47:53 +02:00
committed by GitHub
parent 72d41d776d
commit abf4c58c3a
6 changed files with 173 additions and 10 deletions

36
.github/workflows/ci-workflow.yml vendored Normal file
View File

@@ -0,0 +1,36 @@
name: Checks workflow
on: ['push', 'pull_request']
jobs:
check-toc:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Run
run: make toc-check
release:
needs: check-toc
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Create epub
uses: docker://pandoc/core:2.14
with:
args: --toc --toc-depth=6 -o questions.epub metadata.txt questions.md
- name: Get TAG
if: startsWith(github.ref, 'refs/tags/')
run: echo "TAG=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV
- name: Write build number
if: startsWith(github.ref, 'refs/tags/')
run: sed -i "s/build 1/$TAG/g" metadata.txt
- name: Test
run: cat metadata.txt
- name: Release
if: startsWith(github.ref, 'refs/tags/')
uses: softprops/action-gh-release@v1
with:
files: questions.epub

View File

@@ -1,2 +1,10 @@
questions.epub: questions.md metadata.txt book_res/* attachments/* Makefile ## Generate epub book
pandoc --toc --toc-depth=6 -o questions.epub metadata.txt questions.md
.PHONY: toc
toc: ## Generate TOC from questions.md
python3 generate_toc.py
.PHONY: toc
toc-check: ## Check that toc is actual
python3 generate_toc.py --check

View File

@@ -25,7 +25,10 @@
### Нашел ошибку/опечатку/бред в ответах или хочу добавить еще вопросов
Молодец, создавай PR. Не забудь добавить себя в [contributors.md](contributors.md)
Молодец, создавай PR.
- После того как что-то изменил в [questions.md](questions.md) запусти `make toc` чтобы обновить [Список вопросов](#Список-вопросов)
- Не забудь добавить себя в [metadata.txt](metadata.txt) в раздел `author`
### Не хочу читать в Markdown, хочу читать в электронной книге
@@ -60,7 +63,7 @@
+ [Что возвращает метод items](questions.md/#Что-возвращает-метод-items)
+ [Как отсортировать список словарей по определенному полю](questions.md/#Как-отсортировать-список-словарей-по-определенному-полю)
+ [Что может являться ключом словаря. Что не может. Почему](questions.md/#Что-может-являться-ключом-словаря-Что-не-может-Почему)
+ [Есть два списка ключи и значения. Как составить из них словарь](questions.md/#Есть-два-списка--ключи-и-значения-Как-составить-из-них-словарь)
+ [Есть два списка ключи и значения. Как составить из них словарь](questions.md/#Есть-два-списка--ключи-и-значения-Как-составить-из-них-словарь)
+ [Как работает хэш-таблица](questions.md/#Как-работает-хэш-таблица)
+ [Что такое коллизия](questions.md/#Что-такое-коллизия)
+ [Где будет быстрее поиск, а где перебор и почему: dict, list, set, tuple](questions.md/#Где-будет-быстрее-поиск-а-где-перебор-и-почему-dict-list-set-tuple)
@@ -183,7 +186,7 @@
+ [В чем отличие тредов от мультипроцессинга](questions.md/#В-чем-отличие-тредов-от-мультипроцессинга)
+ [Какие задачи хорошо параллелятся, какие плохо](questions.md/#Какие-задачи-хорошо-параллелятся-какие-плохо)
+ [Нужно посчитать 100 уравнений. Делать это в тредах или нет](questions.md/#Нужно-посчитать-100-уравнений-Делать-это-в-тредах-или-нет)
+ [Треды в Питоне — это нативные треды или нет](questions.md/#Треды-в-Питоне-это-нативные-треды-или-нет)
+ [Треды в Питоне — это нативные треды или нет](questions.md/#Треды-в-Питоне--это-нативные-треды-или-нет)
+ [Что такое гринлеты. Общее понятие. Примеры реализаций](questions.md/#Что-такое-гринлеты-Общее-понятие-Примеры-реализаций)
* [Какие варианты реализации шаблона Singleton на питоне](questions.md/#Какие-варианты-реализации-шаблона-Singleton-на-питоне)
* [Какие вы знаете инструменты для проверки кодстайл](questions.md/#Какие-вы-знаете-инструменты-для-проверки-кодстайл)
@@ -199,7 +202,7 @@
* [Опишите алгоритм работы CSRF middleware](questions.md/#Опишите-алгоритм-работы-CSRF-middleware)
* [Что такое сигналы? Зачем нужны? Назовите основные](questions.md/#Что-такое-сигналы-Зачем-нужны-Назовите-основные)
* [Как реализуется связь m2m на уровне базы данных](questions.md/#Как-реализуется-связь-m2m-на-уровне-базы-данных)
* [Чем лучше отправлять форму — GET или POST](questions.md/#Чем-лучше-отправлять-форму--GET-или-POST)
* [Чем лучше отправлять форму — GET или POST](questions.md/#Чем-лучше-отправлять-форму--GET-или-POST)
* [Как работает Serializer в Django REST Framework](questions.md/#Как-работает-Serializer-в-Django-REST-Framework)
* [Что такое Meta в классах Django и для чего нужен](questions.md/#Что-такое-Meta-в-классах-Django-и-для-чего-нужен)
* [За что отвечает Meta в сериализаторе](questions.md/#За-что-отвечает-Meta-в-сериализаторе)
@@ -232,7 +235,7 @@
+ [Наследование](questions.md/#Наследование)
+ [Полиморфизм](questions.md/#Полиморфизм)
+ [Абстракция](questions.md/#Абстракция)
* [Какие принципы программирования вы знаете](questions.md/#Какиe-принципы-программирования-вы-знаете)
* [Какие принципы программирования вы знаете](questions.md/#Какие-принципы-программирования-вы-знаете)
+ [KISS](questions.md/#KISS)
+ [DRY](questions.md/#DRY)
+ [YAGNI](questions.md/#YAGNI)

View File

@@ -1,2 +0,0 @@
- yakimka: https://github.com/yakimka
- pavlenk0: https://github.com/pavlenk0

118
generate_toc.py Normal file
View File

@@ -0,0 +1,118 @@
import dataclasses
import re
import sys
from typing import List
@dataclasses.dataclass()
class Header:
name: str
level: int
@property
def slug(self):
text = self.name.replace(' ', '-')
# single chars that are removed
text = re.sub(r'[`~!@#$%^&*()+=<>?,./:;"\'|{}\[\]\\–—]', '', text)
# CJK punctuations that are removed
text = re.sub(r'[ 。?!,、;:“”【】()〔〕[]﹃﹄“”‘’﹁﹂—…-~《》〈〉「」]', '', text)
return text
class TOCMaker:
def __init__(
self,
*,
max_depth=6,
link_prefix='',
indentation_size=2,
list_bullets=('-', '*', '+', '-'),
header_class=Header,
):
self.max_depth = max_depth
self.link_prefix = link_prefix
self.indentation_size = indentation_size
self.list_bullets = list_bullets
self.header_class = header_class
def make(self, text):
headers = self._collect_headers(text)
return self._make_toc(headers)
def make_from_file(self, fp):
return self.make(fp.read())
def _collect_headers(self, text):
headers = []
code_blocks = 0
for line in text.splitlines():
line = line.strip()
code_blocks += line.count('```') % 2
if code_blocks % 2 == 0 and line.startswith('#'):
header = self._parse_header_from_line(line)
if header.level <= self.max_depth:
headers.append(self._parse_header_from_line(line))
return headers
def _make_toc(self, headers: List[Header]):
toc = []
for header in headers:
indentation = ' ' * ((header.level - 1) * self.indentation_size)
bullet = self._get_bullet(header.level)
toc.append(f'{indentation}{bullet} [{header.name}]({self.link_prefix}#{header.slug})')
return '\n'.join(toc)
def _get_bullet(self, level):
if level > len(self.list_bullets):
return self.list_bullets[-1]
return self.list_bullets[level - 1]
def _parse_header_from_line(self, line):
level = 0
name = ''
for char in line:
if char == '#':
level += 1
else:
name = line[level + 1:].strip()
break
return self.header_class(
name=name,
level=level
)
def paste_after(delimiter, content, text):
result = []
for line in text.splitlines():
if line.strip() != delimiter:
result.append(line)
else:
result.append(f'{delimiter}\n')
result.append(f'{content}\n')
return '\n'.join(result)
raise ValueError(f"Can't find delimiter '{delimiter}'")
if __name__ == '__main__':
with open('questions.md') as fp:
maker = TOCMaker(link_prefix='questions.md/')
toc = maker.make_from_file(fp)
with open('README.md', 'r') as fp:
original = fp.read()
changed = paste_after('<!-- toc -->', toc, original)
if '--check' in sys.argv:
if original != changed:
print('Error')
sys.exit(1)
else:
with open('README.md', 'w') as fp:
fp.write(changed)
print('Done')

View File

@@ -4,9 +4,9 @@ title:
text: Вопросы для подготовки к Python Developer интервью
- type: edition
text: build 1
creator:
- role: author
text: yakimka
author:
- yakimka <https://github.com/yakimka>
- pavlenk0 <https://github.com/pavlenk0>
toc-title: Содержание
language: ru-RU
stylesheet: book_res/style.css