Skip to content

Commit aebf0d7

Browse files
mrvisschermarc-vdm
andauthored
Multiple improvements for the scenario import panel (#1203)
* Deleted scenario's now actually update the scenario dataframe * Logging changes to fix #1086 * Adding and removing scenario tables now quicker * Changed combination chooser to radio buttons * The combination type can now be succesfully switched after scenario files have been loaded * Add statistiscs to scenario import panel * Improvements to scenario toolbar layout * Stats now also update on empty scenarios or deletions * Fixed tooltip bug on scenario tables * Align scenariotables at the top * Resolve bug with duplicates where 1) DF could not be created 2) file numbering was broken * Minor documentation + code changes * Fix scenario exporter saving with useful file extension by default * Fix scenario exporter saving with useful file extension by default * Set Excel default separator (;) for CSV export * Fix ABPopup default DF export file format * Move cursor override + add todo --------- Co-authored-by: marc-vdm <m.t.van.der.meide@cml.leidenuniv.nl>
1 parent 150c3c1 commit aebf0d7

5 files changed

Lines changed: 155 additions & 70 deletions

File tree

activity_browser/bwutils/superstructure/file_dialogs.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -175,15 +175,16 @@ def save_dataframe(self):
175175
return True
176176
filepath, _ = QtWidgets.QFileDialog.getSaveFileName(
177177
parent=self, caption="Choose the location to save the dataframe",
178-
filter="All Files (*.*);; CSV (*.csv);; Excel (*.xlsx)",
178+
filter="Excel (*.xlsx *.xls);; CSV (*.csv)",
179179
)
180180
QtWidgets.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor)
181-
if not filepath.strip():
182-
return False
183181
if filepath.endswith('.xlsx') or filepath.endswith('.xls'):
184182
self._dataframe.to_excel(filepath, index=False)
185-
else:
186-
self._dataframe.to_csv(filepath, index=False, sep=';')
183+
QtWidgets.QApplication.restoreOverrideCursor()
184+
return True
185+
elif not filepath.endswith('.csv'):
186+
filepath += '.csv'
187+
self._dataframe.to_csv(filepath, index=False, sep=';')
187188
QtWidgets.QApplication.restoreOverrideCursor()
188189
return True
189190

activity_browser/bwutils/superstructure/manager.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from typing import List
44
import numpy as np
55
import pandas as pd
6-
from pandas.api.types import is_numeric_dtype, is_number
6+
from pandas.api.types import is_numeric_dtype
77
from PySide2.QtWidgets import QApplication, QPushButton
88
from PySide2.QtCore import Qt
99
from typing import Union, Optional
@@ -12,7 +12,7 @@
1212

1313
from .activities import fill_df_keys_with_fields, get_activities_from_keys
1414
from .dataframe import scenario_columns
15-
from .utils import guess_flow_type, SUPERSTRUCTURE, _time_it_, edit_superstructure_for_string
15+
from .utils import guess_flow_type, SUPERSTRUCTURE, _time_it_
1616

1717
from .file_dialogs import ABPopup
1818
from ..errors import (CriticalScenarioExtensionError, ScenarioExchangeNotFoundError,
@@ -465,10 +465,10 @@ def check_scenario_exchange_values(df: pd.DataFrame, cols: pd.Index):
465465
QPushButton('Save'),
466466
QPushButton('Cancel')
467467
)
468+
QApplication.restoreOverrideCursor()
468469
critical.dataframe(df[bad_entries.isna().any(axis=1)], SUPERSTRUCTURE)
469470
critical.save_options()
470471
critical.dataframe_to_file(df, bad_entries.isna().any(axis=1))
471-
QApplication.restoreOverrideCursor()
472472
critical.exec_()
473473
raise ScenarioExchangeDataNonNumericError()
474474

@@ -507,18 +507,16 @@ def check_duplicates(data: Optional[Union[pd.DataFrame, list]],
507507
while count < len(data):
508508
count += 1
509509
popped = data[-count]
510-
duplicates = SuperstructureManager._check_duplicates(df, popped)
510+
duplicates = SuperstructureManager._check_duplicates(df, popped, count)
511511
if not duplicates.empty:
512512
duplicated[count] = duplicates
513-
if duplicated:
514513

514+
if duplicated:
515515
msg = "<p>Duplicates have been found, meaning that there are several rows in the scenario file describing "\
516516
"scenarios for the same flow. The AB can deal with this by discarding all but the last row for this "\
517517
"exchange.</p> <p>Press 'Ok' to proceed, press 'Cancel' to abort.</p>"
518-
for file, frame in duplicated.items():
519-
frame.insert(0, 'File', file, allow_duplicates=True)
520518
warning = ABPopup.abWarning('Duplicate flow exchanges', msg, QPushButton('Ok'), QPushButton('Cancel'))
521-
warning.dataframe(pd.concat([file for file in duplicated.values()]), ['File'] + SUPERSTRUCTURE)
519+
warning.dataframe(pd.concat([file for file in duplicated.values()]), ['file'] + SUPERSTRUCTURE.tolist())
522520
QApplication.restoreOverrideCursor()
523521
response = warning.exec_()
524522
QApplication.setOverrideCursor(Qt.WaitCursor)
@@ -527,23 +525,27 @@ def check_duplicates(data: Optional[Union[pd.DataFrame, list]],
527525
return data
528526

529527
@staticmethod
530-
def _check_duplicates(dfp: pd.DataFrame, pdf: pd.DataFrame,
528+
def _check_duplicates(dfp: pd.DataFrame, pdf: pd.DataFrame, count: int,
531529
index: list = ['to key', 'from key', 'flow type']) -> pd.DataFrame:
530+
# TODO fix variable names 'dfp' & 'pdf' to something undearstandeable
531+
# TODO create useful docstring, already clear this is a private method from '_' prefix
532532
""" NOT TO BE USED OUTSIDE OF CALLING METHOD check_duplicates """
533533
# First save the original index and create a new one that can help the user identify duplicates in their files
534534
d_idx = dfp.index
535+
dfp.insert(0, 'file', '1', allow_duplicates=True) # add the file number
535536
dfp.index = pd.Index([str(i) for i in range(dfp.shape[0])])
536537
p_idx = pdf.index
538+
pdf.insert(0, 'file', str(count), allow_duplicates=True) # add the file number
537539
pdf.index = pd.Index([str(i) for i in range(pdf.shape[0])])
538540
df = pd.concat([dfp, pdf], ignore_index=True)
539541
dfp.index = d_idx
540542
pdf.index = p_idx
541543
dfp.drop_duplicates(index, keep='last', inplace=True)
542-
# pdf.drop_duplicates(index, keep='last', inplace=True)
543544
return df.loc[df.duplicated(index, keep=False)]
544545

545546
@staticmethod
546547
def _check_duplicate(data: pd.DataFrame, index: list = ['to key', 'from key', 'flow type']) -> pd.DataFrame:
548+
# TODO create useful docstring, already clear this is a private method from '_' prefix
547549
""" NOT TO BE USED OUTSIDE OF CALLING METHOD check_duplicates """
548550
df = data.copy()
549551
df.index = pd.Index([str(i) for i in range(df.shape[0])])

activity_browser/bwutils/superstructure/utils.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
# Different kinds of indexes, to allow for quick selection of data from
1313
# the Superstructure DataFrame.
14+
#TODO review if this can be made a list instead of pd.Index
1415
SUPERSTRUCTURE = pd.Index([
1516
"from activity name",
1617
"from reference product",

0 commit comments

Comments
 (0)