<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Demonstration of Use Case
Users can enter step by step explanations of changes made to a SciSheet in a Jupyter notebook
Load necessary packages
Step1:  Load data into the notebook
Step2:  BUG currently seems to be coming from handonstable rendering
Display the loaded data as a scisheet widget
Step3:  Testing different ways to convert df to json
<ASSISTANT_TASK:>
Python Code:
import json
import numpy as np
import pandas as pd
from jupyter_scisheets_widget import scisheets_widget
Explanation: Demonstration of Use Case
Users can enter step by step explanations of changes made to a SciSheet in a Jupyter notebook
Load necessary packages
End of explanation
import pandas_datareader as pdr
ibm_data = pdr.get_data_yahoo('IBM')
income_data = pd.read_csv('income_data.csv', sep=';')
income_data
income_data['test_col'] = income_data['2006']
Explanation: Load data into the notebook
End of explanation
import ast
df = income_data
model_data = df.to_json(orient='split')
model_data = ast.literal_eval(model_data)
model_data_2 = json.dumps(model_data)
tbl._model_data = json.dumps(model_data)
model_data_2
tbl._model_data
%%javascript
var json_model = this.model.get('_model_data')
console.log(json_model)
tbl = scisheets_widget.SciSheetTable()
tbl.load_df(income_data)
tbl
income_data
bob = income_data.copy()
bob['House Party 2'] = 5
income_data
bob
from IPython.display import display
display(tbl)
tbl2._widget._model_data
tbl2 = scisheets_widget.HandsonDataFrame(income_data)
tbl2.show()
scisheets_widget.HandsonDataFrame(income_data)._widget._model_data
import ast
data_dic = {}
data_dic['columns'] = ast.literal_eval(tbl._model_header)
data_dic['index'] = ast.literal_eval(tbl._model_row_header)
data_dic['data'] = ast.literal_eval(tbl._model_data)
pd.read_json(json.dumps(data_dic), orient='split')
income_data.to_json(orient='split')
data_dic
cols = {'columns': tbl._model_header.encode('utf-8')}
ind = {'index': tbl._model_row_header.encode('utf-8')}
data = {'data': tbl._model_data.encode('utf-8')}
z=cols
z.update(ind)
z.update(data)
z
json.dumps(z)
pd.read_json(json.dumps(z))
model_data = df.to_json(orient='split')
model_data = ast.literal_eval(model_data)
self._model_data = json.dumps(model_data['data'])
self._model_header = json.dumps(model_data['columns'])
self._model_row_header = json.dumps(model_data['index'])
tbl1._widget._model_data
tbl1 = scisheets_widget.HandsonDataFrame(income_data)
tbl1.show()
import ipywidgets as widgets
print(widgets.Widget.unobserve.__doc__)
tbl1._on_displayed()
tbl1._widget._model_header
tbl_ibm = scisheets_widget.SciSheetTable()
tbl_ibm.load_df(ibm_data)
tbl_ibm
tbl = scisheets_widget.SciSheetTable()
tbl.load_df(income_data[['GEOID', 'State']])
tbl
%%html
<div id="example1" class="hot handsontable"></div>
<script src="https://docs.handsontable.com/0.34.4/bower_components/handsontable/dist/handsontable.full.js"></script>
<link type="text/css" rel="stylesheet" href="https://docs.handsontable.com/0.34.4/bower_components/handsontable/dist/handsontable.full.min.css">
%%javascript
document.addEventListener("DOMContentLoaded", function() {
  var
    data1 = [
      ['', 'Tesla', 'Nissan', 'Toyota', 'Honda', 'Mazda', 'Ford'],
      ['2017', 10, 11, 12, 13, 15, 16],
      ['2018', 10, 11, 12, 13, 15, 16],
      ['2019', 10, 11, 12, 13, 15, 16],
      ['2020', 10, 11, 12, 13, 15, 16],
      ['2021', 10, 11, 12, 13, 15, 16]
    ],
    container1 = document.getElementById('example1'),
    settings1 = {
      data: data1
    },
    hot1;
  
  container1.append('allice')
  hot1 = new Handsontable(container1, settings1);
  data1[0][1] = 'Ford'; // change "Kia" to "Ford" programmatically
  hot1.render();
  
});
%%javascript
this.element.append('steve')
data = [{"name": "Lisp", "value": 1}, {"name": "Scala", "value": 2}, {"name": "Perl", "value": 4}, {"name": "Java", "value": 5}, {"name": "C++", "value": 8}, {"name": "Python", "value": 10}]
tbl = scisheets_widget.SciSheetTable()
tbl.load_list(income_data)
tbl
Explanation: BUG currently seems to be coming from handonstable rendering
Display the loaded data as a scisheet widget
End of explanation
income_data.to_json(orient='index')
income_data.to_json(orient='values')
income_data.to_json(orient='records')
income_data.to_json(orient='columns')
income_data.to_json(orient='split')
bob = income_data.to_json(orient='split')
import ast
bob2 = ast.literal_eval(bob)
for key, value in bob2.items():
    print("Key:")
    print(key)
bob2['columns']
json.dumps(bob2['columns'])
bob2['columns']
'''Illustrates how to detect an assignment for a DataFrame.'''
import pandas as pd
class VirtualDataFrame(object):
    def __init__(self, df):
        self._df = df.copy()
        
    def _value_changed_(self):
        if self._df.__setitem__:
            print "Setting %s to %s" % (str(key), str(value))
        
    def __setitem__(self, key, value):
        print "Setting %s to %s" % (str(key), str(value))
class VirtualDataFrame2(object):
    def __init__(self, df):
        self._df = df
        
#     def _value_changed_(self):
#         if self._df.__setitem__:
#             print "Setting %s to %s" % (str(key), str(value))
        
#     def __setitem__(self, key, value):
#         print "Setting %s to %s" % (str(key), str(value))
bob2 = VirtualDataFrame2(income_data)
bob2._df.loc[3,'State'] = 'Louisiana'
income_data
bob = VirtualDataFrame(income_data)
bob._df.loc[2,'State'] = 'Alex'
income_data
class with_called_attribute:
    def __init__(self, func):
        self.func = func
        self.called = False
    def __call__(self, *args, **kwargs):
        self.called = True
        self.func(*args, **kwargs)
@with_called_attribute
def run_some_thing(*args, **kwargs):
    print("You called with:", *args, **kwargs)
run_some_thing.called
#>>> False
run_some_thing(10)
#>>> You called with: 10
run_some_thing.called
#>>> True
class Detector(object):
    def __init__(self, df):
        self.loadTableIsCalledForObjA = False
        self._df = df
    def __setitem__(self):
        if type(self._df) is pd.DataFrame:
            print('True')
bob = Detector(income_data)
bob._df.loc[1, 'State'] = 
loadTable(income_data)
detector.loadTableIsCalledForObjA
bob._df.loc[1, 'State'] = 'Barber'
bob['Alice'] = bob['State']
income_data
income_data
import pandas as pd
import numpy as np
class MyDF(pd.DataFrame):
    @property
    def _constructor(self):
        return MyDF
mydf = MyDF(np.random.randn(3,4), columns=['A','B','C','D'])
print type(mydf)
mydf_sub = mydf[['A','C']]
print type(mydf_sub)
import pandas as pd
import numpy as np
class MyDF(pd.DataFrame):
    _attributes_ = "myattr1,myattr2"
    def __init__(self, *args, **kw):
        super(MyDF, self).__init__(*args, **kw)
        if len(args) == 1 and isinstance(args[0], MyDF):
            args[0]._copy_attrs(self)
    def _copy_attrs(self, df):
        for attr in self._attributes_.split(","):
            df.__dict__[attr] = getattr(self, attr, None)
    @property
    def _constructor(self):
        def f(*args, **kw):
            df = MyDF(*args, **kw)
            self._copy_attrs(df)
            return df
        return f
mydf = MyDF(np.random.randn(3,4), columns=['A','B','C','D'])
print type(mydf)
mydf_sub = mydf[['A','C']]
print type(mydf_sub)
mydf.myattr1 = 1
mydf_cp1 = MyDF(mydf)
mydf_cp2 = mydf.copy()
print mydf_cp1.myattr1, mydf_cp2.myattr1
mydf_cp1
mydf_cp2
    def write(self):
        return dumps(
            self.obj,
            orient=self.orient,
            double_precision=self.double_precision,
            ensure_ascii=self.ensure_ascii,
            date_unit=self.date_unit,
            iso_dates=self.date_format == 'iso',
            default_handler=self.default_handler
        )
import json
json.dumps(income_data)
import pandas._libs.json as json
dumps = json.dumps
dumps(income_data)
import pandas._libs.
print('help')
print 'help'
Explanation: Testing different ways to convert df to json
End of explanation
<END_TASK>