import json from collections import namedtuple import re def cell_downgrade(cell, language): "Attempts to convert a dev 3 cell to version 2.3" d_graded = {} # create downgraded cell dictionary source = cell['source'] if cell['cell_type'] != "code": # Check to see if it should be a heading if cell['cell_type'] == "markdown": try: pat = re.compile('#+') line = source[0] result = pat.match(line) if result != None: level = result.span()[1] line = line[level:] line = line.strip() if len(source)==1: d_graded['cell_type'] = "heading" d_graded['level'] = level source[0] = line d_graded['metadata'] = {} else: d_graded['cell_type'] = "markdown" else: d_graded['cell_type'] = "markdown" except: d_graded['cell_type'] = "markdown" else: d_graded['cell_type'] = cell['cell_type'] d_graded['source'] = source else: d_graded['cell_type'] = "code" d_graded['input'] = source d_graded['language'] = language outputs = [] try: for output in cell['outputs']: out_dict = {} for key, item in output.items(): if key == 'name': out_dict['stream'] = item else: out_dict[key] = item outputs.append(out_dict) d_graded['outputs'] = outputs except: pass try: if cell['execution_count'] != None: prompt = cell['execution_count'] d_graded['prompt_number'] = prompt except: pass # Convert cell metadata try: m_data = {} for key, item in cell['metadata'].items(): if key == 'collapsed': # Headings do not have a value for 'collapsed' if d_graded['cell_type'] != "heading": d_graded[key] = item continue else: m_data[key] = item d_graded['metadata'] = m_data except: print("Error with cell metadata:") key = 'metadata' m_data = cell.__getitem__(key) if cell.__contains__(key) else None print(m_data) pass return d_graded def meta_downgrade(metadata): d_meta = {} d_meta['signature'] = metadata['signature'] try: d_meta['celltoolbar'] = metadata['celltoolbar'] except: pass d_meta['name'] = '' language = metadata['language_info']['name'] Meta = namedtuple('Meta','metadata language') output = Meta(d_meta,language) return output def downgrade(notebook): d_grade = {} d_grade['nbformat'] = 3 d_grade['nbformat_minor'] = notebook['nbformat_minor'] m_d_grade = meta_downgrade(notebook['metadata']) d_grade['metadata'] = m_d_grade.metadata language = m_d_grade.language cells = [] for cell in notebook['cells']: d_cell = cell_downgrade(cell,language) cells.append(d_cell) d_grade['worksheets'] = [{'cells':cells, 'metadata':{}}] return d_grade def convert2old(filename): "Trys to convert a Dev 3 version of an IPython Notebook to version 2.3" with open(filename,'r') as f: json_data = json.load(f) d_graded = downgrade(json_data) name = filename.strip('.ipynb') outputname = name + "_downgraded.ipynb" # print(pr.pformat(d_graded)) with open(outputname,'w') as f: json.dump(d_graded, f, indent=1, sort_keys=True) print("Downgrade complete.") convert2old("EMPTY_3.ipynb") # convert2old("Examples.ipynb")