привязка текстового поля виджета jupyter к функции, строящей график

#function #ipywidgets

#функция #ipywidgets

Вопрос:

Я пытаюсь создать пользовательский интерфейс в записной книжке Jupyter, который может связать одну функцию с текстовым виджетом и виджетом кнопки.

Моя функция создает график для цены акций данной акции от даты начала до даты окончания. Функции заключаются в следующем

 import pandas_datareader as pdr

from datetime import datetime


 def company(ticker):
    strt=datetime(2020,1,1)
    end=datetime.now()
    dat=pdr.get_data_yahoo(ticker, strt, end)
    return dat['Close'].plot(grid=True)
  

Следующая команда отображает цену акций Apple.

 company('AAPL')
  

Теперь я создаю текстовый виджет и виджет кнопок следующим образом

 import ipywidgets as ipw

 box=ipw.Text(
value='Stock handle',
placeholder='Type something',
description='String:',
disabled=False)


 btn=ipw.ToggleButton(
 value=False,
description='Plot',
disabled=False,
button_style='', # 'success', 'info', 'warning', 'danger' or ''
tooltip='Description',
icon='check' # (FontAwesome names without the `fa-` prefix))
    
  

Я попытался связать функциональную компанию с box следующим образом:
box.on_submit(компания)

Когда я пишу AAPL в поле, это выдает ошибку «TypeError: объект типа ‘Text’ не имеет len() » Моя цель — создать интерфейс, в котором я пишу название акции (‘AAPL’) в поле и нажимаю btn, в этот момент появится график цены акции.

Любая помощь приветствуется. Спасибо.

Комментарии:

1. Пожалуйста, не могли бы вы скопировать и вставить всю ошибку, которую вы получаете, в блок кода? Полная трассировка стека помогает определить причину.

Ответ №1:

Когда вы присоединяете функцию с помощью on_submit , весь виджет передается в качестве аргумента функции (а не только текстовое значение). Таким образом, внутри вашей company функции ticker фактически находится ваш экземпляр Text виджета. Отсюда ошибка, поскольку вы не можете вызвать len виджет.

Чтобы получить текстовое значение виджета, используйте ticker.value , который вы должны иметь возможность вызывать len просто отлично.

 def print_it(ticker):
#     print(len(ticker))  # raises TypeError, you're calling len on the Text widget
    print(len(ticker.value))   # will work, as you're accessing the `value` of the widget which is a string
    
t = ipywidgets.Text(continuous_update=False)
t.on_submit(print_it)
t
  

ПРИМЕЧАНИЕ. on_submit метод устарел с версии ipywidgets 7.0, гораздо лучше создать свой блок с помощью use box.observe() , а при создании своего блока включить continuous_update=False как kwarg. С помощью этого метода вашей функции передается словарь информации, поэтому вам нужно проанализировать новое значение и распечатать его.

 def print_it(ticker):
    print(ticker['new'])   # will work, as you're accessing the string value of the widget
    
t = ipywidgets.Text(continuous_update=False)
t.observe(print_it, names='value')
t
  

Комментарии:

1. Спасибо за ваш ответ. Однако это не то, что я ищу. Я не хочу печатать то, что написано в поле. Для этого есть несколько руководств. Я хочу, чтобы то, что написано в поле, использовалось в качестве входных данных для функции company, а результирующий вывод функции company отображался

2. Прежде чем вы получали TypeError , потому что вы не могли получить доступ к текстовому значению вашего виджета, мой ответ показывает вам, как получить текстовое значение вашего виджета, которое вы должны иметь возможность подключить к своей функции построения графика.