Skip to content

Instantly share code, notes, and snippets.

@danielgran
Created October 2, 2024 07:53
Show Gist options
  • Save danielgran/90ca5b04521b8e350c8c9cf9057a9989 to your computer and use it in GitHub Desktop.
Save danielgran/90ca5b04521b8e350c8c9cf9057a9989 to your computer and use it in GitHub Desktop.
Own Fiber Implementation, heavily inspired from the React Project. Converts General and Binaray trees, vice versa. Unit tests ~ 500 LOC
import uuid
class FiberNode:
def __init__(self,
name: str,
child=None,
sibling=None):
self.guid = uuid.uuid4()
self.name = name
self.child = child
self.sibling = sibling
def __repr__(self):
return f"[{self.name} -> {self.child} -> {self.sibling}]"
def __eq__(self,
other):
return self.__repr__() == other.__repr__()
def clean(self):
new_tree = clean_fiber_tree_recursively(self)
if new_tree is None:
return None
self.child = new_tree.child
self.sibling = new_tree.sibling
self.name = new_tree.name
return self
def clean_fiber_tree_recursively(fiber: FiberNode):
if fiber in [{}, None]:
return None
if isinstance(fiber, FiberNode):
fiber.child = clean_fiber_tree_recursively(fiber.child)
fiber.sibling = clean_fiber_tree_recursively(fiber.sibling)
if fiber.child in [None, dict()] and fiber.sibling is None:
return None
current_child_fiber = fiber.child
current_sibling_fiber = fiber.sibling
fiber.child = clean_fiber_tree_recursively(current_child_fiber)
if current_sibling_fiber:
if current_sibling_fiber.child in [{}, None]:
fiber.sibling = current_sibling_fiber.sibling
return fiber
def dict_to_fiber_tree(dic: dict):
'''
Converts a dictionary to a FiberTree.
Basically, this just is a function which converts a general tree to a binary tree.
:param dic:
:return: FiberNode
'''
if not dic:
return dic
if isinstance(dic, dict):
if len(dic) == 0:
raise ValueError("Empty dictionary")
current_root_fiber = FiberNode(name=list(dic.keys())[0])
if len(dic) == 1:
current_root_fiber.child = dict_to_fiber_tree(list(dic.values())[0])
return current_root_fiber
current_root_fiber.child = dict_to_fiber_tree(list(dic.values())[0])
dic.pop(list(dic.keys())[0]) # only process the n+1 element further
current_root_fiber.sibling = dict_to_fiber_tree(dic)
return current_root_fiber
else:
return dic
def fiber_tree_to_dict_recursively(fiber: FiberNode):
if fiber is None:
return None
if not isinstance(fiber, FiberNode):
return fiber
if isinstance(fiber, dict):
return fiber
if not isinstance(fiber.child, FiberNode) and not fiber.sibling:
return {fiber.name: fiber.child}
result_dictionary = dict()
current_fiber = fiber
while current_fiber:
if isinstance(current_fiber, FiberNode):
result_dictionary[current_fiber.name] = fiber_tree_to_dict_recursively(current_fiber.child)
current_fiber = current_fiber.sibling
return result_dictionary
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment