-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added lca_excel.py and select_values.py
- Loading branch information
Nair, Rahul Ramesh
committed
Nov 6, 2024
1 parent
48c2d89
commit d16860a
Showing
6 changed files
with
371 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
""" | ||
lca_excel.py | ||
This module provides functions for exporting Life Cycle Assessment (LCA) calculation results | ||
to an Excel format, with each result from an impact categort stored in a separate sheet, which is | ||
a recurring theme in lca-related calculations. | ||
Functions: | ||
- clean_sheet_name(name, max_length=30): Cleans and truncates sheet names for Excel compatibility. | ||
- result_to_excel(results, methods_of_interest, filename): Exports LCA results to an Excel file | ||
with a final sheet summarizing impact assessment methods. | ||
Dependencies: | ||
- pandas | ||
- openpyxl (since pandas does not automatically install this) | ||
""" | ||
|
||
import re | ||
import os | ||
import pandas as pd | ||
|
||
|
||
def clean_sheet_name(name, max_length=30): | ||
"""Cleans and truncates a sheet name to make it compatible with Excel's requirements. | ||
This function removes invalid characters, trims leading and trailing underscores, | ||
and ensures that the name does not exceed the specified maximum length. | ||
Args: | ||
name (str): The original sheet name that may contain invalid characters. | ||
max_length (int): Maximum allowed length for the sheet name. Defaults to 30. | ||
Returns: | ||
str: A cleaned and truncated version of the sheet name, compatible with Excel. | ||
""" | ||
# Remove invalid characters and trim whitespace, quotes, and brackets | ||
name = re.sub( | ||
r"[\\/*?:\[\]']", "_", name | ||
) # Replace invalid characters with underscores | ||
name = re.sub(r"[(),]", "", name) # Remove parentheses and commas | ||
name = name.strip("_") # Remove leading/trailing underscores | ||
return name[:max_length] # Ensure the name does not exceed the maximum length | ||
|
||
|
||
def result_to_excel(results, methods_of_interest, filename): | ||
"""Exports LCA calculation results to an Excel file, with each result in a separate sheet. | ||
This function takes a dictionary of LCA calculation results, each associated with a specific | ||
impact assessment method, and writes them to separate sheets in an Excel file. Additionally, | ||
it creates a final sheet with details of the impact assessment methods such as | ||
method names, impact categories, and units. | ||
Args: | ||
results (dict): A dictionary where keys are method names (or other identifiers) and | ||
values are pandas DataFrames containing LCA results for each method. | ||
methods_of_interest (list of tuples): A list of tuples, each containing: | ||
- Method Name (str): The name of the impact assessment method. | ||
- Impact Category (str): The impact category associated with the method. | ||
- Unit (str): The unit of measurement for the impact category. | ||
filename (str): The path where the Excel file should be saved. | ||
Returns: | ||
str: The absolute path to the saved Excel file. | ||
""" | ||
impact_assessment_methods_df = pd.DataFrame( | ||
methods_of_interest, | ||
columns=["Method Name", "Impact category (i.e sheet name here)", "Unit"], | ||
) | ||
with pd.ExcelWriter(filename) as writer: | ||
for method, df in results.items(): | ||
sheet_name = clean_sheet_name(str(method)) | ||
df.to_excel(writer, sheet_name=sheet_name, index=False) | ||
# Add impact assessment methods as the final sheet | ||
impact_assessment_methods_df.to_excel( | ||
writer, sheet_name="IA Methods", index=False | ||
) | ||
file_path = os.path.abspath(filename) | ||
print(f"Results written to {file_path}") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
""" | ||
select_values.py | ||
This module provides some functions for LCA workflows in Jupyter notebook | ||
which require numerous user inputs such as selecting or changing impact assessment methods. | ||
""" | ||
|
||
import ipywidgets as widgets | ||
from IPython.display import display | ||
import os | ||
|
||
|
||
def result_folders(folder_path, result_direcs): | ||
"""Creates folders for storing results if they do not already exist. | ||
Args: | ||
folder_path (str): The base folder path where result directories should be created. | ||
In Windows, use double backslash to enter the path. Eg. "D:\\test" | ||
result_direcs (list of str): A list of folder/directory names to create within the base folder. | ||
Prints: | ||
str: A message indicating the location of folders that were created. | ||
""" | ||
|
||
if not os.path.exists(folder_path): | ||
os.mkdir(folder_path) | ||
print(f"Base folder created at: {os.path.abspath(folder_path)}") | ||
else: | ||
print(f"Base folder already exists at: {os.path.abspath(folder_path)}") | ||
# creates directories for storing results with in the base folder. | ||
for direc in result_direcs: | ||
sub_folder_path = os.path.join(folder_path, direc) | ||
if not os.path.exists(sub_folder_path): | ||
os.mkdir(sub_folder_path) | ||
print(f"Subfolder created at: {os.path.abspath(sub_folder_path)}") | ||
else: | ||
print(f"Subfolder already exists at: {os.path.abspath(sub_folder_path)}") | ||
|
||
|
||
def single_select_dropdown(names): | ||
"""Creates a single-selection dropdown widget for users to select an option. | ||
Args: | ||
names (list of str): A list of names/options to be displayed in the dropdown. | ||
Returns: | ||
dict: A dictionary containing the selected value with the key 'value'. | ||
""" | ||
|
||
if not names: | ||
raise ValueError("The 'names' list cannot be empty.") | ||
|
||
dropdown = widgets.Dropdown( | ||
options=names, | ||
value=names[0], # Default value | ||
description="Assessment methodology:", | ||
disabled=False, | ||
) | ||
|
||
# Display the dropdown widget | ||
display(dropdown) | ||
|
||
# Variable to store the selected value | ||
selected_value = {"value": dropdown.value} | ||
|
||
# Function to update the selected value | ||
def on_change(change): | ||
selected_value["value"] = change["new"] | ||
print(f"You selected: {selected_value['value']}") | ||
|
||
# Attach the function to the dropdown | ||
dropdown.observe(on_change, names="value") | ||
|
||
return selected_value | ||
|
||
|
||
def multi_select_dropdown(names): | ||
"""Creates a multi-selection dropdown widget for users to select multiple options. | ||
Args: | ||
names (list of str): A list of names/options to be displayed in the multi-select widget. | ||
Returns: | ||
dict: A dictionary containing the selected values with the key 'values'. | ||
""" | ||
|
||
if not names: | ||
raise ValueError("The 'names' list cannot be empty.") | ||
|
||
height_of_each_dropdown_item = ( | ||
20 # sets a default height in pixel for dropdown items | ||
) | ||
dropdown_box_height = ( | ||
len(names) * height_of_each_dropdown_item + 20 | ||
) # estimates the total height of the drop down window based on the total number of items. | ||
multi_select = widgets.SelectMultiple( | ||
options=names, | ||
value=[], # Default value, an empty list | ||
description="Impact Categories:", | ||
disabled=False, | ||
layout=widgets.Layout(width="100%", height=f"{dropdown_box_height}px"), | ||
) | ||
|
||
# Display the multiple selection widget | ||
display(multi_select) | ||
|
||
# Variable to store the selected values | ||
selected_values = {"values": multi_select.value} | ||
|
||
# Function to update the selected values | ||
def on_change_multiple_selection(change): | ||
selected_values["values"] = list(change["new"]) | ||
print(f"You selected: {selected_values['values']}") | ||
|
||
# Attach the function to the multiple selection widget | ||
multi_select.observe(on_change_multiple_selection, names="value") | ||
|
||
return selected_values |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.