Интерактивное создание списка с помощью ipywidgets и asyncio в Jupyter Notebook - PullRequest
0 голосов
/ 05 августа 2020

Я пытаюсь написать набор функций, которые позволяют мне использовать Jupyter Notebook для «интерактивного» создания списка (на основе значений из другого предопределенного списка). На самом высоком уровне эти функции будут печатать элемент (например, тип животного), затем я предоставляю аннотацию для этого элемента (например, «птица» или «fi sh») с помощью интерактивного текстового поля, а затем моя аннотация будет сохранена в новом списке.

Что-то вроде этого я хочу сделать (но явно не совсем там):

from ipywidgets import widgets  
import asyncio

#function that waits for an input into the textbox
def wait_for_change(widget):
    future = asyncio.Future()
    def getvalue(change):
        future.set_result(change.description)
        widget #display the textbox (and then wait for user input using the 'return' button?)
        widget.value #get the value in the textbox
    return future

#the textbox widget
input_text = widgets.Text()

#list of animals to classify
list_to_tag = ["seagull", "flounder", "trout", "albatross"]
tagged_animals = []

#function to display the textbox and list of animals to classify, return list of annotations
async def f():
    for i in list_to_tag:
        print("going to tag {}".format(i))
        x = await wait_for_change(input_text)
        print("tagged {} with {}".format(i, x))
        tagged_animals.append(x)
    print("All animals tagged")
    return tagged_animals

#start the annotation task
asyncio.create_task(f())
input_text

В настоящий момент скрипт вылетает с предупреждением :

task: <Task pending coro=<f() done, defined at <ipython-input-31-d698dc6b74bc>:17> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x109a71f10>()]>>

Что-то связано с asyncio.Future()?

Заранее спасибо за помощь.

1 Ответ

0 голосов
/ 05 августа 2020

Хорошо, я понял, как это сделать - приведенный ниже код основан на этом ответе .

from ipywidgets import Button, HBox
import asyncio

#function for waiting for button clicks
def wait_for_change(widget1, widget2):
    future = asyncio.Future()
    def getvalue(change):
        future.set_result(change.description)
        widget1.on_click(getvalue, remove=True)
        widget2.on_click(getvalue, remove=True)
    widget1.on_click(getvalue)
    widget2.on_click(getvalue)
    return future

#annotation buttons
button1=Button(description="bird")
button2=Button(description="fish")

#terms to annotate
list_to_tag = ["seagull", "flounder", "trout", "albatross"]
tagged_animals = []

В следующем блоке кода используется сопрограмма и asyncio (этот ответ объясняет, что здесь происходит).

#use a coroutine function to iterate through all items to annotate
async def f():
    for i in list_to_tag:
        print(i)
        x = await wait_for_change(button1,button2) 
        tagged_animals.append(x)
    return tagged_animals

Затем вызовите функции и сделайте аннотации.

#iterate through annotations, save results
annotations = asyncio.create_task(f())

#display buttons
HBox([button1,button2])

Наконец, как только все элементы аннотированы, откройте аннотации.

#get the results
annotations.result()
['bird', 'fish', 'fish', 'bird']
...