Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# -*- coding: utf-8 -*-
2"""
3@file
4@brief Some automation helpers to test notebooks and check they are still working fine.
5"""
6import os
7from pyquickhelper.loghelper import noLOG
8from pyquickhelper.ipythonhelper import execute_notebook_list
9import pyensae
12def ls_notebooks(subfolder):
13 """
14 Lists the notebooks in a particular subfolder.
16 @param subfolder subfolder (related to this module)
17 @return list of files
18 """
19 this = os.path.abspath(os.path.dirname(__file__))
20 docnote = os.path.join(
21 this,
22 "..",
23 "..",
24 "..",
25 "_doc",
26 "notebooks",
27 subfolder)
28 notes = [
29 os.path.normpath(
30 os.path.join(
31 docnote,
32 _)) for _ in os.listdir(docnote)]
34 keepnote = []
35 for note in notes:
36 ext = os.path.splitext(note)[-1]
37 if ext != ".ipynb":
38 continue
39 keepnote.append(note)
40 return keepnote
43def get_additional_paths():
44 """
45 Returns a list of paths to add before running the notebooks,
46 paths to :epkg:`pyquickhelper`, :epkg:`pyensae`.
48 @return list of paths
49 """
50 import pyquickhelper
51 import jyquickhelper
52 addpath = [os.path.dirname(pyquickhelper.__file__),
53 os.path.dirname(pyensae.__file__),
54 os.path.dirname(jyquickhelper.__file__),
55 os.path.join(os.path.abspath(os.path.dirname(__file__)), ".."),
56 ]
57 addpath = [os.path.normpath(os.path.join(_, "..")) for _ in addpath]
58 return addpath
61def clean_function_notebook(code):
62 """
63 Cleans cells when unittesting notebooks.
65 @param code cell content
66 @return modified code
67 """
68 code = code.replace(
69 'run_cmd("exemple.xlsx"',
70 'skip_run_cmd("exemple.xlsx"')
72 skip = ["faire une chose avec la probabilité 0.7",
73 "# déclenche une exception",
74 "# pour lancer Excel",
75 "for k in list_exercice_1 :",
76 "return ....",
77 "return [ .... ]",
78 "def __init__(self, ...) :",
79 "if random.random() <= 0.7 :",
80 "dictionnaire_depart.items() [0]",
81 "iterateur(0,10) [0]",
82 "# ...... à remplir",
83 'String.Join(",", a.Select(c=>c.ToString()).ToArray())',
84 "# elle n'existe pas encore",
85 "from ggplot import *",
86 # ggplot calls method show and it opens window blocking the offline
87 # execution
88 ]
89 rep = [("# ...", "pass # "),
90 ("%timeit", "#%timeit"),
91 ]
92 spl = ["# ......",
93 "# elle n'existe pas encore",
94 ]
96 for s in skip:
97 if s in code:
98 return ""
100 for s in spl:
101 if s in code:
102 code = code.split(s)[0]
104 for s in rep:
105 code = code.replace(s[0], s[1])
107 return code
110def execute_notebooks(folder, notebooks, filter, # pylint: disable= W0622
111 clean_function=None,
112 fLOG=noLOG,
113 deepfLOG=noLOG,
114 valid_cell=None):
115 """
116 Executes a list of notebooks.
118 @param folder folder
119 @param notebooks list of notebooks
120 @param filter function which validate the notebooks
121 @param clean_function cleaning function to apply to the code before running it
122 @param fLOG logging function
123 @param deepfLOG logging function used to run the notebook
124 @param valid_cell to disable the execution of a cell
125 @return dictionary tuple (statistics, { notebook_file: (isSuccess, outout) })
127 The signature of function ``filter`` is::
129 def filter( i, filename) : return True or False
130 """
132 def _valid_cell(cell):
133 if valid_cell is not None:
134 if not valid_cell(cell):
135 return False
136 if "%system" in cell:
137 return False
138 if "df.plot(...)" in cell:
139 return False
140 if 'df["difference"] = ...' in cell:
141 return False
142 if 'print(next(it))' in cell:
143 return False
144 return True
146 addpaths = get_additional_paths()
147 if filter:
148 notebooks = [_ for i, _ in enumerate(notebooks) if filter(i, _)]
149 if len(notebooks) == 0:
150 raise ValueError("Empty list of notebooks.")
151 return execute_notebook_list(
152 folder, notebooks, fLOG=fLOG, valid=_valid_cell, additional_path=addpaths)