import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import dash_table
from dash.dependencies import Input, Output, State
import io
import base64
#pip install dash==1.15.0
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.scripts.config.serve_locally = True
app.layout = html.Div([
html.Div(html.Center(html.H3('Your Personal File Comparator'))),
html.Div([
html.Center(dcc.Upload(html.Button('Upload file 1 here'),id='upload_file_1')),
html.Hr(),
html.Div(id='datatable_file_1'),
html.Center(dcc.Upload(html.Button('Upload file 2 here'),id='upload_file_2')),
html.Hr(),
html.Div(id='datatable_file_2'),
], style={'columnCount': 2}),
html.Button('Compare'),
html.Div(id='compare_datatable')
]
)
def read_content(contents):
"""
Read the content of file and convert it to DataFrame
"""
content_type, content_string = contents.split(',')
decoded = base64.b64decode(content_string)
s = str(decoded,'utf-8')
df = pd.read_csv(io.StringIO(s))
return df
def parse_content(contents, filename):
"""
To generate an on the fly html and assign it to app.layout above where instead of datatable
we now has used html.Div
"""
df = read_content(contents)
columns = [{"id":i, "name": i} for i in df.columns]
return html.Div([
html.H5("Reading : {}".format(filename)),
dash_table.DataTable(data=df.to_dict('rows'), columns=columns),
html.Hr()
])
def compare_content(contents, filename, secondfilecontents, secondfilename):
"""
Compare the content of the two dfs and returns a DF with diff in it
"""
df_first = read_content(contents)
df_second = read_content(secondfilecontents)
df_merge = pd.merge(df_first, df_second, on=['cusip', 'key'], how='inner', suffixes=('_first', '_second'))
df_merge['diff'] = df_merge['value_first'] - df_merge['value_second']
df_merge['abs_diff'] = abs(df_merge['diff'])
df_merge.sort_values(by=['abs_diff'], ascending=False, inplace=True)
df_merge.drop(['abs_diff'], axis=1, inplace=True)
columns = [{"id":i, "name": i} for i in df_merge.columns]
return html.Div([
html.H5("Comaprison of {} and {}".format(filename, secondfilename)),
dash_table.DataTable(data=df_merge.to_dict('rows'), columns=columns),
html.Hr()
])
@app.callback(
[Output('datatable_file_1', 'children'), Output('datatable_file_2', 'children'), Output('compare_datatable', 'children')],
[Input('upload_file_1', 'contents'), Input('upload_file_2', 'contents')],
[State('upload_file_1', 'filename'), State('upload_file_2', 'filename')]
)
def update_figure(contents, secondfilecontents,filename, secondfilename):
if not contents or not secondfilecontents:
return [[], []], [[], []], [[], []]
return [parse_content(contents, filename)], [parse_content(secondfilecontents, secondfilename)],\
[compare_content(contents, filename, secondfilecontents, secondfilename)]
if __name__ == '__main__':
app.run_server(debug=True)