Skip to content

Commit

Permalink
Hide weight if only one column selected (#170)
Browse files Browse the repository at this point in the history
* factor out weight input

* message shows if only one column

* add a test

* hide the weight control

* update app_test to match
  • Loading branch information
mccalluc authored Nov 21, 2024
1 parent d455df5 commit 2b42029
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 18 deletions.
4 changes: 4 additions & 0 deletions WHAT-WE-LEARNED.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

Even if it seems obvious in retrospect, what have we learned about Python Shiny in this project?

## Some basic html attributes are not supported

I can mark a button as disabled, but it doesn't seem that a `ui.input_select` can be disabled.

## No warning if ID mismatch / type mismatch

Unless I'm missing something, there doesn't seem to be any warning when there isn't a matching function name in the server for an ID in the UI. Either from typos, or fumbling some more complicated display logic, there have been times where this could have been helpful.
Expand Down
1 change: 1 addition & 0 deletions dp_wizard/app/analysis_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ def columns_ui():
bin_counts=bin_counts,
weights=weights,
is_demo=is_demo,
is_single_column=len(column_ids) == 1,
)
confidence_percent = f"{int(confidence * 100)}%"
note_md = f"""
Expand Down
44 changes: 27 additions & 17 deletions dp_wizard/app/components/column_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
from dp_wizard.utils.dp_helper import make_accuracy_histogram
from dp_wizard.utils.shared import plot_histogram
from dp_wizard.utils.code_generators import make_column_config_block
from dp_wizard.app.components.outputs import output_code_sample, demo_tooltip
from dp_wizard.app.components.outputs import output_code_sample, demo_tooltip, hide_if


default_weight = "2"

label_width = "10em" # Just wide enough so the text isn't trucated.
col_widths = {
# Controls stay roughly a constant width;
# Graph expands to fill space.
Expand All @@ -21,29 +21,21 @@

@module.ui
def column_ui(): # pragma: no cover
width = "10em" # Just wide enough so the text isn't trucated.
return ui.layout_columns(
[
# The initial values on these inputs
# should be overridden by the reactive.effect.
ui.input_numeric(
"lower", ["Lower", ui.output_ui("bounds_tooltip_ui")], 0, width=width
"lower",
["Lower", ui.output_ui("bounds_tooltip_ui")],
0,
width=label_width,
),
ui.input_numeric("upper", "Upper", 0, width=width),
ui.input_numeric("upper", "Upper", 0, width=label_width),
ui.input_numeric(
"bins", ["Bins", ui.output_ui("bins_tooltip_ui")], 0, width=width
),
ui.input_select(
"weight",
["Weight", ui.output_ui("weight_tooltip_ui")],
choices={
"1": "Less accurate",
default_weight: "Default",
"4": "More accurate",
},
selected=default_weight,
width=width,
"bins", ["Bins", ui.output_ui("bins_tooltip_ui")], 0, width=label_width
),
ui.output_ui("optional_weight_ui"),
],
[
ui.output_plot("column_plot", height="300px"),
Expand All @@ -67,6 +59,7 @@ def column_server(
bin_counts: reactive.Value[dict[str, int]],
weights: reactive.Value[dict[str, str]],
is_demo: bool,
is_single_column: bool,
): # pragma: no cover
@reactive.effect
def _set_all_inputs():
Expand Down Expand Up @@ -123,6 +116,23 @@ def bins_tooltip_ui():
""",
)

@render.ui
def optional_weight_ui():
return hide_if(
is_single_column,
ui.input_select(
"weight",
["Weight", ui.output_ui("weight_tooltip_ui")],
choices={
"1": "Less accurate",
default_weight: "Default",
"4": "More accurate",
},
selected=default_weight,
width=label_width,
),
)

@render.ui
def weight_tooltip_ui():
return demo_tooltip(
Expand Down
5 changes: 5 additions & 0 deletions dp_wizard/app/components/outputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,8 @@ def demo_tooltip(is_demo: bool, text: str): # pragma: no cover
text,
placement="right",
)


def hide_if(condition: bool, el): # pragma: no cover
display = "none" if condition else "block"
return ui.div(el, style=f"display: {display};")
6 changes: 5 additions & 1 deletion tests/test_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ def expect_no_error():
# Set column details:
page.get_by_label("grade").check()
expect_visible(simulation)
expect_not_visible("Weight")
# Check that default is set correctly:
assert page.get_by_label("Upper").input_value() == "10"
# Reset, and confirm:
Expand All @@ -100,8 +101,11 @@ def expect_no_error():
page.get_by_label("grade").check()
expect_visible(simulation)
assert page.get_by_label("Upper").input_value() == new_value
# Add a second column:
page.get_by_label("blank").check()
expect_visible("Weight")
# TODO: Setting more inputs without checking for updates
# cause recalculations to pile up, and these cause timeouts on CI:
# causes recalculations to pile up, and these cause timeouts on CI:
# It is still rerendering the graph after hitting "Download results".
# https://github.com/opendp/dp-wizard/issues/116
expect_no_error()
Expand Down

0 comments on commit 2b42029

Please sign in to comment.