= [4, 2, 5] a
FunctionNBProcessor
import os import joblib import warnings from execnb.nbio import read_nb, write_nb, new_nb, mk_cell from nbdev.process import NBProcessor, Processor
import pdb
class FunctionNBProcessor(Processor):
def __init__ (self, cell_processor, debug=False):
self.cell_processor = cell_processor
self.function_idx = 0
self.cell_list = []
self.function_name_to_list_idx = {}
self.debug=debug
#for function in self.cell_processor.cell_nodes:
# function.cell_idx = None
def cell(self, cell):
= '\n**********************************************************************\n'
separator = cell.source.splitlines()
cell_lines if len(cell_lines) > 0 and '%%function' in cell_lines[0]:
if self.debug:
pdb.set_trace()if self.function_idx < len(self.cell_processor.cell_nodes):
= self.cell_processor.cell_nodes[self.function_idx]
this_function = cell.idx_
this_function.cell_idx if this_function.name in self.function_name_to_list_idx:
= self.function_name_to_list_idx[this_function.name]
list_idx self.cell_list[list_idx] = '#| export\n' + this_function.code
else:
= len(self.cell_list)-1
list_idx self.cell_list.append (separator + '#| export\n' + this_function.code)
self.function_name_to_list_idx[this_function.name] = list_idx
self.function_idx += 1
else:
self.cell_list.append (cell.source)
def end(self):
for cell in self.cell_list:
print (cell)
## process_notebook
def process_notebook (cell_processor, debug=False):
= FunctionNBProcessor (cell_processor, debug=debug)
function_processor './nbdev_sync.ipynb', function_processor).process()
NBProcessor (
## simple case: each function is written in a single cell
# This is markdown
#%%function first_function
= 3
a print ('a', a)
# normal code cell
print ('outside', a)
#%%function second_function
= 4
b = a+b
c print (a, b, c)
#cell_processor = %cell_processor
'name'] for function in cell_processor.cell_nodes]
[function[
print ('last cell:', a, b, c)
process_notebook (cell_processor)
## second case: functions are split into different cells
#%%function myf
print ('hello')
= 3
a
#%print myf
myf_info.original_cell
#%%function myf --merge
= 4
b
#%print myf
#%%function myf --merge
= 5
c = a+b+c
d
#%print myf
myf_info.original_cell
process_notebook (cell_processor)
### (TODO) Use only the last cell associated with this function, e.g., by replacing previous cells.
## third case: have defined functions in cells
=4
x
#%%function
def my_defined_function (x, a=3):
print (x)
print (a)
=True)
process_notebook (cell_processor, debug
### (TODO) Debug why the code of last function doesn't appear at all
## end
a
[4, 5, 5]
import pdb
class FunctionNBProcessor(Processor):
def __init__ (
self,
cell_processor,
path_to_notebook,=False
debug
):self.cell_processor = cell_processor
self.function_idx = 0
self.cell_list = []
self.function_name_to_list_idx = {}
self.path_to_src_notebook = path_to_notebook
self.path_to_dst_notebook = path_to_notebook.parent / f'{path_to_notebook.name[:-len(".ipynb")]}_nbdev.ipynb'
self.debug=debug
def cell(self, cell):
= '\n**********************************************************************\n'
separator = cell.source.splitlines()
cell_lines if len(cell_lines) > 0 and '%%function' in cell_lines[0]:
if self.debug:
pdb.set_trace()if self.function_idx < len(self.cell_processor.cell_nodes):
= self.cell_processor.cell_nodes[self.function_idx]
this_function = cell.idx_
this_function.cell_idx = mk_cell ('#| export\n' + this_function.code)
new_cell if this_function.name in self.function_name_to_list_idx:
= self.function_name_to_list_idx[this_function.name]
list_idx self.cell_list[list_idx] = new_cell
else:
= len(self.cell_list)
list_idx self.cell_list.append (new_cell)
self.function_name_to_list_idx[this_function.name] = list_idx
self.function_idx += 1
else:
self.cell_list.append (mk_cell(cell.source, cell_type=cell.cell_type))
def end(self):
= read_nb (self.path_to_src_notebook)
original_nb self.cell_list, meta=original_nb.metadata), self.path_to_dst_notebook) write_nb (new_nb (
process_notebook
def process_notebook (
cell_processor, ='./nbdev_sync.ipynb',
path_to_notebook=False
debug
):=Path(path_to_notebook)
path_to_notebook= FunctionNBProcessor (
function_processor
cell_processor, =path_to_notebook,
path_to_notebook=debug,
debug
) NBProcessor (path_to_notebook, function_processor).process()
simple case: each function is written in a single cell
This is markdown
= 3
a print ('a', a)
a 3
Stored the following local variables in the first_function current_values dictionary: ['a']
# normal code cell
print ('outside', a)
outside 3
= 4
b = a+b
c print (a, b, c)
3 4 7
Stored the following local variables in the second_function current_values dictionary: ['b', 'c']
= %cell_processor cell_processor
'name'] for function in cell_processor.cell_nodes] [function[
['first_function', 'second_function']
print ('last cell:', a, b, c)
last cell: 3 4 7
process_notebook (cell_processor)
second case: functions are split into different cells
print ('hello')
= 3 a
hello
Stored the following local variables in the myf current_values dictionary: ['a']
def myf():
print ('hello')
a = 3
return a
myf_info.original_cell
"print ('hello')\na = 3\n"
= 4 b
Stored the following local variables in the myf current_values dictionary: ['b']
hello
Stored the following local variables in the myf current_values dictionary: ['a', 'b']
def myf():
print ('hello')
a = 3
b = 4
return b,a
= 5
c = a+b+c d
Stored the following local variables in the myf current_values dictionary: ['c', 'd']
hello
Stored the following local variables in the myf current_values dictionary: ['a', 'b', 'c', 'd']
def myf():
print ('hello')
a = 3
b = 4
c = 5
d = a+b+c
return b,d,a,c
myf_info.original_cell
"print ('hello')\na = 3\nb = 4\nc = 5\nd = a+b+c\n"
process_notebook (cell_processor)
(TODO) Use only the last cell associated with this function, e.g., by replacing previous cells.
third case: have defined functions in cells
=4 x
def my_defined_function (x, a=3):
print (x)
print (a)
4
3
Stored the following local variables in the my_defined_function current_values dictionary: []
process_notebook (cell_processor)