prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Stocks Example is not working properly 
  https://github.com/bokeh/bokeh/tree/master/examples/app/stocks
  
  The example suppose to change the stats according to the selected points. For some reason 
  
          def selection_change(attrname, old, new):
              print('lol')
              t1, t2 = ticker1.value, ticker2.value
              data = get_data(t1, t2)
              selected = source.selected.indices
              if selected:
                  data = data.iloc[selected, :]
              update_stats(data, t1, t2)
  
          source.on_change('selected', selection_change)
  
  The code never prints 'lol'. 
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `examples/app/stocks/main.py`
  Content:
  ```
  1 ''' Create a simple stocks correlation dashboard.
  2 
  3 Choose stocks to compare in the drop down widgets, and make selections
  4 on the plots to update the summary and histograms accordingly.
  5 
  6 .. note::
  7     Running this example requires downloading sample data. See
  8     the included `README`_ for more information.
  9 
  10 Use the ``bokeh serve`` command to run the example by executing:
  11 
  12     bokeh serve stocks
  13 
  14 at your command prompt. Then navigate to the URL
  15 
  16     http://localhost:5006/stocks
  17 
  18 .. _README: https://github.com/bokeh/bokeh/blob/master/examples/app/stocks/README.md
  19 
  20 '''
  21 try:
  22     from functools import lru_cache
  23 except ImportError:
  24     # Python 2 does stdlib does not have lru_cache so let's just
  25     # create a dummy decorator to avoid crashing
  26     print ("WARNING: Cache for this example is available on Python 3 only.")
  27     def lru_cache():
  28         def dec(f):
  29             def _(*args, **kws):
  30                 return f(*args, **kws)
  31             return _
  32         return dec
  33 
  34 from os.path import dirname, join
  35 
  36 import pandas as pd
  37 
  38 from bokeh.io import curdoc
  39 from bokeh.layouts import row, column
  40 from bokeh.models import ColumnDataSource
  41 from bokeh.models.widgets import PreText, Select
  42 from bokeh.plotting import figure
  43 
  44 DATA_DIR = join(dirname(__file__), 'daily')
  45 
  46 DEFAULT_TICKERS = ['AAPL', 'GOOG', 'INTC', 'BRCM', 'YHOO']
  47 
  48 def nix(val, lst):
  49     return [x for x in lst if x != val]
  50 
  51 @lru_cache()
  52 def load_ticker(ticker):
  53     fname = join(DATA_DIR, 'table_%s.csv' % ticker.lower())
  54     data = pd.read_csv(fname, header=None, parse_dates=['date'],
  55                        names=['date', 'foo', 'o', 'h', 'l', 'c', 'v'])
  56     data = data.set_index('date')
  57     return pd.DataFrame({ticker: data.c, ticker+'_returns': data.c.diff()})
  58 
  59 @lru_cache()
  60 def get_data(t1, t2):
  61     df1 = load_ticker(t1)
  62     df2 = load_ticker(t2)
  63     data = pd.concat([df1, df2], axis=1)
  64     data = data.dropna()
  65     data['t1'] = data[t1]
  66     data['t2'] = data[t2]
  67     data['t1_returns'] = data[t1+'_returns']
  68     data['t2_returns'] = data[t2+'_returns']
  69     return data
  70 
  71 # set up widgets
  72 
  73 stats = PreText(text='', width=500)
  74 ticker1 = Select(value='AAPL', options=nix('GOOG', DEFAULT_TICKERS))
  75 ticker2 = Select(value='GOOG', options=nix('AAPL', DEFAULT_TICKERS))
  76 
  77 # set up plots
  78 
  79 source = ColumnDataSource(data=dict(date=[], t1=[], t2=[], t1_returns=[], t2_returns=[]))
  80 source_static = ColumnDataSource(data=dict(date=[], t1=[], t2=[], t1_returns=[], t2_returns=[]))
  81 tools = 'pan,wheel_zoom,xbox_select,reset'
  82 
  83 corr = figure(plot_width=350, plot_height=350,
  84               tools='pan,wheel_zoom,box_select,reset')
  85 corr.circle('t1_returns', 't2_returns', size=2, source=source,
  86             selection_color="orange", alpha=0.6, nonselection_alpha=0.1, selection_alpha=0.4)
  87 
  88 ts1 = figure(plot_width=900, plot_height=200, tools=tools, x_axis_type='datetime', active_drag="xbox_select")
  89 ts1.line('date', 't1', source=source_static)
  90 ts1.circle('date', 't1', size=1, source=source, color=None, selection_color="orange")
  91 
  92 ts2 = figure(plot_width=900, plot_height=200, tools=tools, x_axis_type='datetime', active_drag="xbox_select")
  93 ts2.x_range = ts1.x_range
  94 ts2.line('date', 't2', source=source_static)
  95 ts2.circle('date', 't2', size=1, source=source, color=None, selection_color="orange")
  96 
  97 # set up callbacks
  98 
  99 def ticker1_change(attrname, old, new):
  100     ticker2.options = nix(new, DEFAULT_TICKERS)
  101     update()
  102 
  103 def ticker2_change(attrname, old, new):
  104     ticker1.options = nix(new, DEFAULT_TICKERS)
  105     update()
  106 
  107 def update(selected=None):
  108     t1, t2 = ticker1.value, ticker2.value
  109 
  110     data = get_data(t1, t2)
  111     source.data = source.from_df(data[['t1', 't2', 't1_returns', 't2_returns']])
  112     source_static.data = source.data
  113 
  114     update_stats(data, t1, t2)
  115 
  116     corr.title.text = '%s returns vs. %s returns' % (t1, t2)
  117     ts1.title.text, ts2.title.text = t1, t2
  118 
  119 def update_stats(data, t1, t2):
  120     stats.text = str(data[[t1, t2, t1+'_returns', t2+'_returns']].describe())
  121 
  122 ticker1.on_change('value', ticker1_change)
  123 ticker2.on_change('value', ticker2_change)
  124 
  125 def selection_change(attrname, old, new):
  126     t1, t2 = ticker1.value, ticker2.value
  127     data = get_data(t1, t2)
  128     selected = source.selected.indices
  129     if selected:
  130         data = data.iloc[selected, :]
  131     update_stats(data, t1, t2)
  132 
  133 source.on_change('selected', selection_change)
  134 
  135 # set up layout
  136 widgets = column(ticker1, ticker2, stats)
  137 main_row = row(corr, widgets)
  138 series = column(ts1, ts2)
  139 layout = column(main_row, series)
  140 
  141 # initialize
  142 update()
  143 
  144 curdoc().add_root(layout)
  145 curdoc().title = "Stocks"
  146
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/examples/app/stocks/main.py b/examples/app/stocks/main.py
  --- a/examples/app/stocks/main.py
  +++ b/examples/app/stocks/main.py
  @@ -130,7 +130,7 @@
           data = data.iloc[selected, :]
       update_stats(data, t1, t2)
   
  -source.on_change('selected', selection_change)
  +source.selected.on_change('indices', selection_change)
   
   # set up layout
   widgets = column(ticker1, ticker2, stats)
  
verification_info: {"golden_diff": "diff --git a/examples/app/stocks/main.py b/examples/app/stocks/main.py\n--- a/examples/app/stocks/main.py\n+++ b/examples/app/stocks/main.py\n@@ -130,7 +130,7 @@\n         data = data.iloc[selected, :]\n     update_stats(data, t1, t2)\n \n-source.on_change('selected', selection_change)\n+source.selected.on_change('indices', selection_change)\n \n # set up layout\n widgets = column(ticker1, ticker2, stats)\n", "issue": "Stocks Example is not working properly \nhttps://github.com/bokeh/bokeh/tree/master/examples/app/stocks\r\n\r\nThe example suppose to change the stats according to the selected points. For some reason \r\n\r\n        def selection_change(attrname, old, new):\r\n            print('lol')\r\n            t1, t2 = ticker1.value, ticker2.value\r\n            data = get_data(t1, t2)\r\n            selected = source.selected.indices\r\n            if selected:\r\n                data = data.iloc[selected, :]\r\n            update_stats(data, t1, t2)\r\n\r\n        source.on_change('selected', selection_change)\r\n\r\nThe code never prints 'lol'. \n", "before_files": [{"content": "''' Create a simple stocks correlation dashboard.\n\nChoose stocks to compare in the drop down widgets, and make selections\non the plots to update the summary and histograms accordingly.\n\n.. note::\n    Running this example requires downloading sample data. See\n    the included `README`_ for more information.\n\nUse the ``bokeh serve`` command to run the example by executing:\n\n    bokeh serve stocks\n\nat your command prompt. Then navigate to the URL\n\n    http://localhost:5006/stocks\n\n.. _README: https://github.com/bokeh/bokeh/blob/master/examples/app/stocks/README.md\n\n'''\ntry:\n    from functools import lru_cache\nexcept ImportError:\n    # Python 2 does stdlib does not have lru_cache so let's just\n    # create a dummy decorator to avoid crashing\n    print (\"WARNING: Cache for this example is available on Python 3 only.\")\n    def lru_cache():\n        def dec(f):\n            def _(*args, **kws):\n                return f(*args, **kws)\n            return _\n        return dec\n\nfrom os.path import dirname, join\n\nimport pandas as pd\n\nfrom bokeh.io import curdoc\nfrom bokeh.layouts import row, column\nfrom bokeh.models import ColumnDataSource\nfrom bokeh.models.widgets import PreText, Select\nfrom bokeh.plotting import figure\n\nDATA_DIR = join(dirname(__file__), 'daily')\n\nDEFAULT_TICKERS = ['AAPL', 'GOOG', 'INTC', 'BRCM', 'YHOO']\n\ndef nix(val, lst):\n    return [x for x in lst if x != val]\n\n@lru_cache()\ndef load_ticker(ticker):\n    fname = join(DATA_DIR, 'table_%s.csv' % ticker.lower())\n    data = pd.read_csv(fname, header=None, parse_dates=['date'],\n                       names=['date', 'foo', 'o', 'h', 'l', 'c', 'v'])\n    data = data.set_index('date')\n    return pd.DataFrame({ticker: data.c, ticker+'_returns': data.c.diff()})\n\n@lru_cache()\ndef get_data(t1, t2):\n    df1 = load_ticker(t1)\n    df2 = load_ticker(t2)\n    data = pd.concat([df1, df2], axis=1)\n    data = data.dropna()\n    data['t1'] = data[t1]\n    data['t2'] = data[t2]\n    data['t1_returns'] = data[t1+'_returns']\n    data['t2_returns'] = data[t2+'_returns']\n    return data\n\n# set up widgets\n\nstats = PreText(text='', width=500)\nticker1 = Select(value='AAPL', options=nix('GOOG', DEFAULT_TICKERS))\nticker2 = Select(value='GOOG', options=nix('AAPL', DEFAULT_TICKERS))\n\n# set up plots\n\nsource = ColumnDataSource(data=dict(date=[], t1=[], t2=[], t1_returns=[], t2_returns=[]))\nsource_static = ColumnDataSource(data=dict(date=[], t1=[], t2=[], t1_returns=[], t2_returns=[]))\ntools = 'pan,wheel_zoom,xbox_select,reset'\n\ncorr = figure(plot_width=350, plot_height=350,\n              tools='pan,wheel_zoom,box_select,reset')\ncorr.circle('t1_returns', 't2_returns', size=2, source=source,\n            selection_color=\"orange\", alpha=0.6, nonselection_alpha=0.1, selection_alpha=0.4)\n\nts1 = figure(plot_width=900, plot_height=200, tools=tools, x_axis_type='datetime', active_drag=\"xbox_select\")\nts1.line('date', 't1', source=source_static)\nts1.circle('date', 't1', size=1, source=source, color=None, selection_color=\"orange\")\n\nts2 = figure(plot_width=900, plot_height=200, tools=tools, x_axis_type='datetime', active_drag=\"xbox_select\")\nts2.x_range = ts1.x_range\nts2.line('date', 't2', source=source_static)\nts2.circle('date', 't2', size=1, source=source, color=None, selection_color=\"orange\")\n\n# set up callbacks\n\ndef ticker1_change(attrname, old, new):\n    ticker2.options = nix(new, DEFAULT_TICKERS)\n    update()\n\ndef ticker2_change(attrname, old, new):\n    ticker1.options = nix(new, DEFAULT_TICKERS)\n    update()\n\ndef update(selected=None):\n    t1, t2 = ticker1.value, ticker2.value\n\n    data = get_data(t1, t2)\n    source.data = source.from_df(data[['t1', 't2', 't1_returns', 't2_returns']])\n    source_static.data = source.data\n\n    update_stats(data, t1, t2)\n\n    corr.title.text = '%s returns vs. %s returns' % (t1, t2)\n    ts1.title.text, ts2.title.text = t1, t2\n\ndef update_stats(data, t1, t2):\n    stats.text = str(data[[t1, t2, t1+'_returns', t2+'_returns']].describe())\n\nticker1.on_change('value', ticker1_change)\nticker2.on_change('value', ticker2_change)\n\ndef selection_change(attrname, old, new):\n    t1, t2 = ticker1.value, ticker2.value\n    data = get_data(t1, t2)\n    selected = source.selected.indices\n    if selected:\n        data = data.iloc[selected, :]\n    update_stats(data, t1, t2)\n\nsource.on_change('selected', selection_change)\n\n# set up layout\nwidgets = column(ticker1, ticker2, stats)\nmain_row = row(corr, widgets)\nseries = column(ts1, ts2)\nlayout = column(main_row, series)\n\n# initialize\nupdate()\n\ncurdoc().add_root(layout)\ncurdoc().title = \"Stocks\"\n", "path": "examples/app/stocks/main.py"}], "after_files": [{"content": "''' Create a simple stocks correlation dashboard.\n\nChoose stocks to compare in the drop down widgets, and make selections\non the plots to update the summary and histograms accordingly.\n\n.. note::\n    Running this example requires downloading sample data. See\n    the included `README`_ for more information.\n\nUse the ``bokeh serve`` command to run the example by executing:\n\n    bokeh serve stocks\n\nat your command prompt. Then navigate to the URL\n\n    http://localhost:5006/stocks\n\n.. _README: https://github.com/bokeh/bokeh/blob/master/examples/app/stocks/README.md\n\n'''\ntry:\n    from functools import lru_cache\nexcept ImportError:\n    # Python 2 does stdlib does not have lru_cache so let's just\n    # create a dummy decorator to avoid crashing\n    print (\"WARNING: Cache for this example is available on Python 3 only.\")\n    def lru_cache():\n        def dec(f):\n            def _(*args, **kws):\n                return f(*args, **kws)\n            return _\n        return dec\n\nfrom os.path import dirname, join\n\nimport pandas as pd\n\nfrom bokeh.io import curdoc\nfrom bokeh.layouts import row, column\nfrom bokeh.models import ColumnDataSource\nfrom bokeh.models.widgets import PreText, Select\nfrom bokeh.plotting import figure\n\nDATA_DIR = join(dirname(__file__), 'daily')\n\nDEFAULT_TICKERS = ['AAPL', 'GOOG', 'INTC', 'BRCM', 'YHOO']\n\ndef nix(val, lst):\n    return [x for x in lst if x != val]\n\n@lru_cache()\ndef load_ticker(ticker):\n    fname = join(DATA_DIR, 'table_%s.csv' % ticker.lower())\n    data = pd.read_csv(fname, header=None, parse_dates=['date'],\n                       names=['date', 'foo', 'o', 'h', 'l', 'c', 'v'])\n    data = data.set_index('date')\n    return pd.DataFrame({ticker: data.c, ticker+'_returns': data.c.diff()})\n\n@lru_cache()\ndef get_data(t1, t2):\n    df1 = load_ticker(t1)\n    df2 = load_ticker(t2)\n    data = pd.concat([df1, df2], axis=1)\n    data = data.dropna()\n    data['t1'] = data[t1]\n    data['t2'] = data[t2]\n    data['t1_returns'] = data[t1+'_returns']\n    data['t2_returns'] = data[t2+'_returns']\n    return data\n\n# set up widgets\n\nstats = PreText(text='', width=500)\nticker1 = Select(value='AAPL', options=nix('GOOG', DEFAULT_TICKERS))\nticker2 = Select(value='GOOG', options=nix('AAPL', DEFAULT_TICKERS))\n\n# set up plots\n\nsource = ColumnDataSource(data=dict(date=[], t1=[], t2=[], t1_returns=[], t2_returns=[]))\nsource_static = ColumnDataSource(data=dict(date=[], t1=[], t2=[], t1_returns=[], t2_returns=[]))\ntools = 'pan,wheel_zoom,xbox_select,reset'\n\ncorr = figure(plot_width=350, plot_height=350,\n              tools='pan,wheel_zoom,box_select,reset')\ncorr.circle('t1_returns', 't2_returns', size=2, source=source,\n            selection_color=\"orange\", alpha=0.6, nonselection_alpha=0.1, selection_alpha=0.4)\n\nts1 = figure(plot_width=900, plot_height=200, tools=tools, x_axis_type='datetime', active_drag=\"xbox_select\")\nts1.line('date', 't1', source=source_static)\nts1.circle('date', 't1', size=1, source=source, color=None, selection_color=\"orange\")\n\nts2 = figure(plot_width=900, plot_height=200, tools=tools, x_axis_type='datetime', active_drag=\"xbox_select\")\nts2.x_range = ts1.x_range\nts2.line('date', 't2', source=source_static)\nts2.circle('date', 't2', size=1, source=source, color=None, selection_color=\"orange\")\n\n# set up callbacks\n\ndef ticker1_change(attrname, old, new):\n    ticker2.options = nix(new, DEFAULT_TICKERS)\n    update()\n\ndef ticker2_change(attrname, old, new):\n    ticker1.options = nix(new, DEFAULT_TICKERS)\n    update()\n\ndef update(selected=None):\n    t1, t2 = ticker1.value, ticker2.value\n\n    data = get_data(t1, t2)\n    source.data = source.from_df(data[['t1', 't2', 't1_returns', 't2_returns']])\n    source_static.data = source.data\n\n    update_stats(data, t1, t2)\n\n    corr.title.text = '%s returns vs. %s returns' % (t1, t2)\n    ts1.title.text, ts2.title.text = t1, t2\n\ndef update_stats(data, t1, t2):\n    stats.text = str(data[[t1, t2, t1+'_returns', t2+'_returns']].describe())\n\nticker1.on_change('value', ticker1_change)\nticker2.on_change('value', ticker2_change)\n\ndef selection_change(attrname, old, new):\n    t1, t2 = ticker1.value, ticker2.value\n    data = get_data(t1, t2)\n    selected = source.selected.indices\n    if selected:\n        data = data.iloc[selected, :]\n    update_stats(data, t1, t2)\n\nsource.selected.on_change('indices', selection_change)\n\n# set up layout\nwidgets = column(ticker1, ticker2, stats)\nmain_row = row(corr, widgets)\nseries = column(ts1, ts2)\nlayout = column(main_row, series)\n\n# initialize\nupdate()\n\ncurdoc().add_root(layout)\ncurdoc().title = \"Stocks\"\n", "path": "examples/app/stocks/main.py"}]}