Add and improve docstrings, JSON dumping and duplicate removal generalised

This commit is contained in:
Rishabh Raj
2014-04-14 02:25:18 +05:30
parent 6c0a5706c3
commit c9a981445d
+100 -38
View File
@@ -29,13 +29,43 @@ sample = """{
}"""
def remove_continuous_duplicates(code):
""" Remove duplicates of elements appearing consecutively.
Parameters
----------
code : list of str
Returns
-------
modified_code : list of str
Notes
-----
We create a new list and add elements to it which do not have
duplicates appearing consecutively.
One use case here,
'import xyz\n\n\n print 2' becomes 'import xyz\n print 2'
"""
modified_code = []
modified_code = [self.code[i] for i in range(len(self.code)) if i == 0 or self.code[i] != self.code[i-1]]
return modified_code
class Notebook():
"""
Notebook object for generating an IPython notebook
Notebook object for generating an IPython notebook,
from an example Python file.
Parameters
----------
example_file : str
Path for example file.
"""
def __init__(self, sample_notebook_path, example_file):
def __init__(self, example_file):
# Object variables, gives the ability to personalise per object
# cell type code
self.cell_code = {
@@ -59,7 +89,7 @@ class Notebook():
}
self.cell_type = {'input': self.cell_code, 'source': self.cell_md}
self.keys = {'input_code': 'input', 'input_markdown': 'source'}
self.valuetype_to_celltype = {'code': 'input', 'markdown': 'source'}
with open(example_file, 'r') as pythonfile:
self.template = json.loads(sample)
self.code = pythonfile.readlines()
@@ -67,32 +97,64 @@ class Notebook():
# this aids in extraction of text segments
self.code.append('\n')
def fetchkey(self, type_of_value):
""" Returns the key required for insertion into notebook,
based on the type of value.
"""
return self.keys[type_of_value]
def fetch_key(self, type_of_value):
""" Find the key required for insertion into notebook.
def filter_continuous_duplication(self):
""" Clusters multiple '\n's into one.
For ex - 'import xyz\n\n\n print 2' becomes 'import xyz\n print 2' """
modified_code = []
modified_code = [self.code[i] for i in range(len(self.code)) if i == 0 or self.code[i] != self.code[i-1]]
return modified_code
Parameters
----------
type_of_value : str
Type of data, to be inserted in a cell.
Returns
-------
str
Key which reflects what is the cell type.
Notes
-----
type_of_value is either, 'code', which maps to cell of type
code('input') or 'markdown', which maps to cell of type markdown('source').
def addcell(self, segment_number, value, type_of_value='input_code'):
""" Adds a notebook cell, by updating the json template.
Cell differs with type of value.
"""
if type_of_value in ['input_markdown', 'input_code']:
key = self.fetchkey(type_of_value)
return self.valuetype_to_celltype[type_of_value]
def add_cell(self, segment_number, value, type_of_value='code'):
""" Adds a notebook cell.
Parameters
----------
segment_number : int
Newline separated sections in example file, are segments.
Code and markdown written together in such a section are,
treated as different segments. Each cell has content from
one section.
value : str
The actual content to be saved in the cell.
type_of_value : str, optional
The type of content in the segment.
The default value will add a cell of type code.
Notes
-----
The cell is only added in the notebook if the segment is of type,
markdown or code.
"""
if type_of_value in ['markdown', 'code']:
key = self.fetch_key(type_of_value)
self.template["worksheets"][0]["cells"].append(copy.deepcopy(self.cell_type[key]))
self.template["worksheets"][0]["cells"][segment_number][key] = value
def json(self, notebook_path):
""" Writes the template to file (json) """
with open(notebook_path, 'w') as output:
json.dump(self.template, output, indent=2)
def json(self):
""" Dumps the template JSON to string.
Returns
-------
str
The template JSON converted to a string with a two char indent.
"""
return json.dump(self.template, indent=2)
def python_to_notebook(example_file, notebook_dir, notebook_path):
@@ -100,23 +162,22 @@ def python_to_notebook(example_file, notebook_dir, notebook_path):
Parameters
----------
example_file : 'str'
path for source Python file
notebook_dir : 'str'
directory for saving the notebook files
notebook_path : 'str'
path for saving the notebook file (includes the filename)
"""
sample_notebook_path = notebook_dir.pjoin('sample.ipynb')
example_file : str
Path for source Python file.
notebook_dir : str
Directory for saving the notebook files.
notebook_path : str
Path for saving the notebook file (includes the filename).
nb = Notebook(sample_notebook_path, example_file)
"""
nb = Notebook(example_file)
segment_number = 0
segment_has_begun = True
docstring = False
source = []
modified_code = nb.filter_continuous_duplication()
modified_code = remove_continuous_duplicates(nb.code)
for line in modified_code:
# A linebreak indicates a segment has ended.
@@ -127,15 +188,15 @@ def python_to_notebook(example_file, notebook_dir, notebook_path):
segment_number += 1
# we've found text segments within the docstring
if docstring is True:
nb.addcell(segment_number, source, 'input_markdown')
nb.add_cell(segment_number, source, 'markdown')
else:
nb.addcell(segment_number, source, 'input_code')
nb.add_cell(segment_number, source, 'code')
source = []
# if it's a comment
elif line.strip().startswith('#'):
segment_number += 1
line = line.strip(' #')
nb.addcell(segment_number, line, 'input_markdown')
nb.add_cell(segment_number, line, 'markdown')
elif line == '"""\n':
if docstring is False:
docstring = True
@@ -146,10 +207,11 @@ def python_to_notebook(example_file, notebook_dir, notebook_path):
# Write leftover docstring if any left
if source:
segment_number += 1
nb.addcell(segment_number, source, 'input_markdown')
nb.add_cell(segment_number, source, 'markdown')
source = []
else:
# some text segment is continuing, so add to source
source.append(line)
nb.json(notebook_path)
with open(notebook_path, 'w') as output:
output.write(nb.json(notebook_path))