Source code for pycropml.render_notebook

""" License, Header

Use pkglts

Problems:
- name of a model unit?
"""
from __future__ import print_function
from __future__ import absolute_import
from path import Path

# The package used to generate Notebook
import nbformat as nbf

from . import render_python as rp
import six



[docs]class Model2Nb(rp.Model2Package): """ Generate a Jupyter Notebook from a set of models. """ def __init__(self, models, dir=None): """TODO. """ super(Model2Nb, self).__init__(models, dir=dir) self.with_import = False
[docs] def run(self): """TODO. """ self.generate_notebook()
[docs] def generate_notebook(self): """Generate a Python package equivalent to the xml definition. Args: - models : a list of model - dir: the directory where the code is generated. Returns: - None or status """ # Create a directory (mymodel) cwd = Path(self.dir) directory=cwd/'python_notebook' if (directory).isdir() : _dir = directory else: _dir = directory.mkdir() count = 0 files=[] for model in self.models: self.generate_component(model) # In the directory notebook/model.py # TODO: The code need to be generated locally in different methods. nb = nbf.v4.new_notebook() text = """\ # Automatic generation of Notebook using PyCropML This notebook implements a crop model.""" _cells = nb['cells'] = [nbf.v4.new_markdown_cell(text), nbf.v4.new_code_cell(self.code)] # Generate the tests text_test = """\ ## Run the model with a set of parameters. Each run will be defined in its own cell.""" _cells.append(nbf.v4.new_markdown_cell(text_test)) #for model in self.models: code_tests = self.generate_test(model) for code in code_tests: _cells.append(nbf.v4.new_code_cell(code)) ext = '' if count == 0 else str(count) fname =_dir/"test%s.ipynb"%ext #fname = _dir/'test.ipynb' with open(fname, "w") as f: nbf.write(nb, f) files.append(fname) count +=1 return files
[docs] def generate_test(self, model_unit): tab = ' '*4 m = model_unit #name = m.description.Title name = m.name name.strip() name = name.replace(' ', '_').lower() model_name = name psets = m.parametersets code_test=[] for v_tests in m.testsets: test_name = v_tests.name # name of tests test_runs = v_tests.test # different run in the thest test_paramsets = v_tests.parameterset # name of paramsets # map the paramsets params = {} if test_paramsets not in list(psets.keys()): print('Unknow parameter %s'%test_paramsets) else: params.update(psets[test_paramsets].params) for each_run in test_runs : test_codes = [] # make a function that transforms a title into a function name tname = list(each_run.keys())[0].replace(' ', '_') tname = tname.replace('-', '_') (run, inouts) = list(each_run.items())[0] ins = inouts['inputs'] outs = inouts['outputs'] code = "params= %s("%model_name test_codes.append(code) run_param = params.copy() run_param.update(ins) for k, v in six.iteritems(run_param): code = " %s = %s,"%(k,v) test_codes.append(code) code = " )" test_codes.append(code) for j, k in enumerate(m.outputs): if k.datatype in ("STRINGLIST", "DATELIST", "STRINGARRAY", "DATEARRAY") : code = "print('%s_estimated =')"%k.name test_codes.append(code) code = "print(params[%s])"%(j) if len(m.outputs)>1 else "print(params)"%k.name test_codes.append(code) code = "# %s_computed = %s"%(k.name,outs[k.name][0]) test_codes.append(code) if k.datatype in ("STRING", "BOOL", "INT", "DATE"): code = "print('%s_estimated =')"%k.name test_codes.append(code) code = "print(params[%s])"%(j) if len(m.outputs)>1 else "print(params)" test_codes.append(code) code = "# %s_computed = %s"%(k.name,outs[k.name][0]) test_codes.append(code) if k.datatype in ("DOUBLELIST", "DOUBLEARRAY"): code = "print('%s_estimated =')"%k.name test_codes.append(code) code = "print(np.around(params[%s], %s))"%(j,outs[k.name][1]) if len(m.outputs)>1 else "print(np.around(params, %s))"%outs[k.name][1] test_codes.append(code) code = "# %s_computed = %s"%(k.name,outs[k.name][0]) test_codes.append(code) if k.datatype in ("INTLIST", "INTARRAY"): code = "print('%s_estimated =')"%k.name test_codes.append(code) code = "print(params[%s])"%(j) if len(m.outputs)>1 else "print(params)" test_codes.append(code) code = "# %s_computed = %s"%(k.name,outs[k.name][0]) test_codes.append(code) if k.datatype == "DOUBLE": code = "print('%s_estimated =')"%k.name test_codes.append(code) code = "print(round(params[%s], %s))"%(j,outs[k.name][1]) if len(m.outputs)>1 else "print(round(params, %s))"%outs[k.name][1] test_codes.append(code) code = "# %s_computed = %s"%(k.name,outs[k.name][0]) test_codes.append(code) code = '\n'.join(test_codes) code_test.append(code) return code_test