2023-10-18 00:19:10 +01:00
|
|
|
import nbformat
|
|
|
|
import re
|
|
|
|
import sys
|
|
|
|
|
|
|
|
sessions = ['']
|
|
|
|
|
|
|
|
FIRST_CELL = '''############## PLEASE RUN THIS CELL FIRST! ###################
|
|
|
|
|
|
|
|
# import everything and define a test runner function
|
|
|
|
from importlib import reload
|
|
|
|
from helper import run
|
|
|
|
'''
|
|
|
|
|
|
|
|
UNITTEST_TEMPLATE_1 = '''### Exercise {exercise_number}
|
|
|
|
|
|
|
|
{instructions}
|
|
|
|
|
|
|
|
#### Make [this test](/edit/{path}/{module}.py) pass: `{module}.py:{test_suite}:{test}`'''
|
|
|
|
|
|
|
|
|
|
|
|
UNITTEST_TEMPLATE_2 = '''# Exercise {exercise_number}
|
|
|
|
|
|
|
|
reload({module})
|
|
|
|
run({module}.{test_suite}('{test}'))'''
|
|
|
|
|
|
|
|
|
|
|
|
EXERCISE_TEMPLATE_1 = '''### Exercise {exercise_number}
|
|
|
|
{instructions}'''
|
|
|
|
|
|
|
|
|
|
|
|
EXERCISE_TEMPLATE_2 = '''# Exercise {exercise_number}
|
|
|
|
|
|
|
|
{code}'''
|
|
|
|
|
|
|
|
|
|
|
|
for session in sessions:
|
|
|
|
notebook = nbformat.v4.new_notebook()
|
|
|
|
notebook_complete = nbformat.v4.new_notebook()
|
|
|
|
cells = notebook['cells']
|
|
|
|
cells_complete = notebook_complete['cells']
|
|
|
|
path = 'session{}'.format(session)
|
2023-10-18 12:06:07 +01:00
|
|
|
with open('{}/complete/answers.py'.format(path), 'r') as f:
|
2023-10-18 00:19:10 +01:00
|
|
|
current = ''
|
|
|
|
cell_type = None
|
|
|
|
exercise_number = 1
|
|
|
|
for l in f:
|
|
|
|
line = l.strip()
|
|
|
|
if line in ('#markdown', '#code', '#exercise', '#unittest'):
|
|
|
|
cell_type = line[1:]
|
|
|
|
elif line == '#end{}'.format(cell_type):
|
|
|
|
if cell_type == 'markdown':
|
|
|
|
markdown_cell = nbformat.v4.new_markdown_cell(current)
|
|
|
|
markdown_cell.metadata['slideshow'] = dict(slide_type='slide')
|
|
|
|
cells.append(markdown_cell)
|
|
|
|
cells_complete.append(markdown_cell)
|
|
|
|
elif cell_type == 'code':
|
|
|
|
# only take >>> or ... lines
|
|
|
|
lines = []
|
|
|
|
for line in current.split('\n'):
|
|
|
|
if line.startswith('>>> ') or line.startswith('... '):
|
|
|
|
line = re.sub(r'\\\\x', r'\\x', line)
|
|
|
|
lines.append(line[4:])
|
|
|
|
if lines[0].startswith('import '):
|
|
|
|
code = FIRST_CELL + '\n'.join(lines)
|
|
|
|
slide_type = 'skip'
|
|
|
|
else:
|
|
|
|
code = '\n'.join(lines)
|
|
|
|
slide_type = 'slide'
|
|
|
|
code_cell = nbformat.v4.new_code_cell(code)
|
|
|
|
code_cell.metadata['slideshow'] = dict(slide_type=slide_type)
|
|
|
|
cells.append(code_cell)
|
|
|
|
cells_complete.append(code_cell)
|
|
|
|
elif cell_type == 'exercise':
|
|
|
|
instructions, code = current.split('---')
|
|
|
|
markdown = EXERCISE_TEMPLATE_1.format(
|
|
|
|
exercise_number=exercise_number,
|
|
|
|
instructions=instructions,
|
|
|
|
)
|
|
|
|
markdown_cell = nbformat.v4.new_markdown_cell(markdown)
|
|
|
|
markdown_cell.metadata['slideshow'] = dict(slide_type='slide')
|
|
|
|
cells.append(markdown_cell)
|
|
|
|
cells_complete.append(markdown_cell)
|
|
|
|
lines = []
|
|
|
|
lines_complete = []
|
|
|
|
for line in code.split('\n'):
|
|
|
|
if line.startswith('>>> ') or line.startswith('... '):
|
|
|
|
line = re.sub(r'\\\\x', r'\\x', line)
|
|
|
|
start_alt = line.find(' #/')
|
|
|
|
if start_alt == -1:
|
|
|
|
lines.append(line[4:])
|
|
|
|
lines_complete.append(line[4:])
|
|
|
|
else:
|
|
|
|
lines.append(line[start_alt+4:])
|
|
|
|
lines_complete.append(line[4:start_alt])
|
|
|
|
code_1 = EXERCISE_TEMPLATE_2.format(
|
|
|
|
code='\n'.join(lines),
|
|
|
|
exercise_number=exercise_number,
|
|
|
|
)
|
|
|
|
code_cell_1 = nbformat.v4.new_code_cell(code_1)
|
|
|
|
cells.append(code_cell_1)
|
|
|
|
code_2 = EXERCISE_TEMPLATE_2.format(
|
|
|
|
code='\n'.join(lines_complete),
|
|
|
|
exercise_number=exercise_number,
|
|
|
|
)
|
|
|
|
code_cell_2 = nbformat.v4.new_code_cell(code_2)
|
|
|
|
cells_complete.append(code_cell_2)
|
|
|
|
exercise_number += 1
|
|
|
|
elif cell_type == 'unittest':
|
|
|
|
module, test_suite, test, instructions = current.split(':', 3)
|
|
|
|
markdown = UNITTEST_TEMPLATE_1.format(
|
|
|
|
exercise_number=exercise_number,
|
|
|
|
instructions=instructions,
|
|
|
|
module=module,
|
|
|
|
path=path,
|
|
|
|
test=test,
|
|
|
|
test_suite=test_suite,
|
|
|
|
)
|
|
|
|
markdown_cell = nbformat.v4.new_markdown_cell(markdown)
|
|
|
|
markdown_cell.metadata['slideshow'] = dict(slide_type='slide')
|
|
|
|
cells.append(markdown_cell)
|
|
|
|
cells_complete.append(markdown_cell)
|
|
|
|
code = UNITTEST_TEMPLATE_2.format(
|
|
|
|
exercise_number=exercise_number,
|
|
|
|
module=module,
|
|
|
|
path=path,
|
|
|
|
test=test,
|
|
|
|
test_suite=test_suite,
|
|
|
|
)
|
|
|
|
code_cell = nbformat.v4.new_code_cell(code)
|
|
|
|
cells.append(code_cell)
|
|
|
|
cells_complete.append(code_cell)
|
|
|
|
exercise_number += 1
|
|
|
|
current = ''
|
|
|
|
cell_type = None
|
|
|
|
elif cell_type:
|
|
|
|
if cell_type == 'markdown':
|
|
|
|
current += l
|
|
|
|
else:
|
|
|
|
current += line + '\n'
|
|
|
|
nbformat.write(notebook, '{}/session{}.ipynb'.format(path, session))
|
|
|
|
nbformat.write(notebook_complete, '{}/complete/session{}.ipynb'.format(path, session))
|