Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CodeDemo does now work with None parameters if update_func is given #33

Merged
merged 1 commit into from
Dec 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
166 changes: 93 additions & 73 deletions src/scwidgets/code/_widget_code_demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,14 @@ def __init__(
button_tooltip="Check the correctness of your code",
)

if self._parameter_panel is None:
self._cue_parameter_panel = self._parameter_panel
if (
self._parameter_panel is None
and self._update_func is None
and self._code is None
):
self._update_button = None
self._self._cue_parameter_panel = None
self._cue_parameter_panel = None
else:
# set up update button and cueing
# -------------------------------
Expand All @@ -178,83 +183,97 @@ def __init__(
# set up parameter panel
# ----------------------

if self._update_mode == "continuous":
self._parameter_panel.set_parameters_widget_attr(
"continuous_update", True
)
elif self._update_mode == "release":
self._parameter_panel.set_parameters_widget_attr(
"continuous_update", False
)

if self._update_mode in ["continuous", "release"]:
self._parameter_panel.observe_parameters(
self._on_trait_parameters_changed, "value"
)
if self._parameter_panel is not None:
if self._update_mode == "continuous":
self._parameter_panel.set_parameters_widget_attr(
"continuous_update", True
)
elif self._update_mode == "release":
self._parameter_panel.set_parameters_widget_attr(
"continuous_update", False
)

if self._update_mode in ["continuous", "release"]:
self._parameter_panel.observe_parameters(
self._on_trait_parameters_changed, "value"
)

if self._code is not None:
# the button only cues on cue_code change
widgets_to_observe = [self._code]
traits_to_observe = ["function_body"]
if self._code is not None:
# the button only cues on cue_code change
widgets_to_observe = [self._code]
traits_to_observe = ["function_body"]
else:
widgets_to_observe = None
traits_to_observe = None
# assume when continuous that the function is fast
# and that disabling causes flicker
update_button_disable_during_action = False
if self._code is not None:
for cue_output in self._cue_outputs:
# TODO this has to be made public
cue_output._widgets_to_observe = [self._code]
cue_output._traits_to_observe = ["function_body"]
cue_output.observe_widgets()

# TODO set this
self._output._widgets_to_observe = [self._code]
self._output._traits_to_observe = ["function_body"]
self._output.observe_widgets()

self._cue_parameter_panel = UpdateCueBox(
[],
[],
self._parameter_panel,
)
else:
widgets_to_observe = None
traits_to_observe = None
# assume when continuous that the function is fast
# and that disabling causes flicker
disable_during_action = False
if self._code is not None:
update_button_disable_during_action = True

self._cue_parameter_panel = UpdateCueBox(
self._parameter_panel.parameters_widget,
self._parameter_panel.parameters_trait,
self._parameter_panel,
)

for cue_output in self._cue_outputs:
# TODO this has to be made public
cue_output._widgets_to_observe = [self._code]
cue_output._traits_to_observe = ["function_body"]
cue_output.observe_widgets()

# TODO set this
self._output._widgets_to_observe = [self._code]
self._output._traits_to_observe = ["function_body"]
self._output.observe_widgets()

self._cue_parameter_panel = UpdateCueBox(
[],
[],
self._parameter_panel,
)
if self._code is not None:
# TODO this has to be made public
cue_output._widgets_to_observe = [
self._code
] + self._parameter_panel.parameters_widget
cue_output._traits_to_observe = [
"function_body"
] + self._parameter_panel.parameters_trait
cue_output.observe_widgets()
else:
# TODO this has to be made public
cue_output._widgets_to_observe = (
self._parameter_panel.parameters_widget
)
cue_output._traits_to_observe = (
self._parameter_panel.parameters_trait
)
cue_output.observe_widgets()
elif self._code is not None:
widgets_to_observe = [self._code]
traits_to_observe = ["function_body"]
# only code demo with an update function exists,
# we therefore assume update is slow
update_button_disable_during_action = True
else:
widgets_to_observe = None
traits_to_observe = None
disable_during_action = True

self._cue_parameter_panel = UpdateCueBox(
self._parameter_panel.parameters_widget,
self._parameter_panel.parameters_trait,
self._parameter_panel,
)

for cue_output in self._cue_outputs:
if self._code is not None:
# TODO this has to be made public
cue_output._widgets_to_observe = [
self._code
] + self._parameter_panel.parameters_widget
cue_output._traits_to_observe = [
"function_body"
] + self._parameter_panel.parameters_trait
cue_output.observe_widgets()
else:
# TODO this has to be made public
cue_output._widgets_to_observe = (
self._parameter_panel.parameters_widget
)
cue_output._traits_to_observe = (
self._parameter_panel.parameters_trait
)
cue_output.observe_widgets()
widgets_to_observe = []
traits_to_observe = []
# only update function exists, we assume update is slow
update_button_disable_during_action = True

reset_update_cue_widgets = []
if self._code is not None:
if self._cue_code is not None:
reset_update_cue_widgets.append(self._cue_code)
reset_update_cue_widgets.append(self._cue_parameter_panel)
reset_update_cue_widgets.extend(self._cue_outputs)
if self._cue_parameter_panel is not None:
reset_update_cue_widgets.append(self._cue_parameter_panel)
if self._cue_outputs is not None:
reset_update_cue_widgets.extend(self._cue_outputs)

if self._code is not None:
description = "Run Code"
Expand All @@ -272,7 +291,8 @@ def __init__(
"disable_update_button_on_successful_action", False
),
disable_during_action=kwargs.pop(
"disable_update_button_during_action", disable_during_action
"disable_update_button_during_action",
update_button_disable_during_action,
),
widgets_to_observe=widgets_to_observe,
traits_to_observe=traits_to_observe,
Expand Down Expand Up @@ -352,9 +372,9 @@ def __init__(
)

demo_children = []
if self._code is not None:
if self._cue_code is not None:
demo_children.append(self._cue_code)
if self._parameters is not None:
if self._cue_parameter_panel is not None:
demo_children.append(self._cue_parameter_panel)

buttons = []
Expand Down
61 changes: 37 additions & 24 deletions tests/notebooks/widget_code_demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,12 @@

scwidgets.get_css_style()


def run_code_demo(checks, include_checks, include_params, tunable_params, update_mode):
return get_code_demo(
checks, include_checks, include_params, tunable_params, update_mode
)


# Test 1:
# -------
# Test if CodeDemo shows correct output

# Test 1.1
run_code_demo(
get_code_demo(
[single_param_check(use_fingerprint=False, failing=False, buggy=False)],
include_checks=True,
include_params=True,
Expand All @@ -48,7 +41,7 @@ def run_code_demo(checks, include_checks, include_params, tunable_params, update
)

# Test 1.2
run_code_demo(
get_code_demo(
[single_param_check(use_fingerprint=False, failing=True, buggy=False)],
include_checks=True,
include_params=True,
Expand All @@ -57,7 +50,7 @@ def run_code_demo(checks, include_checks, include_params, tunable_params, update
)

# Test 1.3
run_code_demo(
get_code_demo(
[single_param_check(use_fingerprint=False, failing=False, buggy=True)],
include_checks=True,
include_params=True,
Expand All @@ -66,7 +59,7 @@ def run_code_demo(checks, include_checks, include_params, tunable_params, update
)

# Test 1.4
run_code_demo(
get_code_demo(
[single_param_check(use_fingerprint=False, failing=False, buggy=False)],
include_checks=True,
include_params=True,
Expand All @@ -75,7 +68,7 @@ def run_code_demo(checks, include_checks, include_params, tunable_params, update
)

# Test 1.5
run_code_demo(
get_code_demo(
[single_param_check(use_fingerprint=False, failing=False, buggy=False)],
include_checks=True,
include_params=True,
Expand All @@ -84,7 +77,7 @@ def run_code_demo(checks, include_checks, include_params, tunable_params, update
)

# Test 1.6
run_code_demo(
get_code_demo(
[single_param_check(use_fingerprint=False, failing=False, buggy=False)],
include_checks=True,
include_params=True,
Expand All @@ -95,28 +88,48 @@ def run_code_demo(checks, include_checks, include_params, tunable_params, update

# Test 2:
# -------
# Test if CodeDemo works correct for only checks
# Test if CodeDemo works correct for only update


# +
# Test 2.1
# TODO
# run_code_demo([single_param_check(use_fingerprint=False, failing=True, buggy=False)],
# include_checks=True, include_params=False)
# Test if update button is shown even if params are None
def function_to_check():
print("SomeText")
return 5


get_code_demo(
[],
code=function_to_check,
include_checks=False,
include_params=False,
tunable_params=False,
update_mode="release",
)
# -

# Test 2.2
# TODO
# run_code_demo([single_param_check(use_fingerprint=True, failing=True, buggy=False)],
# include_checks=True, include_params=False)
# get_code_demo([single_param_check(use_fingerprint=False, failing=True, buggy=False)],
# include_checks=False, include_params=True, tunable_params)

# Test 2.3
# TODO
# get_code_demo([single_param_check(use_fingerprint=True, failing=True, buggy=False)],
# include_checks=False, include_params=True, tunable_params)


# Test 3:
# -------
# Test if CodeDemo works correct for only update
# Test if CodeDemo works correct for only checks

# Test 3.1
# TODO
# run_code_demo([single_param_check(use_fingerprint=False, failing=True, buggy=False)],
# include_checks=False, include_params=True, tunable_params)
# get_code_demo([single_param_check(use_fingerprint=False, failing=True, buggy=False)],
# include_checks=True, include_params=False)

# Test 3.2
# TODO
# run_code_demo([single_param_check(use_fingerprint=True, failing=True, buggy=False)],
# include_checks=False, include_params=True, tunable_params)
# get_code_demo([single_param_check(use_fingerprint=True, failing=True, buggy=False)],
# include_checks=True, include_params=False)
16 changes: 12 additions & 4 deletions tests/test_code.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import List
from typing import Callable, List

import numpy as np
import pytest
Expand Down Expand Up @@ -69,15 +69,21 @@ def test_get_code(self):

def get_code_demo(
checks: List[Check],
code: Callable = None,
include_checks=True,
include_params=True,
tunable_params=False,
update_mode="manual",
):
# Important:
# we take the the function_to_check from the first check as code input
code_input = CodeInput(checks[0].function_to_check)
if tunable_params:
if len(checks) == 0 and code is None:
raise ValueError("Either nonempty checks must given or code")
if code is None:
code_input = CodeInput(checks[0].function_to_check)
else:
code_input = CodeInput(code)
if len(checks) > 0 and tunable_params:
# convert single value arrays to tuples
for value in checks[0].inputs_parameters[0].values():
assert (
Expand All @@ -87,11 +93,13 @@ def get_code_demo(
key: value.reshape(-1)[0]
for key, value in checks[0].inputs_parameters[0].items()
}
else:
elif len(checks) > 0:
# we convert the arguments to fixed one
parameters = {
key: fixed(value) for key, value in checks[0].inputs_parameters[0].items()
}
else:
parameters = None

def update_print(code_demo: CodeDemo):
output = code_demo.run_code(**code_demo.panel_parameters)
Expand Down
Loading