Динамически генерировать галочки в сочетании с поиском с использованием виджетов Jupyter - PullRequest
1 голос
/ 04 октября 2019

Я создал блокнот Jupyter для анализа и сопоставления исторических данных. Поскольку база данных довольно большая, я использовал виджет поиска + наблюдения, чтобы позволить пользователю выбирать эксперименты, которые он хочет, а не прокручивать все данные. Прямо сейчас все флажки для всех экспериментов сгенерированы, но они слишком велики, чтобы поместиться в них, и занимают много времени.

Есть ли способ показать только последние 10 экспериментов по умолчанию И только сгенерировать необходимые флажки после поиска?

Я основал код на этом gist . Я уже пытался переместить виджет флажка внутри цикла else, но это не сработало. Кроме того, ситуация с глобальными / локальными переменными в моем коде кажется запутанной.

import ipywidgets as widgets

#Generate a dummy list
Allfileslist = ["Experiment {}".format(x) for x in range(600)]
#Search box + generate ALL the checkboxes, this seems to be the bottleneck
search_widget = widgets.Text(placeholder='Type for older experiments',                 description= 'Search:')
experiments = {eachfilename: widgets.Checkbox(description=eachfilename, value=False) for eachfilename in Allfileslist}
options = [experiments[eachfilename] for eachfilename in Allfileslist]
options_widget = widgets.VBox(options, layout={'overflow': 'auto'})


def whentextischanged (change):
    """Dynamically update the widget experiments"""
    search_input = change['new']
    if search_input == '':
        # Reset search field, default to last 9 experiments
        new_options = [experiments[eachfilename] for eachfilename in Allfileslist[-10:]]
    else:
        # Filter by search
        close_matches = [x for x in Allfileslist if search_input.upper() in x]
        ### magic code that generates only the match boxes ###
        new_options = [experiments[eachfilename] for eachfilename in close_matches]

    options_widget.children = new_options

#Generate the vbox, search
multi_select = widgets.VBox([search_widget, options_widget])
search_widget.observe(whentextischanged, names='value')
#serve it up
multi_select

Можно ли сгенерировать только флажки, необходимые для ускорения процесса?

ОБНОВЛЕНИЕ Я включил ответ ac24 с некоторой модификацией, и он почти делает то, что ему нужно. Единственное, чего он не делает, это показывает значения по умолчанию, когда окно поиска пусто в начале. После этого очистка окна поиска показывает правильное поведение.

import ipywidgets as widgets

#Generate a dummy list
Allfileslist = ["{}".format(x) for x in range(600)]
#Search box + generate some checboxes
search_widget = widgets.Text(placeholder='Type for older experiments', description= 'Search:',value='')
experiments = {}
options_widget = widgets.VBox(layout={'overflow': 'auto'})
default_options = [widgets.Checkbox(description=eachfilename, value=False) for eachfilename in Allfileslist[-10:]]

def whentextischanged (change):
    """Dynamically update the widget experiments"""
    search_input = change['new']
    if search_input == '':
        # Reset search field, default to last 9 experiments
        new_options = default_options
    else:
        # Filter by search
        close_matches = [x for x in Allfileslist if search_input.lower() in x.lower()][:10]
        for name in close_matches:
            if name not in experiments:
                experiments[name] = widgets.Checkbox(description=name, value=False)
        new_options = [experiments[eachfilename] for eachfilename in close_matches]

    options_widget.children = new_options

#Generate the vbox, search
multi_select = widgets.VBox([search_widget, options_widget])
search_widget.observe(whentextischanged, names='value')
multi_select

1 Ответ

1 голос
/ 10 октября 2019

Попробуйте сначала создать пустой словарь, а затем установить флажки по мере приближения к желаемому эксперименту.

import ipywidgets as widgets

#Generate a dummy list
Allfileslist = ["{}".format(x) for x in range(600)]
#Search box + generate ALL the checkboxes, this seems to be the bottleneck
search_widget = widgets.Text(placeholder='Type for older experiments',                 description= 'Search:')
# experiments = {eachfilename: widgets.Checkbox(description=eachfilename, value=False) for eachfilename in Allfileslist}
experiments = {}
options_widget = widgets.VBox(layout={'overflow': 'auto'})


def whentextischanged (change):
    """Dynamically update the widget experiments"""
    search_input = change['new']
    if search_input == '':
        # Reset search field, default to last 9 experiments
        new_options = [experiments[eachfilename] for eachfilename in Allfileslist[-10:]]
    else:
        # Filter by search
        close_matches = [x for x in Allfileslist if search_input.lower() in x.lower()][:10]
        for name in close_matches:
            if name not in experiments:
                experiments[name] = widgets.Checkbox(description=name, value=False)

        ### magic code that generates only the match boxes ###
        new_options = [experiments[eachfilename] for eachfilename in close_matches]

    options_widget.children = new_options

#Generate the vbox, search
multi_select = widgets.VBox([search_widget, options_widget])
search_widget.observe(whentextischanged, names='value')
#serve it up
multi_select

Затем, выбрав несколько вариантов, позвоните [key for key, exp_check in exp_checkboxes.items() if exp_check.value], чтобы увидетьвыбранные значения.

...