def as_index_list(v): is_range_value = isinstance(v, (list, tuple)) if is_range_value: slider_value = [index_(opt, val) for val in v] start, end = slider_value if start > end: slider_value = [end, start] return slider_value else: # Simplify future logic by always making value a list try: return [index_(opt, v)] except ValueError: if value is not None: raise return [0]
def serialize_radio(v): if len(options) == 0: return 0 return index_(options, v)
def test_index_pandas_series_fails(self): with self.assertRaises(ValueError): index_(pd.Series([1, 2, 3, 4]), 5)
def serialize_select_box(v): if len(opt) == 0: return 0 return index_(opt, v)
def test_index_numpy_array_fails(self): with self.assertRaises(ValueError): index_(np.array([1, 2, 3, 4]), 5)
def test_index_pandas_series(self): self.assertEqual(index_(pd.Series([1, 2, 3, 4]), 1), 0) self.assertEqual(index_(pd.Series([1, 2, 3, 4]), 4), 3)
def test_index_tuple_fails(self): with self.assertRaises(ValueError): index_((1, 2, 3, 4), 5)
def test_index_numpy_array(self): self.assertEqual(index_(np.array([1, 2, 3, 4]), 1), 0) self.assertEqual(index_(np.array([1, 2, 3, 4]), 4), 3)
def test_index_tuple(self): self.assertEqual(index_((1, 2, 3, 4), 1), 0) self.assertEqual(index_((1, 2, 3, 4), 4), 3)
def test_index_list_fails(self): with self.assertRaises(ValueError): index_([1, 2, 3, 4], 5)
def test_index_list(self): self.assertEqual(index_([1, 2, 3, 4], 1), 0) self.assertEqual(index_([1, 2, 3, 4], 4), 3)
def select_slider( self, label, options=[], value=None, format_func=str, key=None, help=None, ): """ Display a slider widget to select items from a list. This also allows you to render a range slider by passing a two-element tuple or list as the `value`. The difference between `st.select_slider` and `st.slider` is that `select_slider` accepts any datatype and takes an iterable set of options, while `slider` only accepts numerical or date/time data and takes a range as input. Parameters ---------- label : str A short label explaining to the user what this slider is for. options : list, tuple, numpy.ndarray, pandas.Series, or pandas.DataFrame Labels for the slider options. All options will be cast to str internally by default. For pandas.DataFrame, the first column is selected. value : a supported type or a tuple/list of supported types or None The value of the slider when it first renders. If a tuple/list of two values is passed here, then a range slider with those lower and upper bounds is rendered. For example, if set to `(1, 10)` the slider will have a selectable range between 1 and 10. Defaults to first option. format_func : function Function to modify the display of the labels from the options. argument. It receives the option as an argument and its output will be cast to str. key : str An optional string to use as the unique key for the widget. If this is omitted, a key will be generated for the widget based on its content. Multiple widgets of the same type may not share the same key. help : str A tooltip that gets displayed next to the select slider. Returns ------- any value or tuple of any value The current value of the slider widget. The return type will match the data type of the value parameter. Examples -------- >>> color = st.select_slider( ... 'Select a color of the rainbow', ... options=['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet']) >>> st.write('My favorite color is', color) And here's an example of a range select slider: >>> start_color, end_color = st.select_slider( ... 'Select a range of color wavelength', ... options=['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet'], ... value=('red', 'blue')) >>> st.write('You selected wavelengths between', start_color, 'and', end_color) """ options = ensure_iterable(options) if len(options) == 0: raise StreamlitAPIException( "The `options` argument needs to be non-empty") is_range_value = isinstance(value, (list, tuple)) slider_value = value # Convert element to index of the elements if is_range_value: slider_value = list(map(lambda v: index_(options, v), value)) start, end = slider_value if start > end: slider_value = [end, start] else: # Simplify future logic by always making value a list try: slider_value = [index_(options, value)] except ValueError: if value is not None: raise slider_value = [0] slider_proto = SliderProto() slider_proto.label = label slider_proto.format = "%s" slider_proto.default[:] = slider_value slider_proto.min = 0 slider_proto.max = len(options) - 1 slider_proto.step = 1 # default for index changes slider_proto.data_type = SliderProto.INT slider_proto.options[:] = [ str(format_func(option)) for option in options ] slider_proto.form_id = current_form_id(self.dg) if help is not None: slider_proto.help = help ui_value = register_widget("slider", slider_proto, user_key=key) if ui_value: current_value = getattr(ui_value, "data") else: # Widget has not been used; fallback to the original value, current_value = slider_value # The widget always returns floats, so convert to ints before indexing current_value = list(map(lambda x: options[int(x)], current_value)) # type: ignore[no-any-return] # If the original value was a list/tuple, so will be the output (and vice versa) return_value = tuple( current_value) if is_range_value else current_value[0] return self.dg._enqueue("slider", slider_proto, return_value)
def serialize_select_slider(v): to_serialize = v if is_range_value else [v] return [index_(opt, u) for u in to_serialize]