CoolFace
Apppublic

Rennie44/Sorting-Algorithm-Visualization

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
app.py162 linesDownload Raw Back to root
1import gradio as gr2import time3import random4 5from algorithms.bubble_sort import bubble_sort_steps6from algorithms.insertion_sort import insertion_sort_steps7from algorithms.selection_sort import selection_sort_steps8from algorithms.binary_search import binary_search_steps9 10from utils.visualizer import render_single_step_html11 12# -------------------------------------------------------13# PAUSE / RESUME CONTROLLER14# -------------------------------------------------------15is_paused = False16 17def pause_sort():18    global is_paused19    is_paused = True20 21def resume_sort():22    global is_paused23    is_paused = False24 25# -------------------------------------------------------26# Helper: parse comma-separated array27# -------------------------------------------------------28def parse_array(text: str):29    if not text:30        raise ValueError("Input array is empty.")31    parts = [p.strip() for p in text.split(",")]32    arr = []33    for p in parts:34        if p == "":35            continue36        try:37            arr.append(float(p) if "." in p else int(p))38        except:39            raise ValueError(f"Invalid number: {p}")40    if len(arr) == 0:41        raise ValueError("No valid numbers found.")42    return arr43 44def generate_random_array(n):45    return [random.randint(1, 99) for _ in range(n)]46 47# -------------------------------------------------------48# Generator for streaming (REAL-TIME updates)49# -------------------------------------------------------50def stream_sort(algo, array_text, speed_ms, search_target, use_random, random_size):51    global is_paused52    is_paused = False53 54    # Get array (random or user input)55    if use_random:56        arr = generate_random_array(random_size)57    else:58        try:59            arr = parse_array(array_text)60        except Exception as e:61            yield f"<div style='color:red;'>Error: {e}</div>"62            return63 64    delay = speed_ms / 1000.065 66    # Choose algorithm67    if algo == "Bubble Sort":68        steps = bubble_sort_steps(arr)69    elif algo == "Insertion Sort":70        steps = insertion_sort_steps(arr)71    elif algo == "Selection Sort":72        steps = selection_sort_steps(arr)73    elif algo == "Binary Search":74        if search_target is None:75            yield "<div style='color:red;'>Binary Search needs a target.</div>"76            return77        arr_sorted = sorted(arr)78        steps = binary_search_steps(arr_sorted, search_target)79    else:80        yield "<div style='color:red;'>Unknown algorithm.</div>"81        return82 83    # Stream steps84    for i, step in enumerate(steps):85        while is_paused:86            time.sleep(0.05)87        yield render_single_step_html(step, i)88        time.sleep(delay)89 90# -------------------------------------------------------91# GRADIO UI (NO DARK THEME)92# -------------------------------------------------------93with gr.Blocks(title="Sorting/Searching Visualization") as demo:94 95    gr.Markdown("# ๐Ÿ” Algorithm Visualizer (Real-Time + Adjustable Speed)")96    gr.Markdown("Choose an algorithm, enter an array, and watch it animate step by step.")97 98    with gr.Row():99        algo_dd = gr.Dropdown(100            label="Algorithm",101            choices=["Bubble Sort", "Insertion Sort", "Selection Sort", "Binary Search"],102            value="Bubble Sort"103        )104        use_random = gr.Checkbox(label="Use random array", value=False)105        random_size = gr.Slider(label="Random array size", minimum=3, maximum=50, step=1, value=10)106        array_input = gr.Textbox(107            label="Input Array",108            value="8, 3, 7, 4, 9, 1",109            interactive=True110        )111        speed = gr.Slider(112            label="Speed (ms per step)",113            minimum=10,114            maximum=1500,115            step=10,116            value=300117        )118 119    search_target = gr.Number(120        label="Binary Search Target",121        value=4,122        interactive=True,123        visible=False124    )125 126    # Auto-update the array textbox when random mode or size changes127    def update_array(use_random_val, size, current_value):128        if use_random_val:129            arr = generate_random_array(size)130            return gr.update(value=", ".join(str(x) for x in arr))131        return gr.update(value=current_value)132 133    use_random.change(update_array, inputs=[use_random, random_size, array_input], outputs=[array_input])134    random_size.change(update_array, inputs=[use_random, random_size, array_input], outputs=[array_input])135 136    # Toggle visibility for binary search target137    def toggle_target(algo_value):138        return gr.update(visible=(algo_value == "Binary Search"))139 140    algo_dd.change(toggle_target, inputs=[algo_dd], outputs=[search_target])141 142    run_btn = gr.Button("Run Visualization")143 144    with gr.Row():145        pause_btn = gr.Button("Pause")146        resume_btn = gr.Button("Resume")147 148    pause_btn.click(pause_sort, inputs=None, outputs=None)149    resume_btn.click(resume_sort, inputs=None, outputs=None)150 151    output = gr.HTML(label="Visualization")152 153    run_btn.click(154        stream_sort,155        inputs=[algo_dd, array_input, speed, search_target, use_random, random_size],156        outputs=[output]157    )158 159# Launch (Spaces auto-selects port)160if __name__ == "__main__":161    demo.launch(server_name="0.0.0.0", server_port=None)162