Skip to main content

A library to visulize algorithms and data structures

Project description

📌 Introduction

This library lets you visualize algorithms that operate on fundamental data structures like stacks, queues, trees, and graphs. It helps you trace your algorithm line by line while bringing its execution to life with animations.

🚀 Install

pip install algofresco

🚀 Example: Stack Visualization

Here’s a simple example of how you can visualize a stack using the library:

tracer = DataStructureTracer(track_code_lines=True)
stack = []

# Tracked operations
def stack_operations():
    tracer.capture(stack, description="Initial state")
    stack.append(10)  # Tracked
    tracer.capture(stack, description="Pushed 10")
    stack.append(20)  # Tracked
    tracer.capture(stack, description="Pushed 20")
    stack.pop()       # Tracked
    tracer.capture(stack, description="Popped 20")

stack_operations()

# Visualization
visualizer = StackVisualizer(tracer)

# Show the final state
# visualizer.display_snapshot(show_code=True, title="Final Stack State")

# Generate animation (save as GIF)
anim = visualizer.create_animation(show_code=True, interval=1500)
# anim.save("stack_demo.gif", writer="pillow")

🔍 Breaking It Down:

  • tracer = DataStructureTracer(track_code_lines=True): Enables tracking of code execution.
  • stack = []: Initializes the stack we’ll trace.
  • visualizer = StackVisualizer(tracer): Prepares the visualization.
  • anim = visualizer.create_animation(show_code=True, interval=1500): Generates an animation—no need for plt.show(), the library handles that for you.

🎯 Result:


🛠 Creating Your Own Custom Data Structure

Let’s go step by step to create a Singly Linked List visualization using the library.

Step 1: Understanding the Core Components

  • DataStructureTracer - Tracks changes in data structures.
  • DataStructureVisualizer - Base class for visualization.
  • Matplotlib - Used for rendering.

Step 2: Define Your Data Structure

class LinkedListNode:
    def __init__(self, value):
        self.value = value
        self.next = None

class LinkedList:
    def __init__(self):
        self.head = None
        self.tracer = DataStructureTracer()

    def append(self, value):
        """Instrumented append operation"""
        new_node = LinkedListNode(value)
        if not self.head:
            self.head = new_node
        else:
            current = self.head
            while current.next:
                current = current.next
            current.next = new_node
        self.tracer.capture(self, description=f"Appended {value}")

Step 3: Implement the Visualization Class

class LinkedListVisualizer(DataStructureVisualizer):
    def __init__(self, tracer):
        super().__init__(tracer)
        self.node_spacing = 1.0  # Horizontal spacing between nodes

    def _convert_to_digraph(self, linked_list):
        """Convert linked list to NetworkX graph for visualization"""
        G = nx.DiGraph()
        current = linked_list.head
        node_id = 0

        while current:
            G.add_node(node_id, value=current.value)
            if current.next:
                G.add_edge(node_id, node_id + 1)
            current = current.next
            node_id += 1

        return G

    def display_snapshot(self, step=-1, figsize=(10, 4), show_code=True):
        data, metadata = self.tracer.get_snapshot(step)
        fig, main_ax, code_ax = self._create_figure_with_code(figsize, show_code)

        if not data.head:
            main_ax.text(0.5, 0.5, "Empty List", ha='center', va='center')
        else:
            G = self._convert_to_digraph(data)
            pos = self._calculate_layout(G)
            self._draw_nodes(main_ax, G, pos)
            self._draw_edges(main_ax, G, pos)

        fig.suptitle(metadata.get('description', f"Step {metadata['step']}"))
        if show_code:
            self._display_code(code_ax, metadata)

        plt.show()

Step 4: Use the Visualization

# Create and populate the linked list
ll = LinkedList()
ll.append(10)
ll.append(20)
ll.append(30)

# Visualize
visualizer = LinkedListVisualizer(ll.tracer)
visualizer.display_snapshot(show_code=True)
visualizer.create_animation(interval=1500).save("list_evolution.gif")

🎨 Customization Options

1️⃣ Highlighting Specific Nodes

def display_snapshot(self, step=-1, highlight_nodes=None, ...):
    # In drawing code:
    if highlight_nodes and node.value in highlight_nodes:
        circle.set_fc('#ff7f7f')  # Change color

2️⃣ Adding Metadata for Better Insights

self.tracer.capture(self, custom_code_line="ll.insert_at(index, value)",
                   algorithm_step="Insertion")

3️⃣ Customizing Layouts

def _calculate_layout(self, G):
    """Vertical layout example"""
    pos = {}
    y = 0
    for node in nx.topological_sort(G):
        pos[node] = (0, y)
        y -= self.node_spacing
    return pos

🔥 Best Practices

✅ Always capture the initial and final states of the data structure. ✅ Call reset() when processing multiple sequences to free up memory. ✅ Ensure valid state transitions before visualization. ✅ Optimize animations by precomputing layouts. ✅ Maintain a consistent color scheme and styling.


🌟 Advanced Features

📌 Composite Visualizations

Combine multiple data structures in a single visualization:

class MultiStructureVisualizer(DataStructureVisualizer):
    def display_snapshot(self, step=-1):
        fig, (ax1, ax2) = plt.subplots(1, 2)
        # Draw stack on ax1, queue on ax2

This lets you analyze interactions between different structures in the same run.

📌 Auto Tracer : Automatically trace function execution

Combine multiple data structures in a single visualization:

# Initialize components
tracer = DataStructureTracer(track_code_lines=True)

# Binary tree node class
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

@tracer.auto_trace
def tree_operations():
    root = TreeNode(1)
    root.left = TreeNode(2)
    root.right = TreeNode(3)
    root.left.right = TreeNode(4)

🎯 Conclusion

This library makes it easy to see your algorithms in action. Whether you’re debugging, teaching, or just curious, visualization makes concepts more intuitive.

🚀 Try it out, tweak it, and make your algorithms come to life!

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

algofresco-0.0.0.tar.gz (14.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

algofresco-0.0.0-py3-none-any.whl (17.7 kB view details)

Uploaded Python 3

File details

Details for the file algofresco-0.0.0.tar.gz.

File metadata

  • Download URL: algofresco-0.0.0.tar.gz
  • Upload date:
  • Size: 14.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.9.21

File hashes

Hashes for algofresco-0.0.0.tar.gz
Algorithm Hash digest
SHA256 4a55c29a319e70267036068ab81984a12d27b08334f95c7fb45cc13c74a7385a
MD5 c3de6ff721a615a16dd4ad8441d8a167
BLAKE2b-256 eac8529edf10ce108f5d1b3206c692efe5dfaa9acbffd9a640a8dbdf3192dc5e

See more details on using hashes here.

File details

Details for the file algofresco-0.0.0-py3-none-any.whl.

File metadata

  • Download URL: algofresco-0.0.0-py3-none-any.whl
  • Upload date:
  • Size: 17.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.9.21

File hashes

Hashes for algofresco-0.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5559f87e5b45822f9733a68ae71416ae0ce816bdb74c62250e059dff7cc17162
MD5 e845ddcafea2676a39c27f35aa0ffc97
BLAKE2b-256 ae5b8523a98cb83dbf5ad61238d43dc361e52aad4572c3586bf8d22d15e1bbc1

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page