Last active
January 23, 2024 01:45
-
-
Save hdary85/716d99fd172e410482957a3026655607 to your computer and use it in GitHub Desktop.
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
import ipywidgets as widgets | |
from IPython.display import display | |
class NestedDictManagerJupyter: | |
def __init__(self, original_data): | |
self.original_data = original_data | |
self.data = original_data.copy() | |
self.accordion = widgets.Accordion(selected_index=None) | |
self.accordion.observe(self.update_selected_item, names='selected_index') | |
self.tree = widgets.TreeView(show_only_select_widget=True) | |
self.tree.observe(self.update_selected_item, names='selected_labels') | |
self.text_output = widgets.Output() | |
self.update_btn = widgets.Button(description="Update") | |
self.update_btn.on_click(self.update_key) | |
self.delete_btn = widgets.Button(description="Delete") | |
self.delete_btn.on_click(self.delete_key) | |
self.rename_btn = widgets.Button(description="Rename") | |
self.rename_btn.on_click(self.rename_key) | |
self.add_btn = widgets.Button(description="Add Key") | |
self.add_btn.on_click(self.add_key) | |
self.display() | |
def display_dict(self, dictionary, parent=None, label=''): | |
if parent is None: | |
parent = self.tree | |
for key, value in dictionary.items(): | |
if isinstance(value, dict): | |
node = widgets.TreeNode(icon='folder-open', open_icon='folder', label=str(key)) | |
parent.children += [node] | |
self.display_dict(value, parent=node, label=str(key)) | |
else: | |
leaf = widgets.LeafNode(icon='file', label=f"{key}: {value}") | |
parent.children += [leaf] | |
def update_selected_item(self, change): | |
if change['owner'] == self.accordion: | |
selected_index = change['new'] | |
if selected_index is not None: | |
selected_label = self.accordion.children[selected_index].value | |
self.selected_item_path = selected_label | |
else: | |
self.selected_item_path = None | |
elif change['owner'] == self.tree: | |
selected_labels = change['new'] | |
if selected_labels: | |
selected_label = selected_labels[0] | |
self.selected_item_path = selected_label | |
else: | |
self.selected_item_path = None | |
def update_key(self, _): | |
if not hasattr(self, "selected_item_path") or not self.selected_item_path: | |
print("Please select a key to update.") | |
return | |
key = self.selected_item_path.split(":")[0].strip() | |
new_value = input(f"Enter new value for '{key}': ") | |
if new_value is not None: | |
self.update_original_dict(key, new_value) | |
self.refresh_display() | |
def delete_key(self, _): | |
if not hasattr(self, "selected_item_path") or not self.selected_item_path: | |
print("Please select a key to delete.") | |
return | |
key = self.selected_item_path.split(":")[0].strip() | |
confirm = input(f"Are you sure you want to delete the key '{key}'? (yes/no): ").lower() | |
if confirm == 'yes': | |
self.delete_from_original_dict(key) | |
self.refresh_display() | |
def rename_key(self, _): | |
if not hasattr(self, "selected_item_path") or not self.selected_item_path: | |
print("Please select a key to rename.") | |
return | |
old_key = self.selected_item_path.split(":")[0].strip() | |
new_key = input(f"Enter new key name for '{old_key}': ") | |
if new_key is not None: | |
self.rename_in_original_dict(old_key, new_key) | |
self.refresh_display() | |
def add_key(self, _): | |
parent_path, new_key = input("Enter parent key path (e.g., key1/key2) and new key name: ").split() | |
parent_dict = self.get_dict_by_path(parent_path) | |
parent_dict[new_key] = "New Value" | |
self.refresh_display() | |
def refresh_display(self): | |
self.accordion.children = [] | |
self.display_dict(self.original_data) | |
def update_original_dict(self, key, new_value): | |
nested_keys = key.split('/') | |
current_dict = self.original_data | |
for nested_key in nested_keys[:-1]: | |
current_dict = current_dict[nested_key] | |
current_dict[nested_keys[-1]] = new_value | |
def delete_from_original_dict(self, key): | |
nested_keys = key.split('/') | |
current_dict = self.original_data | |
for nested_key in nested_keys[:-1]: | |
current_dict = current_dict[nested_key] | |
del current_dict[nested_keys[-1]] | |
def rename_in_original_dict(self, old_key, new_key): | |
nested_keys = old_key.split('/') | |
current_dict = self.original_data | |
for nested_key in nested_keys[:-1]: | |
current_dict = current_dict[nested_key] | |
current_dict[new_key] = current_dict.pop(nested_keys[-1]) | |
def get_dict_by_path(self, path): | |
keys = path.split('/') | |
current_dict = self.original_data | |
for key in keys: | |
current_dict = current_dict[key] | |
return current_dict | |
def display(self): | |
with self.text_output: | |
display(self.tree) | |
self.accordion.children = [widgets.VBox([self.text_output])] | |
display(self.accordion) | |
display(widgets.HBox([self.update_btn, self.delete_btn, self.rename_btn, self.add_btn])) | |
# Example of an existing dictionary | |
original_dictionary = { | |
'key1': 'value1', | |
'key2': { | |
'key3': 'value3', | |
'key4': 'value4' | |
}, | |
'key5': { | |
'key6': { | |
'key7': 'value7' | |
} | |
} | |
} | |
app_jupyter = NestedDictManagerJupyter(original_dictionary) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment