fable-pyculator 0.1.0a1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fable_pyculator/__init__.py +92 -0
- fable_pyculator/controls.py +87 -0
- fable_pyculator/discovery.py +618 -0
- fable_pyculator/notebook.py +180 -0
- fable_pyculator/spec.py +387 -0
- fable_pyculator/surface.py +491 -0
- fable_pyculator-0.1.0a1.dist-info/METADATA +267 -0
- fable_pyculator-0.1.0a1.dist-info/RECORD +11 -0
- fable_pyculator-0.1.0a1.dist-info/WHEEL +5 -0
- fable_pyculator-0.1.0a1.dist-info/licenses/LICENSE +22 -0
- fable_pyculator-0.1.0a1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"""FABLE Calculator-specific notebook helpers for Modelwright-generated models."""
|
|
2
|
+
|
|
3
|
+
from fable_pyculator.discovery import (
|
|
4
|
+
curate_default_headline_series,
|
|
5
|
+
discover_output_tables,
|
|
6
|
+
discover_scenario_parameters,
|
|
7
|
+
discover_scenario_definition_tables,
|
|
8
|
+
discover_selection_controls,
|
|
9
|
+
)
|
|
10
|
+
from fable_pyculator.spec import (
|
|
11
|
+
FABLE_OUTPUT_SURFACE_SHEETS,
|
|
12
|
+
FableCalculatorSpec,
|
|
13
|
+
HeadlinePoint,
|
|
14
|
+
HeadlineSeries,
|
|
15
|
+
OutputIndicator,
|
|
16
|
+
OutputTable,
|
|
17
|
+
ScenarioDefinitionTable,
|
|
18
|
+
ScenarioParameter,
|
|
19
|
+
SelectionControl,
|
|
20
|
+
SelectionOption,
|
|
21
|
+
)
|
|
22
|
+
from fable_pyculator.controls import ScenarioControlSurface
|
|
23
|
+
from fable_pyculator.notebook import (
|
|
24
|
+
DEFAULT_2020_GENERATED_MODEL_PATH,
|
|
25
|
+
DEFAULT_2020_WORKBOOK_PATH,
|
|
26
|
+
DEFAULT_HEADLINE_SERIES,
|
|
27
|
+
DEFAULT_OUTPUT_TABLES,
|
|
28
|
+
NotebookLoopResult,
|
|
29
|
+
build_2020_notebook_spec,
|
|
30
|
+
load_generated_model,
|
|
31
|
+
run_2020_notebook_loop,
|
|
32
|
+
run_notebook_loop,
|
|
33
|
+
)
|
|
34
|
+
from fable_pyculator.surface import (
|
|
35
|
+
ScenarioRun,
|
|
36
|
+
headline_frame,
|
|
37
|
+
headline_frames,
|
|
38
|
+
output_table_frame,
|
|
39
|
+
output_tables,
|
|
40
|
+
outputs_frame,
|
|
41
|
+
plot_headline,
|
|
42
|
+
plot_outputs,
|
|
43
|
+
run_scenario,
|
|
44
|
+
scenario_definition_table_frame,
|
|
45
|
+
scenario_definition_tables,
|
|
46
|
+
scenario_definition_tables_for_location,
|
|
47
|
+
scenario_frame,
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
__version__ = "0.1.0a1"
|
|
51
|
+
|
|
52
|
+
__all__ = [
|
|
53
|
+
"FableCalculatorSpec",
|
|
54
|
+
"FABLE_OUTPUT_SURFACE_SHEETS",
|
|
55
|
+
"DEFAULT_2020_GENERATED_MODEL_PATH",
|
|
56
|
+
"DEFAULT_2020_WORKBOOK_PATH",
|
|
57
|
+
"DEFAULT_HEADLINE_SERIES",
|
|
58
|
+
"DEFAULT_OUTPUT_TABLES",
|
|
59
|
+
"HeadlinePoint",
|
|
60
|
+
"HeadlineSeries",
|
|
61
|
+
"NotebookLoopResult",
|
|
62
|
+
"OutputIndicator",
|
|
63
|
+
"OutputTable",
|
|
64
|
+
"ScenarioControlSurface",
|
|
65
|
+
"ScenarioDefinitionTable",
|
|
66
|
+
"ScenarioParameter",
|
|
67
|
+
"ScenarioRun",
|
|
68
|
+
"SelectionControl",
|
|
69
|
+
"SelectionOption",
|
|
70
|
+
"__version__",
|
|
71
|
+
"build_2020_notebook_spec",
|
|
72
|
+
"curate_default_headline_series",
|
|
73
|
+
"discover_output_tables",
|
|
74
|
+
"discover_scenario_definition_tables",
|
|
75
|
+
"discover_scenario_parameters",
|
|
76
|
+
"discover_selection_controls",
|
|
77
|
+
"headline_frame",
|
|
78
|
+
"headline_frames",
|
|
79
|
+
"output_table_frame",
|
|
80
|
+
"output_tables",
|
|
81
|
+
"outputs_frame",
|
|
82
|
+
"plot_headline",
|
|
83
|
+
"plot_outputs",
|
|
84
|
+
"load_generated_model",
|
|
85
|
+
"run_2020_notebook_loop",
|
|
86
|
+
"run_notebook_loop",
|
|
87
|
+
"run_scenario",
|
|
88
|
+
"scenario_definition_table_frame",
|
|
89
|
+
"scenario_definition_tables",
|
|
90
|
+
"scenario_definition_tables_for_location",
|
|
91
|
+
"scenario_frame",
|
|
92
|
+
]
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"""Jupyter widget controls for FABLE scenario inputs.
|
|
2
|
+
|
|
3
|
+
The widgets in this module are intentionally thin. They collect values for curated scalar parameters
|
|
4
|
+
and FABLE-C selection controls, then hand those values back to
|
|
5
|
+
:class:`~fable_pyculator.spec.FableCalculatorSpec` for conversion into generated-model cell inputs.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
from fable_pyculator.spec import FableCalculatorSpec, ScenarioParameter
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ScenarioControlSurface:
|
|
16
|
+
"""Small ipywidgets-backed control surface for a FABLE scenario spec.
|
|
17
|
+
|
|
18
|
+
The surface displays scalar parameters and mutually exclusive selection controls. It does not yet
|
|
19
|
+
render editable widgets for the detailed ``SCENARIOS definition`` tables.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def __init__(self, spec: FableCalculatorSpec) -> None:
|
|
23
|
+
self.spec = spec
|
|
24
|
+
widgets = _load_widgets()
|
|
25
|
+
self._controls = {
|
|
26
|
+
**{parameter.name: _parameter_widget(widgets, parameter) for parameter in spec.parameters},
|
|
27
|
+
**{control.name: _selection_widget(widgets, control) for control in spec.selection_controls},
|
|
28
|
+
}
|
|
29
|
+
self.widget = widgets.VBox(list(self._controls.values()))
|
|
30
|
+
|
|
31
|
+
def values(self) -> dict[str, object]:
|
|
32
|
+
"""Return current widget values keyed by spec input name."""
|
|
33
|
+
|
|
34
|
+
return {name: control.value for name, control in self._controls.items()}
|
|
35
|
+
|
|
36
|
+
def set_values(self, values: dict[str, object]) -> None:
|
|
37
|
+
"""Set current widget values by spec input name."""
|
|
38
|
+
|
|
39
|
+
unknown = sorted(set(values) - set(self._controls))
|
|
40
|
+
if unknown:
|
|
41
|
+
raise KeyError(f"unknown scenario parameter(s): {', '.join(unknown)}")
|
|
42
|
+
for name, value in values.items():
|
|
43
|
+
self._controls[name].value = value
|
|
44
|
+
|
|
45
|
+
def _ipython_display_(self) -> None:
|
|
46
|
+
display = _load_display()
|
|
47
|
+
display(self.widget)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _parameter_widget(widgets: Any, parameter: ScenarioParameter) -> Any:
|
|
51
|
+
description = parameter.label
|
|
52
|
+
if parameter.choices:
|
|
53
|
+
return widgets.Dropdown(
|
|
54
|
+
options=list(parameter.choices),
|
|
55
|
+
value=parameter.default if parameter.default is not None else parameter.choices[0],
|
|
56
|
+
description=description,
|
|
57
|
+
)
|
|
58
|
+
if parameter.kind == "boolean":
|
|
59
|
+
return widgets.Checkbox(value=bool(parameter.default), description=description)
|
|
60
|
+
if parameter.kind == "number":
|
|
61
|
+
value = 0 if parameter.default is None else parameter.default
|
|
62
|
+
return widgets.FloatText(value=value, description=description)
|
|
63
|
+
return widgets.Text(value="" if parameter.default is None else str(parameter.default), description=description)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def _selection_widget(widgets: Any, control: Any) -> Any:
|
|
67
|
+
return widgets.Dropdown(
|
|
68
|
+
options=[(option.label or option.value, option.value) for option in control.options],
|
|
69
|
+
value=control.default,
|
|
70
|
+
description=control.label,
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def _load_widgets() -> Any:
|
|
75
|
+
try:
|
|
76
|
+
import ipywidgets as widgets
|
|
77
|
+
except ImportError as error:
|
|
78
|
+
raise RuntimeError("Install fable-pyculator[notebook] to use ScenarioControlSurface.") from error
|
|
79
|
+
return widgets
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def _load_display() -> Any:
|
|
83
|
+
try:
|
|
84
|
+
from IPython.display import display
|
|
85
|
+
except ImportError as error:
|
|
86
|
+
raise RuntimeError("Install fable-pyculator[notebook] to display ScenarioControlSurface.") from error
|
|
87
|
+
return display
|