forked from IngoScholtes/eurocss2019-tutorial
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathipynb2py.py
136 lines (123 loc) · 6.28 KB
/
ipynb2py.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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#%%
import json
def remove_code(ipynb_file, output_file):
print('Removing code from ipynb file ...')
with open(ipynb_file, 'r') as f:
notebook = json.load(f)
for cell in notebook['cells']:
if cell['cell_type'] == 'code':
cell['source'] = []
cell['outputs'] = []
with open(output_file, 'w') as f:
json.dump(notebook, f)
print('Done.')
def extract_code(ipynb_file, output_file=None):
"""
Converts an ipython notebook file to a plain .py file that
only contains the code cells. Nice to use as a template for
generating the live solution.
Parameters:
-----------
ipynb_file: str
filename of ipynb jupyter notebook file
output_file: str
where to store the .py output file
blank_code: bool
if True, this will generate blank code cells, resulting in
files that can be used as exercise skeletons. If False (default),
all code cells will be populated with actual code.
todo_msg: str
A string text by which code cells will be replaced if blank_code
is set to True. If set to None, no todo message will be created.
"""
print('Converting ipynb file ...')
output = ''
with open(ipynb_file, 'r') as f:
notebook = json.load(f)
for cell in notebook['cells']:
if cell['cell_type'] == 'code':
cell_output = '#%% In [' + str(cell['execution_count']) + ']\n'
for line in cell['source']:
# remap relative path data directory from jupyter notebook to VS Code
cell_output += line.replace('../', '')
cell_output += '\n\n'
output += cell_output
with open(output_file, 'w') as f:
f.write(output)
print('Done.')
def convert(ipynb_file, output_file=None, blank_code = False, todo_msg = '# TODO: Fill code here'):
"""
Converts an ipython notebook file to a plain .py file that
can be used with the jupyter extension in Visual Studio Code.
Markdown cells in the notebook will be output properly formatted
in the VS Code Results panel.
Parameters:
-----------
ipynb_file: str
filename of ipynb jupyter notebook file
output_file: str
where to store the .py output file
blank_code: bool
if True, this will generate blank code cells, resulting in
files that can be used as exercise skeletons. If False (default),
all code cells will be populated with actual code.
todo_msg: str
A string text by which code cells will be replaced if blank_code
is set to True. If set to None, no todo message will be created.
"""
print('Converting ipynb file {} to {} ...'.format(ipynb_file, output_file))
output = '#%%\nimport markdown\n' \
'from IPython.core.display import display, HTML\n'\
'def md(str):\n'\
' display(HTML(markdown.markdown(str + "<br />")))\n\n'
with open(ipynb_file, 'r') as f:
notebook = json.load(f)
for cell in notebook['cells']:
if cell['cell_type'] == 'markdown':
cell_output = '#%%\nmd("""\n'
for line in cell['source']:
cell_output += line
cell_output += '\n""")\n\n'
output += cell_output
elif cell['cell_type'] == 'code':
cell_output = '#%% In [' + str(cell['execution_count']) + ']\n'
if not blank_code or cell['source'][0].startswith('%NOREMOVE'):
for line in cell['source']:
# remap relative path data directory from jupyter notebook to VS Code
cell_output += line.replace('../', '').replace('from state_lumping_network', 'from solutions.state_lumping_network')
elif todo_msg is not None:
cell_output += todo_msg + '\n'
cell_output += '\n\n'
output += cell_output
with open(output_file, 'w') as f:
f.write(output)
print('Done.')
# To apply the script to the sample solutions, just execute the following cells:
#%% Unit 2
#convert('code/2_pathpy.ipynb', 'code/2_pathpy_.py', blank_code=True, todo_msg=None)
extract_code('code/2_pathpy.ipynb', 'code/2_pathpy_code.py')
#remove_code('solutions/2_pathpy.ipynb', 'code/2_pathpy.ipynb')
convert('code/2_pathpy.ipynb', 'code/2_pathpy.py', blank_code=False, todo_msg=None)
#%% Unit 3
#convert('solutions/3_higher_order.ipynb', 'code/3_higher_order.py', blank_code=True, todo_msg=None)
extract_code('code/3_higher_order.ipynb', 'code/3_higher_order_code.py')
#remove_code('solutions/3_higher_order.ipynb', 'code/3_higher_order.ipynb')
convert('code/3_higher_order.ipynb', 'code/3_higher_order.py', blank_code=False, todo_msg=None)
#%% Unit 4
#convert('solutions/4_temporal_networks.ipynb', 'code/4_temporal_networks.py', blank_code=True, todo_msg=None)
extract_code('code/4_temporal_networks.ipynb', 'code/4_temporal_networks_code.py')
#remove_code('solutions/4_temporal_networks.ipynb', 'code/4_temporal_networks.ipynb')
convert('code/4_temporal_networks.ipynb', 'code/4_temporal_networks.py', blank_code=False, todo_msg=None)
#%% Unit 5
#convert('solutions/6_multi_order.ipynb', 'code/6_multi_order.py', blank_code=True, todo_msg=None)
extract_code('code/5_multi_order.ipynb', 'code/5_multi_order_code.py')
#remove_code('solutions/6_multi_order.ipynb', 'code/6_multi_order.ipynb')
convert('code/5_multi_order.ipynb', 'code/5_multi_order.py', blank_code=False, todo_msg=None)
#%% Unit 6
#convert('solutions/7_optimal_analysis.ipynb', 'code/7_optimal_analysis.py', blank_code=True, todo_msg=None)
extract_code('code/6_optimal_analysis.ipynb', 'code/6_optimal_analysis_code.py')
#remove_code('solutions/7_optimal_analysis.ipynb', 'code/7_optimal_analysis.ipynb')
convert('code/6_optimal_analysis.ipynb', 'code/6_optimal_analysis.py', blank_code=False, todo_msg=None)
#%% Unit 7
convert('code/7_exploration.ipynb', 'code/7_exploration.py', blank_code=False, todo_msg=None)
extract_code('code/7_exploration.ipynb', 'code/7_exploration_code.py')