a = [4, 2, 5]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):
separator = '\n**********************************************************************\n'
cell_lines = cell.source.splitlines()
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):
this_function = self.cell_processor.cell_nodes[self.function_idx]
this_function.cell_idx = cell.idx_
if this_function.name in self.function_name_to_list_idx:
list_idx = self.function_name_to_list_idx[this_function.name]
self.cell_list[list_idx] = '#| export\n' + this_function.code
else:
list_idx = len(self.cell_list)-1
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):
function_processor = FunctionNBProcessor (cell_processor, debug=debug)
NBProcessor ('./nbdev_sync.ipynb', function_processor).process()
## simple case: each function is written in a single cell
# This is markdown
#%%function first_function
a = 3
print ('a', a)
# normal code cell
print ('outside', a)
#%%function second_function
b = 4
c = a+b
print (a, b, c)
#cell_processor = %cell_processor
[function['name'] for function in cell_processor.cell_nodes]
print ('last cell:', a, b, c)
process_notebook (cell_processor)
## second case: functions are split into different cells
#%%function myf
print ('hello')
a = 3
#%print myf
myf_info.original_cell
#%%function myf --merge
b = 4
#%print myf
#%%function myf --merge
c = 5
d = a+b+c
#%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
x=4
#%%function
def my_defined_function (x, a=3):
print (x)
print (a)
process_notebook (cell_processor, debug=True)
### (TODO) Debug why the code of last function doesn't appear at all
## enda[4, 5, 5]
import pdb
class FunctionNBProcessor(Processor):
def __init__ (
self,
cell_processor,
path_to_notebook,
debug=False
):
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):
separator = '\n**********************************************************************\n'
cell_lines = cell.source.splitlines()
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):
this_function = self.cell_processor.cell_nodes[self.function_idx]
this_function.cell_idx = cell.idx_
new_cell = mk_cell ('#| export\n' + this_function.code)
if this_function.name in self.function_name_to_list_idx:
list_idx = self.function_name_to_list_idx[this_function.name]
self.cell_list[list_idx] = new_cell
else:
list_idx = len(self.cell_list)
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):
original_nb = read_nb (self.path_to_src_notebook)
write_nb (new_nb (self.cell_list, meta=original_nb.metadata), self.path_to_dst_notebook)process_notebook
def process_notebook (
cell_processor,
path_to_notebook='./nbdev_sync.ipynb',
debug=False
):
path_to_notebook=Path(path_to_notebook)
function_processor = FunctionNBProcessor (
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
a = 3
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
b = 4
c = a+b
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[function['name'] for function in cell_processor.cell_nodes]['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')
a = 3hello
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"
b = 4Stored 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
c = 5
d = a+b+cStored 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
x=4def 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)