aeori/insertionsorter
0
1import gradio as gr2import matplotlib.pyplot as plt3import time4import copy5 6 7def visual_array(array, highlighted_index=-1, comparison_index=-1, insertion_highlight=-1, title=""):8 9 # Used to generate the visual aspect (bar chart) using Matplotlib for the current state of the array,10 # highlighting the key and comparison elements11 12 fig, ax = plt.subplots(figsize=(8, 4))13 14 # normal color for bars set to light gray15 colors = ['lightgray'] * len(array)16 17 # Highlights the current considered element (key)18 if highlighted_index != -1 and 0 <= highlighted_index < len(array):19 colors[highlighted_index] = 'green' # Key = green20 21 # Highlights the current comparison element22 if comparison_index != -1 and 0 <= comparison_index < len(array):23 # Comparison element (array[j]) = red24 colors[comparison_index] = 'red'25 26 # Highlights the current considered insertion position27 # Also checks to make sure the index is valid and insertion cant go out of bounds28 if insertion_highlight != -1 and 0 <= insertion_highlight < len(array):29 # Insertion position = skyblue30 colors[insertion_highlight] = 'skyblue'31 32 # Code here ensures that the highlighted and comparison colors have priority over the insertion highlight33 if highlighted_index != -1 and 0 <= highlighted_index < len(array):34 colors[highlighted_index] = 'green'35 if comparison_index != -1 and 0 <= comparison_index < len(array):36 colors[comparison_index] = 'red'37 38 bars = ax.bar(range(len(array)), array, color=colors)39 40 # Adds value labels to the top of each bar41 for i, bar in enumerate(bars):42 ax.text(bar.get_x() + bar.get_width() / 2, bar.get_height(), # Used Gemini to help with this line (other two lines I wrote myself)43 str(array[i]), ha='center', va='bottom')44 45 # Creates the background labels and title for the plot46 ax.set_title(title, fontsize=14)47 ax.set_xticks(range(len(array)))48 ax.set_xticklabels([str(x) for x in array])49 ax.set_xlabel("Array Index")50 ax.set_ylabel("Value")51 ax.set_ylim(0, max(array) * 1.2 if array else 1)52 53 # Returns the figure54 return fig55 56 57def insertion_sort_visualizer(input_string, step_delay=0.5):58 59 # Visual aspect of insertion sort through yielding a plot and changing status after each step of the sort60 61 # Initial check for valid integer array62 try:63 array = [int(num) for num in input_string.split()]64 except ValueError:65 # Return error message and an empty plot/message state66 yield None, "Invalid input. Please enter only integers separated by spaces (e.g., '5 2 4 6 1')."67 return68 69 # Initial check for empty array70 n = len(array)71 if n == 0:72 yield None, "The array is empty. Please enter some numbers."73 return74 75 # Initial state yield76 yield visual_array(array, title="Initial Array State"), f"Initial Array: {array}"77 time.sleep(step_delay)78 79 # Makes a copy for better visual changes80 current_array = copy.deepcopy(array)81 82 # Start of the actual insertion sort code83 for i in range(1, n):84 key = current_array[i]85 j = i - 186 87 insertion_highlight = i88 # Visualize before starting shifts, highlighting the key, comparison, and considered insertion position89 yield visual_array(current_array, highlighted_index=i, comparison_index=j, insertion_highlight=insertion_highlight, title=f"Step {i}: Key is {key}"), \90 f"**Step {i}**: Key element (green): **{key}**\nCurrent Insertion spot (skyblue): '{current_array[insertion_highlight]}'\nComparing with (red): `{current_array[j]}`"91 time.sleep(step_delay)92 93 # While loop for shifting94 while j >= 0 and current_array[j] > key:95 # Shift operation96 current_array[j+1] = current_array[j]97 insertion_highlight = j # Update insertion highlight to the current j98 j -= 199 100 # Plot after each shift, still highlighting the original key position and the new comparison101 next_j = j if j >= 0 else -1102 103 # Shows the new insertion spot and index104 yield visual_array(current_array, highlighted_index=i, comparison_index=next_j, insertion_highlight=insertion_highlight, title=f"Shifting `{current_array[j+2]}` to the right"), \105 f"Shifting `{current_array[j+2]}` right. New insertion spot (skyblue) is index {insertion_highlight}"106 time.sleep(step_delay)107 108 # Insertion operation109 current_array[j+1] = key110 111 # Plot after insertion (show the new sorted portion, and current array state)112 yield visual_array(current_array, highlighted_index=j+1, title=f"Key {key} Inserted. Array State: {current_array}"), \113 f"Key **{key}** inserted at index {j+1}.\nSorted portion size: {i+1}"114 time.sleep(step_delay)115 116 # Final state yield117 yield visual_array(current_array, title="Final Sorted Array"), f"**FINISH**\nSorted Array: {current_array}"118 119 120# Gradio Setup121# One output for the plot and one for the text log122iface = gr.Interface(123 fn=insertion_sort_visualizer,124 inputs=[125 gr.Textbox(126 lines=1,127 placeholder="Enter numbers separated by spaces (e.g., 8 5 3 1 9 4)",128 label="Input Array"129 ),130 gr.Slider(131 minimum=0.1,132 maximum=2.0,133 step=0.1,134 value=0.5,135 label="Step Delay (seconds)"136 )137 ],138 outputs=[139 # The output component for Matplotlib figures140 gr.Plot(label="Insertion Sort Animation"),141 gr.Markdown(label="Step-by-Step Log")142 ],143 title="Insertion Sort Visualizer (Animated)",144 description="Enter a list of numbers to see the process of Insertion Sort step-by-step using a live bar chart. Note: The animation speed is controlled by the Step Delay slider.",145 live=False146)147 148# Launches the app!149iface.launch(share=False)150 