Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Linear Search Visualizer using PyQt5
Understanding data structures and algorithms is essential for any prospective programmer because they are the foundation of computer science. Visualizing these concepts can significantly aid understanding. This article demonstrates how to create a linear search visualizer using Python's PyQt5 library with step-by-step animation of the search process.
Introduction to PyQt5
PyQt5 is a comprehensive set of Python bindings for Qt libraries that enables building complex and feature-rich GUI applications. It is highly versatile and works across various operating systems, making it ideal for creating interactive visualizations.
Understanding Linear Search
Linear search is a straightforward algorithm for finding a specific element in a list or array. It starts at the beginning of the array and sequentially checks each element until it finds the target or reaches the end of the array. The time complexity is O(n) in the worst case.
Setting Up PyQt5
First, ensure PyQt5 is installed in your Python environment ?
pip install pyqt5
Building the Linear Search Visualizer
Example 1: Creating the Basic Window
Let's start by creating a simple window using PyQt5. This code creates an application with a window titled "Linear Search Visualizer" ?
import sys
from PyQt5 import QtWidgets, QtGui, QtCore
class LinearSearchVisualizer(QtWidgets.QWidget):
def __init__(self):
super().__init__()
# Set window properties
self.setWindowTitle('Linear Search Visualizer')
self.setGeometry(100, 100, 800, 400)
# Initialize array and search parameters
self.array = [50, 70, 30, 90, 60, 10, 40, 20, 80]
self.target = 60
self.current_index = -1
self.found = False
self.searching = False
# Create application instance
app = QtWidgets.QApplication(sys.argv)
visualizer = LinearSearchVisualizer()
visualizer.show()
sys.exit(app.exec_())
Example 2: Drawing the Array Representation
Now we'll add visual representation using rectangles. Each rectangle's height represents the value it contains ?
import sys
from PyQt5 import QtWidgets, QtGui, QtCore
class LinearSearchVisualizer(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('Linear Search Visualizer')
self.setGeometry(100, 100, 800, 400)
# Initialize array and search parameters
self.array = [50, 70, 30, 90, 60, 10, 40, 20, 80]
self.target = 60
self.current_index = -1
self.found = False
self.searching = False
def paintEvent(self, event):
painter = QtGui.QPainter()
painter.begin(self)
# Set background
painter.fillRect(self.rect(), QtGui.QColor(240, 240, 240))
# Draw array elements
bar_width = 60
bar_spacing = 70
start_x = 50
base_y = 300
for i in range(len(self.array)):
x = start_x + i * bar_spacing
height = self.array[i] * 2
# Choose color based on search state
if i == self.current_index:
if self.found:
painter.setBrush(QtGui.QColor(0, 255, 0)) # Green for found
else:
painter.setBrush(QtGui.QColor(255, 0, 0)) # Red for current
else:
painter.setBrush(QtGui.QColor(100, 150, 200)) # Blue for normal
# Draw rectangle
painter.drawRect(x, base_y - height, bar_width, height)
# Draw value text
painter.setPen(QtGui.QColor(0, 0, 0))
painter.drawText(x + 20, base_y + 20, str(self.array[i]))
# Draw target information
painter.setPen(QtGui.QColor(0, 0, 0))
painter.drawText(50, 50, f"Target: {self.target}")
if self.found:
painter.drawText(50, 70, f"Found at index: {self.current_index}")
elif self.searching:
painter.drawText(50, 70, f"Checking index: {self.current_index}")
painter.end()
# Create application instance
app = QtWidgets.QApplication(sys.argv)
visualizer = LinearSearchVisualizer()
visualizer.show()
sys.exit(app.exec_())
Example 3: Adding Animation and Search Logic
This example adds the complete linear search animation with timer-based progression ?
import sys
from PyQt5 import QtWidgets, QtGui, QtCore
class LinearSearchVisualizer(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('Linear Search Visualizer')
self.setGeometry(100, 100, 800, 500)
# Initialize array and search parameters
self.array = [50, 70, 30, 90, 60, 10, 40, 20, 80]
self.target = 60
self.current_index = -1
self.found = False
self.searching = False
# Create start button
self.start_button = QtWidgets.QPushButton('Start Search', self)
self.start_button.setGeometry(50, 350, 100, 30)
self.start_button.clicked.connect(self.start_search)
# Create reset button
self.reset_button = QtWidgets.QPushButton('Reset', self)
self.reset_button.setGeometry(160, 350, 100, 30)
self.reset_button.clicked.connect(self.reset_search)
# Timer for animation
self.timer = QtCore.QTimer()
self.timer.timeout.connect(self.advance_search)
def paintEvent(self, event):
painter = QtGui.QPainter()
painter.begin(self)
# Set background
painter.fillRect(self.rect(), QtGui.QColor(240, 240, 240))
# Draw array elements
bar_width = 60
bar_spacing = 70
start_x = 50
base_y = 300
for i in range(len(self.array)):
x = start_x + i * bar_spacing
height = self.array[i] * 2
# Choose color based on search state
if i == self.current_index:
if self.found:
painter.setBrush(QtGui.QColor(0, 255, 0)) # Green for found
else:
painter.setBrush(QtGui.QColor(255, 0, 0)) # Red for current
elif self.searching and i < self.current_index:
painter.setBrush(QtGui.QColor(150, 150, 150)) # Gray for checked
else:
painter.setBrush(QtGui.QColor(100, 150, 200)) # Blue for normal
# Draw rectangle
painter.drawRect(x, base_y - height, bar_width, height)
# Draw value text
painter.setPen(QtGui.QColor(0, 0, 0))
painter.drawText(x + 20, base_y + 20, str(self.array[i]))
# Draw target information
painter.setPen(QtGui.QColor(0, 0, 0))
painter.drawText(50, 50, f"Target: {self.target}")
if self.found:
painter.drawText(50, 70, f"Found at index: {self.current_index}")
elif self.searching and self.current_index >= 0:
painter.drawText(50, 70, f"Checking index: {self.current_index}")
elif self.searching:
painter.drawText(50, 70, "Search completed - Target not found")
painter.end()
def start_search(self):
self.searching = True
self.current_index = 0
self.found = False
self.start_button.setEnabled(False)
self.timer.start(1000) # 1 second interval
def advance_search(self):
if self.current_index < len(self.array):
# Check if current element matches target
if self.array[self.current_index] == self.target:
self.found = True
self.timer.stop()
self.start_button.setEnabled(True)
else:
self.current_index += 1
if self.current_index >= len(self.array):
# Search completed, target not found
self.timer.stop()
self.start_button.setEnabled(True)
self.current_index = -1
# Trigger repaint
self.update()
def reset_search(self):
self.timer.stop()
self.searching = False
self.current_index = -1
self.found = False
self.start_button.setEnabled(True)
self.update()
# Create application instance
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
visualizer = LinearSearchVisualizer()
visualizer.show()
sys.exit(app.exec_())
Key Features of the Visualizer
Color Coding: Blue rectangles represent unvisited elements, red shows the currently checked element, green indicates the found target, and gray marks previously checked elements.
Interactive Controls: Start and Reset buttons allow users to control the animation and repeat the visualization multiple times.
Real-time Updates: The QTimer creates smooth animation by updating the display every second, making the search process easy to follow.
Conclusion
This linear search visualizer demonstrates how PyQt5 can effectively illustrate algorithmic concepts through interactive graphics. The step-by-step animation helps users understand how linear search systematically examines each element until finding the target or exhausting all possibilities.
---