spnch/Binary_Code_Visualization
2
1# AI Disclaimer:2# For parts of this project the help from AI (such as ChatGPT) 3# were used for debugging, explanations, and code4# formatting. All final decisions, logic, structure, and testing5# were done by me, and I fully understand how the program works.6 7import gradio as gr8import random9 10# Helper Function: Check if sorted11 12def is_sorted(arr):13 return all(arr[i] <= arr[i + 1] for i in range(len(arr) - 1))14 15# Visualization Helper: Create HTML boxes for each element16 17def visualize_array(arr, left, right, mid):18 """19 Returns an HTML string that visually displays the array.20 This function builds HTML <span> boxes with inline CSS.21 22 - Orange box = middle index23 - Blue box = active search range (low..right)24 - Grey box = excluded elements25 """26 27 html_parts = []28 29 for i, val in enumerate(arr):30 31 # HTML BOX FOR MIDDLE ELEMENT (explanation of every step of the code line)32 # <span> creates a small box with inline CSS.33 # - display:inline-block → makes it behave like a box34 # - width/height → sets size35 # - background-color:#FFA500 → orange color36 # - line-height:40px → vertically centers text37 # - font-weight:bold → makes number bold38 39 if i == mid:40 html_parts.append(f'<span style="display:inline-block; width:40px; height:40px; line-height:40px; '41 f'text-align:center; background-color:#FFA500; color:white; margin:2px; ' f'border-radius:4px; font-weight:bold;">{val}</span>')42 43 # HTML BOX FOR ACTIVE SEARCH RANGE (left → right)44 # - Light blue color (#ADD8E6)45 # - Same styling as above but without bold or orange46 47 elif left<= i <= right:48 html_parts.append(f'<span style="display:inline-block; width:40px; height:40px; line-height:40px; '49 f'text-align:center; background-color:#ADD8E6; color:black; margin:2px; ' f'border-radius:4px;">{val}</span>')50 51 # HTML BOX FOR EXCLUDED ELEMENTS52 # - Grey color (#E0E0E0)53 # - Slightly faded text (#888)54 55 else:56 html_parts.append(f'<span style="display:inline-block; width:40px; height:40px; line-height:40px; ' 57 f'text-align:center; background-color:#E0E0E0; color:#888; margin:2px; ' f'border-radius:4px;">{val}</span>')58 59 # Join all HTML <span> boxes together into one string60 return "".join(html_parts)61 62# Create a random sorted list of unique numbers 63def generate_random_list(size):64 nums = random.sample(range(1,100),size)65 nums.sort()66 return ",".join(str(n)for n in nums)67 68# Binary Search Logic + Step by Step Visualization69 70def binary_search_visualizer(array_str: str, target_str: str):71 72 try: 73 target = int(target_str)74 arr = array_str.split(",")75 arr = [int(x.strip()) for x in arr]76 77 except ValueError:78 return "Error: Please make sure all values are integers.", "", "", ""79 80 # Check if the list is empty81 if arr == []:82 return "Error: The list cannot be empty.", "", "", ""83 84 # Make sure the list is sorted85 if not is_sorted(arr):86 return "Error: The list must already be sorted from smallest to biggest.", "", "", ""87 88 # Binary search setup89 left = 090 right = len(arr) - 191 steps_html = [] 92 found = False93 found_index = -194 comparisons = 095 step_num = 196 97 # Binary search loop98 while left <= right:99 mid = (left + right) // 2100 comparisons += 1101 102 # HTML visual representation of current step103 viz_html = visualize_array(arr, left, right, mid)104 105 # This next part of the code creates a styled HTML <div> containing:106 # - Step number107 # - Explanation text108 # - The array visualization HTML109 #110 # <div> is used because:111 # - Makes each step look like a separate box112 #113 # border-left:3px solid #4CAF50 → Green line that is simply used for decoration114 115 step_html = f"""116 <div style="margin-bottom:20px; padding:10px; border-left:3px solid #4CAF50;"> <strong>Step {step_num}:</strong> Checking index {mid} → value {arr[mid]}<br> 117 118 Target = {target} → { "Found!" if arr[mid] == target else "Too small → search right" if arr[mid] < target else "Too large → search left" }119 <div style="margin-top:10px;">{viz_html}</div> </div> """120 121 steps_html.append(step_html)122 123 # Binary search logic124 if arr[mid] == target:125 found = True126 found_index = mid127 break128 elif arr[mid] < target:129 left = mid + 1130 else:131 right = mid - 1132 133 step_num += 1134 135 # Final result message136 result_msg = (f"✅ Target {target} found at index {found_index}." if found else f"❌ Target {target} not found in the list.")137 138 139 # FINAL VISUALIZATION140 # Using same HTML <span> boxes but rightlighting the final target141 142 final_viz = (143 visualize_array(arr, -1, -1, found_index) if found144 else visualize_array(arr, 0, -1, -1))145 146 # HTML wrapper <div> to center the final visualization147 148 final_display = f'<div style="text-align:center; margin-top:10px;">{final_viz}</div>'149 150 return result_msg, final_display, "".join(steps_html), str(comparisons)151 152 153# Gradio Interface154with gr.Blocks(title="Binary Search Visualizer") as demo:155 156 # Page title + short description157 gr.Markdown("# 🔍 Binary Search Visualizer")158 with gr.Accordion("Learn More About Binary Search", open=False):159 gr.Markdown("""160 About Binary Search:161 Binary Search is an efficient algorithm that works only on **sorted lists**. 162 It repeatedly checks the **middle value** and cuts the serch space in half 163 until the target is found or the range of the list becomes empty.164 """)165 gr.Markdown("Enter a sorted **list of integers, separated by commas**, and see binary search visualized!")166 167 # Slider that lets the user choose a number for a random sorted list 168 with gr.Row():169 random_size = gr.Slider(170 minimum = 5,171 maximum = 30,172 step = 1,173 value = 10,174 label = "Random List Size"175 )176 random_btn = gr.Button("Generate Random Sorted List")177 178 # This row groups the two textboxes side-by-side179 with gr.Row():180 array_input = gr.Textbox(label="Sorted List (comma-separated)", placeholder="e.g., 1,3,5,7,9,11,13,15")181 target_input = gr.Textbox(label="Target Value", placeholder="e.g., 7")182 183 run_btn = gr.Button("🔍 Run Binary Search")184 185 result_output = gr.Textbox(label="Result", interactive=False)186 comparisons_output = gr.Textbox(label="Number of Comparisons", interactive=False)187 final_array_display = gr.HTML(label="Final Array State") 188 steps_display = gr.HTML(label="Step-by-Step Visualization") 189 190 191 #Connects the button to the generate_random_list function so it runs when clicked192 random_btn.click(fn=lambda size: generate_random_list(size), inputs=[random_size],outputs=[array_input])193 194 # Connect the button to the binary_search_visualizer function so it runs when clicked195 run_btn.click(fn=binary_search_visualizer, inputs=[array_input, target_input], outputs=[result_output, final_array_display, steps_display, comparisons_output])196 197 # Color legend (HTML elements explaining colors)198 gr.Markdown("""199 ### 🎨 Color Legend200 - <span style="display:inline-block; width:20px; height:20px; background-color:#FFA500;"></span> Middle element 201 - <span style="display:inline-block; width:20px; height:20px; background-color:#ADD8E6;"></span> Active search range 202 - <span style="display:inline-block; width:20px; height:20px; background-color:#E0E0E0;"></span> Excluded 203 """)204 205# This launches the app when the file is run206if __name__ == "__main__":207 demo.launch()208 