From 0dd26a53d886e176694828a29146c98f99841f1f Mon Sep 17 00:00:00 2001 From: taruma sakti Date: Wed, 18 May 2022 17:00:03 +0700 Subject: [PATCH 1/2] removing global variable SUMMARY_ALL --- app.py | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/app.py b/app.py index d4ad768..a2d5691 100644 --- a/app.py +++ b/app.py @@ -21,9 +21,6 @@ "https://cdn.jsdelivr.net/gh/AnnMarieW/dash-bootstrap-templates@V1.0.4/dbc.min.css" ) -# GLOBAL VARS -SUMMARY_ALL = None - # APP app = dash.Dash( APP_TITLE, @@ -184,7 +181,6 @@ def callback_download_table(_, table_data, table_columns): prevent_initial_call=True, ) def callback_analyze(_, table_data, table_columns): - global SUMMARY_ALL button_viz_analysis_disabled = True button_viz_analysis_outline = True @@ -192,12 +188,12 @@ def callback_analyze(_, table_data, table_columns): try: dataframe = pyfunc.transform_to_dataframe(table_data, table_columns) - SUMMARY_ALL = pyfunc.generate_summary_all(dataframe, n_days=["16D", "MS", "YS"]) + summary_all = pyfunc.generate_summary_all(dataframe, n_days=["16D", "MS", "YS"]) tables = [ pylayoutfunc.create_table_summary( summary, f"table-analyze-{counter}", deletable=False ) - for counter, summary in enumerate(SUMMARY_ALL) + for counter, summary in enumerate(summary_all) ] children = pylayoutfunc.create_tabcard_table_layout(tables) @@ -222,7 +218,11 @@ def callback_analyze(_, table_data, table_columns): ) def callback_download_results(_): - dataframe = pd.concat(SUMMARY_ALL, axis=1, keys=["Biweekly", "Monthly", "Yearly"]) + # TODO: FIX GLOBAL VARIABLE SUMMARY ALL + + summary_all = ... + + dataframe = pd.concat(summary_all, axis=1, keys=["Biweekly", "Monthly", "Yearly"]) return dcc.send_data_frame(dataframe.to_csv, "results.csv") @@ -231,7 +231,7 @@ def callback_download_results(_): Input("button-viz-analysis", "n_clicks"), prevent_initial_call=True, ) -def callback_troubleshoot(_): +def callback_graph_analysis(_): from itertools import product label_periods = ["Biweekly", "Monthly", "Yearly"] @@ -239,6 +239,10 @@ def callback_troubleshoot(_): label_raindry = ["Dry + Rain"] label_ufunc = label_maxsum + label_raindry + # TODO: FIX GLOBAL VARIABLE SUMMARY_ALL + + summary_all = ... + graphs_maxsum = [ pyfigure.figure_summary_maxsum( summary, @@ -246,15 +250,15 @@ def callback_troubleshoot(_): period=period, subplot_titles=["Max", "Sum"], ) - for summary, title, period in zip(SUMMARY_ALL, label_maxsum * 3, label_periods) + for summary, title, period in zip(summary_all, label_maxsum * 3, label_periods) ] graphs_raindry = [ pyfigure.figure_summary_raindry( summary, title=f"{period}: {title}", period=period ) - for summary, title, period in zip(SUMMARY_ALL, label_raindry * 3, label_periods) + for summary, title, period in zip(summary_all, label_raindry * 3, label_periods) ] - graph_maxdate = [pyfigure.figure_summary_maxdate(SUMMARY_ALL)] + graph_maxdate = [pyfigure.figure_summary_maxdate(summary_all)] all_graphs = graphs_maxsum + graphs_raindry + graph_maxdate labels = [": ".join(i) for i in product(label_ufunc, label_periods)] From f5eb5a63d8eb6e1a455de6d460846ff8bfe3ee46 Mon Sep 17 00:00:00 2001 From: taruma sakti Date: Thu, 19 May 2022 10:55:00 +0700 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=8C=8D=20remove=20global=20variables?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app.py | 77 +++++++++++++++++++++++++++++++++++++++++++++++-------- pyfunc.py | 33 +++++++++++++++++++++--- 2 files changed, 96 insertions(+), 14 deletions(-) diff --git a/app.py b/app.py index a2d5691..eb0c7c7 100644 --- a/app.py +++ b/app.py @@ -214,24 +214,67 @@ def callback_analyze(_, table_data, table_columns): @app.callback( Output("download-analysis-csv", "data"), Input("button-download-analysis-csv", "n_clicks"), + State("table-analyze-0", "data"), + State("table-analyze-0", "columns"), + State("table-analyze-1", "data"), + State("table-analyze-1", "columns"), + State("table-analyze-2", "data"), + State("table-analyze-2", "columns"), prevent_initial_call=True, ) -def callback_download_results(_): +def callback_download_results( + _, + biweekly_data, + biweekly_columns, + monthly_data, + monthly_columns, + yearly_data, + yearly_columns, +): + + biweekly = (biweekly_data, biweekly_columns) + monthly = (monthly_data, monthly_columns) + yearly = (yearly_data, yearly_columns) + + summary_all = [] + for period in (biweekly, monthly, yearly): + data, columns = period + dataframe = pyfunc.transform_to_dataframe( + data, + columns, + multiindex=True, + apply_numeric=False, + parse_dates=["max_date"], + ) + summary_all.append(dataframe) - # TODO: FIX GLOBAL VARIABLE SUMMARY ALL - - summary_all = ... + dataframe_all = pd.concat( + summary_all, axis=1, keys=["Biweekly", "Monthly", "Yearly"] + ) - dataframe = pd.concat(summary_all, axis=1, keys=["Biweekly", "Monthly", "Yearly"]) - return dcc.send_data_frame(dataframe.to_csv, "results.csv") + return dcc.send_data_frame(dataframe_all.to_csv, "results.csv") @app.callback( Output("tab-graph-analysis", "children"), Input("button-viz-analysis", "n_clicks"), + State("table-analyze-0", "data"), + State("table-analyze-0", "columns"), + State("table-analyze-1", "data"), + State("table-analyze-1", "columns"), + State("table-analyze-2", "data"), + State("table-analyze-2", "columns"), prevent_initial_call=True, ) -def callback_graph_analysis(_): +def callback_graph_analysis( + _, + biweekly_data, + biweekly_columns, + monthly_data, + monthly_columns, + yearly_data, + yearly_columns, +): from itertools import product label_periods = ["Biweekly", "Monthly", "Yearly"] @@ -239,10 +282,22 @@ def callback_graph_analysis(_): label_raindry = ["Dry + Rain"] label_ufunc = label_maxsum + label_raindry - # TODO: FIX GLOBAL VARIABLE SUMMARY_ALL - - summary_all = ... - + biweekly = (biweekly_data, biweekly_columns) + monthly = (monthly_data, monthly_columns) + yearly = (yearly_data, yearly_columns) + + summary_all = [] + for summary_period in (biweekly, monthly, yearly): + data, columns = summary_period + dataframe = pyfunc.transform_to_dataframe( + data, + columns, + multiindex=True, + apply_numeric=False, + parse_dates=["max_date"], + ) + summary_all.append(dataframe) + graphs_maxsum = [ pyfigure.figure_summary_maxsum( summary, diff --git a/pyfunc.py b/pyfunc.py index e1eb153..086702b 100644 --- a/pyfunc.py +++ b/pyfunc.py @@ -58,7 +58,7 @@ def max_date(vector): if vector.any(): return vector.idxmax().date() else: - return np.nan + return pd.NaT def max(vector): return vector.max() @@ -70,7 +70,7 @@ def max(vector): dataframe, ufunc=ufunc, ufunc_col=ufunc_col, n_days=n_days ) - return summary + return summary.infer_objects() def generate_summary_all(dataframe, n_days: list = None): @@ -84,10 +84,15 @@ def generate_summary_all(dataframe, n_days: list = None): def transform_to_dataframe( - table_data, table_columns, multiindex: bool = False, apply_numeric: bool = True + table_data, + table_columns, + multiindex: bool = False, + apply_numeric: bool = True, + parse_dates: list = None, ): dataframe = pd.DataFrame(table_data) + if multiindex is True: dataframe.columns = pd.MultiIndex.from_tuples( [item["name"] for item in table_columns] @@ -98,9 +103,31 @@ def transform_to_dataframe( dataframe["DATE"] = pd.to_datetime(dataframe.DATE) dataframe = dataframe.set_index("DATE").sort_index() + if multiindex is True: + # removing date (index.name) from top level multiindex + dataframe.columns = pd.MultiIndex.from_tuples(dataframe.columns.to_flat_index()) + if apply_numeric is True: dataframe = dataframe.apply(pd.to_numeric, errors="coerce") else: dataframe = dataframe.infer_objects() + if parse_dates is not None: + if multiindex: + for col_dates in parse_dates: + col_parsing = [ + col_tuple + for col_tuple in dataframe.columns + if col_dates in col_tuple + ] + for col_dates in col_parsing: + dataframe[col_dates] = pd.to_datetime( + dataframe[col_dates], errors="coerce" + ) + else: + for col_dates in parse_dates: + dataframe[col_dates] = pd.to_datetime( + dataframe[col_dates], errors="coerce" + ) + return dataframe